diff --git a/bash_completion.d/aptly b/bash_completion.d/aptly index 4ed8e2c0..0d460510 100644 --- a/bash_completion.d/aptly +++ b/bash_completion.d/aptly @@ -64,7 +64,7 @@ _aptly() mirror_subcommands="create drop show list rename search update" publish_subcommands="drop list repo snapshot switch update" snapshot_subcommands="create diff drop filter list merge pull rename search show verify" - repo_subcommands="add copy create drop edit import list move remove rename search show" + repo_subcommands="add copy create drop edit import include list move remove rename search show" package_subcommands="search show" task_subcommands="run" config_subcommands="show" @@ -185,7 +185,7 @@ _aptly() "search") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-with-deps" -- ${cur})) + COMPREPLY=($(compgen -W "-format= -with-deps" -- ${cur})) else COMPREPLY=($(compgen -W "$(__aptly_mirror_list)" -- ${cur})) fi @@ -239,7 +239,7 @@ _aptly() return 0 ;; 1) - local files=$(find . -mindepth 1 -maxdepth 1 \( -type d -or -name \*.deb -or -name \*.dsc \) -exec basename {} \;) + local files=$(find . -mindepth 1 -maxdepth 1 \( -type d -or -name \*.deb -or -name \*.dsc -or -name \*.udeb \) -exec basename {} \;) COMPREPLY=($(compgen -W "${files}" -- ${cur})) return 0 ;; @@ -264,7 +264,7 @@ _aptly() "create") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-comment= -distribution= -component=" -- ${cur})) + COMPREPLY=($(compgen -W "-comment= -distribution= -component= -uploaders-file=" -- ${cur})) return 0 fi fi @@ -282,7 +282,7 @@ _aptly() "edit") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-comment= -distribution= -component=" -- ${cur})) + COMPREPLY=($(compgen -W "-comment= -distribution= -component= -uploaders-file=" -- ${cur})) else COMPREPLY=($(compgen -W "$(__aptly_repo_list)" -- ${cur})) fi @@ -292,7 +292,7 @@ _aptly() "search") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-with-deps" -- ${cur})) + COMPREPLY=($(compgen -W "-format= -with-deps" -- ${cur})) else COMPREPLY=($(compgen -W "$(__aptly_repo_list)" -- ${cur})) fi @@ -305,6 +305,20 @@ _aptly() return 0 fi ;; + "include") + case $numargs in + 0) + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-accept-unsigned -force-replace -ignore-signatures -keyring= -no-remove-files -repo= -uploaders-file=" -- ${cur})) + else + comptopt -o filenames 2>/dev/null + COMPREPLY=($(compgen -f -- ${cur})) + return 0 + fi + return 0 + ;; + esac + ;; "import") case $numargs in 0) @@ -446,7 +460,7 @@ _aptly() "search") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-with-deps" -- ${cur})) + COMPREPLY=($(compgen -W "-format= -with-deps" -- ${cur})) else COMPREPLY=($(compgen -W "$(__aptly_snapshot_list)" -- ${cur})) fi @@ -472,7 +486,7 @@ _aptly() "snapshot"|"repo") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-batch -force-overwrite -distribution= -component= -gpg-key= -keyring= -label= -origin= -passphrase= -passphrase-file= -secret-keyring= -skip-signing" -- ${cur})) + COMPREPLY=($(compgen -W "-batch -force-overwrite -distribution= -component= -gpg-key= -keyring= -label= -origin= -passphrase= -passphrase-file= -secret-keyring= -skip-contents -skip-signing" -- ${cur})) else if [[ "$subcmd" == "snapshot" ]]; then COMPREPLY=($(compgen -W "$(__aptly_snapshot_list)" -- ${cur})) @@ -497,7 +511,7 @@ _aptly() "update") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-batch -force-overwrite -gpg-key= -keyring= -passphrase= -passphrase-file= -secret-keyring= -skip-signing" -- ${cur})) + COMPREPLY=($(compgen -W "-batch -force-overwrite -gpg-key= -keyring= -passphrase= -passphrase-file= -secret-keyring= -skip-contents -skip-signing" -- ${cur})) else COMPREPLY=($(compgen -W "$(__aptly_published_distributions)" -- ${cur})) fi @@ -512,7 +526,7 @@ _aptly() "switch") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then - COMPREPLY=($(compgen -W "-batch -force-overwrite -component= -gpg-key= -keyring= -passphrase= -passphrase-file= -secret-keyring= -skip-signing" -- ${cur})) + COMPREPLY=($(compgen -W "-batch -force-overwrite -component= -gpg-key= -keyring= -passphrase= -passphrase-file= -secret-keyring= -skip-contents -skip-signing" -- ${cur})) else COMPREPLY=($(compgen -W "$(__aptly_published_distributions)" -- ${cur})) fi @@ -531,7 +545,11 @@ _aptly() ;; "drop") if [[ $numargs -eq 0 ]]; then - COMPREPLY=($(compgen -W "$(__aptly_published_distributions)" -- ${cur})) + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-force-drop" -- ${cur})) + else + COMPREPLY=($(compgen -W "$(__aptly_published_distributions)" -- ${cur})) + fi return 0 fi @@ -544,6 +562,14 @@ _aptly() ;; "package") case "$subcmd" in + "search") + if [[ $numargs -eq 0 ]]; then + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-format=" -- ${cur})) + fi + return 0 + fi + ;; "show") if [[ $numargs -eq 0 ]]; then if [[ "$cur" == -* ]]; then @@ -560,6 +586,12 @@ _aptly() return 0 fi ;; + "graph") + if [[ "$cur" == -* ]]; then + COMPREPLY=($(compgen -W "-format= -output=" -- ${cur})) + return 0 + fi + ;; "api") case "$subcmd" in "serve") diff --git a/src/github.com/smira/aptly/.travis.yml b/src/github.com/smira/aptly/.travis.yml index 30d2f40c..3ce97535 100644 --- a/src/github.com/smira/aptly/.travis.yml +++ b/src/github.com/smira/aptly/.travis.yml @@ -1,31 +1,36 @@ +sudo: false + language: go go: - - 1.3.3 + - 1.4 + - 1.5 - tip +addons: + apt: + packages: + - python-virtualenv + - graphviz + env: global: - secure: "YSwtFrMqh4oUvdSQTXBXMHHLWeQgyNEL23ChIZwU0nuDGIcQZ65kipu0PzefedtUbK4ieC065YCUi4UDDh6gPotB/Wu1pnYg3dyQ7rFvhaVYAAUEpajAdXZhlx+7+J8a4FZMeC/kqiahxoRgLbthF9019ouIqhGB9zHKI6/yZwc=" - secure: "V7OjWrfQ8UbktgT036jYQPb/7GJT3Ol9LObDr8FYlzsQ+F1uj2wLac6ePuxcOS4FwWOJinWGM1h+JiFkbxbyFqfRNJ0jj0O2p93QyDojxFVOn1mXqqvV66KFqAWR2Vzkny/gDvj8LTvdB1cgAIm2FNOkQc6E1BFnyWS2sN9ea5E=" - secure: "OxiVNmre2JzUszwPNNilKDgIqtfX2gnRSsVz6nuySB1uO2yQsOQmKWJ9cVYgH2IB5H8eWXKOhexcSE28kz6TPLRuEcU9fnqKY3uEkdwm7rJfz9lf+7C4bJEUdA1OIzJppjnWUiXxD7CEPL1DlnMZM24eDQYqa/4WKACAgkK53gE=" before_install: - - sudo apt-get update -qq - - sudo apt-get install -y python-virtualenv graphviz - virtualenv env - . env/bin/activate - pip install boto requests python-swiftclient install: - make prepare - script: make travis matrix: allow_failures: - go: tip - notifications: webhooks: urls: diff --git a/src/github.com/smira/aptly/AUTHORS b/src/github.com/smira/aptly/AUTHORS index 2769f327..3d7f29ae 100644 --- a/src/github.com/smira/aptly/AUTHORS +++ b/src/github.com/smira/aptly/AUTHORS @@ -15,3 +15,7 @@ List of contributors, in chronological order: * Michael Koval (https://github.com/mkoval) * Alexander Guy (https://github.com/alexanderguy) * Sebastien Badia (https://github.com/sbadia) +* Szymon Sobik (https://github.com/sobczyk) +* Paul Krohn (https://github.com/paul-krohn) +* Vincent Bernat (https://github.com/vincentbernat) +* x539 (https://github.com/x539) diff --git a/src/github.com/smira/aptly/Gomfile b/src/github.com/smira/aptly/Gomfile index 7ef20532..d044cae3 100644 --- a/src/github.com/smira/aptly/Gomfile +++ b/src/github.com/smira/aptly/Gomfile @@ -1,21 +1,23 @@ -gom 'code.google.com/p/go-uuid/uuid', :commit => '5fac954758f5' -gom 'code.google.com/p/gographviz', :commit => '454bc64fdfa2' -gom 'code.google.com/p/mxk/go1/flowcontrol', :commit => '5ff2502e2556' -gom 'code.google.com/p/snappy-go/snappy', :commit => '12e4b4183793' gom 'github.com/AlekSi/pointer', :commit => '5f6d527dae3d678b46fbb20331ddf44e2b841943' +gom 'github.com/awalterschulze/gographviz', :commit => '20d1f693416d9be045340150094aa42035a41c9e' gom 'github.com/cheggaaa/pb', :commit => '2c1b74620cc58a81ac152ee2d322e28c806d81ed' +gom 'github.com/DisposaBoy/JsonConfigReader', :commit => '33a99fdf1d5ee1f79b5077e9c06f955ad356d5f4' gom 'github.com/gin-gonic/gin', :commit => 'b1758d3bfa09e61ddbc1c9a627e936eec6a170de' gom 'github.com/jlaffaye/ftp', :commit => 'fec71e62e457557fbe85cefc847a048d57815d76' gom 'github.com/julienschmidt/httprouter', :commit => '46807412fe50aaceb73bb57061c2230fd26a1640' gom 'github.com/mattn/go-shellwords', :commit => 'c7ca6f94add751566a61cf2199e1de78d4c3eee4' -gom 'github.com/mitchellh/goamz/s3', :commit => 'e7664b32019f31fd1bdf33f9e85f28722f700405' -gom 'github.com/mkrautz/goar', :commit => '36eb5f3452b1283a211fa35bc00c646fd0db5c4b' +gom 'github.com/mitchellh/goamz/s3', :commit => 'caaaea8b30ee15616494ee68abd5d8ebbbef05cf' +gom 'github.com/mkrautz/goar', :commit => '282caa8bd9daba480b51f1d5a988714913b97aad' +gom 'github.com/mxk/go-flowrate/flowrate', :commit => 'cca7078d478f8520f85629ad7c68962d31ed7682' gom 'github.com/ncw/swift', :commit => '384ef27c70645e285f8bb9d02276bf654d06027e' +gom 'github.com/smira/go-xz', :commit => '0c531f070014e218b21f3cfca801cc992d52726d' gom 'github.com/smira/commander', :commit => 'f408b00e68d5d6e21b9f18bd310978dafc604e47' gom 'github.com/smira/flag', :commit => '357ed3e599ffcbd4aeaa828e1d10da2df3ea5107' gom 'github.com/smira/go-ftp-protocol/protocol', :commit => '066b75c2b70dca7ae10b1b88b47534a3c31ccfaa' -gom 'github.com/syndtr/gosnappy/snappy', :commit => 'ce8acff4829e0c2458a67ead32390ac0a381c862' -gom 'github.com/syndtr/goleveldb/leveldb', :commit => '97e257099d2ab9578151ba85e2641e2cd14d3ca8' +gom 'github.com/smira/go-uuid/uuid', :commit => 'ed3ca8a15a931b141440a7e98e4f716eec255f7d' +gom 'github.com/smira/lzma', :commit => '2a7c55cad4a2d02ab972a03357db5760833a49bc' +gom 'github.com/golang/snappy', :commit => '723cc1e459b8eea2dea4583200fd60757d40097a' +gom 'github.com/syndtr/goleveldb/leveldb', :commit => '1a9d62f03ea92815b46fcaab357cfd4df264b1a0' gom 'github.com/ugorji/go/codec', :commit => '71c2886f5a673a35f909803f38ece5810165097b' gom 'github.com/vaughan0/go-ini', :commit => 'a98ad7ee00ec53921f08832bc06ecf7fd600e6a1' gom 'github.com/wsxiaoys/terminal/color', :commit => '5668e431776a7957528361f90ce828266c69ed08' diff --git a/src/github.com/smira/aptly/LICENSE b/src/github.com/smira/aptly/LICENSE index aeb91a2c..ba83ce30 100644 --- a/src/github.com/smira/aptly/LICENSE +++ b/src/github.com/smira/aptly/LICENSE @@ -1,4 +1,4 @@ -Copyright 2013-2014 Andrey Smirnov. All rights reserved. +Copyright 2013-2015 aptly authors. All rights reserved. MIT License diff --git a/src/github.com/smira/aptly/Makefile b/src/github.com/smira/aptly/Makefile index a4c224aa..69067384 100644 --- a/src/github.com/smira/aptly/Makefile +++ b/src/github.com/smira/aptly/Makefile @@ -67,7 +67,8 @@ package: (cd root/etc/bash_completion.d && wget https://raw.github.com/aptly-dev/aptly-bash-completion/master/aptly) gzip root/usr/share/man/man1/aptly.1 fpm -s dir -t deb -n aptly -v $(VERSION) --url=http://www.aptly.info/ --license=MIT --vendor="Andrey Smirnov " \ - -f -m "Andrey Smirnov " --description="Debian repository management tool" --deb-recommends bzip2 --deb-recommends graphviz -C root/ . + -f -m "Andrey Smirnov " --description="Debian repository management tool" --deb-recommends bzip2 \ + --deb-recommends graphviz --deb-recommends xz-utils -C root/ . mv aptly_$(VERSION)_*.deb ~ src-package: diff --git a/src/github.com/smira/aptly/README.rst b/src/github.com/smira/aptly/README.rst index 14c17046..c5c7b07f 100644 --- a/src/github.com/smira/aptly/README.rst +++ b/src/github.com/smira/aptly/README.rst @@ -64,7 +64,7 @@ If you would like to use nightly builds (unstable), please use following reposit Binary executables (depends almost only on libc) are available for download from `Bintray `_. -If you have Go environment set up, you can build aptly from source by running (go 1.3+ required):: +If you have Go environment set up, you can build aptly from source by running (go 1.4+ required):: go get -u github.com/mattn/gom mkdir -p $GOPATH/src/github.com/smira/aptly @@ -78,4 +78,29 @@ should work as well, but might fail or produce different result (if external lib If you don't have Go installed (or older version), you can easily install Go using `gvm `_. +Integrations +------------ +Vagrant: + +- `Vagrant configuration `_ by + Zane Williamson, allowing to bring two virtual servers, one with aptly installed + and another one set up to install packages from repository published by aptly + +Docker: + +- `Docker container `_ with aptly inside by Mike Purvis + +With configuration management systems: + +- `Chef cookbook `_ by Aaron Baer + (Heavy Water Operations, LLC) +- `Puppet module `_ by + Government Digital Services +- `SaltStack Formula `_ by + Forrest Alvarez and Brian Jackson +- `Ansible role `_ by Tom Paine + +CLI for aptly API: + +- `Ruby aptly CLI/library `_ by Zane Williamson diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/pbkdf2.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/pbkdf2.go deleted file mode 100644 index eafac862..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/pbkdf2.go +++ /dev/null @@ -1,219 +0,0 @@ -// -// Written by Maxim Khitrov (October 2012) -// - -/* -Package pbkdf2 provides an incremental version of the PBKDF2 key derivation -algorithm, as described in RFC 2898. - -Password-Based Key Derivation Function 2 derives cryptographic keys of a -specified length from the provided password and salt values. The derivation is -performed by a CPU-bound loop, with the iteration count specified as one of the -function parameters. The higher the iteration count, the more difficult (time -consuming) it is for an attacker to brute-force the password/salt combination. - -An incremental PBKDF2 implementation allows the key derivation loop to resume -execution from its previous state. This allows the user to derive keys after -1000 and 2000 iterations, for example, without having to recompute the first -1000 iterations twice. The package uses this feature to implement time-based key -derivation functions (see Derive and Search methods), which gradually increment -the iteration count until the time limit is reached. -*/ -package pbkdf2 - -import ( - "crypto/hmac" - "errors" - "hash" - "runtime" - "time" -) - -// precision determines the timing accuracy of Derive and Search methods by -// varying the exponential growth rate of the iteration count. The derivation -// begins with 1024 iterations and the count is incremented exponentially at the -// rate of 1/(2^precision). The minimum precision is 0 (100% growth rate) and -// the maximum is 10 (0.1% growth rate). The theoretical timing error is plus or -// minus timelimit*rate/(rate+2). -// -// A higher precision results in more accurate timing, but at the expense of -// having to make many additional calls to the callback function when searching -// for a previously derived key. A precision of 4 (6.25%) is a good compromise, -// which covers 2^32 iterations in 252 steps with a timing error of 3%. -const precision = 4 - -// KeyFound is returned by the PBKDF2.Search callback function to indicate that -// the correct key was found. -var KeyFound = errors.New("pbkdf2: key found") - -// ErrTimeout is returned by PBKDF2.Search when a valid key is not found in the -// allocated time. -var ErrTimeout = errors.New("pbkdf2: key search timeout") - -// Key derives a key from the password, salt, and iteration count, returning a -// []byte of length dkLen that can be used as cryptographic key. This function -// provides compatibility with the go.crypto/pbkdf2 package. -func Key(pass, salt []byte, iter, dkLen int, h func() hash.Hash) []byte { - return New(pass, salt, dkLen, h).Next(iter) -} - -type PBKDF2 struct { - prf hash.Hash // HMAC - dkLen int // Key length returned by key derivation methods - salt []byte // Salt value used in the first iteration - t []byte // Current T values (len >= dkLen, multiple of prf.Size()) - u []byte // Current U values (same len as t) - iters int // Current iteration count -} - -// New returns a new PBKDF2 state initialized to zero iterations. -func New(pass, salt []byte, dkLen int, h func() hash.Hash) *PBKDF2 { - return &PBKDF2{prf: hmac.New(h, pass), dkLen: dkLen, salt: dup(salt)} -} - -// Derive derives a new key in time d. -func (kdf *PBKDF2) Derive(d time.Duration) []byte { - dk, _ := kdf.derive(d, precision, func([]byte) error { return nil }) - return dk -} - -// Search tries to find a previously derived key. The callback function f is -// used to test the current key after each step in the derivation process. This -// test must be reasonably fast to maintain accurate derivation timing. The -// search stops when f returns a non-nil error or the time limit is reached. The -// correct key is found when f returns KeyFound. -// -// As a general rule, Search should be given more time than Derive, especially -// if the two operations are being performed on different computers. If Derive -// was given 1 second, a reasonable limit for Search is 3 to 5 seconds. -func (kdf *PBKDF2) Search(d time.Duration, f func(dk []byte) error) (dk []byte, err error) { - if dk, err = kdf.derive(d, precision, f); err == KeyFound { - err = nil - } else { - dk = nil - if err == nil { - err = ErrTimeout - } - } - return -} - -// Next runs the key derivation algorithm for c additional iterations and -// returns a copy of the new key. -func (kdf *PBKDF2) Next(c int) []byte { - if c <= 0 { - panic("pbkdf2: invalid iteration count") - } - prf := kdf.prf - hLen := prf.Size() - - if kdf.iters == 0 { - n := (kdf.dkLen + hLen - 1) / hLen - t := make([]byte, 0, 2*n*hLen) - for i := 1; i <= n; i++ { - prf.Reset() - prf.Write(kdf.salt) - prf.Write([]byte{byte(i >> 24), byte(i >> 16), byte(i >> 8), byte(i)}) - t = prf.Sum(t) - } - kdf.t, kdf.u = t, t[len(t):cap(t)] - copy(kdf.u, kdf.t) - c-- - kdf.iters = 1 - } - - t, u := kdf.t, kdf.u - for i := 0; i < c; i++ { - for j := 0; j < len(u); j += hLen { - prf.Reset() - prf.Write(u[j : j+hLen]) - prf.Sum(u[:j]) - } - for j, v := range u { - t[j] ^= v - } - } - kdf.iters += c - return dup(t[:kdf.dkLen]) -} - -// Salt returns a copy of the current salt value. -func (kdf *PBKDF2) Salt() []byte { - return dup(kdf.salt) -} - -// Size returns the derived key size. -func (kdf *PBKDF2) Size() int { - return kdf.dkLen -} - -// Iters returns the total number of iterations performed so far. -func (kdf *PBKDF2) Iters() int { - return kdf.iters -} - -// Reset returns kdf to the initial state at zero iterations. Salt and dkLen -// parameters for subsequent iterations can be changed by passing non-nil and -// non-zero values, respectively. -func (kdf *PBKDF2) Reset(salt []byte, dkLen int) { - if dkLen > 0 { - kdf.dkLen = dkLen - } - if salt != nil { - kdf.salt = dup(salt) - } - kdf.t = nil - kdf.u = nil - kdf.iters = 0 -} - -// derive performs time-based key derivation. -func (kdf *PBKDF2) derive(d time.Duration, p uint, f func(dk []byte) error) (dk []byte, err error) { - if p > 10 { - panic("pbkdf2: invalid derivation precision") - } - kdf.Reset(nil, 0) - ch := make(chan struct{}) - go func() { - defer close(ch) - runtime.LockOSThread() - r := 1.0 / float64(uint(1)<> p) - } - }() - <-ch - return -} - -type timer struct { - wall time.Time - user time.Duration -} - -// elapsed returns true when time d has elapsed from the point when the timer -// was created. Timing is done according to the user CPU time of the current -// thread with the wall clock time acting as a backup. Systems that don't -// provide per-thread timing information use the process CPU time instead. The -// wall clock time defines lower (d) and upper (2*d) limits as a workaround for -// inaccurate CPU time accounting on some systems (e.g. Windows). -func (t *timer) elapsed(d time.Duration) bool { - wall := time.Since(t.wall) - emin := wall >= d - if emin && wall < d<<1 { - return utime()-t.user >= d - } - return emin -} - -func dup(b []byte) []byte { - t := make([]byte, len(b)) - copy(t, b) - return t -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/pbkdf2_test.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/pbkdf2_test.go deleted file mode 100644 index 9fd52bd8..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/pbkdf2_test.go +++ /dev/null @@ -1,85 +0,0 @@ -// -// Written by Maxim Khitrov (October 2012) -// - -package pbkdf2 - -import ( - "bytes" - "crypto/sha1" - "crypto/sha256" - "fmt" - "testing" - "time" -) - -func TestRFC6070(t *testing.T) { - tests := []struct { - P, S string - c []int - dkLen int - out string - }{ - {"password", "salt", []int{1}, 20, - "0c 60 c8 0f 96 1f 0e 71 f3 a9 b5 24 af 60 12 06 2f e0 37 a6"}, - {"password", "salt", []int{2}, 20, - "ea 6c 01 4d c7 2d 6f 8c cd 1e d9 2a ce 1d 41 f0 d8 de 89 57"}, - {"password", "salt", []int{1, 1}, 20, - "ea 6c 01 4d c7 2d 6f 8c cd 1e d9 2a ce 1d 41 f0 d8 de 89 57"}, - {"password", "salt", []int{4096}, 20, - "4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1"}, - {"password", "salt", []int{1, 4095}, 20, - "4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1"}, - {"password", "salt", []int{2048, 2048}, 20, - "4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1"}, - {"password", "salt", []int{4095, 1}, 20, - "4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1"}, - {"password", "salt", []int{1, 4094, 1}, 20, - "4b 00 79 01 b7 65 48 9a be ad 49 d9 26 f7 21 d0 65 a4 29 c1"}, - //{"password", "salt", []int{16777216}, 20, - // "ee fe 3d 61 cd 4d a4 e4 e9 94 5b 3d 6b a2 15 8c 26 34 e9 84"}, - {"passwordPASSWORDpassword", "saltSALTsaltSALTsaltSALTsaltSALTsalt", []int{4096}, 25, - "3d 2e ec 4f e4 1c 84 9b 80 c8 d8 36 62 c0 e4 4a 8b 29 1a 96 4c f2 f0 70 38"}, - {"pass\x00word", "sa\x00lt", []int{4096}, 16, - "56 fa 6a a7 55 48 09 9d cc 37 d7 f0 34 25 e0 c3"}, - } - var dk []byte - for _, test := range tests { - kdf := New([]byte(test.P), []byte(test.S), test.dkLen, sha1.New) - for _, c := range test.c { - dk = kdf.Next(c) - } - if out := fmt.Sprintf("% x", dk); out != test.out { - t.Errorf("kdf.Next() expected %q; got %q", test.out, out) - } - } -} - -func TestKeyGen(t *testing.T) { - kdf := New([]byte("pass"), []byte("salt"), 10, sha256.New) - key := kdf.Derive(100 * time.Millisecond) - itr := kdf.Iters() - - tryKey := func(dk []byte) error { - if bytes.Equal(dk, key) { - return KeyFound - } - return nil - } - - d := 10 * time.Millisecond - dk, err := kdf.Search(d, tryKey) - if dk != nil || err != ErrTimeout { - t.Errorf("kdf.Search(%v) expected ErrTimeout; got % x (%v)", d, dk, err) - } - - d = 200 * time.Millisecond - dk, err = kdf.Search(d, tryKey) - if !bytes.Equal(dk, key) || err != nil { - t.Errorf("kdf.Search(%v) expected % x; got % x (%v)", d, key, dk, err) - } - - if kdf.Iters() != itr { - t.Errorf("kdf.Iters() expected %v; got %v", itr, kdf.Iters()) - } -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_unix_proc.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_unix_proc.go deleted file mode 100644 index c88126ae..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_unix_proc.go +++ /dev/null @@ -1,20 +0,0 @@ -// -// Written by Maxim Khitrov (October 2012) -// - -// +build !freebsd,!linux,!windows - -package pbkdf2 - -import ( - "syscall" - "time" -) - -func utime() time.Duration { - var u syscall.Rusage - if err := syscall.Getrusage(syscall.RUSAGE_SELF, &u); err != nil { - panic(err) - } - return time.Duration(u.Utime.Nano()) -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_unix_thread.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_unix_thread.go deleted file mode 100644 index e9b0030f..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_unix_thread.go +++ /dev/null @@ -1,29 +0,0 @@ -// -// Written by Maxim Khitrov (October 2012) -// - -// +build freebsd linux - -package pbkdf2 - -import ( - "syscall" - "time" -) - -var getrusage_who = syscall.RUSAGE_THREAD - -func init() { - var u syscall.Rusage - if syscall.Getrusage(getrusage_who, &u) == syscall.EINVAL { - getrusage_who = syscall.RUSAGE_SELF - } -} - -func utime() time.Duration { - var u syscall.Rusage - if err := syscall.Getrusage(getrusage_who, &u); err != nil { - panic(err) - } - return time.Duration(u.Utime.Nano()) -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_windows.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_windows.go deleted file mode 100644 index 3451c98d..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/pbkdf2/time_windows.go +++ /dev/null @@ -1,64 +0,0 @@ -// -// Written by Maxim Khitrov (October 2012) -// - -package pbkdf2 - -import ( - "syscall" - "time" - "unsafe" -) - -/* -Note: GetThreadTimes function may return inaccurate values when the calling -thread is frequently interrupted prior to consuming all of its quantum. This -shouldn't be a huge problem for PBKDF2 calculation since it doesn't enter any -wait states, but some additional testing in high-load situations is needed. - -http://blog.kalmbachnet.de/?postid=28 -http://www.tech-archive.net/Archive/Development/microsoft.public.win32.programmer.kernel/2004-10/0689.html -*/ - -var ( - modkernel32 = syscall.MustLoadDLL("kernel32.dll") - - procGetCurrentThread = modkernel32.MustFindProc("GetCurrentThread") - procGetThreadTimes = modkernel32.MustFindProc("GetThreadTimes") -) - -func utime() time.Duration { - var u syscall.Rusage - h, _ := getCurrentThread() - err := getThreadTimes(h, &u.CreationTime, &u.ExitTime, &u.KernelTime, &u.UserTime) - if err != nil { - panic(err) - } - t := uint64(u.UserTime.HighDateTime)<<32 | uint64(u.UserTime.LowDateTime) - return time.Duration(t * 100) -} - -func getCurrentThread() (pseudoHandle syscall.Handle, err error) { - r0, _, e1 := syscall.Syscall(procGetCurrentThread.Addr(), 0, 0, 0, 0) - pseudoHandle = syscall.Handle(r0) - if pseudoHandle == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} - -func getThreadTimes(handle syscall.Handle, creationTime, exitTime, kernelTime, userTime *syscall.Filetime) (err error) { - r1, _, e1 := syscall.Syscall6(procGetThreadTimes.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(creationTime)), uintptr(unsafe.Pointer(exitTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime)), 0) - if int(r1) == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/alert.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/alert.go deleted file mode 100644 index b48ab2a2..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/alert.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2009 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 main - -import "strconv" - -type alert uint8 - -const ( - // alert level - alertLevelWarning = 1 - alertLevelError = 2 -) - -const ( - alertCloseNotify alert = 0 - alertUnexpectedMessage alert = 10 - alertBadRecordMAC alert = 20 - alertDecryptionFailed alert = 21 - alertRecordOverflow alert = 22 - alertDecompressionFailure alert = 30 - alertHandshakeFailure alert = 40 - alertBadCertificate alert = 42 - alertUnsupportedCertificate alert = 43 - alertCertificateRevoked alert = 44 - alertCertificateExpired alert = 45 - alertCertificateUnknown alert = 46 - alertIllegalParameter alert = 47 - alertUnknownCA alert = 48 - alertAccessDenied alert = 49 - alertDecodeError alert = 50 - alertDecryptError alert = 51 - alertProtocolVersion alert = 70 - alertInsufficientSecurity alert = 71 - alertInternalError alert = 80 - alertUserCanceled alert = 90 - alertNoRenegotiation alert = 100 -) - -var alertText = map[alert]string{ - alertCloseNotify: "close notify", - alertUnexpectedMessage: "unexpected message", - alertBadRecordMAC: "bad record MAC", - alertDecryptionFailed: "decryption failed", - alertRecordOverflow: "record overflow", - alertDecompressionFailure: "decompression failure", - alertHandshakeFailure: "handshake failure", - alertBadCertificate: "bad certificate", - alertUnsupportedCertificate: "unsupported certificate", - alertCertificateRevoked: "revoked certificate", - alertCertificateExpired: "expired certificate", - alertCertificateUnknown: "unknown certificate", - alertIllegalParameter: "illegal parameter", - alertUnknownCA: "unknown certificate authority", - alertAccessDenied: "access denied", - alertDecodeError: "error decoding message", - alertDecryptError: "error decrypting message", - alertProtocolVersion: "protocol version not supported", - alertInsufficientSecurity: "insufficient security level", - alertInternalError: "internal error", - alertUserCanceled: "user canceled", - alertNoRenegotiation: "no renegotiation", -} - -func (e alert) String() string { - s, ok := alertText[e] - if ok { - return s - } - return "alert(" + strconv.Itoa(int(e)) + ")" -} - -func (e alert) Error() string { - return e.String() -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/cipher_suites.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/cipher_suites.go deleted file mode 100644 index 7c8135aa..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/cipher_suites.go +++ /dev/null @@ -1,270 +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 main - -import ( - "crypto/aes" - "crypto/cipher" - "crypto/des" - "crypto/hmac" - "crypto/rc4" - "crypto/sha1" - "crypto/x509" - "hash" -) - -// a keyAgreement implements the client and server side of a TLS key agreement -// protocol by generating and processing key exchange messages. -type keyAgreement interface { - // On the server side, the first two methods are called in order. - - // In the case that the key agreement protocol doesn't use a - // ServerKeyExchange message, generateServerKeyExchange can return nil, - // nil. - generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error) - processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error) - - // On the client side, the next two methods are called in order. - - // This method may not be called if the server doesn't send a - // ServerKeyExchange message. - processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error - generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) -} - -const ( - // suiteECDH indicates that the cipher suite involves elliptic curve - // Diffie-Hellman. This means that it should only be selected when the - // client indicates that it supports ECC with a curve and point format - // that we're happy with. - suiteECDHE = 1 << iota - // suiteECDSA indicates that the cipher suite involves an ECDSA - // signature and therefore may only be selected when the server's - // certificate is ECDSA. If this is not set then the cipher suite is - // RSA based. - suiteECDSA - // suiteTLS12 indicates that the cipher suite should only be advertised - // and accepted when using TLS 1.2. - suiteTLS12 -) - -// A cipherSuite is a specific combination of key agreement, cipher and MAC -// function. All cipher suites currently assume RSA key agreement. -type cipherSuite struct { - id uint16 - // the lengths, in bytes, of the key material needed for each component. - keyLen int - macLen int - ivLen int - ka func(version uint16) keyAgreement - // flags is a bitmask of the suite* values, above. - flags int - cipher func(key, iv []byte, isRead bool) interface{} - mac func(version uint16, macKey []byte) macFunction - aead func(key, fixedNonce []byte) cipher.AEAD -} - -var cipherSuites = []*cipherSuite{ - // Ciphersuite order is chosen so that ECDHE comes before plain RSA - // and RC4 comes before AES (because of the Lucky13 attack). - {TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheRSAKA, suiteECDHE | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12, nil, nil, aeadAESGCM}, - {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, suiteECDHE, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherRC4, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil}, - {TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, 0, cipherRC4, macSHA1, nil}, - {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, 0, cipherAES, macSHA1, nil}, - {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil}, - {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil}, -} - -func cipherRC4(key, iv []byte, isRead bool) interface{} { - cipher, _ := rc4.NewCipher(key) - return cipher -} - -func cipher3DES(key, iv []byte, isRead bool) interface{} { - block, _ := des.NewTripleDESCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -func cipherAES(key, iv []byte, isRead bool) interface{} { - block, _ := aes.NewCipher(key) - if isRead { - return cipher.NewCBCDecrypter(block, iv) - } - return cipher.NewCBCEncrypter(block, iv) -} - -// macSHA1 returns a macFunction for the given protocol version. -func macSHA1(version uint16, key []byte) macFunction { - if version == VersionSSL30 { - mac := ssl30MAC{ - h: sha1.New(), - key: make([]byte, len(key)), - } - copy(mac.key, key) - return mac - } - return tls10MAC{hmac.New(sha1.New, key)} -} - -type macFunction interface { - Size() int - MAC(digestBuf, seq, header, data []byte) []byte -} - -// fixedNonceAEAD wraps an AEAD and prefixes a fixed portion of the nonce to -// each call. -type fixedNonceAEAD struct { - // sealNonce and openNonce are buffers where the larger nonce will be - // constructed. Since a seal and open operation may be running - // concurrently, there is a separate buffer for each. - sealNonce, openNonce []byte - aead cipher.AEAD -} - -func (f *fixedNonceAEAD) NonceSize() int { return 8 } -func (f *fixedNonceAEAD) Overhead() int { return f.aead.Overhead() } - -func (f *fixedNonceAEAD) Seal(out, nonce, plaintext, additionalData []byte) []byte { - copy(f.sealNonce[len(f.sealNonce)-8:], nonce) - return f.aead.Seal(out, f.sealNonce, plaintext, additionalData) -} - -func (f *fixedNonceAEAD) Open(out, nonce, plaintext, additionalData []byte) ([]byte, error) { - copy(f.openNonce[len(f.openNonce)-8:], nonce) - return f.aead.Open(out, f.openNonce, plaintext, additionalData) -} - -func aeadAESGCM(key, fixedNonce []byte) cipher.AEAD { - aes, err := aes.NewCipher(key) - if err != nil { - panic(err) - } - aead, err := cipher.NewGCM(aes) - if err != nil { - panic(err) - } - - nonce1, nonce2 := make([]byte, 12), make([]byte, 12) - copy(nonce1, fixedNonce) - copy(nonce2, fixedNonce) - - return &fixedNonceAEAD{nonce1, nonce2, aead} -} - -// ssl30MAC implements the SSLv3 MAC function, as defined in -// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1 -type ssl30MAC struct { - h hash.Hash - key []byte -} - -func (s ssl30MAC) Size() int { - return s.h.Size() -} - -var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36} - -var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c} - -func (s ssl30MAC) MAC(digestBuf, seq, header, data []byte) []byte { - padLength := 48 - if s.h.Size() == 20 { - padLength = 40 - } - - s.h.Reset() - s.h.Write(s.key) - s.h.Write(ssl30Pad1[:padLength]) - s.h.Write(seq) - s.h.Write(header[:1]) - s.h.Write(header[3:5]) - s.h.Write(data) - digestBuf = s.h.Sum(digestBuf[:0]) - - s.h.Reset() - s.h.Write(s.key) - s.h.Write(ssl30Pad2[:padLength]) - s.h.Write(digestBuf) - return s.h.Sum(digestBuf[:0]) -} - -// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3. -type tls10MAC struct { - h hash.Hash -} - -func (s tls10MAC) Size() int { - return s.h.Size() -} - -func (s tls10MAC) MAC(digestBuf, seq, header, data []byte) []byte { - s.h.Reset() - s.h.Write(seq) - s.h.Write(header) - s.h.Write(data) - return s.h.Sum(digestBuf[:0]) -} - -func rsaKA(version uint16) keyAgreement { - return rsaKeyAgreement{} -} - -func ecdheECDSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - sigType: signatureECDSA, - version: version, - } -} - -func ecdheRSAKA(version uint16) keyAgreement { - return &ecdheKeyAgreement{ - sigType: signatureRSA, - version: version, - } -} - -// mutualCipherSuite returns a cipherSuite given a list of supported -// ciphersuites and the id requested by the peer. -func mutualCipherSuite(have []uint16, want uint16) *cipherSuite { - for _, id := range have { - if id == want { - for _, suite := range cipherSuites { - if suite.id == want { - return suite - } - } - return nil - } - } - return nil -} - -// A list of the possible cipher suite ids. Taken from -// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml -const ( - TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005 - TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a - TLS_RSA_WITH_AES_128_CBC_SHA uint16 = 0x002f - TLS_RSA_WITH_AES_256_CBC_SHA uint16 = 0x0035 - TLS_ECDHE_ECDSA_WITH_RC4_128_SHA uint16 = 0xc007 - TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA uint16 = 0xc009 - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA uint16 = 0xc00a - TLS_ECDHE_RSA_WITH_RC4_128_SHA uint16 = 0xc011 - TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012 - TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA uint16 = 0xc013 - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA uint16 = 0xc014 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02f - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 uint16 = 0xc02b -) diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/common.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/common.go deleted file mode 100644 index f43bb1ec..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/common.go +++ /dev/null @@ -1,437 +0,0 @@ -// Copyright 2009 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 main - -import ( - "crypto" - "crypto/rand" - "crypto/x509" - "io" - "math/big" - "strings" - "sync" - "time" -) - -const ( - VersionSSL30 = 0x0300 - VersionTLS10 = 0x0301 - VersionTLS11 = 0x0302 - VersionTLS12 = 0x0303 -) - -const ( - maxPlaintext = 16384 // maximum plaintext payload length - maxCiphertext = 16384 + 2048 // maximum ciphertext payload length - recordHeaderLen = 5 // record header length - maxHandshake = 65536 // maximum handshake we support (protocol max is 16 MB) - - minVersion = VersionSSL30 - maxVersion = VersionTLS12 -) - -// TLS record types. -type recordType uint8 - -const ( - recordTypeChangeCipherSpec recordType = 20 - recordTypeAlert recordType = 21 - recordTypeHandshake recordType = 22 - recordTypeApplicationData recordType = 23 -) - -// TLS handshake message types. -const ( - typeClientHello uint8 = 1 - typeServerHello uint8 = 2 - typeNewSessionTicket uint8 = 4 - typeCertificate uint8 = 11 - typeServerKeyExchange uint8 = 12 - typeCertificateRequest uint8 = 13 - typeServerHelloDone uint8 = 14 - typeCertificateVerify uint8 = 15 - typeClientKeyExchange uint8 = 16 - typeFinished uint8 = 20 - typeCertificateStatus uint8 = 22 - typeNextProtocol uint8 = 67 // Not IANA assigned -) - -// TLS compression types. -const ( - compressionNone uint8 = 0 -) - -// TLS extension numbers -var ( - extensionServerName uint16 = 0 - extensionStatusRequest uint16 = 5 - extensionSupportedCurves uint16 = 10 - extensionSupportedPoints uint16 = 11 - extensionSignatureAlgorithms uint16 = 13 - extensionSessionTicket uint16 = 35 - extensionNextProtoNeg uint16 = 13172 // not IANA assigned -) - -// TLS Elliptic Curves -// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-8 -var ( - curveP256 uint16 = 23 - curveP384 uint16 = 24 - curveP521 uint16 = 25 -) - -// TLS Elliptic Curve Point Formats -// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml#tls-parameters-9 -var ( - pointFormatUncompressed uint8 = 0 -) - -// TLS CertificateStatusType (RFC 3546) -const ( - statusTypeOCSP uint8 = 1 -) - -// Certificate types (for certificateRequestMsg) -const ( - certTypeRSASign = 1 // A certificate containing an RSA key - certTypeDSSSign = 2 // A certificate containing a DSA key - certTypeRSAFixedDH = 3 // A certificate containing a static DH key - certTypeDSSFixedDH = 4 // A certificate containing a static DH key - - // See RFC4492 sections 3 and 5.5. - certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. - certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. - certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. - - // Rest of these are reserved by the TLS spec -) - -// Hash functions for TLS 1.2 (See RFC 5246, section A.4.1) -const ( - hashSHA1 uint8 = 2 - hashSHA256 uint8 = 4 -) - -// Signature algorithms for TLS 1.2 (See RFC 5246, section A.4.1) -const ( - signatureRSA uint8 = 1 - signatureECDSA uint8 = 3 -) - -// signatureAndHash mirrors the TLS 1.2, SignatureAndHashAlgorithm struct. See -// RFC 5246, section A.4.1. -type signatureAndHash struct { - hash, signature uint8 -} - -// supportedSKXSignatureAlgorithms contains the signature and hash algorithms -// that the code advertises as supported in a TLS 1.2 ClientHello. -var supportedSKXSignatureAlgorithms = []signatureAndHash{ - {hashSHA256, signatureRSA}, - {hashSHA256, signatureECDSA}, - {hashSHA1, signatureRSA}, - {hashSHA1, signatureECDSA}, -} - -// supportedClientCertSignatureAlgorithms contains the signature and hash -// algorithms that the code advertises as supported in a TLS 1.2 -// CertificateRequest. -var supportedClientCertSignatureAlgorithms = []signatureAndHash{ - {hashSHA256, signatureRSA}, - {hashSHA256, signatureECDSA}, -} - -// ConnectionState records basic TLS details about the connection. -type ConnectionState struct { - HandshakeComplete bool // TLS handshake is complete - DidResume bool // connection resumes a previous TLS connection - CipherSuite uint16 // cipher suite in use (TLS_RSA_WITH_RC4_128_SHA, ...) - NegotiatedProtocol string // negotiated next protocol (from Config.NextProtos) - NegotiatedProtocolIsMutual bool // negotiated protocol was advertised by server - ServerName string // server name requested by client, if any (server side only) - PeerCertificates []*x509.Certificate // certificate chain presented by remote peer - VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates -} - -// ClientAuthType declares the policy the server will follow for -// TLS Client Authentication. -type ClientAuthType int - -const ( - NoClientCert ClientAuthType = iota - RequestClientCert - RequireAnyClientCert - VerifyClientCertIfGiven - RequireAndVerifyClientCert -) - -// A Config structure is used to configure a TLS client or server. After one -// has been passed to a TLS function it must not be modified. -type Config struct { - // Rand provides the source of entropy for nonces and RSA blinding. - // If Rand is nil, TLS uses the cryptographic random reader in package - // crypto/rand. - Rand io.Reader - - // Time returns the current time as the number of seconds since the epoch. - // If Time is nil, TLS uses time.Now. - Time func() time.Time - - // Certificates contains one or more certificate chains - // to present to the other side of the connection. - // Server configurations must include at least one certificate. - Certificates []Certificate - - // NameToCertificate maps from a certificate name to an element of - // Certificates. Note that a certificate name can be of the form - // '*.example.com' and so doesn't have to be a domain name as such. - // See Config.BuildNameToCertificate - // The nil value causes the first element of Certificates to be used - // for all connections. - NameToCertificate map[string]*Certificate - - // RootCAs defines the set of root certificate authorities - // that clients use when verifying server certificates. - // If RootCAs is nil, TLS uses the host's root CA set. - RootCAs *x509.CertPool - - // NextProtos is a list of supported, application level protocols. - NextProtos []string - - // ServerName is included in the client's handshake to support virtual - // hosting. - ServerName string - - // ClientAuth determines the server's policy for - // TLS Client Authentication. The default is NoClientCert. - ClientAuth ClientAuthType - - // ClientCAs defines the set of root certificate authorities - // that servers use if required to verify a client certificate - // by the policy in ClientAuth. - ClientCAs *x509.CertPool - - // InsecureSkipVerify controls whether a client verifies the - // server's certificate chain and host name. - // If InsecureSkipVerify is true, TLS accepts any certificate - // presented by the server and any host name in that certificate. - // In this mode, TLS is susceptible to man-in-the-middle attacks. - // This should be used only for testing. - InsecureSkipVerify bool - - // CipherSuites is a list of supported cipher suites. If CipherSuites - // is nil, TLS uses a list of suites supported by the implementation. - CipherSuites []uint16 - - // PreferServerCipherSuites controls whether the server selects the - // client's most preferred ciphersuite, or the server's most preferred - // ciphersuite. If true then the server's preference, as expressed in - // the order of elements in CipherSuites, is used. - PreferServerCipherSuites bool - - // SessionTicketsDisabled may be set to true to disable session ticket - // (resumption) support. - SessionTicketsDisabled bool - - // SessionTicketKey is used by TLS servers to provide session - // resumption. See RFC 5077. If zero, it will be filled with - // random data before the first server handshake. - // - // If multiple servers are terminating connections for the same host - // they should all have the same SessionTicketKey. If the - // SessionTicketKey leaks, previously recorded and future TLS - // connections using that key are compromised. - SessionTicketKey [32]byte - - // MinVersion contains the minimum SSL/TLS version that is acceptable. - // If zero, then SSLv3 is taken as the minimum. - MinVersion uint16 - - // MaxVersion contains the maximum SSL/TLS version that is acceptable. - // If zero, then the maximum version supported by this package is used, - // which is currently TLS 1.2. - MaxVersion uint16 - - serverInitOnce sync.Once // guards calling (*Config).serverInit -} - -func (c *Config) serverInit() { - if c.SessionTicketsDisabled { - return - } - - // If the key has already been set then we have nothing to do. - for _, b := range c.SessionTicketKey { - if b != 0 { - return - } - } - - if _, err := io.ReadFull(c.rand(), c.SessionTicketKey[:]); err != nil { - c.SessionTicketsDisabled = true - } -} - -func (c *Config) rand() io.Reader { - r := c.Rand - if r == nil { - return rand.Reader - } - return r -} - -func (c *Config) time() time.Time { - t := c.Time - if t == nil { - t = time.Now - } - return t() -} - -func (c *Config) cipherSuites() []uint16 { - s := c.CipherSuites - if s == nil { - s = defaultCipherSuites() - } - return s -} - -func (c *Config) minVersion() uint16 { - if c == nil || c.MinVersion == 0 { - return minVersion - } - return c.MinVersion -} - -func (c *Config) maxVersion() uint16 { - if c == nil || c.MaxVersion == 0 { - return maxVersion - } - return c.MaxVersion -} - -// mutualVersion returns the protocol version to use given the advertised -// version of the peer. -func (c *Config) mutualVersion(vers uint16) (uint16, bool) { - minVersion := c.minVersion() - maxVersion := c.maxVersion() - - if vers < minVersion { - return 0, false - } - if vers > maxVersion { - vers = maxVersion - } - return vers, true -} - -// getCertificateForName returns the best certificate for the given name, -// defaulting to the first element of c.Certificates if there are no good -// options. -func (c *Config) getCertificateForName(name string) *Certificate { - if len(c.Certificates) == 1 || c.NameToCertificate == nil { - // There's only one choice, so no point doing any work. - return &c.Certificates[0] - } - - name = strings.ToLower(name) - for len(name) > 0 && name[len(name)-1] == '.' { - name = name[:len(name)-1] - } - - if cert, ok := c.NameToCertificate[name]; ok { - return cert - } - - // try replacing labels in the name with wildcards until we get a - // match. - labels := strings.Split(name, ".") - for i := range labels { - labels[i] = "*" - candidate := strings.Join(labels, ".") - if cert, ok := c.NameToCertificate[candidate]; ok { - return cert - } - } - - // If nothing matches, return the first certificate. - return &c.Certificates[0] -} - -// BuildNameToCertificate parses c.Certificates and builds c.NameToCertificate -// from the CommonName and SubjectAlternateName fields of each of the leaf -// certificates. -func (c *Config) BuildNameToCertificate() { - c.NameToCertificate = make(map[string]*Certificate) - for i := range c.Certificates { - cert := &c.Certificates[i] - x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - continue - } - if len(x509Cert.Subject.CommonName) > 0 { - c.NameToCertificate[x509Cert.Subject.CommonName] = cert - } - for _, san := range x509Cert.DNSNames { - c.NameToCertificate[san] = cert - } - } -} - -// A Certificate is a chain of one or more certificates, leaf first. -type Certificate struct { - Certificate [][]byte - PrivateKey crypto.PrivateKey // supported types: *rsa.PrivateKey, *ecdsa.PrivateKey - // OCSPStaple contains an optional OCSP response which will be served - // to clients that request it. - OCSPStaple []byte - // Leaf is the parsed form of the leaf certificate, which may be - // initialized using x509.ParseCertificate to reduce per-handshake - // processing for TLS clients doing client authentication. If nil, the - // leaf certificate will be parsed as needed. - Leaf *x509.Certificate -} - -// A TLS record. -type record struct { - contentType recordType - major, minor uint8 - payload []byte -} - -type handshakeMessage interface { - marshal() []byte - unmarshal([]byte) bool -} - -// TODO(jsing): Make these available to both crypto/x509 and crypto/tls. -type dsaSignature struct { - R, S *big.Int -} - -type ecdsaSignature dsaSignature - -var emptyConfig Config - -func defaultConfig() *Config { - return &emptyConfig -} - -var ( - once sync.Once - varDefaultCipherSuites []uint16 -) - -func defaultCipherSuites() []uint16 { - once.Do(initDefaultCipherSuites) - return varDefaultCipherSuites -} - -func initDefaultCipherSuites() { - varDefaultCipherSuites = make([]uint16, len(cipherSuites)) - for i, suite := range cipherSuites { - varDefaultCipherSuites[i] = suite.id - } -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/conn.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/conn.go deleted file mode 100644 index 334f227b..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/conn.go +++ /dev/null @@ -1,1006 +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. - -// TLS low level connection and record layer - -package main - -import ( - "bytes" - "crypto/cipher" - "crypto/subtle" - "crypto/x509" - "errors" - "io" - "net" - "sync" - "time" -) - -// A Conn represents a secured connection. -// It implements the net.Conn interface. -type Conn struct { - // constant - conn net.Conn - isClient bool - - // constant after handshake; protected by handshakeMutex - handshakeMutex sync.Mutex // handshakeMutex < in.Mutex, out.Mutex, errMutex - vers uint16 // TLS version - haveVers bool // version has been negotiated - config *Config // configuration passed to constructor - handshakeComplete bool - didResume bool // whether this connection was a session resumption - cipherSuite uint16 - ocspResponse []byte // stapled OCSP response - peerCertificates []*x509.Certificate - // verifiedChains contains the certificate chains that we built, as - // opposed to the ones presented by the server. - verifiedChains [][]*x509.Certificate - // serverName contains the server name indicated by the client, if any. - serverName string - - clientProtocol string - clientProtocolFallback bool - - // first permanent error - connErr - - // input/output - in, out halfConn // in.Mutex < out.Mutex - rawInput *block // raw input, right off the wire - input *block // application data waiting to be read - hb *block // heartbeat data waiting to be read - hand bytes.Buffer // handshake data waiting to be read - - tmp [16]byte -} - -type connErr struct { - mu sync.Mutex - value error -} - -func (e *connErr) setError(err error) error { - e.mu.Lock() - defer e.mu.Unlock() - - if e.value == nil { - e.value = err - } - return err -} - -func (e *connErr) error() error { - e.mu.Lock() - defer e.mu.Unlock() - return e.value -} - -// Access to net.Conn methods. -// Cannot just embed net.Conn because that would -// export the struct field too. - -// 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() -} - -// SetDeadline sets the read and write deadlines associated with the connection. -// A zero value for t means Read and Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetDeadline(t time.Time) error { - return c.conn.SetDeadline(t) -} - -// SetReadDeadline sets the read deadline on the underlying connection. -// A zero value for t means Read will not time out. -func (c *Conn) SetReadDeadline(t time.Time) error { - return c.conn.SetReadDeadline(t) -} - -// SetWriteDeadline sets the write deadline on the underlying conneciton. -// A zero value for t means Write will not time out. -// After a Write has timed out, the TLS state is corrupt and all future writes will return the same error. -func (c *Conn) SetWriteDeadline(t time.Time) error { - return c.conn.SetWriteDeadline(t) -} - -// A halfConn represents one direction of the record layer -// connection, either sending or receiving. -type halfConn struct { - sync.Mutex - version uint16 // protocol version - cipher interface{} // cipher algorithm - mac macFunction - seq [8]byte // 64-bit sequence number - bfree *block // list of free blocks - - nextCipher interface{} // next encryption state - nextMac macFunction // next MAC algorithm - - // used to save allocating a new buffer for each MAC. - inDigestBuf, outDigestBuf []byte -} - -// prepareCipherSpec sets the encryption and MAC states -// that a subsequent changeCipherSpec will use. -func (hc *halfConn) prepareCipherSpec(version uint16, cipher interface{}, mac macFunction) { - hc.version = version - hc.nextCipher = cipher - hc.nextMac = mac -} - -// changeCipherSpec changes the encryption and MAC states -// to the ones previously passed to prepareCipherSpec. -func (hc *halfConn) changeCipherSpec() error { - if hc.nextCipher == nil { - return alertInternalError - } - hc.cipher = hc.nextCipher - hc.mac = hc.nextMac - hc.nextCipher = nil - hc.nextMac = nil - for i := range hc.seq { - hc.seq[i] = 0 - } - return nil -} - -// incSeq increments the sequence number. -func (hc *halfConn) incSeq() { - for i := 7; i >= 0; i-- { - hc.seq[i]++ - if hc.seq[i] != 0 { - return - } - } - - // Not allowed to let sequence number wrap. - // Instead, must renegotiate before it does. - // Not likely enough to bother. - panic("TLS: sequence number wraparound") -} - -// resetSeq resets the sequence number to zero. -func (hc *halfConn) resetSeq() { - for i := range hc.seq { - hc.seq[i] = 0 - } -} - -// removePadding returns an unpadded slice, in constant time, which is a prefix -// of the input. It also returns a byte which is equal to 255 if the padding -// was valid and 0 otherwise. See RFC 2246, section 6.2.3.2 -func removePadding(payload []byte) ([]byte, byte) { - if len(payload) < 1 { - return payload, 0 - } - - paddingLen := payload[len(payload)-1] - t := uint(len(payload)-1) - uint(paddingLen) - // if len(payload) >= (paddingLen - 1) then the MSB of t is zero - good := byte(int32(^t) >> 31) - - toCheck := 255 // the maximum possible padding length - // The length of the padded data is public, so we can use an if here - if toCheck+1 > len(payload) { - toCheck = len(payload) - 1 - } - - for i := 0; i < toCheck; i++ { - t := uint(paddingLen) - uint(i) - // if i <= paddingLen then the MSB of t is zero - mask := byte(int32(^t) >> 31) - b := payload[len(payload)-1-i] - good &^= mask&paddingLen ^ mask&b - } - - // We AND together the bits of good and replicate the result across - // all the bits. - good &= good << 4 - good &= good << 2 - good &= good << 1 - good = uint8(int8(good) >> 7) - - toRemove := good&paddingLen + 1 - return payload[:len(payload)-int(toRemove)], good -} - -// removePaddingSSL30 is a replacement for removePadding in the case that the -// protocol version is SSLv3. In this version, the contents of the padding -// are random and cannot be checked. -func removePaddingSSL30(payload []byte) ([]byte, byte) { - if len(payload) < 1 { - return payload, 0 - } - - paddingLen := int(payload[len(payload)-1]) + 1 - if paddingLen > len(payload) { - return payload, 0 - } - - return payload[:len(payload)-paddingLen], 255 -} - -func roundUp(a, b int) int { - return a + (b-a%b)%b -} - -// cbcMode is an interface for block ciphers using cipher block chaining. -type cbcMode interface { - cipher.BlockMode - SetIV([]byte) -} - -// decrypt checks and strips the mac and decrypts the data in b. Returns a -// success boolean, the number of bytes to skip from the start of the record in -// order to get the application payload, and an optional alert value. -func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert) { - // pull out payload - payload := b.data[recordHeaderLen:] - - macSize := 0 - if hc.mac != nil { - macSize = hc.mac.Size() - } - - paddingGood := byte(255) - explicitIVLen := 0 - - // decrypt - if hc.cipher != nil { - switch c := hc.cipher.(type) { - case cipher.Stream: - c.XORKeyStream(payload, payload) - case cipher.AEAD: - explicitIVLen = 8 - if len(payload) < explicitIVLen { - return false, 0, alertBadRecordMAC - } - nonce := payload[:8] - payload = payload[8:] - - var additionalData [13]byte - copy(additionalData[:], hc.seq[:]) - copy(additionalData[8:], b.data[:3]) - n := len(payload) - c.Overhead() - additionalData[11] = byte(n >> 8) - additionalData[12] = byte(n) - var err error - payload, err = c.Open(payload[:0], nonce, payload, additionalData[:]) - if err != nil { - return false, 0, alertBadRecordMAC - } - b.resize(recordHeaderLen + explicitIVLen + len(payload)) - case cbcMode: - blockSize := c.BlockSize() - if hc.version >= VersionTLS11 { - explicitIVLen = blockSize - } - - if len(payload)%blockSize != 0 || len(payload) < roundUp(explicitIVLen+macSize+1, blockSize) { - return false, 0, alertBadRecordMAC - } - - if explicitIVLen > 0 { - c.SetIV(payload[:explicitIVLen]) - payload = payload[explicitIVLen:] - } - c.CryptBlocks(payload, payload) - if hc.version == VersionSSL30 { - payload, paddingGood = removePaddingSSL30(payload) - } else { - payload, paddingGood = removePadding(payload) - } - b.resize(recordHeaderLen + explicitIVLen + len(payload)) - - // note that we still have a timing side-channel in the - // MAC check, below. An attacker can align the record - // so that a correct padding will cause one less hash - // block to be calculated. Then they can iteratively - // decrypt a record by breaking each byte. See - // "Password Interception in a SSL/TLS Channel", Brice - // Canvel et al. - // - // However, our behavior matches OpenSSL, so we leak - // only as much as they do. - default: - panic("unknown cipher type") - } - } - - // check, strip mac - if hc.mac != nil { - if len(payload) < macSize { - return false, 0, alertBadRecordMAC - } - - // strip mac off payload, b.data - n := len(payload) - macSize - b.data[3] = byte(n >> 8) - b.data[4] = byte(n) - b.resize(recordHeaderLen + explicitIVLen + n) - remoteMAC := payload[n:] - localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], payload[:n]) - - if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 { - return false, 0, alertBadRecordMAC - } - hc.inDigestBuf = localMAC - } - hc.incSeq() - - return true, recordHeaderLen + explicitIVLen, 0 -} - -// padToBlockSize calculates the needed padding block, if any, for a payload. -// On exit, prefix aliases payload and extends to the end of the last full -// block of payload. finalBlock is a fresh slice which contains the contents of -// any suffix of payload as well as the needed padding to make finalBlock a -// full block. -func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) { - overrun := len(payload) % blockSize - paddingLen := blockSize - overrun - prefix = payload[:len(payload)-overrun] - finalBlock = make([]byte, blockSize) - copy(finalBlock, payload[len(payload)-overrun:]) - for i := overrun; i < blockSize; i++ { - finalBlock[i] = byte(paddingLen - 1) - } - return -} - -// encrypt encrypts and macs the data in b. -func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) { - // mac - if hc.mac != nil { - mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:]) - - n := len(b.data) - b.resize(n + len(mac)) - copy(b.data[n:], mac) - hc.outDigestBuf = mac - } - - payload := b.data[recordHeaderLen:] - - // encrypt - if hc.cipher != nil { - switch c := hc.cipher.(type) { - case cipher.Stream: - c.XORKeyStream(payload, payload) - case cipher.AEAD: - payloadLen := len(b.data) - recordHeaderLen - explicitIVLen - b.resize(len(b.data) + c.Overhead()) - nonce := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] - payload := b.data[recordHeaderLen+explicitIVLen:] - payload = payload[:payloadLen] - - var additionalData [13]byte - copy(additionalData[:], hc.seq[:]) - copy(additionalData[8:], b.data[:3]) - additionalData[11] = byte(payloadLen >> 8) - additionalData[12] = byte(payloadLen) - - c.Seal(payload[:0], nonce, payload, additionalData[:]) - case cbcMode: - blockSize := c.BlockSize() - if explicitIVLen > 0 { - c.SetIV(payload[:explicitIVLen]) - payload = payload[explicitIVLen:] - } - prefix, finalBlock := padToBlockSize(payload, blockSize) - b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock)) - c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix) - c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock) - default: - panic("unknown cipher type") - } - } - - // update length to include MAC and any block padding needed. - n := len(b.data) - recordHeaderLen - b.data[3] = byte(n >> 8) - b.data[4] = byte(n) - hc.incSeq() - - return true, 0 -} - -// A block is a simple data buffer. -type block struct { - data []byte - off int // index for Read - link *block -} - -// resize resizes block to be n bytes, growing if necessary. -func (b *block) resize(n int) { - if n > cap(b.data) { - b.reserve(n) - } - b.data = b.data[0:n] -} - -// reserve makes sure that block contains a capacity of at least n bytes. -func (b *block) reserve(n int) { - if cap(b.data) >= n { - return - } - m := cap(b.data) - if m == 0 { - m = 1024 - } - for m < n { - m *= 2 - } - data := make([]byte, len(b.data), m) - copy(data, b.data) - b.data = data -} - -// readFromUntil reads from r into b until b contains at least n bytes -// or else returns an error. -func (b *block) readFromUntil(r io.Reader, n int) error { - // quick case - if len(b.data) >= n { - return nil - } - - // read until have enough. - b.reserve(n) - for { - m, err := r.Read(b.data[len(b.data):cap(b.data)]) - b.data = b.data[0 : len(b.data)+m] - if len(b.data) >= n { - break - } - if err != nil { - return err - } - } - return nil -} - -func (b *block) Read(p []byte) (n int, err error) { - n = copy(p, b.data[b.off:]) - b.off += n - return -} - -// newBlock allocates a new block, from hc's free list if possible. -func (hc *halfConn) newBlock() *block { - b := hc.bfree - if b == nil { - return new(block) - } - hc.bfree = b.link - b.link = nil - b.resize(0) - return b -} - -// freeBlock returns a block to hc's free list. -// The protocol is such that each side only has a block or two on -// its free list at a time, so there's no need to worry about -// trimming the list, etc. -func (hc *halfConn) freeBlock(b *block) { - b.link = hc.bfree - hc.bfree = b -} - -// splitBlock splits a block after the first n bytes, -// returning a block with those n bytes and a -// block with the remainder. the latter may be nil. -func (hc *halfConn) splitBlock(b *block, n int) (*block, *block) { - if len(b.data) <= n { - return b, nil - } - bb := hc.newBlock() - bb.resize(len(b.data) - n) - copy(bb.data, b.data[n:]) - b.data = b.data[0:n] - return b, bb -} - -// readRecord reads the next TLS record from the connection -// and updates the record layer state. -// c.in.Mutex <= L; c.input == nil. -func (c *Conn) readRecord(want recordType) error { - // Caller must be in sync with connection: - // handshake data if handshake not yet completed, - // else application data. (We don't support renegotiation.) - switch want { - default: - return c.sendAlert(alertInternalError) - case recordTypeHandshake, recordTypeChangeCipherSpec: - if c.handshakeComplete { - return c.sendAlert(alertInternalError) - } - case recordTypeApplicationData, recordTypeHeartbeat: - if !c.handshakeComplete { - return c.sendAlert(alertInternalError) - } - } - -Again: - if c.rawInput == nil { - c.rawInput = c.in.newBlock() - } - b := c.rawInput - - // Read header, payload. - if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil { - // RFC suggests that EOF without an alertCloseNotify is - // an error, but popular web sites seem to do this, - // so we can't make it an error. - // if err == io.EOF { - // err = io.ErrUnexpectedEOF - // } - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.setError(err) - } - return err - } - typ := recordType(b.data[0]) - - // No valid TLS record has a type of 0x80, however SSLv2 handshakes - // start with a uint16 length where the MSB is set and the first record - // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests - // an SSLv2 client. - if want == recordTypeHandshake && typ == 0x80 { - c.sendAlert(alertProtocolVersion) - return errors.New("tls: unsupported SSLv2 handshake received") - } - - vers := uint16(b.data[1])<<8 | uint16(b.data[2]) - n := int(b.data[3])<<8 | int(b.data[4]) - if c.haveVers && vers != c.vers { - return c.sendAlert(alertProtocolVersion) - } - if n > maxCiphertext { - return c.sendAlert(alertRecordOverflow) - } - if !c.haveVers { - // First message, be extra suspicious: - // this might not be a TLS client. - // Bail out before reading a full 'body', if possible. - // The current max version is 3.1. - // If the version is >= 16.0, it's probably not real. - // Similarly, a clientHello message encodes in - // well under a kilobyte. If the length is >= 12 kB, - // it's probably not real. - if (typ != recordTypeAlert && typ != want) || vers >= 0x1000 || n >= 0x3000 { - return c.sendAlert(alertUnexpectedMessage) - } - } - if err := b.readFromUntil(c.conn, recordHeaderLen+n); err != nil { - if err == io.EOF { - err = io.ErrUnexpectedEOF - } - if e, ok := err.(net.Error); !ok || !e.Temporary() { - c.setError(err) - } - return err - } - - // Process message. - b, c.rawInput = c.in.splitBlock(b, recordHeaderLen+n) - ok, off, err := c.in.decrypt(b) - if !ok { - return c.sendAlert(err) - } - b.off = off - data := b.data[b.off:] - if len(data) > maxPlaintext { - c.sendAlert(alertRecordOverflow) - c.in.freeBlock(b) - return c.error() - } - - switch typ { - default: - c.sendAlert(alertUnexpectedMessage) - - case recordTypeAlert: - if len(data) != 2 { - c.sendAlert(alertUnexpectedMessage) - break - } - if alert(data[1]) == alertCloseNotify { - c.setError(io.EOF) - break - } - switch data[0] { - case alertLevelWarning: - // drop on the floor - c.in.freeBlock(b) - goto Again - case alertLevelError: - c.setError(&net.OpError{Op: "remote error", Err: alert(data[1])}) - default: - c.sendAlert(alertUnexpectedMessage) - } - - case recordTypeChangeCipherSpec: - if typ != want || len(data) != 1 || data[0] != 1 { - c.sendAlert(alertUnexpectedMessage) - break - } - err := c.in.changeCipherSpec() - if err != nil { - c.sendAlert(err.(alert)) - } - - case recordTypeHeartbeat: - if typ != want { - c.sendAlert(alertUnexpectedMessage) - break - } - c.hb = b - b = nil - - case recordTypeApplicationData: - if typ != want { - c.sendAlert(alertUnexpectedMessage) - break - } - c.input = b - b = nil - - case recordTypeHandshake: - // TODO(rsc): Should at least pick off connection close. - if typ != want { - return c.sendAlert(alertNoRenegotiation) - } - c.hand.Write(data) - } - - if b != nil { - c.in.freeBlock(b) - } - return c.error() -} - -// sendAlert sends a TLS alert message. -// c.out.Mutex <= L. -func (c *Conn) sendAlertLocked(err alert) error { - switch err { - case alertNoRenegotiation, alertCloseNotify: - c.tmp[0] = alertLevelWarning - default: - c.tmp[0] = alertLevelError - } - c.tmp[1] = byte(err) - c.writeRecord(recordTypeAlert, c.tmp[0:2]) - // closeNotify is a special case in that it isn't an error: - if err != alertCloseNotify { - return c.setError(&net.OpError{Op: "local error", Err: err}) - } - return nil -} - -// sendAlert sends a TLS alert message. -// L < c.out.Mutex. -func (c *Conn) sendAlert(err alert) error { - c.out.Lock() - defer c.out.Unlock() - return c.sendAlertLocked(err) -} - -// writeRecord writes a TLS record with the given type and payload -// to the connection and updates the record layer state. -// c.out.Mutex <= L. -func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) { - b := c.out.newBlock() - for len(data) > 0 { - m := len(data) - if m > maxPlaintext { - m = maxPlaintext - } - explicitIVLen := 0 - explicitIVIsSeq := false - - var cbc cbcMode - if c.out.version >= VersionTLS11 { - var ok bool - if cbc, ok = c.out.cipher.(cbcMode); ok { - explicitIVLen = cbc.BlockSize() - } - } - if explicitIVLen == 0 { - if _, ok := c.out.cipher.(cipher.AEAD); ok { - explicitIVLen = 8 - // The AES-GCM construction in TLS has an - // explicit nonce so that the nonce can be - // random. However, the nonce is only 8 bytes - // which is too small for a secure, random - // nonce. Therefore we use the sequence number - // as the nonce. - explicitIVIsSeq = true - } - } - b.resize(recordHeaderLen + explicitIVLen + m) - b.data[0] = byte(typ) - vers := c.vers - if vers == 0 { - // Some TLS servers fail if the record version is - // greater than TLS 1.0 for the initial ClientHello. - vers = VersionTLS10 - } - b.data[1] = byte(vers >> 8) - b.data[2] = byte(vers) - b.data[3] = byte(m >> 8) - b.data[4] = byte(m) - if explicitIVLen > 0 { - explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen] - if explicitIVIsSeq { - copy(explicitIV, c.out.seq[:]) - } else { - if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil { - break - } - } - } - copy(b.data[recordHeaderLen+explicitIVLen:], data) - c.out.encrypt(b, explicitIVLen) - _, err = c.conn.Write(b.data) - if err != nil { - break - } - n += m - data = data[m:] - } - c.out.freeBlock(b) - - if typ == recordTypeChangeCipherSpec { - err = c.out.changeCipherSpec() - if err != nil { - // Cannot call sendAlert directly, - // because we already hold c.out.Mutex. - c.tmp[0] = alertLevelError - c.tmp[1] = byte(err.(alert)) - c.writeRecord(recordTypeAlert, c.tmp[0:2]) - return n, c.setError(&net.OpError{Op: "local error", Err: err}) - } - } - return -} - -// readHandshake reads the next handshake message from -// the record layer. -// c.in.Mutex < L; c.out.Mutex < L. -func (c *Conn) readHandshake() (interface{}, error) { - for c.hand.Len() < 4 { - if err := c.error(); err != nil { - return nil, err - } - if err := c.readRecord(recordTypeHandshake); err != nil { - return nil, err - } - } - - data := c.hand.Bytes() - n := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if n > maxHandshake { - c.sendAlert(alertInternalError) - return nil, c.error() - } - for c.hand.Len() < 4+n { - if err := c.error(); err != nil { - return nil, err - } - if err := c.readRecord(recordTypeHandshake); err != nil { - return nil, err - } - } - data = c.hand.Next(4 + n) - var m handshakeMessage - switch data[0] { - case typeClientHello: - m = new(clientHelloMsg) - case typeServerHello: - m = new(serverHelloMsg) - case typeCertificate: - m = new(certificateMsg) - case typeCertificateRequest: - m = &certificateRequestMsg{ - hasSignatureAndHash: c.vers >= VersionTLS12, - } - case typeCertificateStatus: - m = new(certificateStatusMsg) - case typeServerKeyExchange: - m = new(serverKeyExchangeMsg) - case typeServerHelloDone: - m = new(serverHelloDoneMsg) - case typeClientKeyExchange: - m = new(clientKeyExchangeMsg) - case typeCertificateVerify: - m = &certificateVerifyMsg{ - hasSignatureAndHash: c.vers >= VersionTLS12, - } - case typeNextProtocol: - m = new(nextProtoMsg) - case typeFinished: - m = new(finishedMsg) - default: - c.sendAlert(alertUnexpectedMessage) - return nil, alertUnexpectedMessage - } - - // The handshake message unmarshallers - // expect to be able to keep references to data, - // so pass in a fresh copy that won't be overwritten. - data = append([]byte(nil), data...) - - if !m.unmarshal(data) { - c.sendAlert(alertUnexpectedMessage) - return nil, alertUnexpectedMessage - } - return m, nil -} - -// Write writes data to the connection. -func (c *Conn) Write(b []byte) (int, error) { - if err := c.error(); err != nil { - return 0, err - } - - if err := c.Handshake(); err != nil { - return 0, c.setError(err) - } - - c.out.Lock() - defer c.out.Unlock() - - if !c.handshakeComplete { - return 0, alertInternalError - } - - // SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext - // attack when using block mode ciphers due to predictable IVs. - // This can be prevented by splitting each Application Data - // record into two records, effectively randomizing the IV. - // - // http://www.openssl.org/~bodo/tls-cbc.txt - // https://bugzilla.mozilla.org/show_bug.cgi?id=665814 - // http://www.imperialviolet.org/2012/01/15/beastfollowup.html - - var m int - if len(b) > 1 && c.vers <= VersionTLS10 { - if _, ok := c.out.cipher.(cipher.BlockMode); ok { - n, err := c.writeRecord(recordTypeApplicationData, b[:1]) - if err != nil { - return n, c.setError(err) - } - m, b = 1, b[1:] - } - } - - n, err := c.writeRecord(recordTypeApplicationData, b) - return n + m, c.setError(err) -} - -// Read can be made to time out and return a net.Error with Timeout() == true -// after a fixed time limit; see SetDeadline and SetReadDeadline. -func (c *Conn) Read(b []byte) (n int, err error) { - if err = c.Handshake(); err != nil { - return - } - - c.in.Lock() - defer c.in.Unlock() - - // Some OpenSSL servers send empty records in order to randomize the - // CBC IV. So this loop ignores a limited number of empty records. - const maxConsecutiveEmptyRecords = 100 - for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ { - for c.input == nil && c.error() == nil { - if err := c.readRecord(recordTypeApplicationData); err != nil { - // Soft error, like EAGAIN - return 0, err - } - } - if err := c.error(); err != nil { - return 0, err - } - - n, err = c.input.Read(b) - if c.input.off >= len(c.input.data) { - c.in.freeBlock(c.input) - c.input = nil - } - - if n != 0 || err != nil { - return n, err - } - } - - return 0, io.ErrNoProgress -} - -// Close closes the connection. -func (c *Conn) Close() error { - var alertErr error - - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if c.handshakeComplete { - alertErr = c.sendAlert(alertCloseNotify) - } - - if err := c.conn.Close(); err != nil { - return err - } - return alertErr -} - -// Handshake runs the client or server handshake -// protocol if it has not yet been run. -// Most uses of this package need not call Handshake -// explicitly: the first Read or Write will call it automatically. -func (c *Conn) Handshake() error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if err := c.error(); err != nil { - return err - } - if c.handshakeComplete { - return nil - } - if c.isClient { - return c.clientHandshake() - } - return c.serverHandshake() -} - -// ConnectionState returns basic TLS details about the connection. -func (c *Conn) ConnectionState() ConnectionState { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - var state ConnectionState - state.HandshakeComplete = c.handshakeComplete - if c.handshakeComplete { - state.NegotiatedProtocol = c.clientProtocol - state.DidResume = c.didResume - state.NegotiatedProtocolIsMutual = !c.clientProtocolFallback - state.CipherSuite = c.cipherSuite - state.PeerCertificates = c.peerCertificates - state.VerifiedChains = c.verifiedChains - state.ServerName = c.serverName - } - - return state -} - -// OCSPResponse returns the stapled OCSP response from the TLS server, if -// any. (Only valid for client connections.) -func (c *Conn) OCSPResponse() []byte { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - - return c.ocspResponse -} - -// VerifyHostname checks that the peer certificate chain is valid for -// connecting to host. If so, it returns nil; if not, it returns an error -// describing the problem. -func (c *Conn) VerifyHostname(host string) error { - c.handshakeMutex.Lock() - defer c.handshakeMutex.Unlock() - if !c.isClient { - return errors.New("VerifyHostname called on TLS server connection") - } - if !c.handshakeComplete { - return errors.New("TLS handshake has not yet been performed") - } - return c.peerCertificates[0].VerifyHostname(host) -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_client.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_client.go deleted file mode 100644 index ed8b3130..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_client.go +++ /dev/null @@ -1,411 +0,0 @@ -// Copyright 2009 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 main - -import ( - "bytes" - "crypto/ecdsa" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "encoding/asn1" - "errors" - "io" - "strconv" -) - -func (c *Conn) clientHandshake() error { - if c.config == nil { - c.config = defaultConfig() - } - - hello := &clientHelloMsg{ - vers: c.config.maxVersion(), - compressionMethods: []uint8{compressionNone}, - random: make([]byte, 32), - ocspStapling: true, - serverName: c.config.ServerName, - supportedCurves: []uint16{curveP256, curveP384, curveP521}, - supportedPoints: []uint8{pointFormatUncompressed}, - nextProtoNeg: len(c.config.NextProtos) > 0, - } - - possibleCipherSuites := c.config.cipherSuites() - hello.cipherSuites = make([]uint16, 0, len(possibleCipherSuites)) - -NextCipherSuite: - for _, suiteId := range possibleCipherSuites { - for _, suite := range cipherSuites { - if suite.id != suiteId { - continue - } - // Don't advertise TLS 1.2-only cipher suites unless - // we're attempting TLS 1.2. - if hello.vers < VersionTLS12 && suite.flags&suiteTLS12 != 0 { - continue - } - hello.cipherSuites = append(hello.cipherSuites, suiteId) - continue NextCipherSuite - } - } - - t := uint32(c.config.time().Unix()) - hello.random[0] = byte(t >> 24) - hello.random[1] = byte(t >> 16) - hello.random[2] = byte(t >> 8) - hello.random[3] = byte(t) - _, err := io.ReadFull(c.config.rand(), hello.random[4:]) - if err != nil { - c.sendAlert(alertInternalError) - return errors.New("short read from Rand") - } - - if hello.vers >= VersionTLS12 { - hello.signatureAndHashes = supportedSKXSignatureAlgorithms - } - - c.writeRecord(recordTypeHandshake, hello.marshal()) - - msg, err := c.readHandshake() - if err != nil { - return err - } - serverHello, ok := msg.(*serverHelloMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - vers, ok := c.config.mutualVersion(serverHello.vers) - if !ok || vers < VersionTLS10 { - // TLS 1.0 is the minimum version supported as a client. - return c.sendAlert(alertProtocolVersion) - } - c.vers = vers - c.haveVers = true - - finishedHash := newFinishedHash(c.vers) - finishedHash.Write(hello.marshal()) - finishedHash.Write(serverHello.marshal()) - - if serverHello.compressionMethod != compressionNone { - return c.sendAlert(alertUnexpectedMessage) - } - - if !hello.nextProtoNeg && serverHello.nextProtoNeg { - c.sendAlert(alertHandshakeFailure) - return errors.New("server advertised unrequested NPN") - } - - suite := mutualCipherSuite(c.config.cipherSuites(), serverHello.cipherSuite) - if suite == nil { - return c.sendAlert(alertHandshakeFailure) - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - certMsg, ok := msg.(*certificateMsg) - if !ok || len(certMsg.certificates) == 0 { - return c.sendAlert(alertUnexpectedMessage) - } - finishedHash.Write(certMsg.marshal()) - - certs := make([]*x509.Certificate, len(certMsg.certificates)) - for i, asn1Data := range certMsg.certificates { - cert, err := x509.ParseCertificate(asn1Data) - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("failed to parse certificate from server: " + err.Error()) - } - certs[i] = cert - } - - if !c.config.InsecureSkipVerify { - opts := x509.VerifyOptions{ - Roots: c.config.RootCAs, - CurrentTime: c.config.time(), - DNSName: c.config.ServerName, - Intermediates: x509.NewCertPool(), - } - - for i, cert := range certs { - if i == 0 { - continue - } - opts.Intermediates.AddCert(cert) - } - c.verifiedChains, err = certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return err - } - } - - switch certs[0].PublicKey.(type) { - case *rsa.PublicKey, *ecdsa.PublicKey: - break - default: - return c.sendAlert(alertUnsupportedCertificate) - } - - c.peerCertificates = certs - - if serverHello.ocspStapling { - msg, err = c.readHandshake() - if err != nil { - return err - } - cs, ok := msg.(*certificateStatusMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - finishedHash.Write(cs.marshal()) - - if cs.statusType == statusTypeOCSP { - c.ocspResponse = cs.response - } - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - - keyAgreement := suite.ka(c.vers) - - skx, ok := msg.(*serverKeyExchangeMsg) - if ok { - finishedHash.Write(skx.marshal()) - err = keyAgreement.processServerKeyExchange(c.config, hello, serverHello, certs[0], skx) - if err != nil { - c.sendAlert(alertUnexpectedMessage) - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - var chainToSend *Certificate - var certRequested bool - certReq, ok := msg.(*certificateRequestMsg) - if ok { - certRequested = true - - // RFC 4346 on the certificateAuthorities field: - // A list of the distinguished names of acceptable certificate - // authorities. These distinguished names may specify a desired - // distinguished name for a root CA or for a subordinate CA; - // thus, this message can be used to describe both known roots - // and a desired authorization space. If the - // certificate_authorities list is empty then the client MAY - // send any certificate of the appropriate - // ClientCertificateType, unless there is some external - // arrangement to the contrary. - - finishedHash.Write(certReq.marshal()) - - var rsaAvail, ecdsaAvail bool - for _, certType := range certReq.certificateTypes { - switch certType { - case certTypeRSASign: - rsaAvail = true - case certTypeECDSASign: - ecdsaAvail = true - } - } - - // We need to search our list of client certs for one - // where SignatureAlgorithm is RSA and the Issuer is in - // certReq.certificateAuthorities - findCert: - for i, chain := range c.config.Certificates { - if !rsaAvail && !ecdsaAvail { - continue - } - - for j, cert := range chain.Certificate { - x509Cert := chain.Leaf - // parse the certificate if this isn't the leaf - // node, or if chain.Leaf was nil - if j != 0 || x509Cert == nil { - if x509Cert, err = x509.ParseCertificate(cert); err != nil { - c.sendAlert(alertInternalError) - return errors.New("tls: failed to parse client certificate #" + strconv.Itoa(i) + ": " + err.Error()) - } - } - - switch { - case rsaAvail && x509Cert.PublicKeyAlgorithm == x509.RSA: - case ecdsaAvail && x509Cert.PublicKeyAlgorithm == x509.ECDSA: - default: - continue findCert - } - - if len(certReq.certificateAuthorities) == 0 { - // they gave us an empty list, so just take the - // first RSA cert from c.config.Certificates - chainToSend = &chain - break findCert - } - - for _, ca := range certReq.certificateAuthorities { - if bytes.Equal(x509Cert.RawIssuer, ca) { - chainToSend = &chain - break findCert - } - } - } - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - shd, ok := msg.(*serverHelloDoneMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - finishedHash.Write(shd.marshal()) - - // If the server requested a certificate then we have to send a - // Certificate message, even if it's empty because we don't have a - // certificate to send. - if certRequested { - certMsg = new(certificateMsg) - if chainToSend != nil { - certMsg.certificates = chainToSend.Certificate - } - finishedHash.Write(certMsg.marshal()) - c.writeRecord(recordTypeHandshake, certMsg.marshal()) - } - - preMasterSecret, ckx, err := keyAgreement.generateClientKeyExchange(c.config, hello, certs[0]) - if err != nil { - c.sendAlert(alertInternalError) - return err - } - if ckx != nil { - finishedHash.Write(ckx.marshal()) - c.writeRecord(recordTypeHandshake, ckx.marshal()) - } - - if chainToSend != nil { - var signed []byte - certVerify := &certificateVerifyMsg{ - hasSignatureAndHash: c.vers >= VersionTLS12, - } - - switch key := c.config.Certificates[0].PrivateKey.(type) { - case *ecdsa.PrivateKey: - digest, _, hashId := finishedHash.hashForClientCertificate(signatureECDSA) - r, s, err := ecdsa.Sign(c.config.rand(), key, digest) - if err == nil { - signed, err = asn1.Marshal(ecdsaSignature{r, s}) - } - certVerify.signatureAndHash.signature = signatureECDSA - certVerify.signatureAndHash.hash = hashId - case *rsa.PrivateKey: - digest, hashFunc, hashId := finishedHash.hashForClientCertificate(signatureRSA) - signed, err = rsa.SignPKCS1v15(c.config.rand(), key, hashFunc, digest) - certVerify.signatureAndHash.signature = signatureRSA - certVerify.signatureAndHash.hash = hashId - default: - err = errors.New("unknown private key type") - } - if err != nil { - return c.sendAlert(alertInternalError) - } - certVerify.signature = signed - - finishedHash.Write(certVerify.marshal()) - c.writeRecord(recordTypeHandshake, certVerify.marshal()) - } - - masterSecret := masterFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random) - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, masterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen) - - var clientCipher interface{} - var clientHash macFunction - if suite.cipher != nil { - clientCipher = suite.cipher(clientKey, clientIV, false /* not for reading */) - clientHash = suite.mac(c.vers, clientMAC) - } else { - clientCipher = suite.aead(clientKey, clientIV) - } - c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) - c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - - if serverHello.nextProtoNeg { - nextProto := new(nextProtoMsg) - proto, fallback := mutualProtocol(c.config.NextProtos, serverHello.nextProtos) - nextProto.proto = proto - c.clientProtocol = proto - c.clientProtocolFallback = fallback - - finishedHash.Write(nextProto.marshal()) - c.writeRecord(recordTypeHandshake, nextProto.marshal()) - } - - finished := new(finishedMsg) - finished.verifyData = finishedHash.clientSum(masterSecret) - finishedHash.Write(finished.marshal()) - c.writeRecord(recordTypeHandshake, finished.marshal()) - - var serverCipher interface{} - var serverHash macFunction - if suite.cipher != nil { - serverCipher = suite.cipher(serverKey, serverIV, true /* for reading */) - serverHash = suite.mac(c.vers, serverMAC) - } else { - serverCipher = suite.aead(serverKey, serverIV) - } - c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) - c.readRecord(recordTypeChangeCipherSpec) - if err := c.error(); err != nil { - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - serverFinished, ok := msg.(*finishedMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - verify := finishedHash.serverSum(masterSecret) - if len(verify) != len(serverFinished.verifyData) || - subtle.ConstantTimeCompare(verify, serverFinished.verifyData) != 1 { - return c.sendAlert(alertHandshakeFailure) - } - - c.handshakeComplete = true - c.cipherSuite = suite.id - return nil -} - -// mutualProtocol finds the mutual Next Protocol Negotiation protocol given the -// set of client and server supported protocols. The set of client supported -// protocols must not be empty. It returns the resulting protocol and flag -// indicating if the fallback case was reached. -func mutualProtocol(clientProtos, serverProtos []string) (string, bool) { - for _, s := range serverProtos { - for _, c := range clientProtos { - if s == c { - return s, false - } - } - } - - return clientProtos[0], true -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_messages.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_messages.go deleted file mode 100644 index ffa92f97..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_messages.go +++ /dev/null @@ -1,1293 +0,0 @@ -// Copyright 2009 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 main - -import "bytes" - -type clientHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuites []uint16 - compressionMethods []uint8 - nextProtoNeg bool - serverName string - ocspStapling bool - supportedCurves []uint16 - supportedPoints []uint8 - ticketSupported bool - sessionTicket []uint8 - signatureAndHashes []signatureAndHash -} - -func (m *clientHelloMsg) equal(i interface{}) bool { - m1, ok := i.(*clientHelloMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.vers == m1.vers && - bytes.Equal(m.random, m1.random) && - bytes.Equal(m.sessionId, m1.sessionId) && - eqUint16s(m.cipherSuites, m1.cipherSuites) && - bytes.Equal(m.compressionMethods, m1.compressionMethods) && - m.nextProtoNeg == m1.nextProtoNeg && - m.serverName == m1.serverName && - m.ocspStapling == m1.ocspStapling && - eqUint16s(m.supportedCurves, m1.supportedCurves) && - bytes.Equal(m.supportedPoints, m1.supportedPoints) && - m.ticketSupported == m1.ticketSupported && - bytes.Equal(m.sessionTicket, m1.sessionTicket) && - eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) -} - -func (m *clientHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - length := 2 + 32 + 1 + len(m.sessionId) + 2 + len(m.cipherSuites)*2 + 1 + len(m.compressionMethods) - numExtensions := 0 - extensionsLength := 0 - if m.nextProtoNeg { - numExtensions++ - } - if m.ocspStapling { - extensionsLength += 1 + 2 + 2 - numExtensions++ - } - if len(m.serverName) > 0 { - extensionsLength += 5 + len(m.serverName) - numExtensions++ - } - if len(m.supportedCurves) > 0 { - extensionsLength += 2 + 2*len(m.supportedCurves) - numExtensions++ - } - if len(m.supportedPoints) > 0 { - extensionsLength += 1 + len(m.supportedPoints) - numExtensions++ - } - if m.ticketSupported { - extensionsLength += len(m.sessionTicket) - numExtensions++ - } - if len(m.signatureAndHashes) > 0 { - extensionsLength += 2 + 2*len(m.signatureAndHashes) - numExtensions++ - } - if numExtensions > 0 { - extensionsLength += 4 * numExtensions - length += 2 + extensionsLength - } - - x := make([]byte, 4+length) - x[0] = typeClientHello - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[4] = uint8(m.vers >> 8) - x[5] = uint8(m.vers) - copy(x[6:38], m.random) - x[38] = uint8(len(m.sessionId)) - copy(x[39:39+len(m.sessionId)], m.sessionId) - y := x[39+len(m.sessionId):] - y[0] = uint8(len(m.cipherSuites) >> 7) - y[1] = uint8(len(m.cipherSuites) << 1) - for i, suite := range m.cipherSuites { - y[2+i*2] = uint8(suite >> 8) - y[3+i*2] = uint8(suite) - } - z := y[2+len(m.cipherSuites)*2:] - z[0] = uint8(len(m.compressionMethods)) - copy(z[1:], m.compressionMethods) - - z = z[1+len(m.compressionMethods):] - if numExtensions > 0 { - z[0] = byte(extensionsLength >> 8) - z[1] = byte(extensionsLength) - z = z[2:] - } - if m.nextProtoNeg { - z[0] = byte(extensionNextProtoNeg >> 8) - z[1] = byte(extensionNextProtoNeg) - // The length is always 0 - z = z[4:] - } - if len(m.serverName) > 0 { - z[0] = byte(extensionServerName >> 8) - z[1] = byte(extensionServerName) - l := len(m.serverName) + 5 - z[2] = byte(l >> 8) - z[3] = byte(l) - z = z[4:] - - // RFC 3546, section 3.1 - // - // struct { - // NameType name_type; - // select (name_type) { - // case host_name: HostName; - // } name; - // } ServerName; - // - // enum { - // host_name(0), (255) - // } NameType; - // - // opaque HostName<1..2^16-1>; - // - // struct { - // ServerName server_name_list<1..2^16-1> - // } ServerNameList; - - z[0] = byte((len(m.serverName) + 3) >> 8) - z[1] = byte(len(m.serverName) + 3) - z[3] = byte(len(m.serverName) >> 8) - z[4] = byte(len(m.serverName)) - copy(z[5:], []byte(m.serverName)) - z = z[l:] - } - if m.ocspStapling { - // RFC 4366, section 3.6 - z[0] = byte(extensionStatusRequest >> 8) - z[1] = byte(extensionStatusRequest) - z[2] = 0 - z[3] = 5 - z[4] = 1 // OCSP type - // Two zero valued uint16s for the two lengths. - z = z[9:] - } - if len(m.supportedCurves) > 0 { - // http://tools.ietf.org/html/rfc4492#section-5.5.1 - z[0] = byte(extensionSupportedCurves >> 8) - z[1] = byte(extensionSupportedCurves) - l := 2 + 2*len(m.supportedCurves) - z[2] = byte(l >> 8) - z[3] = byte(l) - l -= 2 - z[4] = byte(l >> 8) - z[5] = byte(l) - z = z[6:] - for _, curve := range m.supportedCurves { - z[0] = byte(curve >> 8) - z[1] = byte(curve) - z = z[2:] - } - } - if len(m.supportedPoints) > 0 { - // http://tools.ietf.org/html/rfc4492#section-5.5.2 - z[0] = byte(extensionSupportedPoints >> 8) - z[1] = byte(extensionSupportedPoints) - l := 1 + len(m.supportedPoints) - z[2] = byte(l >> 8) - z[3] = byte(l) - l-- - z[4] = byte(l) - z = z[5:] - for _, pointFormat := range m.supportedPoints { - z[0] = byte(pointFormat) - z = z[1:] - } - } - if m.ticketSupported { - // http://tools.ietf.org/html/rfc5077#section-3.2 - z[0] = byte(extensionSessionTicket >> 8) - z[1] = byte(extensionSessionTicket) - l := len(m.sessionTicket) - z[2] = byte(l >> 8) - z[3] = byte(l) - z = z[4:] - copy(z, m.sessionTicket) - z = z[len(m.sessionTicket):] - } - if len(m.signatureAndHashes) > 0 { - // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 - z[0] = byte(extensionSignatureAlgorithms >> 8) - z[1] = byte(extensionSignatureAlgorithms) - l := 2 + 2*len(m.signatureAndHashes) - z[2] = byte(l >> 8) - z[3] = byte(l) - z = z[4:] - - l -= 2 - z[0] = byte(l >> 8) - z[1] = byte(l) - z = z[2:] - for _, sigAndHash := range m.signatureAndHashes { - z[0] = sigAndHash.hash - z[1] = sigAndHash.signature - z = z[2:] - } - } - - m.raw = x - - return x -} - -func (m *clientHelloMsg) unmarshal(data []byte) bool { - if len(data) < 42 { - return false - } - m.raw = data - m.vers = uint16(data[4])<<8 | uint16(data[5]) - m.random = data[6:38] - sessionIdLen := int(data[38]) - if sessionIdLen > 32 || len(data) < 39+sessionIdLen { - return false - } - m.sessionId = data[39 : 39+sessionIdLen] - data = data[39+sessionIdLen:] - if len(data) < 2 { - return false - } - // cipherSuiteLen is the number of bytes of cipher suite numbers. Since - // they are uint16s, the number must be even. - cipherSuiteLen := int(data[0])<<8 | int(data[1]) - if cipherSuiteLen%2 == 1 || len(data) < 2+cipherSuiteLen { - return false - } - numCipherSuites := cipherSuiteLen / 2 - m.cipherSuites = make([]uint16, numCipherSuites) - for i := 0; i < numCipherSuites; i++ { - m.cipherSuites[i] = uint16(data[2+2*i])<<8 | uint16(data[3+2*i]) - } - data = data[2+cipherSuiteLen:] - if len(data) < 1 { - return false - } - compressionMethodsLen := int(data[0]) - if len(data) < 1+compressionMethodsLen { - return false - } - m.compressionMethods = data[1 : 1+compressionMethodsLen] - - data = data[1+compressionMethodsLen:] - - m.nextProtoNeg = false - m.serverName = "" - m.ocspStapling = false - m.ticketSupported = false - m.sessionTicket = nil - m.signatureAndHashes = nil - - if len(data) == 0 { - // ClientHello is optionally followed by extension data - return true - } - if len(data) < 2 { - return false - } - - extensionsLength := int(data[0])<<8 | int(data[1]) - data = data[2:] - if extensionsLength != len(data) { - return false - } - - for len(data) != 0 { - if len(data) < 4 { - return false - } - extension := uint16(data[0])<<8 | uint16(data[1]) - length := int(data[2])<<8 | int(data[3]) - data = data[4:] - if len(data) < length { - return false - } - - switch extension { - case extensionServerName: - if length < 2 { - return false - } - numNames := int(data[0])<<8 | int(data[1]) - d := data[2:] - for i := 0; i < numNames; i++ { - if len(d) < 3 { - return false - } - nameType := d[0] - nameLen := int(d[1])<<8 | int(d[2]) - d = d[3:] - if len(d) < nameLen { - return false - } - if nameType == 0 { - m.serverName = string(d[0:nameLen]) - break - } - d = d[nameLen:] - } - case extensionNextProtoNeg: - if length > 0 { - return false - } - m.nextProtoNeg = true - case extensionStatusRequest: - m.ocspStapling = length > 0 && data[0] == statusTypeOCSP - case extensionSupportedCurves: - // http://tools.ietf.org/html/rfc4492#section-5.5.1 - if length < 2 { - return false - } - l := int(data[0])<<8 | int(data[1]) - if l%2 == 1 || length != l+2 { - return false - } - numCurves := l / 2 - m.supportedCurves = make([]uint16, numCurves) - d := data[2:] - for i := 0; i < numCurves; i++ { - m.supportedCurves[i] = uint16(d[0])<<8 | uint16(d[1]) - d = d[2:] - } - case extensionSupportedPoints: - // http://tools.ietf.org/html/rfc4492#section-5.5.2 - if length < 1 { - return false - } - l := int(data[0]) - if length != l+1 { - return false - } - m.supportedPoints = make([]uint8, l) - copy(m.supportedPoints, data[1:]) - case extensionSessionTicket: - // http://tools.ietf.org/html/rfc5077#section-3.2 - m.ticketSupported = true - m.sessionTicket = data[:length] - case extensionSignatureAlgorithms: - // https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 - if length < 2 || length&1 != 0 { - return false - } - l := int(data[0])<<8 | int(data[1]) - if l != length-2 { - return false - } - n := l / 2 - d := data[2:] - m.signatureAndHashes = make([]signatureAndHash, n) - for i := range m.signatureAndHashes { - m.signatureAndHashes[i].hash = d[0] - m.signatureAndHashes[i].signature = d[1] - d = d[2:] - } - } - data = data[length:] - } - - return true -} - -type serverHelloMsg struct { - raw []byte - vers uint16 - random []byte - sessionId []byte - cipherSuite uint16 - compressionMethod uint8 - nextProtoNeg bool - nextProtos []string - ocspStapling bool - ticketSupported bool -} - -func (m *serverHelloMsg) equal(i interface{}) bool { - m1, ok := i.(*serverHelloMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.vers == m1.vers && - bytes.Equal(m.random, m1.random) && - bytes.Equal(m.sessionId, m1.sessionId) && - m.cipherSuite == m1.cipherSuite && - m.compressionMethod == m1.compressionMethod && - m.nextProtoNeg == m1.nextProtoNeg && - eqStrings(m.nextProtos, m1.nextProtos) && - m.ocspStapling == m1.ocspStapling && - m.ticketSupported == m1.ticketSupported -} - -func (m *serverHelloMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - length := 38 + len(m.sessionId) - numExtensions := 0 - extensionsLength := 0 - - nextProtoLen := 0 - if m.nextProtoNeg { - numExtensions++ - for _, v := range m.nextProtos { - nextProtoLen += len(v) - } - nextProtoLen += len(m.nextProtos) - extensionsLength += nextProtoLen - } - if m.ocspStapling { - numExtensions++ - } - if m.ticketSupported { - numExtensions++ - } - if numExtensions > 0 { - extensionsLength += 4 * numExtensions - length += 2 + extensionsLength - } - - x := make([]byte, 4+length) - x[0] = typeServerHello - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[4] = uint8(m.vers >> 8) - x[5] = uint8(m.vers) - copy(x[6:38], m.random) - x[38] = uint8(len(m.sessionId)) - copy(x[39:39+len(m.sessionId)], m.sessionId) - z := x[39+len(m.sessionId):] - z[0] = uint8(m.cipherSuite >> 8) - z[1] = uint8(m.cipherSuite) - z[2] = uint8(m.compressionMethod) - - z = z[3:] - if numExtensions > 0 { - z[0] = byte(extensionsLength >> 8) - z[1] = byte(extensionsLength) - z = z[2:] - } - if m.nextProtoNeg { - z[0] = byte(extensionNextProtoNeg >> 8) - z[1] = byte(extensionNextProtoNeg) - z[2] = byte(nextProtoLen >> 8) - z[3] = byte(nextProtoLen) - z = z[4:] - - for _, v := range m.nextProtos { - l := len(v) - if l > 255 { - l = 255 - } - z[0] = byte(l) - copy(z[1:], []byte(v[0:l])) - z = z[1+l:] - } - } - if m.ocspStapling { - z[0] = byte(extensionStatusRequest >> 8) - z[1] = byte(extensionStatusRequest) - z = z[4:] - } - if m.ticketSupported { - z[0] = byte(extensionSessionTicket >> 8) - z[1] = byte(extensionSessionTicket) - z = z[4:] - } - - m.raw = x - - return x -} - -func (m *serverHelloMsg) unmarshal(data []byte) bool { - if len(data) < 42 { - return false - } - m.raw = data - m.vers = uint16(data[4])<<8 | uint16(data[5]) - m.random = data[6:38] - sessionIdLen := int(data[38]) - if sessionIdLen > 32 || len(data) < 39+sessionIdLen { - return false - } - m.sessionId = data[39 : 39+sessionIdLen] - data = data[39+sessionIdLen:] - if len(data) < 3 { - return false - } - m.cipherSuite = uint16(data[0])<<8 | uint16(data[1]) - m.compressionMethod = data[2] - data = data[3:] - - m.nextProtoNeg = false - m.nextProtos = nil - m.ocspStapling = false - m.ticketSupported = false - - if len(data) == 0 { - // ServerHello is optionally followed by extension data - return true - } - if len(data) < 2 { - return false - } - - extensionsLength := int(data[0])<<8 | int(data[1]) - data = data[2:] - if len(data) != extensionsLength { - return false - } - - for len(data) != 0 { - if len(data) < 4 { - return false - } - extension := uint16(data[0])<<8 | uint16(data[1]) - length := int(data[2])<<8 | int(data[3]) - data = data[4:] - if len(data) < length { - return false - } - - switch extension { - case extensionNextProtoNeg: - m.nextProtoNeg = true - d := data[:length] - for len(d) > 0 { - l := int(d[0]) - d = d[1:] - if l == 0 || l > len(d) { - return false - } - m.nextProtos = append(m.nextProtos, string(d[:l])) - d = d[l:] - } - case extensionStatusRequest: - if length > 0 { - return false - } - m.ocspStapling = true - case extensionSessionTicket: - if length > 0 { - return false - } - m.ticketSupported = true - } - data = data[length:] - } - - return true -} - -type certificateMsg struct { - raw []byte - certificates [][]byte -} - -func (m *certificateMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - eqByteSlices(m.certificates, m1.certificates) -} - -func (m *certificateMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - var i int - for _, slice := range m.certificates { - i += len(slice) - } - - length := 3 + 3*len(m.certificates) + i - x = make([]byte, 4+length) - x[0] = typeCertificate - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - certificateOctets := length - 3 - x[4] = uint8(certificateOctets >> 16) - x[5] = uint8(certificateOctets >> 8) - x[6] = uint8(certificateOctets) - - y := x[7:] - for _, slice := range m.certificates { - y[0] = uint8(len(slice) >> 16) - y[1] = uint8(len(slice) >> 8) - y[2] = uint8(len(slice)) - copy(y[3:], slice) - y = y[3+len(slice):] - } - - m.raw = x - return -} - -func (m *certificateMsg) unmarshal(data []byte) bool { - if len(data) < 7 { - return false - } - - m.raw = data - certsLen := uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6]) - if uint32(len(data)) != certsLen+7 { - return false - } - - numCerts := 0 - d := data[7:] - for certsLen > 0 { - if len(d) < 4 { - return false - } - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - if uint32(len(d)) < 3+certLen { - return false - } - d = d[3+certLen:] - certsLen -= 3 + certLen - numCerts++ - } - - m.certificates = make([][]byte, numCerts) - d = data[7:] - for i := 0; i < numCerts; i++ { - certLen := uint32(d[0])<<16 | uint32(d[1])<<8 | uint32(d[2]) - m.certificates[i] = d[3 : 3+certLen] - d = d[3+certLen:] - } - - return true -} - -type serverKeyExchangeMsg struct { - raw []byte - key []byte -} - -func (m *serverKeyExchangeMsg) equal(i interface{}) bool { - m1, ok := i.(*serverKeyExchangeMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.key, m1.key) -} - -func (m *serverKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.key) - x := make([]byte, length+4) - x[0] = typeServerKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.key) - - m.raw = x - return x -} - -func (m *serverKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - m.key = data[4:] - return true -} - -type certificateStatusMsg struct { - raw []byte - statusType uint8 - response []byte -} - -func (m *certificateStatusMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateStatusMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.statusType == m1.statusType && - bytes.Equal(m.response, m1.response) -} - -func (m *certificateStatusMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - - var x []byte - if m.statusType == statusTypeOCSP { - x = make([]byte, 4+4+len(m.response)) - x[0] = typeCertificateStatus - l := len(m.response) + 4 - x[1] = byte(l >> 16) - x[2] = byte(l >> 8) - x[3] = byte(l) - x[4] = statusTypeOCSP - - l -= 4 - x[5] = byte(l >> 16) - x[6] = byte(l >> 8) - x[7] = byte(l) - copy(x[8:], m.response) - } else { - x = []byte{typeCertificateStatus, 0, 0, 1, m.statusType} - } - - m.raw = x - return x -} - -func (m *certificateStatusMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 5 { - return false - } - m.statusType = data[4] - - m.response = nil - if m.statusType == statusTypeOCSP { - if len(data) < 8 { - return false - } - respLen := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7]) - if uint32(len(data)) != 4+4+respLen { - return false - } - m.response = data[8:] - } - return true -} - -type serverHelloDoneMsg struct{} - -func (m *serverHelloDoneMsg) equal(i interface{}) bool { - _, ok := i.(*serverHelloDoneMsg) - return ok -} - -func (m *serverHelloDoneMsg) marshal() []byte { - x := make([]byte, 4) - x[0] = typeServerHelloDone - return x -} - -func (m *serverHelloDoneMsg) unmarshal(data []byte) bool { - return len(data) == 4 -} - -type clientKeyExchangeMsg struct { - raw []byte - ciphertext []byte -} - -func (m *clientKeyExchangeMsg) equal(i interface{}) bool { - m1, ok := i.(*clientKeyExchangeMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.ciphertext, m1.ciphertext) -} - -func (m *clientKeyExchangeMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - length := len(m.ciphertext) - x := make([]byte, length+4) - x[0] = typeClientKeyExchange - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - copy(x[4:], m.ciphertext) - - m.raw = x - return x -} - -func (m *clientKeyExchangeMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - l := int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - if l != len(data)-4 { - return false - } - m.ciphertext = data[4:] - return true -} - -type finishedMsg struct { - raw []byte - verifyData []byte -} - -func (m *finishedMsg) equal(i interface{}) bool { - m1, ok := i.(*finishedMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.verifyData, m1.verifyData) -} - -func (m *finishedMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - x = make([]byte, 4+len(m.verifyData)) - x[0] = typeFinished - x[3] = byte(len(m.verifyData)) - copy(x[4:], m.verifyData) - m.raw = x - return -} - -func (m *finishedMsg) unmarshal(data []byte) bool { - m.raw = data - if len(data) < 4 { - return false - } - m.verifyData = data[4:] - return true -} - -type nextProtoMsg struct { - raw []byte - proto string -} - -func (m *nextProtoMsg) equal(i interface{}) bool { - m1, ok := i.(*nextProtoMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.proto == m1.proto -} - -func (m *nextProtoMsg) marshal() []byte { - if m.raw != nil { - return m.raw - } - l := len(m.proto) - if l > 255 { - l = 255 - } - - padding := 32 - (l+2)%32 - length := l + padding + 2 - x := make([]byte, length+4) - x[0] = typeNextProtocol - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - y := x[4:] - y[0] = byte(l) - copy(y[1:], []byte(m.proto[0:l])) - y = y[1+l:] - y[0] = byte(padding) - - m.raw = x - - return x -} - -func (m *nextProtoMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 5 { - return false - } - data = data[4:] - protoLen := int(data[0]) - data = data[1:] - if len(data) < protoLen { - return false - } - m.proto = string(data[0:protoLen]) - data = data[protoLen:] - - if len(data) < 1 { - return false - } - paddingLen := int(data[0]) - data = data[1:] - if len(data) != paddingLen { - return false - } - - return true -} - -type certificateRequestMsg struct { - raw []byte - // hasSignatureAndHash indicates whether this message includes a list - // of signature and hash functions. This change was introduced with TLS - // 1.2. - hasSignatureAndHash bool - - certificateTypes []byte - signatureAndHashes []signatureAndHash - certificateAuthorities [][]byte -} - -func (m *certificateRequestMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateRequestMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.certificateTypes, m1.certificateTypes) && - eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) && - eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes) -} - -func (m *certificateRequestMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See http://tools.ietf.org/html/rfc4346#section-7.4.4 - length := 1 + len(m.certificateTypes) + 2 - casLength := 0 - for _, ca := range m.certificateAuthorities { - casLength += 2 + len(ca) - } - length += casLength - - if m.hasSignatureAndHash { - length += 2 + 2*len(m.signatureAndHashes) - } - - x = make([]byte, 4+length) - x[0] = typeCertificateRequest - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - - x[4] = uint8(len(m.certificateTypes)) - - copy(x[5:], m.certificateTypes) - y := x[5+len(m.certificateTypes):] - - if m.hasSignatureAndHash { - n := len(m.signatureAndHashes) * 2 - y[0] = uint8(n >> 8) - y[1] = uint8(n) - y = y[2:] - for _, sigAndHash := range m.signatureAndHashes { - y[0] = sigAndHash.hash - y[1] = sigAndHash.signature - y = y[2:] - } - } - - y[0] = uint8(casLength >> 8) - y[1] = uint8(casLength) - y = y[2:] - for _, ca := range m.certificateAuthorities { - y[0] = uint8(len(ca) >> 8) - y[1] = uint8(len(ca)) - y = y[2:] - copy(y, ca) - y = y[len(ca):] - } - - m.raw = x - return -} - -func (m *certificateRequestMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 5 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - numCertTypes := int(data[4]) - data = data[5:] - if numCertTypes == 0 || len(data) <= numCertTypes { - return false - } - - m.certificateTypes = make([]byte, numCertTypes) - if copy(m.certificateTypes, data) != numCertTypes { - return false - } - - data = data[numCertTypes:] - - if m.hasSignatureAndHash { - if len(data) < 2 { - return false - } - sigAndHashLen := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if sigAndHashLen&1 != 0 { - return false - } - if len(data) < int(sigAndHashLen) { - return false - } - numSigAndHash := sigAndHashLen / 2 - m.signatureAndHashes = make([]signatureAndHash, numSigAndHash) - for i := range m.signatureAndHashes { - m.signatureAndHashes[i].hash = data[0] - m.signatureAndHashes[i].signature = data[1] - data = data[2:] - } - } - - if len(data) < 2 { - return false - } - casLength := uint16(data[0])<<8 | uint16(data[1]) - data = data[2:] - if len(data) < int(casLength) { - return false - } - cas := make([]byte, casLength) - copy(cas, data) - data = data[casLength:] - - m.certificateAuthorities = nil - for len(cas) > 0 { - if len(cas) < 2 { - return false - } - caLen := uint16(cas[0])<<8 | uint16(cas[1]) - cas = cas[2:] - - if len(cas) < int(caLen) { - return false - } - - m.certificateAuthorities = append(m.certificateAuthorities, cas[:caLen]) - cas = cas[caLen:] - } - if len(data) > 0 { - return false - } - - return true -} - -type certificateVerifyMsg struct { - raw []byte - hasSignatureAndHash bool - signatureAndHash signatureAndHash - signature []byte -} - -func (m *certificateVerifyMsg) equal(i interface{}) bool { - m1, ok := i.(*certificateVerifyMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - m.hasSignatureAndHash == m1.hasSignatureAndHash && - m.signatureAndHash.hash == m1.signatureAndHash.hash && - m.signatureAndHash.signature == m1.signatureAndHash.signature && - bytes.Equal(m.signature, m1.signature) -} - -func (m *certificateVerifyMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See http://tools.ietf.org/html/rfc4346#section-7.4.8 - siglength := len(m.signature) - length := 2 + siglength - if m.hasSignatureAndHash { - length += 2 - } - x = make([]byte, 4+length) - x[0] = typeCertificateVerify - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - y := x[4:] - if m.hasSignatureAndHash { - y[0] = m.signatureAndHash.hash - y[1] = m.signatureAndHash.signature - y = y[2:] - } - y[0] = uint8(siglength >> 8) - y[1] = uint8(siglength) - copy(y[2:], m.signature) - - m.raw = x - - return -} - -func (m *certificateVerifyMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 6 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - data = data[4:] - if m.hasSignatureAndHash { - m.signatureAndHash.hash = data[0] - m.signatureAndHash.signature = data[1] - data = data[2:] - } - - if len(data) < 2 { - return false - } - siglength := int(data[0])<<8 + int(data[1]) - data = data[2:] - if len(data) != siglength { - return false - } - - m.signature = data - - return true -} - -type newSessionTicketMsg struct { - raw []byte - ticket []byte -} - -func (m *newSessionTicketMsg) equal(i interface{}) bool { - m1, ok := i.(*newSessionTicketMsg) - if !ok { - return false - } - - return bytes.Equal(m.raw, m1.raw) && - bytes.Equal(m.ticket, m1.ticket) -} - -func (m *newSessionTicketMsg) marshal() (x []byte) { - if m.raw != nil { - return m.raw - } - - // See http://tools.ietf.org/html/rfc5077#section-3.3 - ticketLen := len(m.ticket) - length := 2 + 4 + ticketLen - x = make([]byte, 4+length) - x[0] = typeNewSessionTicket - x[1] = uint8(length >> 16) - x[2] = uint8(length >> 8) - x[3] = uint8(length) - x[8] = uint8(ticketLen >> 8) - x[9] = uint8(ticketLen) - copy(x[10:], m.ticket) - - m.raw = x - - return -} - -func (m *newSessionTicketMsg) unmarshal(data []byte) bool { - m.raw = data - - if len(data) < 10 { - return false - } - - length := uint32(data[1])<<16 | uint32(data[2])<<8 | uint32(data[3]) - if uint32(len(data))-4 != length { - return false - } - - ticketLen := int(data[8])<<8 + int(data[9]) - if len(data)-10 != ticketLen { - return false - } - - m.ticket = data[10:] - - return true -} - -func eqUint16s(x, y []uint16) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - if y[i] != v { - return false - } - } - return true -} - -func eqStrings(x, y []string) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - if y[i] != v { - return false - } - } - return true -} - -func eqByteSlices(x, y [][]byte) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - if !bytes.Equal(v, y[i]) { - return false - } - } - return true -} - -func eqSignatureAndHashes(x, y []signatureAndHash) bool { - if len(x) != len(y) { - return false - } - for i, v := range x { - v2 := y[i] - if v.hash != v2.hash || v.signature != v2.signature { - return false - } - } - return true -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_server.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_server.go deleted file mode 100644 index f722bc2a..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/handshake_server.go +++ /dev/null @@ -1,638 +0,0 @@ -// Copyright 2009 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 main - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "crypto/subtle" - "crypto/x509" - "encoding/asn1" - "errors" - "io" -) - -// serverHandshakeState contains details of a server handshake in progress. -// It's discarded once the handshake has completed. -type serverHandshakeState struct { - c *Conn - clientHello *clientHelloMsg - hello *serverHelloMsg - suite *cipherSuite - ellipticOk bool - ecdsaOk bool - sessionState *sessionState - finishedHash finishedHash - masterSecret []byte - certsFromClient [][]byte - cert *Certificate -} - -// serverHandshake performs a TLS handshake as a server. -func (c *Conn) serverHandshake() error { - config := c.config - - // If this is the first server handshake, we generate a random key to - // encrypt the tickets with. - config.serverInitOnce.Do(config.serverInit) - - hs := serverHandshakeState{ - c: c, - } - isResume, err := hs.readClientHello() - if err != nil { - return err - } - - // For an overview of TLS handshaking, see https://tools.ietf.org/html/rfc5246#section-7.3 - if isResume { - // The client has included a session ticket and so we do an abbreviated handshake. - if err := hs.doResumeHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.sendFinished(); err != nil { - return err - } - if err := hs.readFinished(); err != nil { - return err - } - c.didResume = true - } else { - // The client didn't include a session ticket, or it wasn't - // valid so we do a full handshake. - if err := hs.doFullHandshake(); err != nil { - return err - } - if err := hs.establishKeys(); err != nil { - return err - } - if err := hs.readFinished(); err != nil { - return err - } - if err := hs.sendSessionTicket(); err != nil { - return err - } - if err := hs.sendFinished(); err != nil { - return err - } - } - c.handshakeComplete = true - - return nil -} - -// readClientHello reads a ClientHello message from the client and decides -// whether we will perform session resumption. -func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) { - config := hs.c.config - c := hs.c - - msg, err := c.readHandshake() - if err != nil { - return false, err - } - var ok bool - hs.clientHello, ok = msg.(*clientHelloMsg) - if !ok { - return false, c.sendAlert(alertUnexpectedMessage) - } - c.vers, ok = config.mutualVersion(hs.clientHello.vers) - if !ok { - return false, c.sendAlert(alertProtocolVersion) - } - c.haveVers = true - - hs.finishedHash = newFinishedHash(c.vers) - hs.finishedHash.Write(hs.clientHello.marshal()) - - hs.hello = new(serverHelloMsg) - - supportedCurve := false -Curves: - for _, curve := range hs.clientHello.supportedCurves { - switch curve { - case curveP256, curveP384, curveP521: - supportedCurve = true - break Curves - } - } - - supportedPointFormat := false - for _, pointFormat := range hs.clientHello.supportedPoints { - if pointFormat == pointFormatUncompressed { - supportedPointFormat = true - break - } - } - hs.ellipticOk = supportedCurve && supportedPointFormat - - foundCompression := false - // We only support null compression, so check that the client offered it. - for _, compression := range hs.clientHello.compressionMethods { - if compression == compressionNone { - foundCompression = true - break - } - } - - if !foundCompression { - return false, c.sendAlert(alertHandshakeFailure) - } - - hs.hello.vers = c.vers - t := uint32(config.time().Unix()) - hs.hello.random = make([]byte, 32) - hs.hello.random[0] = byte(t >> 24) - hs.hello.random[1] = byte(t >> 16) - hs.hello.random[2] = byte(t >> 8) - hs.hello.random[3] = byte(t) - _, err = io.ReadFull(config.rand(), hs.hello.random[4:]) - if err != nil { - return false, c.sendAlert(alertInternalError) - } - hs.hello.compressionMethod = compressionNone - if len(hs.clientHello.serverName) > 0 { - c.serverName = hs.clientHello.serverName - } - // Although sending an empty NPN extension is reasonable, Firefox has - // had a bug around this. Best to send nothing at all if - // config.NextProtos is empty. See - // https://code.google.com/p/go/issues/detail?id=5445. - if hs.clientHello.nextProtoNeg && len(config.NextProtos) > 0 { - hs.hello.nextProtoNeg = true - hs.hello.nextProtos = config.NextProtos - } - - if len(config.Certificates) == 0 { - return false, c.sendAlert(alertInternalError) - } - hs.cert = &config.Certificates[0] - if len(hs.clientHello.serverName) > 0 { - hs.cert = config.getCertificateForName(hs.clientHello.serverName) - } - - _, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey) - - if hs.checkForResumption() { - return true, nil - } - - var preferenceList, supportedList []uint16 - if c.config.PreferServerCipherSuites { - preferenceList = c.config.cipherSuites() - supportedList = hs.clientHello.cipherSuites - } else { - preferenceList = hs.clientHello.cipherSuites - supportedList = c.config.cipherSuites() - } - - for _, id := range preferenceList { - if hs.suite = c.tryCipherSuite(id, supportedList, c.vers, hs.ellipticOk, hs.ecdsaOk); hs.suite != nil { - break - } - } - - if hs.suite == nil { - return false, c.sendAlert(alertHandshakeFailure) - } - - return false, nil -} - -// checkForResumption returns true if we should perform resumption on this connection. -func (hs *serverHandshakeState) checkForResumption() bool { - c := hs.c - - var ok bool - if hs.sessionState, ok = c.decryptTicket(hs.clientHello.sessionTicket); !ok { - return false - } - - if hs.sessionState.vers > hs.clientHello.vers { - return false - } - if vers, ok := c.config.mutualVersion(hs.sessionState.vers); !ok || vers != hs.sessionState.vers { - return false - } - - cipherSuiteOk := false - // Check that the client is still offering the ciphersuite in the session. - for _, id := range hs.clientHello.cipherSuites { - if id == hs.sessionState.cipherSuite { - cipherSuiteOk = true - break - } - } - if !cipherSuiteOk { - return false - } - - // Check that we also support the ciphersuite from the session. - hs.suite = c.tryCipherSuite(hs.sessionState.cipherSuite, c.config.cipherSuites(), hs.sessionState.vers, hs.ellipticOk, hs.ecdsaOk) - if hs.suite == nil { - return false - } - - sessionHasClientCerts := len(hs.sessionState.certificates) != 0 - needClientCerts := c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert - if needClientCerts && !sessionHasClientCerts { - return false - } - if sessionHasClientCerts && c.config.ClientAuth == NoClientCert { - return false - } - - return true -} - -func (hs *serverHandshakeState) doResumeHandshake() error { - c := hs.c - - hs.hello.cipherSuite = hs.suite.id - // We echo the client's session ID in the ServerHello to let it know - // that we're doing a resumption. - hs.hello.sessionId = hs.clientHello.sessionId - hs.finishedHash.Write(hs.hello.marshal()) - c.writeRecord(recordTypeHandshake, hs.hello.marshal()) - - if len(hs.sessionState.certificates) > 0 { - if _, err := hs.processCertsFromClient(hs.sessionState.certificates); err != nil { - return err - } - } - - hs.masterSecret = hs.sessionState.masterSecret - - return nil -} - -func (hs *serverHandshakeState) doFullHandshake() error { - config := hs.c.config - c := hs.c - - if hs.clientHello.ocspStapling && len(hs.cert.OCSPStaple) > 0 { - hs.hello.ocspStapling = true - } - - hs.hello.ticketSupported = hs.clientHello.ticketSupported && !config.SessionTicketsDisabled - hs.hello.cipherSuite = hs.suite.id - hs.finishedHash.Write(hs.hello.marshal()) - c.writeRecord(recordTypeHandshake, hs.hello.marshal()) - - certMsg := new(certificateMsg) - certMsg.certificates = hs.cert.Certificate - hs.finishedHash.Write(certMsg.marshal()) - c.writeRecord(recordTypeHandshake, certMsg.marshal()) - - if hs.hello.ocspStapling { - certStatus := new(certificateStatusMsg) - certStatus.statusType = statusTypeOCSP - certStatus.response = hs.cert.OCSPStaple - hs.finishedHash.Write(certStatus.marshal()) - c.writeRecord(recordTypeHandshake, certStatus.marshal()) - } - - keyAgreement := hs.suite.ka(c.vers) - skx, err := keyAgreement.generateServerKeyExchange(config, hs.cert, hs.clientHello, hs.hello) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - if skx != nil { - hs.finishedHash.Write(skx.marshal()) - c.writeRecord(recordTypeHandshake, skx.marshal()) - } - - if config.ClientAuth >= RequestClientCert { - // Request a client certificate - certReq := new(certificateRequestMsg) - certReq.certificateTypes = []byte{ - byte(certTypeRSASign), - byte(certTypeECDSASign), - } - if c.vers >= VersionTLS12 { - certReq.hasSignatureAndHash = true - certReq.signatureAndHashes = supportedClientCertSignatureAlgorithms - } - - // An empty list of certificateAuthorities signals to - // the client that it may send any certificate in response - // to our request. When we know the CAs we trust, then - // we can send them down, so that the client can choose - // an appropriate certificate to give to us. - if config.ClientCAs != nil { - certReq.certificateAuthorities = config.ClientCAs.Subjects() - } - hs.finishedHash.Write(certReq.marshal()) - c.writeRecord(recordTypeHandshake, certReq.marshal()) - } - - helloDone := new(serverHelloDoneMsg) - hs.finishedHash.Write(helloDone.marshal()) - c.writeRecord(recordTypeHandshake, helloDone.marshal()) - - var pub crypto.PublicKey // public key for client auth, if any - - msg, err := c.readHandshake() - if err != nil { - return err - } - - var ok bool - // If we requested a client certificate, then the client must send a - // certificate message, even if it's empty. - if config.ClientAuth >= RequestClientCert { - if certMsg, ok = msg.(*certificateMsg); !ok { - return c.sendAlert(alertHandshakeFailure) - } - hs.finishedHash.Write(certMsg.marshal()) - - if len(certMsg.certificates) == 0 { - // The client didn't actually send a certificate - switch config.ClientAuth { - case RequireAnyClientCert, RequireAndVerifyClientCert: - c.sendAlert(alertBadCertificate) - return errors.New("tls: client didn't provide a certificate") - } - } - - pub, err = hs.processCertsFromClient(certMsg.certificates) - if err != nil { - return err - } - - msg, err = c.readHandshake() - if err != nil { - return err - } - } - - // Get client key exchange - ckx, ok := msg.(*clientKeyExchangeMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - hs.finishedHash.Write(ckx.marshal()) - - // If we received a client cert in response to our certificate request message, - // the client will send us a certificateVerifyMsg immediately after the - // clientKeyExchangeMsg. This message is a digest of all preceding - // handshake-layer messages that is signed using the private key corresponding - // to the client's certificate. This allows us to verify that the client is in - // possession of the private key of the certificate. - if len(c.peerCertificates) > 0 { - msg, err = c.readHandshake() - if err != nil { - return err - } - certVerify, ok := msg.(*certificateVerifyMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - switch key := pub.(type) { - case *ecdsa.PublicKey: - ecdsaSig := new(ecdsaSignature) - if _, err = asn1.Unmarshal(certVerify.signature, ecdsaSig); err != nil { - break - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - err = errors.New("ECDSA signature contained zero or negative values") - break - } - digest, _, _ := hs.finishedHash.hashForClientCertificate(signatureECDSA) - if !ecdsa.Verify(key, digest, ecdsaSig.R, ecdsaSig.S) { - err = errors.New("ECDSA verification failure") - break - } - case *rsa.PublicKey: - digest, hashFunc, _ := hs.finishedHash.hashForClientCertificate(signatureRSA) - err = rsa.VerifyPKCS1v15(key, hashFunc, digest, certVerify.signature) - } - if err != nil { - c.sendAlert(alertBadCertificate) - return errors.New("could not validate signature of connection nonces: " + err.Error()) - } - - hs.finishedHash.Write(certVerify.marshal()) - } - - preMasterSecret, err := keyAgreement.processClientKeyExchange(config, hs.cert, ckx, c.vers) - if err != nil { - c.sendAlert(alertHandshakeFailure) - return err - } - hs.masterSecret = masterFromPreMasterSecret(c.vers, preMasterSecret, hs.clientHello.random, hs.hello.random) - - return nil -} - -func (hs *serverHandshakeState) establishKeys() error { - c := hs.c - - clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := - keysFromMasterSecret(c.vers, hs.masterSecret, hs.clientHello.random, hs.hello.random, hs.suite.macLen, hs.suite.keyLen, hs.suite.ivLen) - - var clientCipher, serverCipher interface{} - var clientHash, serverHash macFunction - - if hs.suite.aead == nil { - clientCipher = hs.suite.cipher(clientKey, clientIV, true /* for reading */) - clientHash = hs.suite.mac(c.vers, clientMAC) - serverCipher = hs.suite.cipher(serverKey, serverIV, false /* not for reading */) - serverHash = hs.suite.mac(c.vers, serverMAC) - } else { - clientCipher = hs.suite.aead(clientKey, clientIV) - serverCipher = hs.suite.aead(serverKey, serverIV) - } - - c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) - c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) - - return nil -} - -func (hs *serverHandshakeState) readFinished() error { - c := hs.c - - c.readRecord(recordTypeChangeCipherSpec) - if err := c.error(); err != nil { - return err - } - - if hs.hello.nextProtoNeg { - msg, err := c.readHandshake() - if err != nil { - return err - } - nextProto, ok := msg.(*nextProtoMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - hs.finishedHash.Write(nextProto.marshal()) - c.clientProtocol = nextProto.proto - } - - msg, err := c.readHandshake() - if err != nil { - return err - } - clientFinished, ok := msg.(*finishedMsg) - if !ok { - return c.sendAlert(alertUnexpectedMessage) - } - - verify := hs.finishedHash.clientSum(hs.masterSecret) - if len(verify) != len(clientFinished.verifyData) || - subtle.ConstantTimeCompare(verify, clientFinished.verifyData) != 1 { - return c.sendAlert(alertHandshakeFailure) - } - - hs.finishedHash.Write(clientFinished.marshal()) - return nil -} - -func (hs *serverHandshakeState) sendSessionTicket() error { - if !hs.hello.ticketSupported { - return nil - } - - c := hs.c - m := new(newSessionTicketMsg) - - var err error - state := sessionState{ - vers: c.vers, - cipherSuite: hs.suite.id, - masterSecret: hs.masterSecret, - certificates: hs.certsFromClient, - } - m.ticket, err = c.encryptTicket(&state) - if err != nil { - return err - } - - hs.finishedHash.Write(m.marshal()) - c.writeRecord(recordTypeHandshake, m.marshal()) - - return nil -} - -func (hs *serverHandshakeState) sendFinished() error { - c := hs.c - - c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) - - finished := new(finishedMsg) - finished.verifyData = hs.finishedHash.serverSum(hs.masterSecret) - hs.finishedHash.Write(finished.marshal()) - c.writeRecord(recordTypeHandshake, finished.marshal()) - - c.cipherSuite = hs.suite.id - - return nil -} - -// processCertsFromClient takes a chain of client certificates either from a -// Certificates message or from a sessionState and verifies them. It returns -// the public key of the leaf certificate. -func (hs *serverHandshakeState) processCertsFromClient(certificates [][]byte) (crypto.PublicKey, error) { - c := hs.c - - hs.certsFromClient = certificates - certs := make([]*x509.Certificate, len(certificates)) - var err error - for i, asn1Data := range certificates { - if certs[i], err = x509.ParseCertificate(asn1Data); err != nil { - c.sendAlert(alertBadCertificate) - return nil, errors.New("tls: failed to parse client certificate: " + err.Error()) - } - } - - if c.config.ClientAuth >= VerifyClientCertIfGiven && len(certs) > 0 { - opts := x509.VerifyOptions{ - Roots: c.config.ClientCAs, - CurrentTime: c.config.time(), - Intermediates: x509.NewCertPool(), - KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, - } - - for _, cert := range certs[1:] { - opts.Intermediates.AddCert(cert) - } - - chains, err := certs[0].Verify(opts) - if err != nil { - c.sendAlert(alertBadCertificate) - return nil, errors.New("tls: failed to verify client's certificate: " + err.Error()) - } - - ok := false - for _, ku := range certs[0].ExtKeyUsage { - if ku == x509.ExtKeyUsageClientAuth { - ok = true - break - } - } - if !ok { - c.sendAlert(alertHandshakeFailure) - return nil, errors.New("tls: client's certificate's extended key usage doesn't permit it to be used for client authentication") - } - - c.verifiedChains = chains - } - - if len(certs) > 0 { - var pub crypto.PublicKey - switch key := certs[0].PublicKey.(type) { - case *ecdsa.PublicKey, *rsa.PublicKey: - pub = key - default: - return nil, c.sendAlert(alertUnsupportedCertificate) - } - c.peerCertificates = certs - return pub, nil - } - - return nil, nil -} - -// tryCipherSuite returns a cipherSuite with the given id if that cipher suite -// is acceptable to use. -func (c *Conn) tryCipherSuite(id uint16, supportedCipherSuites []uint16, version uint16, ellipticOk, ecdsaOk bool) *cipherSuite { - for _, supported := range supportedCipherSuites { - if id == supported { - var candidate *cipherSuite - - for _, s := range cipherSuites { - if s.id == id { - candidate = s - break - } - } - if candidate == nil { - continue - } - // Don't select a ciphersuite which we can't - // support for this client. - if (candidate.flags&suiteECDHE != 0) && !ellipticOk { - continue - } - if (candidate.flags&suiteECDSA != 0) != ecdsaOk { - continue - } - if version < VersionTLS12 && candidate.flags&suiteTLS12 != 0 { - continue - } - return candidate - } - } - - return nil -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/key_agreement.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/key_agreement.go deleted file mode 100644 index c53473a6..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/key_agreement.go +++ /dev/null @@ -1,400 +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 main - -import ( - "crypto" - "crypto/ecdsa" - "crypto/elliptic" - "crypto/md5" - "crypto/rsa" - "crypto/sha1" - "crypto/sha256" - "crypto/x509" - "encoding/asn1" - "errors" - "io" - "math/big" -) - -// rsaKeyAgreement implements the standard TLS key agreement where the client -// encrypts the pre-master secret to the server's public key. -type rsaKeyAgreement struct{} - -func (ka rsaKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - return nil, nil -} - -func (ka rsaKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - preMasterSecret := make([]byte, 48) - _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) - if err != nil { - return nil, err - } - - if len(ckx.ciphertext) < 2 { - return nil, errors.New("bad ClientKeyExchange") - } - - ciphertext := ckx.ciphertext - if version != VersionSSL30 { - ciphertextLen := int(ckx.ciphertext[0])<<8 | int(ckx.ciphertext[1]) - if ciphertextLen != len(ckx.ciphertext)-2 { - return nil, errors.New("bad ClientKeyExchange") - } - ciphertext = ckx.ciphertext[2:] - } - - err = rsa.DecryptPKCS1v15SessionKey(config.rand(), cert.PrivateKey.(*rsa.PrivateKey), ciphertext, preMasterSecret) - if err != nil { - return nil, err - } - // We don't check the version number in the premaster secret. For one, - // by checking it, we would leak information about the validity of the - // encrypted pre-master secret. Secondly, it provides only a small - // benefit against a downgrade attack and some implementations send the - // wrong version anyway. See the discussion at the end of section - // 7.4.7.1 of RFC 4346. - return preMasterSecret, nil -} - -func (ka rsaKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - return errors.New("unexpected ServerKeyExchange") -} - -func (ka rsaKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - preMasterSecret := make([]byte, 48) - preMasterSecret[0] = byte(clientHello.vers >> 8) - preMasterSecret[1] = byte(clientHello.vers) - _, err := io.ReadFull(config.rand(), preMasterSecret[2:]) - if err != nil { - return nil, nil, err - } - - encrypted, err := rsa.EncryptPKCS1v15(config.rand(), cert.PublicKey.(*rsa.PublicKey), preMasterSecret) - if err != nil { - return nil, nil, err - } - ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, len(encrypted)+2) - ckx.ciphertext[0] = byte(len(encrypted) >> 8) - ckx.ciphertext[1] = byte(len(encrypted)) - copy(ckx.ciphertext[2:], encrypted) - return preMasterSecret, ckx, nil -} - -// sha1Hash calculates a SHA1 hash over the given byte slices. -func sha1Hash(slices [][]byte) []byte { - hsha1 := sha1.New() - for _, slice := range slices { - hsha1.Write(slice) - } - return hsha1.Sum(nil) -} - -// md5SHA1Hash implements TLS 1.0's hybrid hash function which consists of the -// concatenation of an MD5 and SHA1 hash. -func md5SHA1Hash(slices [][]byte) []byte { - md5sha1 := make([]byte, md5.Size+sha1.Size) - hmd5 := md5.New() - for _, slice := range slices { - hmd5.Write(slice) - } - copy(md5sha1, hmd5.Sum(nil)) - copy(md5sha1[md5.Size:], sha1Hash(slices)) - return md5sha1 -} - -// sha256Hash implements TLS 1.2's hash function. -func sha256Hash(slices [][]byte) []byte { - h := sha256.New() - for _, slice := range slices { - h.Write(slice) - } - return h.Sum(nil) -} - -// hashForServerKeyExchange hashes the given slices and returns their digest -// and the identifier of the hash function used. The hashFunc argument is only -// used for >= TLS 1.2 and precisely identifies the hash function to use. -func hashForServerKeyExchange(sigType, hashFunc uint8, version uint16, slices ...[]byte) ([]byte, crypto.Hash, error) { - if version >= VersionTLS12 { - switch hashFunc { - case hashSHA256: - return sha256Hash(slices), crypto.SHA256, nil - case hashSHA1: - return sha1Hash(slices), crypto.SHA1, nil - default: - return nil, crypto.Hash(0), errors.New("tls: unknown hash function used by peer") - } - } - if sigType == signatureECDSA { - return sha1Hash(slices), crypto.SHA1, nil - } - return md5SHA1Hash(slices), crypto.MD5SHA1, nil -} - -// pickTLS12HashForSignature returns a TLS 1.2 hash identifier for signing a -// ServerKeyExchange given the signature type being used and the client's -// advertized list of supported signature and hash combinations. -func pickTLS12HashForSignature(sigType uint8, clientSignatureAndHashes []signatureAndHash) (uint8, error) { - if len(clientSignatureAndHashes) == 0 { - // If the client didn't specify any signature_algorithms - // extension then we can assume that it supports SHA1. See - // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 - return hashSHA1, nil - } - - for _, sigAndHash := range clientSignatureAndHashes { - if sigAndHash.signature != sigType { - continue - } - switch sigAndHash.hash { - case hashSHA1, hashSHA256: - return sigAndHash.hash, nil - } - } - - return 0, errors.New("tls: client doesn't support any common hash functions") -} - -// ecdheRSAKeyAgreement implements a TLS key agreement where the server -// generates a ephemeral EC public/private key pair and signs it. The -// pre-master secret is then calculated using ECDH. The signature may -// either be ECDSA or RSA. -type ecdheKeyAgreement struct { - version uint16 - sigType uint8 - privateKey []byte - curve elliptic.Curve - x, y *big.Int -} - -func (ka *ecdheKeyAgreement) generateServerKeyExchange(config *Config, cert *Certificate, clientHello *clientHelloMsg, hello *serverHelloMsg) (*serverKeyExchangeMsg, error) { - var curveid uint16 - -Curve: - for _, c := range clientHello.supportedCurves { - switch c { - case curveP256: - ka.curve = elliptic.P256() - curveid = c - break Curve - case curveP384: - ka.curve = elliptic.P384() - curveid = c - break Curve - case curveP521: - ka.curve = elliptic.P521() - curveid = c - break Curve - } - } - - if curveid == 0 { - return nil, errors.New("tls: no supported elliptic curves offered") - } - - var x, y *big.Int - var err error - ka.privateKey, x, y, err = elliptic.GenerateKey(ka.curve, config.rand()) - if err != nil { - return nil, err - } - ecdhePublic := elliptic.Marshal(ka.curve, x, y) - - // http://tools.ietf.org/html/rfc4492#section-5.4 - serverECDHParams := make([]byte, 1+2+1+len(ecdhePublic)) - serverECDHParams[0] = 3 // named curve - serverECDHParams[1] = byte(curveid >> 8) - serverECDHParams[2] = byte(curveid) - serverECDHParams[3] = byte(len(ecdhePublic)) - copy(serverECDHParams[4:], ecdhePublic) - - var tls12HashId uint8 - if ka.version >= VersionTLS12 { - if tls12HashId, err = pickTLS12HashForSignature(ka.sigType, clientHello.signatureAndHashes); err != nil { - return nil, err - } - } - - digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, hello.random, serverECDHParams) - if err != nil { - return nil, err - } - var sig []byte - switch ka.sigType { - case signatureECDSA: - privKey, ok := cert.PrivateKey.(*ecdsa.PrivateKey) - if !ok { - return nil, errors.New("ECDHE ECDSA requires an ECDSA server private key") - } - r, s, err := ecdsa.Sign(config.rand(), privKey, digest) - if err != nil { - return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) - } - sig, err = asn1.Marshal(ecdsaSignature{r, s}) - case signatureRSA: - privKey, ok := cert.PrivateKey.(*rsa.PrivateKey) - if !ok { - return nil, errors.New("ECDHE RSA requires a RSA server private key") - } - sig, err = rsa.SignPKCS1v15(config.rand(), privKey, hashFunc, digest) - if err != nil { - return nil, errors.New("failed to sign ECDHE parameters: " + err.Error()) - } - default: - return nil, errors.New("unknown ECDHE signature algorithm") - } - - skx := new(serverKeyExchangeMsg) - sigAndHashLen := 0 - if ka.version >= VersionTLS12 { - sigAndHashLen = 2 - } - skx.key = make([]byte, len(serverECDHParams)+sigAndHashLen+2+len(sig)) - copy(skx.key, serverECDHParams) - k := skx.key[len(serverECDHParams):] - if ka.version >= VersionTLS12 { - k[0] = tls12HashId - k[1] = ka.sigType - k = k[2:] - } - k[0] = byte(len(sig) >> 8) - k[1] = byte(len(sig)) - copy(k[2:], sig) - - return skx, nil -} - -func (ka *ecdheKeyAgreement) processClientKeyExchange(config *Config, cert *Certificate, ckx *clientKeyExchangeMsg, version uint16) ([]byte, error) { - if len(ckx.ciphertext) == 0 || int(ckx.ciphertext[0]) != len(ckx.ciphertext)-1 { - return nil, errors.New("bad ClientKeyExchange") - } - x, y := elliptic.Unmarshal(ka.curve, ckx.ciphertext[1:]) - if x == nil { - return nil, errors.New("bad ClientKeyExchange") - } - x, _ = ka.curve.ScalarMult(x, y, ka.privateKey) - preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3) - xBytes := x.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) - - return preMasterSecret, nil -} - -var errServerKeyExchange = errors.New("invalid ServerKeyExchange") - -func (ka *ecdheKeyAgreement) processServerKeyExchange(config *Config, clientHello *clientHelloMsg, serverHello *serverHelloMsg, cert *x509.Certificate, skx *serverKeyExchangeMsg) error { - if len(skx.key) < 4 { - return errServerKeyExchange - } - if skx.key[0] != 3 { // named curve - return errors.New("server selected unsupported curve") - } - curveid := uint16(skx.key[1])<<8 | uint16(skx.key[2]) - - switch curveid { - case curveP256: - ka.curve = elliptic.P256() - case curveP384: - ka.curve = elliptic.P384() - case curveP521: - ka.curve = elliptic.P521() - default: - return errors.New("server selected unsupported curve") - } - - publicLen := int(skx.key[3]) - if publicLen+4 > len(skx.key) { - return errServerKeyExchange - } - ka.x, ka.y = elliptic.Unmarshal(ka.curve, skx.key[4:4+publicLen]) - if ka.x == nil { - return errServerKeyExchange - } - serverECDHParams := skx.key[:4+publicLen] - - sig := skx.key[4+publicLen:] - if len(sig) < 2 { - return errServerKeyExchange - } - - var tls12HashId uint8 - if ka.version >= VersionTLS12 { - // handle SignatureAndHashAlgorithm - var sigAndHash []uint8 - sigAndHash, sig = sig[:2], sig[2:] - if sigAndHash[1] != ka.sigType { - return errServerKeyExchange - } - tls12HashId = sigAndHash[0] - if len(sig) < 2 { - return errServerKeyExchange - } - } - sigLen := int(sig[0])<<8 | int(sig[1]) - if sigLen+2 != len(sig) { - return errServerKeyExchange - } - sig = sig[2:] - - digest, hashFunc, err := hashForServerKeyExchange(ka.sigType, tls12HashId, ka.version, clientHello.random, serverHello.random, serverECDHParams) - if err != nil { - return err - } - switch ka.sigType { - case signatureECDSA: - pubKey, ok := cert.PublicKey.(*ecdsa.PublicKey) - if !ok { - return errors.New("ECDHE ECDSA requires a ECDSA server public key") - } - ecdsaSig := new(ecdsaSignature) - if _, err := asn1.Unmarshal(sig, ecdsaSig); err != nil { - return err - } - if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 { - return errors.New("ECDSA signature contained zero or negative values") - } - if !ecdsa.Verify(pubKey, digest, ecdsaSig.R, ecdsaSig.S) { - return errors.New("ECDSA verification failure") - } - case signatureRSA: - pubKey, ok := cert.PublicKey.(*rsa.PublicKey) - if !ok { - return errors.New("ECDHE RSA requires a RSA server public key") - } - if err := rsa.VerifyPKCS1v15(pubKey, hashFunc, digest, sig); err != nil { - return err - } - default: - return errors.New("unknown ECDHE signature algorithm") - } - - return nil -} - -func (ka *ecdheKeyAgreement) generateClientKeyExchange(config *Config, clientHello *clientHelloMsg, cert *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error) { - if ka.curve == nil { - return nil, nil, errors.New("missing ServerKeyExchange message") - } - priv, mx, my, err := elliptic.GenerateKey(ka.curve, config.rand()) - if err != nil { - return nil, nil, err - } - x, _ := ka.curve.ScalarMult(ka.x, ka.y, priv) - preMasterSecret := make([]byte, (ka.curve.Params().BitSize+7)>>3) - xBytes := x.Bytes() - copy(preMasterSecret[len(preMasterSecret)-len(xBytes):], xBytes) - - serialized := elliptic.Marshal(ka.curve, mx, my) - - ckx := new(clientKeyExchangeMsg) - ckx.ciphertext = make([]byte, 1+len(serialized)) - ckx.ciphertext[0] = byte(len(serialized)) - copy(ckx.ciphertext[1:], serialized) - - return preMasterSecret, ckx, nil -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/main.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/main.go deleted file mode 100644 index 0b43ce8e..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/main.go +++ /dev/null @@ -1,151 +0,0 @@ -package main - -import ( - "crypto/rand" - "encoding/hex" - "flag" - "fmt" - "io" - "io/ioutil" - "net" - "os" - "time" -) - -const disclaimer = ` -This program was written to help system administrators test their servers for -the OpenSSL "heartbleed" vulnerability. The author is not responsible for any -damages as a result of using this tool (may eat your data, etc.) or for any -misuse of this tool for malicious purposes. -` - -var ( - nbytes = flag.Int("n", 16, "number of bytes to request") - output = flag.String("o", "", "write binary data to the specified file") - quiet = flag.Bool("q", false, "quiet, use exit code to report server status (0=safe)") - timeout = flag.Duration("t", 5*time.Second, "i/o timeout") -) - -func init() { - flag.Usage = func() { - fmt.Fprintf(os.Stderr, "usage: %s [options] host:port\n\n", os.Args[0]) - flag.PrintDefaults() - fmt.Fprintf(os.Stderr, disclaimer) - } - if flag.Parse(); flag.NArg() != 1 { - flag.Usage() - os.Exit(2) - } -} - -func main() { - c, err := Dial("tcp", flag.Arg(0), &Config{InsecureSkipVerify: true}) - if err != nil { - panic(err) - } - defer c.Close() - - info("Connected to %s", flag.Arg(0)) - c.SetDeadline(time.Now().Add(*timeout)) - - if _, err := c.Heartbeat(nil); err != nil { - info("Server does not support TLS heartbeats :)") - if isTimeout(err) || isUnexpected(err) { - return - } - panic(err) - } - - info("Server supports TLS heartbeats, requesting %d bytes...", *nbytes) - b, err := c.Heartbleed(*nbytes) - if len(b) == 0 && err != nil { - info("Server is not vulnerable :)") - if err == io.EOF || isTimeout(err) { - return - } - panic(err) - } - - if *output != "" { - ioutil.WriteFile(*output, b, 0666) - } - if !*quiet { - w := hex.Dumper(os.Stdout) - w.Write(b) - w.Close() - } - info("Server is vulnerable :(") - if err != nil { - panic(err) - } - os.Exit(1) -} - -func info(format string, a ...interface{}) { - if !*quiet { - fmt.Fprintf(os.Stderr, format+"\n", a...) - } -} - -func isTimeout(err error) bool { - e, ok := err.(net.Error) - return ok && e.Timeout() -} - -func isUnexpected(err error) bool { - e, ok := err.(*net.OpError) - return ok && e.Err == alertUnexpectedMessage -} - -func (c *Conn) Heartbeat(b []byte) ([]byte, error) { - io.ReadFull(rand.Reader, c.tmp[:16]) - return c.heartbeat(len(b), b, c.tmp[:16]) -} - -func (c *Conn) Heartbleed(n int) ([]byte, error) { - return c.heartbeat(n, nil, nil) -} - -const ( - recordTypeHeartbeat recordType = 24 - heartbeatRequest byte = 1 - heartbeatResponse byte = 2 -) - -func (c *Conn) heartbeat(n int, payload, padding []byte) ([]byte, error) { - if err := c.Handshake(); err != nil { - return nil, err - } - - buf := make([]byte, 3, 3+len(payload)+len(padding)) - buf[0] = heartbeatRequest - buf[1] = byte(n >> 8) - buf[2] = byte(n) - buf = append(append(buf, payload...), padding...) - - c.out.Lock() - defer c.out.Unlock() - c.writeRecord(recordTypeHeartbeat, buf) - - const maxConsecutiveEmptyRecords = 100 - for emptyRecordCount := 0; emptyRecordCount <= maxConsecutiveEmptyRecords; emptyRecordCount++ { - for c.hb == nil && c.error() == nil { - if err := c.readRecord(recordTypeHeartbeat); err != nil { - // Soft error, like EAGAIN - return nil, err - } - } - var b []byte - if c.hb != nil { - b = c.hb.data[c.hb.off:] - c.hb = nil - if len(b) < 1+2+16 || b[0] != heartbeatResponse { - b = nil - } else { - b = b[3 : len(b)-16] - } - } - return b, c.error() - } - return nil, io.ErrNoProgress -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/prf.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/prf.go deleted file mode 100644 index 36ca210c..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/prf.go +++ /dev/null @@ -1,291 +0,0 @@ -// Copyright 2009 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 main - -import ( - "crypto" - "crypto/hmac" - "crypto/md5" - "crypto/sha1" - "crypto/sha256" - "hash" -) - -// Split a premaster secret in two as specified in RFC 4346, section 5. -func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { - s1 = secret[0 : (len(secret)+1)/2] - s2 = secret[len(secret)/2:] - return -} - -// pHash implements the P_hash function, as defined in RFC 4346, section 5. -func pHash(result, secret, seed []byte, hash func() hash.Hash) { - h := hmac.New(hash, secret) - h.Write(seed) - a := h.Sum(nil) - - j := 0 - for j < len(result) { - h.Reset() - h.Write(a) - h.Write(seed) - b := h.Sum(nil) - todo := len(b) - if j+todo > len(result) { - todo = len(result) - j - } - copy(result[j:j+todo], b) - j += todo - - h.Reset() - h.Write(a) - a = h.Sum(nil) - } -} - -// prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5. -func prf10(result, secret, label, seed []byte) { - hashSHA1 := sha1.New - hashMD5 := md5.New - - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - s1, s2 := splitPreMasterSecret(secret) - pHash(result, s1, labelAndSeed, hashMD5) - result2 := make([]byte, len(result)) - pHash(result2, s2, labelAndSeed, hashSHA1) - - for i, b := range result2 { - result[i] ^= b - } -} - -// prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5. -func prf12(result, secret, label, seed []byte) { - labelAndSeed := make([]byte, len(label)+len(seed)) - copy(labelAndSeed, label) - copy(labelAndSeed[len(label):], seed) - - pHash(result, secret, labelAndSeed, sha256.New) -} - -// prf30 implements the SSL 3.0 pseudo-random function, as defined in -// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6. -func prf30(result, secret, label, seed []byte) { - hashSHA1 := sha1.New() - hashMD5 := md5.New() - - done := 0 - i := 0 - // RFC5246 section 6.3 says that the largest PRF output needed is 128 - // bytes. Since no more ciphersuites will be added to SSLv3, this will - // remain true. Each iteration gives us 16 bytes so 10 iterations will - // be sufficient. - var b [11]byte - for done < len(result) { - for j := 0; j <= i; j++ { - b[j] = 'A' + byte(i) - } - - hashSHA1.Reset() - hashSHA1.Write(b[:i+1]) - hashSHA1.Write(secret) - hashSHA1.Write(seed) - digest := hashSHA1.Sum(nil) - - hashMD5.Reset() - hashMD5.Write(secret) - hashMD5.Write(digest) - - done += copy(result[done:], hashMD5.Sum(nil)) - i++ - } -} - -const ( - tlsRandomLength = 32 // Length of a random nonce in TLS 1.1. - masterSecretLength = 48 // Length of a master secret in TLS 1.1. - finishedVerifyLength = 12 // Length of verify_data in a Finished message. -) - -var masterSecretLabel = []byte("master secret") -var keyExpansionLabel = []byte("key expansion") -var clientFinishedLabel = []byte("client finished") -var serverFinishedLabel = []byte("server finished") - -func prfForVersion(version uint16) func(result, secret, label, seed []byte) { - switch version { - case VersionSSL30: - return prf30 - case VersionTLS10, VersionTLS11: - return prf10 - case VersionTLS12: - return prf12 - default: - panic("unknown version") - } -} - -// masterFromPreMasterSecret generates the master secret from the pre-master -// secret. See http://tools.ietf.org/html/rfc5246#section-8.1 -func masterFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte) []byte { - var seed [tlsRandomLength * 2]byte - copy(seed[0:len(clientRandom)], clientRandom) - copy(seed[len(clientRandom):], serverRandom) - masterSecret := make([]byte, masterSecretLength) - prfForVersion(version)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) - return masterSecret -} - -// keysFromMasterSecret generates the connection keys from the master -// secret, given the lengths of the MAC key, cipher key and IV, as defined in -// RFC 2246, section 6.3. -func keysFromMasterSecret(version uint16, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { - var seed [tlsRandomLength * 2]byte - copy(seed[0:len(clientRandom)], serverRandom) - copy(seed[len(serverRandom):], clientRandom) - - n := 2*macLen + 2*keyLen + 2*ivLen - keyMaterial := make([]byte, n) - prfForVersion(version)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) - clientMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - serverMAC = keyMaterial[:macLen] - keyMaterial = keyMaterial[macLen:] - clientKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - serverKey = keyMaterial[:keyLen] - keyMaterial = keyMaterial[keyLen:] - clientIV = keyMaterial[:ivLen] - keyMaterial = keyMaterial[ivLen:] - serverIV = keyMaterial[:ivLen] - return -} - -func newFinishedHash(version uint16) finishedHash { - if version >= VersionTLS12 { - return finishedHash{sha256.New(), sha256.New(), nil, nil, version} - } - return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), version} -} - -// A finishedHash calculates the hash of a set of handshake messages suitable -// for including in a Finished message. -type finishedHash struct { - client hash.Hash - server hash.Hash - - // Prior to TLS 1.2, an additional MD5 hash is required. - clientMD5 hash.Hash - serverMD5 hash.Hash - - version uint16 -} - -func (h finishedHash) Write(msg []byte) (n int, err error) { - h.client.Write(msg) - h.server.Write(msg) - - if h.version < VersionTLS12 { - h.clientMD5.Write(msg) - h.serverMD5.Write(msg) - } - return len(msg), nil -} - -// finishedSum30 calculates the contents of the verify_data member of a SSLv3 -// Finished message given the MD5 and SHA1 hashes of a set of handshake -// messages. -func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte { - md5.Write(magic[:]) - md5.Write(masterSecret) - md5.Write(ssl30Pad1[:]) - md5Digest := md5.Sum(nil) - - md5.Reset() - md5.Write(masterSecret) - md5.Write(ssl30Pad2[:]) - md5.Write(md5Digest) - md5Digest = md5.Sum(nil) - - sha1.Write(magic[:]) - sha1.Write(masterSecret) - sha1.Write(ssl30Pad1[:40]) - sha1Digest := sha1.Sum(nil) - - sha1.Reset() - sha1.Write(masterSecret) - sha1.Write(ssl30Pad2[:40]) - sha1.Write(sha1Digest) - sha1Digest = sha1.Sum(nil) - - ret := make([]byte, len(md5Digest)+len(sha1Digest)) - copy(ret, md5Digest) - copy(ret[len(md5Digest):], sha1Digest) - return ret -} - -var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54} -var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52} - -// clientSum returns the contents of the verify_data member of a client's -// Finished message. -func (h finishedHash) clientSum(masterSecret []byte) []byte { - if h.version == VersionSSL30 { - return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic) - } - - out := make([]byte, finishedVerifyLength) - if h.version >= VersionTLS12 { - seed := h.client.Sum(nil) - prf12(out, masterSecret, clientFinishedLabel, seed) - } else { - seed := make([]byte, 0, md5.Size+sha1.Size) - seed = h.clientMD5.Sum(seed) - seed = h.client.Sum(seed) - prf10(out, masterSecret, clientFinishedLabel, seed) - } - return out -} - -// serverSum returns the contents of the verify_data member of a server's -// Finished message. -func (h finishedHash) serverSum(masterSecret []byte) []byte { - if h.version == VersionSSL30 { - return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic) - } - - out := make([]byte, finishedVerifyLength) - if h.version >= VersionTLS12 { - seed := h.server.Sum(nil) - prf12(out, masterSecret, serverFinishedLabel, seed) - } else { - seed := make([]byte, 0, md5.Size+sha1.Size) - seed = h.serverMD5.Sum(seed) - seed = h.server.Sum(seed) - prf10(out, masterSecret, serverFinishedLabel, seed) - } - return out -} - -// hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash -// id suitable for signing by a TLS client certificate. -func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash, uint8) { - if h.version >= VersionTLS12 { - digest := h.server.Sum(nil) - return digest, crypto.SHA256, hashSHA256 - } - if sigType == signatureECDSA { - digest := h.server.Sum(nil) - return digest, crypto.SHA1, hashSHA1 - } - - digest := make([]byte, 0, 36) - digest = h.serverMD5.Sum(digest) - digest = h.server.Sum(digest) - return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */ -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/ticket.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/ticket.go deleted file mode 100644 index 70e91cfc..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/ticket.go +++ /dev/null @@ -1,182 +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 main - -import ( - "bytes" - "crypto/aes" - "crypto/cipher" - "crypto/hmac" - "crypto/sha256" - "crypto/subtle" - "errors" - "io" -) - -// sessionState contains the information that is serialized into a session -// ticket in order to later resume a connection. -type sessionState struct { - vers uint16 - cipherSuite uint16 - masterSecret []byte - certificates [][]byte -} - -func (s *sessionState) equal(i interface{}) bool { - s1, ok := i.(*sessionState) - if !ok { - return false - } - - if s.vers != s1.vers || - s.cipherSuite != s1.cipherSuite || - !bytes.Equal(s.masterSecret, s1.masterSecret) { - return false - } - - if len(s.certificates) != len(s1.certificates) { - return false - } - - for i := range s.certificates { - if !bytes.Equal(s.certificates[i], s1.certificates[i]) { - return false - } - } - - return true -} - -func (s *sessionState) marshal() []byte { - length := 2 + 2 + 2 + len(s.masterSecret) + 2 - for _, cert := range s.certificates { - length += 4 + len(cert) - } - - ret := make([]byte, length) - x := ret - x[0] = byte(s.vers >> 8) - x[1] = byte(s.vers) - x[2] = byte(s.cipherSuite >> 8) - x[3] = byte(s.cipherSuite) - x[4] = byte(len(s.masterSecret) >> 8) - x[5] = byte(len(s.masterSecret)) - x = x[6:] - copy(x, s.masterSecret) - x = x[len(s.masterSecret):] - - x[0] = byte(len(s.certificates) >> 8) - x[1] = byte(len(s.certificates)) - x = x[2:] - - for _, cert := range s.certificates { - x[0] = byte(len(cert) >> 24) - x[1] = byte(len(cert) >> 16) - x[2] = byte(len(cert) >> 8) - x[3] = byte(len(cert)) - copy(x[4:], cert) - x = x[4+len(cert):] - } - - return ret -} - -func (s *sessionState) unmarshal(data []byte) bool { - if len(data) < 8 { - return false - } - - s.vers = uint16(data[0])<<8 | uint16(data[1]) - s.cipherSuite = uint16(data[2])<<8 | uint16(data[3]) - masterSecretLen := int(data[4])<<8 | int(data[5]) - data = data[6:] - if len(data) < masterSecretLen { - return false - } - - s.masterSecret = data[:masterSecretLen] - data = data[masterSecretLen:] - - if len(data) < 2 { - return false - } - - numCerts := int(data[0])<<8 | int(data[1]) - data = data[2:] - - s.certificates = make([][]byte, numCerts) - for i := range s.certificates { - if len(data) < 4 { - return false - } - certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3]) - data = data[4:] - if certLen < 0 { - return false - } - if len(data) < certLen { - return false - } - s.certificates[i] = data[:certLen] - data = data[certLen:] - } - - if len(data) > 0 { - return false - } - - return true -} - -func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) { - serialized := state.marshal() - encrypted := make([]byte, aes.BlockSize+len(serialized)+sha256.Size) - iv := encrypted[:aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - - if _, err := io.ReadFull(c.config.rand(), iv); err != nil { - return nil, err - } - block, err := aes.NewCipher(c.config.SessionTicketKey[:16]) - if err != nil { - return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) - } - cipher.NewCTR(block, iv).XORKeyStream(encrypted[aes.BlockSize:], serialized) - - mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - mac.Sum(macBytes[:0]) - - return encrypted, nil -} - -func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) { - if len(encrypted) < aes.BlockSize+sha256.Size { - return nil, false - } - - iv := encrypted[:aes.BlockSize] - macBytes := encrypted[len(encrypted)-sha256.Size:] - - mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32]) - mac.Write(encrypted[:len(encrypted)-sha256.Size]) - expected := mac.Sum(nil) - - if subtle.ConstantTimeCompare(macBytes, expected) != 1 { - return nil, false - } - - block, err := aes.NewCipher(c.config.SessionTicketKey[:16]) - if err != nil { - return nil, false - } - ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size] - plaintext := ciphertext - cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext) - - state := new(sessionState) - ok := state.unmarshal(plaintext) - return state, ok -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/tls.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/tls.go deleted file mode 100644 index c8574bb4..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/tlshb/tls.go +++ /dev/null @@ -1,225 +0,0 @@ -// Copyright 2009 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 tls partially implements TLS 1.2, as specified in RFC 5246. -package main - -import ( - "crypto" - "crypto/ecdsa" - "crypto/rsa" - "crypto/x509" - "encoding/pem" - "errors" - "io/ioutil" - "net" - "strings" -) - -// Server returns a new TLS server side connection -// using conn as the underlying transport. -// The configuration config must be non-nil and must have -// at least one certificate. -func Server(conn net.Conn, config *Config) *Conn { - return &Conn{conn: conn, config: config} -} - -// Client returns a new TLS client side connection -// using conn as the underlying transport. -// Client interprets a nil configuration as equivalent to -// the zero configuration; see the documentation of Config -// for the defaults. -func Client(conn net.Conn, config *Config) *Conn { - return &Conn{conn: conn, config: config, isClient: true} -} - -// A listener implements a network listener (net.Listener) for TLS connections. -type listener struct { - net.Listener - config *Config -} - -// Accept waits for and returns the next incoming TLS connection. -// The returned connection c is a *tls.Conn. -func (l *listener) Accept() (c net.Conn, err error) { - c, err = l.Listener.Accept() - if err != nil { - return - } - c = Server(c, l.config) - return -} - -// NewListener creates a Listener which accepts connections from an inner -// Listener and wraps each connection with Server. -// The configuration config must be non-nil and must have -// at least one certificate. -func NewListener(inner net.Listener, config *Config) net.Listener { - l := new(listener) - l.Listener = inner - l.config = config - return l -} - -// Listen creates a TLS listener accepting connections on the -// given network address using net.Listen. -// The configuration config must be non-nil and must have -// at least one certificate. -func Listen(network, laddr string, config *Config) (net.Listener, error) { - if config == nil || len(config.Certificates) == 0 { - return nil, errors.New("tls.Listen: no certificates in configuration") - } - l, err := net.Listen(network, laddr) - if err != nil { - return nil, err - } - return NewListener(l, config), nil -} - -// Dial connects to the given network address using net.Dial -// and then initiates a TLS handshake, returning the resulting -// TLS connection. -// Dial interprets a nil configuration as equivalent to -// the zero configuration; see the documentation of Config -// for the defaults. -func Dial(network, addr string, config *Config) (*Conn, error) { - raddr := addr - c, err := net.Dial(network, raddr) - if err != nil { - return nil, err - } - - colonPos := strings.LastIndex(raddr, ":") - if colonPos == -1 { - colonPos = len(raddr) - } - hostname := raddr[:colonPos] - - if config == nil { - config = defaultConfig() - } - // If no ServerName is set, infer the ServerName - // from the hostname we're connecting to. - if config.ServerName == "" { - // Make a copy to avoid polluting argument or default. - c := *config - c.ServerName = hostname - config = &c - } - conn := Client(c, config) - if err = conn.Handshake(); err != nil { - c.Close() - return nil, err - } - return conn, nil -} - -// LoadX509KeyPair reads and parses a public/private key pair from a pair of -// files. The files must contain PEM encoded data. -func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) { - certPEMBlock, err := ioutil.ReadFile(certFile) - if err != nil { - return - } - keyPEMBlock, err := ioutil.ReadFile(keyFile) - if err != nil { - return - } - return X509KeyPair(certPEMBlock, keyPEMBlock) -} - -// X509KeyPair parses a public/private key pair from a pair of -// PEM encoded data. -func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) { - var certDERBlock *pem.Block - for { - certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) - if certDERBlock == nil { - break - } - if certDERBlock.Type == "CERTIFICATE" { - cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) - } - } - - if len(cert.Certificate) == 0 { - err = errors.New("crypto/tls: failed to parse certificate PEM data") - return - } - - var keyDERBlock *pem.Block - for { - keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) - if keyDERBlock == nil { - err = errors.New("crypto/tls: failed to parse key PEM data") - return - } - if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { - break - } - } - - cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) - if err != nil { - return - } - - // We don't need to parse the public key for TLS, but we so do anyway - // to check that it looks sane and matches the private key. - x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) - if err != nil { - return - } - - switch pub := x509Cert.PublicKey.(type) { - case *rsa.PublicKey: - priv, ok := cert.PrivateKey.(*rsa.PrivateKey) - if !ok { - err = errors.New("crypto/tls: private key type does not match public key type") - return - } - if pub.N.Cmp(priv.N) != 0 { - err = errors.New("crypto/tls: private key does not match public key") - return - } - case *ecdsa.PublicKey: - priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) - if !ok { - err = errors.New("crypto/tls: private key type does not match public key type") - return - - } - if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { - err = errors.New("crypto/tls: private key does not match public key") - return - } - default: - err = errors.New("crypto/tls: unknown public key algorithm") - return - } - - return -} - -// Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates -// PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys. -// OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. -func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { - if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { - return key, nil - } - if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { - switch key := key.(type) { - case *rsa.PrivateKey, *ecdsa.PrivateKey: - return key, nil - default: - return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping") - } - } - if key, err := x509.ParseECPrivateKey(der); err == nil { - return key, nil - } - - return nil, errors.New("crypto/tls: failed to parse private key") -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/.hgignore b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/.hgignore deleted file mode 100644 index d804706f..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/.hgignore +++ /dev/null @@ -1,30 +0,0 @@ -syntax:glob -.DS_Store -.git -.gitignore -*.[568ao] -*.ao -*.so -*.pyc -._* -.nfs.* -[568a].out -*~ -*.orig -*.rej -*.exe -.*.swp -core -*.cgo*.go -*.cgo*.c -_cgo_* -_obj -_test -_testmain.go -build.out -snappy/testdata -test.out -y.tab.[ch] - -syntax:regexp -^.*/core.[0-9]*$ diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/AUTHORS b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/AUTHORS deleted file mode 100644 index 8ddb5b7a..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/AUTHORS +++ /dev/null @@ -1,12 +0,0 @@ -# This is the official list of Snappy-Go authors for copyright purposes. -# This file is distinct from the CONTRIBUTORS files. -# See the latter for an explanation. - -# Names should be added to this file as -# Name or Organization -# The email address is not required for organizations. - -# Please keep the list sorted. - -Google Inc. -Jan Mercl <0xjnml@gmail.com> diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/CONTRIBUTORS b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/CONTRIBUTORS deleted file mode 100644 index 50b69c80..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/CONTRIBUTORS +++ /dev/null @@ -1,34 +0,0 @@ -# This is the official list of people who can contribute -# (and typically have contributed) code to the Snappy-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 - -# Please keep the list sorted. - -Jan Mercl <0xjnml@gmail.com> -Kai Backman -Marc-Antoine Ruel -Nigel Tao -Rob Pike -Russ Cox diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/README b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/README deleted file mode 100644 index 3cf8be1f..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/README +++ /dev/null @@ -1,11 +0,0 @@ -This is a Snappy library for the Go programming language. - -To download and install from source: -$ go get code.google.com/p/snappy-go/snappy - -Unless otherwise noted, the Snappy-Go source files are distributed -under the BSD-style license found in the LICENSE file. - -Contributions should follow the same procedure as for the Go project: -http://golang.org/doc/contribute.html - diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/lib/codereview/codereview.cfg b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/lib/codereview/codereview.cfg deleted file mode 100644 index 93b55c0a..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/lib/codereview/codereview.cfg +++ /dev/null @@ -1 +0,0 @@ -defaultcc: golang-dev@googlegroups.com diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/decode.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/decode.go deleted file mode 100644 index d93c1b9d..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/decode.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2011 The Snappy-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 snappy - -import ( - "encoding/binary" - "errors" -) - -// ErrCorrupt reports that the input is invalid. -var ErrCorrupt = errors.New("snappy: corrupt input") - -// DecodedLen returns the length of the decoded block. -func DecodedLen(src []byte) (int, error) { - v, _, err := decodedLen(src) - return v, err -} - -// decodedLen returns the length of the decoded block and the number of bytes -// that the length header occupied. -func decodedLen(src []byte) (blockLen, headerLen int, err error) { - v, n := binary.Uvarint(src) - if n == 0 { - return 0, 0, ErrCorrupt - } - if uint64(int(v)) != v { - return 0, 0, errors.New("snappy: decoded block is too large") - } - return int(v), n, nil -} - -// Decode returns the decoded form of src. The returned slice may be a sub- -// slice of dst if dst was large enough to hold the entire decoded block. -// Otherwise, a newly allocated slice will be returned. -// It is valid to pass a nil dst. -func Decode(dst, src []byte) ([]byte, error) { - dLen, s, err := decodedLen(src) - if err != nil { - return nil, err - } - if len(dst) < dLen { - dst = make([]byte, dLen) - } - - var d, offset, length int - for s < len(src) { - switch src[s] & 0x03 { - case tagLiteral: - x := uint(src[s] >> 2) - switch { - case x < 60: - s += 1 - case x == 60: - s += 2 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-1]) - case x == 61: - s += 3 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-2]) | uint(src[s-1])<<8 - case x == 62: - s += 4 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16 - case x == 63: - s += 5 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24 - } - length = int(x + 1) - if length <= 0 { - return nil, errors.New("snappy: unsupported literal length") - } - if length > len(dst)-d || length > len(src)-s { - return nil, ErrCorrupt - } - copy(dst[d:], src[s:s+length]) - d += length - s += length - continue - - case tagCopy1: - s += 2 - if s > len(src) { - return nil, ErrCorrupt - } - length = 4 + int(src[s-2])>>2&0x7 - offset = int(src[s-2])&0xe0<<3 | int(src[s-1]) - - case tagCopy2: - s += 3 - if s > len(src) { - return nil, ErrCorrupt - } - length = 1 + int(src[s-3])>>2 - offset = int(src[s-2]) | int(src[s-1])<<8 - - case tagCopy4: - return nil, errors.New("snappy: unsupported COPY_4 tag") - } - - end := d + length - if offset > d || end > len(dst) { - return nil, ErrCorrupt - } - for ; d < end; d++ { - dst[d] = dst[d-offset] - } - } - if d != dLen { - return nil, ErrCorrupt - } - return dst[:d], nil -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/encode.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/encode.go deleted file mode 100644 index b2371db1..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/encode.go +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2011 The Snappy-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 snappy - -import ( - "encoding/binary" -) - -// We limit how far copy back-references can go, the same as the C++ code. -const maxOffset = 1 << 15 - -// emitLiteral writes a literal chunk and returns the number of bytes written. -func emitLiteral(dst, lit []byte) int { - i, n := 0, uint(len(lit)-1) - switch { - case n < 60: - dst[0] = uint8(n)<<2 | tagLiteral - i = 1 - case n < 1<<8: - dst[0] = 60<<2 | tagLiteral - dst[1] = uint8(n) - i = 2 - case n < 1<<16: - dst[0] = 61<<2 | tagLiteral - dst[1] = uint8(n) - dst[2] = uint8(n >> 8) - i = 3 - case n < 1<<24: - dst[0] = 62<<2 | tagLiteral - dst[1] = uint8(n) - dst[2] = uint8(n >> 8) - dst[3] = uint8(n >> 16) - i = 4 - case int64(n) < 1<<32: - dst[0] = 63<<2 | tagLiteral - dst[1] = uint8(n) - dst[2] = uint8(n >> 8) - dst[3] = uint8(n >> 16) - dst[4] = uint8(n >> 24) - i = 5 - default: - panic("snappy: source buffer is too long") - } - if copy(dst[i:], lit) != len(lit) { - panic("snappy: destination buffer is too short") - } - return i + len(lit) -} - -// emitCopy writes a copy chunk and returns the number of bytes written. -func emitCopy(dst []byte, offset, length int) int { - i := 0 - for length > 0 { - x := length - 4 - if 0 <= x && x < 1<<3 && offset < 1<<11 { - dst[i+0] = uint8(offset>>8)&0x07<<5 | uint8(x)<<2 | tagCopy1 - dst[i+1] = uint8(offset) - i += 2 - break - } - - x = length - if x > 1<<6 { - x = 1 << 6 - } - dst[i+0] = uint8(x-1)<<2 | tagCopy2 - dst[i+1] = uint8(offset) - dst[i+2] = uint8(offset >> 8) - i += 3 - length -= x - } - return i -} - -// Encode returns the encoded form of src. The returned slice may be a sub- -// slice of dst if dst was large enough to hold the entire encoded block. -// Otherwise, a newly allocated slice will be returned. -// It is valid to pass a nil dst. -func Encode(dst, src []byte) ([]byte, error) { - if n := MaxEncodedLen(len(src)); len(dst) < n { - dst = make([]byte, n) - } - - // The block starts with the varint-encoded length of the decompressed bytes. - d := binary.PutUvarint(dst, uint64(len(src))) - - // Return early if src is short. - if len(src) <= 4 { - if len(src) != 0 { - d += emitLiteral(dst[d:], src) - } - return dst[:d], nil - } - - // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. - const maxTableSize = 1 << 14 - shift, tableSize := uint(32-8), 1<<8 - for tableSize < maxTableSize && tableSize < len(src) { - shift-- - tableSize *= 2 - } - var table [maxTableSize]int - - // Iterate over the source bytes. - var ( - s int // The iterator position. - t int // The last position with the same hash as s. - lit int // The start position of any pending literal bytes. - ) - for s+3 < len(src) { - // Update the hash table. - b0, b1, b2, b3 := src[s], src[s+1], src[s+2], src[s+3] - h := uint32(b0) | uint32(b1)<<8 | uint32(b2)<<16 | uint32(b3)<<24 - p := &table[(h*0x1e35a7bd)>>shift] - // We need to to store values in [-1, inf) in table. To save - // some initialization time, (re)use the table's zero value - // and shift the values against this zero: add 1 on writes, - // subtract 1 on reads. - t, *p = *p-1, s+1 - // If t is invalid or src[s:s+4] differs from src[t:t+4], accumulate a literal byte. - if t < 0 || s-t >= maxOffset || b0 != src[t] || b1 != src[t+1] || b2 != src[t+2] || b3 != src[t+3] { - s++ - continue - } - // Otherwise, we have a match. First, emit any pending literal bytes. - if lit != s { - d += emitLiteral(dst[d:], src[lit:s]) - } - // Extend the match to be as long as possible. - s0 := s - s, t = s+4, t+4 - for s < len(src) && src[s] == src[t] { - s++ - t++ - } - // Emit the copied bytes. - d += emitCopy(dst[d:], s-t, s-s0) - lit = s - } - - // Emit any final pending literal bytes and return. - if lit != len(src) { - d += emitLiteral(dst[d:], src[lit:]) - } - return dst[:d], nil -} - -// MaxEncodedLen returns the maximum length of a snappy block, given its -// uncompressed length. -func MaxEncodedLen(srcLen int) int { - // Compressed data can be defined as: - // compressed := item* literal* - // item := literal* copy - // - // The trailing literal sequence has a space blowup of at most 62/60 - // since a literal of length 60 needs one tag byte + one extra byte - // for length information. - // - // Item blowup is trickier to measure. Suppose the "copy" op copies - // 4 bytes of data. Because of a special check in the encoding code, - // we produce a 4-byte copy only if the offset is < 65536. Therefore - // the copy op takes 3 bytes to encode, and this type of item leads - // to at most the 62/60 blowup for representing literals. - // - // Suppose the "copy" op copies 5 bytes of data. If the offset is big - // enough, it will take 5 bytes to encode the copy op. Therefore the - // worst case here is a one-byte literal followed by a five-byte copy. - // That is, 6 bytes of input turn into 7 bytes of "compressed" data. - // - // This last factor dominates the blowup, so the final estimate is: - return 32 + srcLen + srcLen/6 -} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/snappy.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/snappy.go deleted file mode 100644 index 2f1b790d..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/snappy.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2011 The Snappy-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 snappy implements the snappy block-based compression format. -// It aims for very high speeds and reasonable compression. -// -// The C++ snappy implementation is at http://code.google.com/p/snappy/ -package snappy - -/* -Each encoded block begins with the varint-encoded length of the decoded data, -followed by a sequence of chunks. Chunks begin and end on byte boundaries. The -first byte of each chunk is broken into its 2 least and 6 most significant bits -called l and m: l ranges in [0, 4) and m ranges in [0, 64). l is the chunk tag. -Zero means a literal tag. All other values mean a copy tag. - -For literal tags: - - If m < 60, the next 1 + m bytes are literal bytes. - - Otherwise, let n be the little-endian unsigned integer denoted by the next - m - 59 bytes. The next 1 + n bytes after that are literal bytes. - -For copy tags, length bytes are copied from offset bytes ago, in the style of -Lempel-Ziv compression algorithms. In particular: - - For l == 1, the offset ranges in [0, 1<<11) and the length in [4, 12). - The length is 4 + the low 3 bits of m. The high 3 bits of m form bits 8-10 - of the offset. The next byte is bits 0-7 of the offset. - - For l == 2, the offset ranges in [0, 1<<16) and the length in [1, 65). - The length is 1 + m. The offset is the little-endian unsigned integer - denoted by the next 2 bytes. - - For l == 3, this tag is a legacy format that is no longer supported. -*/ -const ( - tagLiteral = 0x00 - tagCopy1 = 0x01 - tagCopy2 = 0x02 - tagCopy4 = 0x03 -) diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/snappy_test.go b/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/snappy_test.go deleted file mode 100644 index 7ba83924..00000000 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/snappy/snappy_test.go +++ /dev/null @@ -1,261 +0,0 @@ -// Copyright 2011 The Snappy-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 snappy - -import ( - "bytes" - "flag" - "fmt" - "io" - "io/ioutil" - "math/rand" - "net/http" - "os" - "path/filepath" - "strings" - "testing" -) - -var download = flag.Bool("download", false, "If true, download any missing files before running benchmarks") - -func roundtrip(b, ebuf, dbuf []byte) error { - e, err := Encode(ebuf, b) - if err != nil { - return fmt.Errorf("encoding error: %v", err) - } - d, err := Decode(dbuf, e) - if err != nil { - return fmt.Errorf("decoding error: %v", err) - } - if !bytes.Equal(b, d) { - return fmt.Errorf("roundtrip mismatch:\n\twant %v\n\tgot %v", b, d) - } - return nil -} - -func TestEmpty(t *testing.T) { - if err := roundtrip(nil, nil, nil); err != nil { - t.Fatal(err) - } -} - -func TestSmallCopy(t *testing.T) { - for _, ebuf := range [][]byte{nil, make([]byte, 20), make([]byte, 64)} { - for _, dbuf := range [][]byte{nil, make([]byte, 20), make([]byte, 64)} { - for i := 0; i < 32; i++ { - s := "aaaa" + strings.Repeat("b", i) + "aaaabbbb" - if err := roundtrip([]byte(s), ebuf, dbuf); err != nil { - t.Errorf("len(ebuf)=%d, len(dbuf)=%d, i=%d: %v", len(ebuf), len(dbuf), i, err) - } - } - } - } -} - -func TestSmallRand(t *testing.T) { - rand.Seed(27354294) - for n := 1; n < 20000; n += 23 { - b := make([]byte, n) - for i, _ := range b { - b[i] = uint8(rand.Uint32()) - } - if err := roundtrip(b, nil, nil); err != nil { - t.Fatal(err) - } - } -} - -func TestSmallRegular(t *testing.T) { - for n := 1; n < 20000; n += 23 { - b := make([]byte, n) - for i, _ := range b { - b[i] = uint8(i%10 + 'a') - } - if err := roundtrip(b, nil, nil); err != nil { - t.Fatal(err) - } - } -} - -func benchDecode(b *testing.B, src []byte) { - encoded, err := Encode(nil, src) - if err != nil { - b.Fatal(err) - } - // Bandwidth is in amount of uncompressed data. - b.SetBytes(int64(len(src))) - b.ResetTimer() - for i := 0; i < b.N; i++ { - Decode(src, encoded) - } -} - -func benchEncode(b *testing.B, src []byte) { - // Bandwidth is in amount of uncompressed data. - b.SetBytes(int64(len(src))) - dst := make([]byte, MaxEncodedLen(len(src))) - b.ResetTimer() - for i := 0; i < b.N; i++ { - Encode(dst, src) - } -} - -func readFile(b *testing.B, filename string) []byte { - src, err := ioutil.ReadFile(filename) - if err != nil { - b.Fatalf("failed reading %s: %s", filename, err) - } - if len(src) == 0 { - b.Fatalf("%s has zero length", filename) - } - return src -} - -// expand returns a slice of length n containing repeated copies of src. -func expand(src []byte, n int) []byte { - dst := make([]byte, n) - for x := dst; len(x) > 0; { - i := copy(x, src) - x = x[i:] - } - return dst -} - -func benchWords(b *testing.B, n int, decode bool) { - // Note: the file is OS-language dependent so the resulting values are not - // directly comparable for non-US-English OS installations. - data := expand(readFile(b, "/usr/share/dict/words"), n) - if decode { - benchDecode(b, data) - } else { - benchEncode(b, data) - } -} - -func BenchmarkWordsDecode1e3(b *testing.B) { benchWords(b, 1e3, true) } -func BenchmarkWordsDecode1e4(b *testing.B) { benchWords(b, 1e4, true) } -func BenchmarkWordsDecode1e5(b *testing.B) { benchWords(b, 1e5, true) } -func BenchmarkWordsDecode1e6(b *testing.B) { benchWords(b, 1e6, true) } -func BenchmarkWordsEncode1e3(b *testing.B) { benchWords(b, 1e3, false) } -func BenchmarkWordsEncode1e4(b *testing.B) { benchWords(b, 1e4, false) } -func BenchmarkWordsEncode1e5(b *testing.B) { benchWords(b, 1e5, false) } -func BenchmarkWordsEncode1e6(b *testing.B) { benchWords(b, 1e6, false) } - -// testFiles' values are copied directly from -// https://code.google.com/p/snappy/source/browse/trunk/snappy_unittest.cc. -// The label field is unused in snappy-go. -var testFiles = []struct { - label string - filename string -}{ - {"html", "html"}, - {"urls", "urls.10K"}, - {"jpg", "house.jpg"}, - {"pdf", "mapreduce-osdi-1.pdf"}, - {"html4", "html_x_4"}, - {"cp", "cp.html"}, - {"c", "fields.c"}, - {"lsp", "grammar.lsp"}, - {"xls", "kennedy.xls"}, - {"txt1", "alice29.txt"}, - {"txt2", "asyoulik.txt"}, - {"txt3", "lcet10.txt"}, - {"txt4", "plrabn12.txt"}, - {"bin", "ptt5"}, - {"sum", "sum"}, - {"man", "xargs.1"}, - {"pb", "geo.protodata"}, - {"gaviota", "kppkn.gtb"}, -} - -// The test data files are present at this canonical URL. -const baseURL = "https://snappy.googlecode.com/svn/trunk/testdata/" - -func downloadTestdata(basename string) (errRet error) { - filename := filepath.Join("testdata", basename) - f, err := os.Create(filename) - if err != nil { - return fmt.Errorf("failed to create %s: %s", filename, err) - } - defer f.Close() - defer func() { - if errRet != nil { - os.Remove(filename) - } - }() - resp, err := http.Get(baseURL + basename) - if err != nil { - return fmt.Errorf("failed to download %s: %s", baseURL+basename, err) - } - defer resp.Body.Close() - _, err = io.Copy(f, resp.Body) - if err != nil { - return fmt.Errorf("failed to write %s: %s", filename, err) - } - return nil -} - -func benchFile(b *testing.B, n int, decode bool) { - filename := filepath.Join("testdata", testFiles[n].filename) - if stat, err := os.Stat(filename); err != nil || stat.Size() == 0 { - if !*download { - b.Fatal("test data not found; skipping benchmark without the -download flag") - } - // Download the official snappy C++ implementation reference test data - // files for benchmarking. - if err := os.Mkdir("testdata", 0777); err != nil && !os.IsExist(err) { - b.Fatalf("failed to create testdata: %s", err) - } - for _, tf := range testFiles { - if err := downloadTestdata(tf.filename); err != nil { - b.Fatalf("failed to download testdata: %s", err) - } - } - } - data := readFile(b, filename) - if decode { - benchDecode(b, data) - } else { - benchEncode(b, data) - } -} - -// Naming convention is kept similar to what snappy's C++ implementation uses. -func Benchmark_UFlat0(b *testing.B) { benchFile(b, 0, true) } -func Benchmark_UFlat1(b *testing.B) { benchFile(b, 1, true) } -func Benchmark_UFlat2(b *testing.B) { benchFile(b, 2, true) } -func Benchmark_UFlat3(b *testing.B) { benchFile(b, 3, true) } -func Benchmark_UFlat4(b *testing.B) { benchFile(b, 4, true) } -func Benchmark_UFlat5(b *testing.B) { benchFile(b, 5, true) } -func Benchmark_UFlat6(b *testing.B) { benchFile(b, 6, true) } -func Benchmark_UFlat7(b *testing.B) { benchFile(b, 7, true) } -func Benchmark_UFlat8(b *testing.B) { benchFile(b, 8, true) } -func Benchmark_UFlat9(b *testing.B) { benchFile(b, 9, true) } -func Benchmark_UFlat10(b *testing.B) { benchFile(b, 10, true) } -func Benchmark_UFlat11(b *testing.B) { benchFile(b, 11, true) } -func Benchmark_UFlat12(b *testing.B) { benchFile(b, 12, true) } -func Benchmark_UFlat13(b *testing.B) { benchFile(b, 13, true) } -func Benchmark_UFlat14(b *testing.B) { benchFile(b, 14, true) } -func Benchmark_UFlat15(b *testing.B) { benchFile(b, 15, true) } -func Benchmark_UFlat16(b *testing.B) { benchFile(b, 16, true) } -func Benchmark_UFlat17(b *testing.B) { benchFile(b, 17, true) } -func Benchmark_ZFlat0(b *testing.B) { benchFile(b, 0, false) } -func Benchmark_ZFlat1(b *testing.B) { benchFile(b, 1, false) } -func Benchmark_ZFlat2(b *testing.B) { benchFile(b, 2, false) } -func Benchmark_ZFlat3(b *testing.B) { benchFile(b, 3, false) } -func Benchmark_ZFlat4(b *testing.B) { benchFile(b, 4, false) } -func Benchmark_ZFlat5(b *testing.B) { benchFile(b, 5, false) } -func Benchmark_ZFlat6(b *testing.B) { benchFile(b, 6, false) } -func Benchmark_ZFlat7(b *testing.B) { benchFile(b, 7, false) } -func Benchmark_ZFlat8(b *testing.B) { benchFile(b, 8, false) } -func Benchmark_ZFlat9(b *testing.B) { benchFile(b, 9, false) } -func Benchmark_ZFlat10(b *testing.B) { benchFile(b, 10, false) } -func Benchmark_ZFlat11(b *testing.B) { benchFile(b, 11, false) } -func Benchmark_ZFlat12(b *testing.B) { benchFile(b, 12, false) } -func Benchmark_ZFlat13(b *testing.B) { benchFile(b, 13, false) } -func Benchmark_ZFlat14(b *testing.B) { benchFile(b, 14, false) } -func Benchmark_ZFlat15(b *testing.B) { benchFile(b, 15, false) } -func Benchmark_ZFlat16(b *testing.B) { benchFile(b, 16, false) } -func Benchmark_ZFlat17(b *testing.B) { benchFile(b, 17, false) } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/AUTHORS.md b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/AUTHORS.md new file mode 100644 index 00000000..d495fb75 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/AUTHORS.md @@ -0,0 +1,4 @@ +This is the official list of JsonConfigReader authors for copyright purposes. + +* DisposaBoy `https://github.com/DisposaBoy` +* Steven Osborn `https://github.com/steve918` diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/LICENSE.md b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/LICENSE.md new file mode 100644 index 00000000..3f4ba513 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/LICENSE.md @@ -0,0 +1,7 @@ +Copyright (c) 2012 The JsonConfigReader Authors + +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/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/README.md b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/README.md new file mode 100644 index 00000000..5df22075 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/README.md @@ -0,0 +1,36 @@ +JsonConfigReader is a proxy for [golang's io.Reader](http://golang.org/pkg/io/#Reader) that strips line comments and trailing commas, allowing you to use json as a *reasonable* config format. + +Comments start with `//` and continue to the end of the line. + +If a trailing comma is in front of `]` or `}` it will be stripped as well. + + +Given `settings.json` + + { + "key": "value", // k:v + + // a list of numbers + "list": [1, 2, 3], + } + + +You can read it in as a *normal* json file: + + package main + + import ( + "encoding/json" + "fmt" + "github.com/DisposaBoy/JsonConfigReader" + "os" + ) + + func main() { + var v interface{} + f, _ := os.Open("settings.json") + // wrap our reader before passing it to the json decoder + r := JsonConfigReader.New(f) + json.NewDecoder(r).Decode(&v) + fmt.Println(v) + } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/reader.go b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/reader.go new file mode 100644 index 00000000..06ae65d2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/reader.go @@ -0,0 +1,94 @@ +package JsonConfigReader + +import ( + "bytes" + "io" +) + +type state struct { + r io.Reader + br *bytes.Reader +} + +func isNL(c byte) bool { + return c == '\n' || c == '\r' +} + +func isWS(c byte) bool { + return c == ' ' || c == '\t' || isNL(c) +} + +func consumeComment(s []byte, i int) int { + if i < len(s) && s[i] == '/' { + s[i-1] = ' ' + for ; i < len(s) && !isNL(s[i]); i += 1 { + s[i] = ' ' + } + } + return i +} + +func prep(r io.Reader) (s []byte, err error) { + buf := &bytes.Buffer{} + _, err = io.Copy(buf, r) + s = buf.Bytes() + if err != nil { + return + } + + i := 0 + for i < len(s) { + switch s[i] { + case '"': + i += 1 + for i < len(s) { + if s[i] == '"' { + i += 1 + break + } else if s[i] == '\\' { + i += 1 + } + i += 1 + } + case '/': + i = consumeComment(s, i+1) + case ',': + j := i + for { + i += 1 + if i >= len(s) { + break + } else if s[i] == '}' || s[i] == ']' { + s[j] = ' ' + break + } else if s[i] == '/' { + i = consumeComment(s, i+1) + } else if !isWS(s[i]) { + break + } + } + default: + i += 1 + } + } + return +} + +// Read acts as a proxy for the underlying reader and cleans p +// of comments and trailing commas preceeding ] and } +// comments are delimitted by // up until the end the line +func (st *state) Read(p []byte) (n int, err error) { + if st.br == nil { + var s []byte + if s, err = prep(st.r); err != nil { + return + } + st.br = bytes.NewReader(s) + } + return st.br.Read(p) +} + +// New returns an io.Reader acting as proxy to r +func New(r io.Reader) io.Reader { + return &state{r: r} +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/reader_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/reader_test.go new file mode 100644 index 00000000..c8331e9c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/DisposaBoy/JsonConfigReader/reader_test.go @@ -0,0 +1,66 @@ +package JsonConfigReader + +import ( + "bytes" + "io" + "strings" + "testing" +) + +var tests = map[string]string{ + `{ + // a + "x": "y", // b + "x": "y", // c + }`: `{ + + "x": "y", + "x": "y" + }`, + + `// serve a directory + "l/test": [ + { + "handler": "fs", + "dir": "../", + // "strip_prefix": "", + }, + ],`: ` + "l/test": [ + { + "handler": "fs", + "dir": "../" + + } + ],`, + + `[1, 2, 3]`: `[1, 2, 3]`, + `[1, 2, 3, 4,]`: `[1, 2, 3, 4 ]`, + `{"x":1}//[1, 2, 3, 4,]`: `{"x":1} `, + `//////`: ` `, + `{}/ /..`: `{}/ /..`, + `{,}/ /..`: `{ }/ /..`, + `{,}//..`: `{ } `, + `{[],}`: `{[] }`, + `{[,}`: `{[ }`, + `[[",",],]`: `[["," ] ]`, + `[",\"",]`: `[",\"" ]`, + `[",\"\\\",]`: `[",\"\\\",]`, + `[",//"]`: `[",//"]`, + `[",//\" + "],`: `[",//\" + "],`, +} + +func TestMain(t *testing.T) { + for a, b := range tests { + buf := &bytes.Buffer{} + io.Copy(buf, New(strings.NewReader(a))) + a = buf.String() + if a != b { + a = strings.Replace(a, " ", ".", -1) + b = strings.Replace(b, " ", ".", -1) + t.Errorf("reader failed to clean json: expected: `%s`, got `%s`", b, a) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/LICENSE similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/LICENSE rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/LICENSE diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/Readme.md b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/Readme.md new file mode 100644 index 00000000..9057ffa6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/Readme.md @@ -0,0 +1,18 @@ +Parses the Graphviz DOT language and creates an interface, in golang, with which to easily create new and manipulate existing graphs which can be written back to the DOT format. + +This parser has been created using [gocc](http://code.google.com/p/gocc). + +### Installation ### +go get github.com/awalterschulze/gographviz + +### Tests ### + +[![Build Status](https://drone.io/github.com/awalterschulze/gographviz/status.png)](https://drone.io/github.com/awalterschulze/gographviz/latest) + +### Users ### + +[aptly](https://github.com/smira/aptly) - Debian repository management tool + +### Mentions ### + +[Using Golang and GraphViz to Visualize Complex Grails Applications](http://ilikeorangutans.github.io/2014/05/03/using-golang-and-graphviz-to-visualize-complex-grails-applications/) diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/analyse.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/analyse.go similarity index 99% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/analyse.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/analyse.go index cdcb21fc..2f0f2285 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/analyse.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/analyse.go @@ -15,7 +15,7 @@ package gographviz import ( - "code.google.com/p/gographviz/ast" + "github.com/awalterschulze/gographviz/ast" ) //Creates a Graph structure by analysing an Abstract Syntax Tree representing a parsed graph. diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/analysewrite_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/analysewrite_test.go similarity index 99% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/analysewrite_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/analysewrite_test.go index c99d6025..4241065a 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/analysewrite_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/analysewrite_test.go @@ -15,8 +15,8 @@ package gographviz import ( - "code.google.com/p/gographviz/parser" "fmt" + "github.com/awalterschulze/gographviz/parser" "io/ioutil" "os" "testing" diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/ast/ast.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/ast/ast.go similarity index 99% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/ast/ast.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/ast/ast.go index a5b8a651..3e10a7f9 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/ast/ast.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/ast/ast.go @@ -16,9 +16,9 @@ package ast import ( - "code.google.com/p/gographviz/token" "errors" "fmt" + "github.com/awalterschulze/gographviz/token" "math/rand" "sort" "strings" diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/attrs.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/attrs.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/attrs.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/attrs.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/bug_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/bug_test.go similarity index 88% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/bug_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/bug_test.go index 5568f2de..286a4ba4 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/bug_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/bug_test.go @@ -1,8 +1,8 @@ package gographviz import ( - "code.google.com/p/gographviz/ast" - "code.google.com/p/gographviz/parser" + "github.com/awalterschulze/gographviz/ast" + "github.com/awalterschulze/gographviz/parser" "testing" ) diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/dot.bnf b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/dot.bnf similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/dot.bnf rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/dot.bnf diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/edges.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/edges.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/edges.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/edges.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/escape.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/escape.go similarity index 97% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/escape.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/escape.go index 8ce6ee3c..26a4f4cb 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/escape.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/escape.go @@ -15,9 +15,9 @@ package gographviz import ( - "code.google.com/p/gographviz/scanner" - "code.google.com/p/gographviz/token" "fmt" + "github.com/awalterschulze/gographviz/scanner" + "github.com/awalterschulze/gographviz/token" "strings" "text/template" "unicode" diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/escape_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/escape_test.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/escape_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/escape_test.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/example_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/example_test.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/example_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/example_test.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/gen.sh b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/gen.sh similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/gen.sh rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/gen.sh diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/gographviz.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/gographviz.go similarity index 95% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/gographviz.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/gographviz.go index ef7fd3d3..eee3d008 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/gographviz.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/gographviz.go @@ -19,8 +19,8 @@ package gographviz import ( - "code.google.com/p/gographviz/ast" - "code.google.com/p/gographviz/parser" + "github.com/awalterschulze/gographviz/ast" + "github.com/awalterschulze/gographviz/parser" ) var _ Interface = NewGraph() diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/graph.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/graph.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/graph.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/graph.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/nodes.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/nodes.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/nodes.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/nodes.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/main.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/main.go similarity index 93% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/main.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/main.go index d19e17b9..de37d6ca 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/main.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/main.go @@ -16,10 +16,10 @@ package parser import ( - "code.google.com/p/gographviz/ast" - "code.google.com/p/gographviz/scanner" - "code.google.com/p/gographviz/token" "fmt" + "github.com/awalterschulze/gographviz/ast" + "github.com/awalterschulze/gographviz/scanner" + "github.com/awalterschulze/gographviz/token" "io" "io/ioutil" "os" diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser.go similarity index 98% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser.go index a341cf82..42456a96 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser.go @@ -19,7 +19,7 @@ import ( "strconv" ) -import "code.google.com/p/gographviz/token" +import "github.com/awalterschulze/gographviz/token" type ( ActionTab []ActionRow diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser.temp b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser.temp similarity index 98% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser.temp rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser.temp index a341cf82..42456a96 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser.temp +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser.temp @@ -19,7 +19,7 @@ import ( "strconv" ) -import "code.google.com/p/gographviz/token" +import "github.com/awalterschulze/gographviz/token" type ( ActionTab []ActionRow diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser_test.go similarity index 99% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser_test.go index 788ca35a..8b534e1f 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/parser_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/parser_test.go @@ -15,8 +15,8 @@ package parser import ( - "code.google.com/p/gographviz/ast" "fmt" + "github.com/awalterschulze/gographviz/ast" "io/ioutil" "testing" ) diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/tables.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/tables.go similarity index 99% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/tables.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/tables.go index c9011f33..35ee0d1d 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/parser/tables.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/parser/tables.go @@ -14,7 +14,7 @@ package parser -import "code.google.com/p/gographviz/ast" +import "github.com/awalterschulze/gographviz/ast" var ProductionsTable = ProdTab{ /* [0] */ diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/relations.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/relations.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/relations.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/relations.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/scanner/scanner.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/scanner/scanner.go similarity index 99% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/scanner/scanner.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/scanner/scanner.go index b4aad6dc..65ea787a 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/scanner/scanner.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/scanner/scanner.go @@ -17,7 +17,7 @@ import ( "unicode" "unicode/utf8" ) -import "code.google.com/p/gographviz/token" +import "github.com/awalterschulze/gographviz/token" // A Scanner holds the scanner's internal state while processing // a given text. It can be allocated as part of another data diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/subgraphs.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/subgraphs.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/subgraphs.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/subgraphs.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/README b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/README similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/README rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/README diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/cluster.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/cluster.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/cluster.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/cluster.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/crazy.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/crazy.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/crazy.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/crazy.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/datastruct.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/datastruct.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/datastruct.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/datastruct.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/er.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/er.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/er.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/er.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/fdpclust.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/fdpclust.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/fdpclust.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/fdpclust.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/fsm.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/fsm.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/fsm.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/fsm.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/gd_1994_2007.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/gd_1994_2007.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/gd_1994_2007.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/gd_1994_2007.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/helloworld.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/helloworld.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/helloworld.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/helloworld.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/kennedyanc.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/kennedyanc.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/kennedyanc.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/kennedyanc.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/lion_share.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/lion_share.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/lion_share.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/lion_share.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/networkmap_twopi.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/networkmap_twopi.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/networkmap_twopi.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/networkmap_twopi.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/philo.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/philo.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/philo.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/philo.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/process.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/process.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/process.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/process.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/profile.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/profile.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/profile.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/profile.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/psg.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/psg.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/psg.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/psg.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/root.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/root.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/root.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/root.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/sdh.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/sdh.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/sdh.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/sdh.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/siblings.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/siblings.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/siblings.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/siblings.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/softmaint.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/softmaint.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/softmaint.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/softmaint.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/switch.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/switch.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/switch.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/switch.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/traffic_lights.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/traffic_lights.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/traffic_lights.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/traffic_lights.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/transparency.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/transparency.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/transparency.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/transparency.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/twopi.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/twopi.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/twopi.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/twopi.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/unix.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/unix.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/unix.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/unix.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/world.gv.txt b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/world.gv.txt similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/testdata/world.gv.txt rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/testdata/world.gv.txt diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/token/dottokens.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/token/dottokens.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/token/dottokens.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/token/dottokens.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/token/token.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/token/token.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/token/token.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/token/token.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/write.go b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/write.go similarity index 98% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/write.go rename to src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/write.go index 07e51e80..e3a977e7 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/gographviz/write.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/awalterschulze/gographviz/write.go @@ -15,8 +15,8 @@ package gographviz import ( - "code.google.com/p/gographviz/ast" "fmt" + "github.com/awalterschulze/gographviz/ast" ) type writer struct { diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/.gitignore b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/.gitignore new file mode 100644 index 00000000..0bf694c9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/.gitignore @@ -0,0 +1,17 @@ +.DS_Store +*.[568ao] +*.pb.go +*.ao +*.so +*.pyc +._* +.nfs.* +[568a].out +*~ +*.orig +core +_obj +_test +_testmain.go +compiler/protoc-gen-go +compiler/testdata/extension_test diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/AUTHORS b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/AUTHORS new file mode 100644 index 00000000..15167cd7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/CONTRIBUTORS b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/CONTRIBUTORS new file mode 100644 index 00000000..1c4577e9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/LICENSE new file mode 100644 index 00000000..1b1b1921 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/LICENSE @@ -0,0 +1,31 @@ +Go support for Protocol Buffers - Google's data interchange format + +Copyright 2010 The Go Authors. All rights reserved. +https://github.com/golang/protobuf + +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/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/Make.protobuf b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/Make.protobuf new file mode 100644 index 00000000..15071de1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/Make.protobuf @@ -0,0 +1,40 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +# Includable Makefile to add a rule for generating .pb.go files from .proto files +# (Google protocol buffer descriptions). +# Typical use if myproto.proto is a file in package mypackage in this directory: +# +# include $(GOROOT)/src/pkg/github.com/golang/protobuf/Make.protobuf + +%.pb.go: %.proto + protoc --go_out=. $< + diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/Makefile new file mode 100644 index 00000000..d24239e4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/Makefile @@ -0,0 +1,56 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + + +all: install + +install: + go install ./proto + go install ./jsonpb + go install ./protoc-gen-go + +test: + go test ./proto + go test ./jsonpb + make -C protoc-gen-go/testdata test + +clean: + go clean ./... + +nuke: + go clean -i ./... + +regenerate: + make -C protoc-gen-go/descriptor regenerate + make -C protoc-gen-go/plugin regenerate + make -C protoc-gen-go/testdata regenerate + make -C proto/testdata regenerate + make -C jsonpb/jsonpb_test_proto regenerate diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/README.md b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/README.md new file mode 100644 index 00000000..d48e91a2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/README.md @@ -0,0 +1,193 @@ +# Go support for Protocol Buffers + +Google's data interchange format. +Copyright 2010 The Go Authors. +https://github.com/golang/protobuf + +This package and the code it generates requires at least Go 1.4. + +This software implements Go bindings for protocol buffers. For +information about protocol buffers themselves, see + https://developers.google.com/protocol-buffers/ + +## Installation ## + +To use this software, you must: +- Install the standard C++ implementation of protocol buffers from + https://developers.google.com/protocol-buffers/ +- Of course, install the Go compiler and tools from + https://golang.org/ + See + https://golang.org/doc/install + for details or, if you are using gccgo, follow the instructions at + https://golang.org/doc/install/gccgo +- Grab the code from the repository and install the proto package. + The simplest way is to run `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`. + The compiler plugin, protoc-gen-go, will be installed in $GOBIN, + defaulting to $GOPATH/bin. It must be in your $PATH for the protocol + compiler, protoc, to find it. + +This software has two parts: a 'protocol compiler plugin' that +generates Go source files that, once compiled, can access and manage +protocol buffers; and a library that implements run-time support for +encoding (marshaling), decoding (unmarshaling), and accessing protocol +buffers. + +There is support for gRPC in Go using protocol buffers. +See the note at the bottom of this file for details. + +There are no insertion points in the plugin. + + +## Using protocol buffers with Go ## + +Once the software is installed, there are two steps to using it. +First you must compile the protocol buffer definitions and then import +them, with the support library, into your program. + +To compile the protocol buffer definition, run protoc with the --go_out +parameter set to the directory you want to output the Go code to. + + protoc --go_out=. *.proto + +The generated files will be suffixed .pb.go. See the Test code below +for an example using such a file. + + +The package comment for the proto library contains text describing +the interface provided in Go for protocol buffers. Here is an edited +version. + +========== + +The proto package converts data structures to and from the +wire format of protocol buffers. It works in concert with the +Go source code generated for .proto files by the protocol compiler. + +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: + + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + Helpers for getting values are superseded by the + GetFoo methods and their use is deprecated. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed with the enum's type name. Enum types have + a String method, and a Enum method to assist in message construction. + - Nested groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. + - Marshal and Unmarshal are functions to encode and decode the wire format. + +When the .proto file specifies `syntax="proto3"`, there are some differences: + + - Non-repeated fields of non-message type are values instead of pointers. + - Getters are only generated for message and oneof fields. + - Enum types do not get an Enum method. + +Consider file test.proto, containing + +```proto + package example; + + enum FOO { X = 17; }; + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + } +``` + +To create and play with a Test object from the example package, + +```go + package main + + import ( + "log" + + "github.com/golang/protobuf/proto" + "path/to/example" + ) + + func main() { + test := &example.Test { + Label: proto.String("hello"), + Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, + Optionalgroup: &example.Test_OptionalGroup { + RequiredField: proto.String("good bye"), + }, + } + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) + } + newTest := &example.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) + } + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) + } + // etc. + } +``` + +## Parameters ## + +To pass extra parameters to the plugin, use a comma-separated +parameter list separated from the output directory by a colon: + + + protoc --go_out=plugins=grpc,import_path=mypackage:. *.proto + + +- `import_prefix=xxx` - a prefix that is added onto the beginning of + all imports. Useful for things like generating protos in a + subdirectory, or regenerating vendored protobufs in-place. +- `import_path=foo/bar` - used as the package if no input files + declare `go_package`. If it contains slashes, everything up to the + rightmost slash is ignored. +- `plugins=plugin1+plugin2` - specifies the list of sub-plugins to + load. The only plugin in this repo is `grpc`. +- `Mfoo/bar.proto=quux/shme` - declares that foo/bar.proto is + associated with Go package quux/shme. This is subject to the + import_prefix parameter. + +## gRPC Support ## + +If a proto file specifies RPC services, protoc-gen-go can be instructed to +generate code compatible with gRPC (http://www.grpc.io/). To do this, pass +the `plugins` parameter to protoc-gen-go; the usual way is to insert it into +the --go_out argument to protoc: + + protoc --go_out=plugins=grpc:. *.proto diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb.go new file mode 100644 index 00000000..3522ac2b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb.go @@ -0,0 +1,550 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +/* +Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON. +It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json. + +This package produces a different output than the standard "encoding/json" package, +which does not operate correctly on protocol buffers. +*/ +package jsonpb + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "reflect" + "sort" + "strconv" + "strings" + + "github.com/golang/protobuf/proto" +) + +var ( + byteArrayType = reflect.TypeOf([]byte{}) +) + +// Marshaler is a configurable object for converting between +// protocol buffer objects and a JSON representation for them. +type Marshaler struct { + // Whether to render enum values as integers, as opposed to string values. + EnumsAsInts bool + + // Whether to render fields with zero values. + EmitDefaults bool + + // A string to indent each level by. The presence of this field will + // also cause a space to appear between the field separator and + // value, and for newlines to be appear between fields and array + // elements. + Indent string +} + +// Marshal marshals a protocol buffer into JSON. +func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error { + writer := &errWriter{writer: out} + return m.marshalObject(writer, pb, "") +} + +// MarshalToString converts a protocol buffer object to JSON string. +func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) { + var buf bytes.Buffer + if err := m.Marshal(&buf, pb); err != nil { + return "", err + } + return buf.String(), nil +} + +type int32Slice []int32 + +// For sorting extensions ids to ensure stable output. +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// marshalObject writes a struct to the Writer. +func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent string) error { + out.write("{") + if m.Indent != "" { + out.write("\n") + } + + s := reflect.ValueOf(v).Elem() + firstField := true + for i := 0; i < s.NumField(); i++ { + value := s.Field(i) + valueField := s.Type().Field(i) + if strings.HasPrefix(valueField.Name, "XXX_") { + continue + } + + // IsNil will panic on most value kinds. + switch value.Kind() { + case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + if value.IsNil() { + continue + } + } + + if !m.EmitDefaults { + switch value.Kind() { + case reflect.Bool: + if !value.Bool() { + continue + } + case reflect.Int32, reflect.Int64: + if value.Int() == 0 { + continue + } + case reflect.Uint32, reflect.Uint64: + if value.Uint() == 0 { + continue + } + case reflect.Float32, reflect.Float64: + if value.Float() == 0 { + continue + } + case reflect.String: + if value.Len() == 0 { + continue + } + } + } + + // Oneof fields need special handling. + if valueField.Tag.Get("protobuf_oneof") != "" { + // value is an interface containing &T{real_value}. + sv := value.Elem().Elem() // interface -> *T -> T + value = sv.Field(0) + valueField = sv.Type().Field(0) + } + prop := jsonProperties(valueField) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, prop, value, indent); err != nil { + return err + } + firstField = false + } + + // Handle proto2 extensions. + if ep, ok := v.(extendableProto); ok { + extensions := proto.RegisteredExtensions(v) + extensionMap := ep.ExtensionMap() + // Sort extensions for stable output. + ids := make([]int32, 0, len(extensionMap)) + for id := range extensionMap { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + for _, id := range ids { + desc := extensions[id] + if desc == nil { + // unknown extension + continue + } + ext, extErr := proto.GetExtension(ep, desc) + if extErr != nil { + return extErr + } + value := reflect.ValueOf(ext) + var prop proto.Properties + prop.Parse(desc.Tag) + prop.OrigName = fmt.Sprintf("[%s]", desc.Name) + if !firstField { + m.writeSep(out) + } + if err := m.marshalField(out, &prop, value, indent); err != nil { + return err + } + firstField = false + } + + } + + if m.Indent != "" { + out.write("\n") + out.write(indent) + } + out.write("}") + return out.err +} + +func (m *Marshaler) writeSep(out *errWriter) { + if m.Indent != "" { + out.write(",\n") + } else { + out.write(",") + } +} + +// marshalField writes field description and value to the Writer. +func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + if m.Indent != "" { + out.write(indent) + out.write(m.Indent) + } + out.write(`"`) + out.write(prop.OrigName) + out.write(`":`) + if m.Indent != "" { + out.write(" ") + } + if err := m.marshalValue(out, prop, v, indent); err != nil { + return err + } + return nil +} + +// marshalValue writes the value to the Writer. +func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { + + var err error + v = reflect.Indirect(v) + + // Handle repeated elements. + if v.Type() != byteArrayType && v.Kind() == reflect.Slice { + out.write("[") + comma := "" + for i := 0; i < v.Len(); i++ { + sliceVal := v.Index(i) + out.write(comma) + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + m.marshalValue(out, prop, sliceVal, indent+m.Indent) + comma = "," + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write("]") + return out.err + } + + // Handle enumerations. + if !m.EnumsAsInts && prop.Enum != "" { + // Unknown enum values will are stringified by the proto library as their + // value. Such values should _not_ be quoted or they will be interpreted + // as an enum string instead of their value. + enumStr := v.Interface().(fmt.Stringer).String() + var valStr string + if v.Kind() == reflect.Ptr { + valStr = strconv.Itoa(int(v.Elem().Int())) + } else { + valStr = strconv.Itoa(int(v.Int())) + } + isKnownEnum := enumStr != valStr + if isKnownEnum { + out.write(`"`) + } + out.write(enumStr) + if isKnownEnum { + out.write(`"`) + } + return out.err + } + + // Handle nested messages. + if v.Kind() == reflect.Struct { + return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent) + } + + // Handle maps. + // Since Go randomizes map iteration, we sort keys for stable output. + if v.Kind() == reflect.Map { + out.write(`{`) + keys := v.MapKeys() + sort.Sort(mapKeys(keys)) + for i, k := range keys { + if i > 0 { + out.write(`,`) + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + out.write(m.Indent) + } + + b, err := json.Marshal(k.Interface()) + if err != nil { + return err + } + s := string(b) + + // If the JSON is not a string value, encode it again to make it one. + if !strings.HasPrefix(s, `"`) { + b, err := json.Marshal(s) + if err != nil { + return err + } + s = string(b) + } + + out.write(s) + out.write(`:`) + if m.Indent != "" { + out.write(` `) + } + + if err := m.marshalValue(out, prop, v.MapIndex(k), indent+m.Indent); err != nil { + return err + } + } + if m.Indent != "" { + out.write("\n") + out.write(indent) + out.write(m.Indent) + } + out.write(`}`) + return out.err + } + + // Default handling defers to the encoding/json library. + b, err := json.Marshal(v.Interface()) + if err != nil { + return err + } + needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64) + if needToQuote { + out.write(`"`) + } + out.write(string(b)) + if needToQuote { + out.write(`"`) + } + return out.err +} + +// Unmarshal unmarshals a JSON object stream into a protocol +// buffer. This function is lenient and will decode any options +// permutations of the related Marshaler. +func Unmarshal(r io.Reader, pb proto.Message) error { + inputValue := json.RawMessage{} + if err := json.NewDecoder(r).Decode(&inputValue); err != nil { + return err + } + return unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue) +} + +// UnmarshalString will populate the fields of a protocol buffer based +// on a JSON string. This function is lenient and will decode any options +// permutations of the related Marshaler. +func UnmarshalString(str string, pb proto.Message) error { + return Unmarshal(strings.NewReader(str), pb) +} + +// unmarshalValue converts/copies a value into the target. +func unmarshalValue(target reflect.Value, inputValue json.RawMessage) error { + targetType := target.Type() + + // Allocate memory for pointer fields. + if targetType.Kind() == reflect.Ptr { + target.Set(reflect.New(targetType.Elem())) + return unmarshalValue(target.Elem(), inputValue) + } + + // Handle nested messages. + if targetType.Kind() == reflect.Struct { + var jsonFields map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &jsonFields); err != nil { + return err + } + + sprops := proto.GetProperties(targetType) + for i := 0; i < target.NumField(); i++ { + ft := target.Type().Field(i) + if strings.HasPrefix(ft.Name, "XXX_") { + continue + } + fieldName := jsonProperties(ft).OrigName + + valueForField, ok := jsonFields[fieldName] + if !ok { + continue + } + delete(jsonFields, fieldName) + + // Handle enums, which have an underlying type of int32, + // and may appear as strings. We do this while handling + // the struct so we have access to the enum info. + // The case of an enum appearing as a number is handled + // by the recursive call to unmarshalValue. + if enum := sprops.Prop[i].Enum; valueForField[0] == '"' && enum != "" { + vmap := proto.EnumValueMap(enum) + // Don't need to do unquoting; valid enum names + // are from a limited character set. + s := valueForField[1 : len(valueForField)-1] + n, ok := vmap[string(s)] + if !ok { + return fmt.Errorf("unknown value %q for enum %s", s, enum) + } + f := target.Field(i) + if f.Kind() == reflect.Ptr { // proto2 + f.Set(reflect.New(f.Type().Elem())) + f = f.Elem() + } + f.SetInt(int64(n)) + continue + } + + if err := unmarshalValue(target.Field(i), valueForField); err != nil { + return err + } + } + // Check for any oneof fields. + for fname, raw := range jsonFields { + if oop, ok := sprops.OneofTypes[fname]; ok { + nv := reflect.New(oop.Type.Elem()) + target.Field(oop.Field).Set(nv) + if err := unmarshalValue(nv.Elem().Field(0), raw); err != nil { + return err + } + delete(jsonFields, fname) + } + } + if len(jsonFields) > 0 { + // Pick any field to be the scapegoat. + var f string + for fname := range jsonFields { + f = fname + break + } + return fmt.Errorf("unknown field %q in %v", f, targetType) + } + return nil + } + + // Handle arrays (which aren't encoded bytes) + if targetType != byteArrayType && targetType.Kind() == reflect.Slice { + var slc []json.RawMessage + if err := json.Unmarshal(inputValue, &slc); err != nil { + return err + } + len := len(slc) + target.Set(reflect.MakeSlice(targetType, len, len)) + for i := 0; i < len; i++ { + if err := unmarshalValue(target.Index(i), slc[i]); err != nil { + return err + } + } + return nil + } + + // Handle maps (whose keys are always strings) + if targetType.Kind() == reflect.Map { + var mp map[string]json.RawMessage + if err := json.Unmarshal(inputValue, &mp); err != nil { + return err + } + target.Set(reflect.MakeMap(targetType)) + for ks, raw := range mp { + // Unmarshal map key. The core json library already decoded the key into a + // string, so we handle that specially. Other types were quoted post-serialization. + var k reflect.Value + if targetType.Key().Kind() == reflect.String { + k = reflect.ValueOf(ks) + } else { + k = reflect.New(targetType.Key()).Elem() + if err := unmarshalValue(k, json.RawMessage(ks)); err != nil { + return err + } + } + + // Unmarshal map value. + v := reflect.New(targetType.Elem()).Elem() + if err := unmarshalValue(v, raw); err != nil { + return err + } + target.SetMapIndex(k, v) + } + return nil + } + + // 64-bit integers can be encoded as strings. In this case we drop + // the quotes and proceed as normal. + isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 + if isNum && strings.HasPrefix(string(inputValue), `"`) { + inputValue = inputValue[1 : len(inputValue)-1] + } + + // Use the encoding/json for parsing other value types. + return json.Unmarshal(inputValue, target.Addr().Interface()) +} + +// jsonProperties returns parsed proto.Properties for the field. +func jsonProperties(f reflect.StructField) *proto.Properties { + var prop proto.Properties + prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f) + return &prop +} + +// extendableProto is an interface implemented by any protocol buffer that may be extended. +type extendableProto interface { + proto.Message + ExtensionRangeArray() []proto.ExtensionRange + ExtensionMap() map[int32]proto.Extension +} + +// Writer wrapper inspired by https://blog.golang.org/errors-are-values +type errWriter struct { + writer io.Writer + err error +} + +func (w *errWriter) write(str string) { + if w.err != nil { + return + } + _, w.err = w.writer.Write([]byte(str)) +} + +// Map fields may have key types of non-float scalars, strings and enums. +// The easiest way to sort them in some deterministic order is to use fmt. +// If this turns out to be inefficient we can always consider other options, +// such as doing a Schwartzian transform. +type mapKeys []reflect.Value + +func (s mapKeys) Len() int { return len(s) } +func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } +func (s mapKeys) Less(i, j int) bool { + return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test.go new file mode 100644 index 00000000..97a648eb --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test.go @@ -0,0 +1,392 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package jsonpb + +import ( + "reflect" + "testing" + + pb "github.com/golang/protobuf/jsonpb/jsonpb_test_proto" + "github.com/golang/protobuf/proto" + proto3pb "github.com/golang/protobuf/proto/proto3_proto" +) + +var ( + marshaler = Marshaler{} + + marshalerAllOptions = Marshaler{ + Indent: " ", + } + + simpleObject = &pb.Simple{ + OInt32: proto.Int32(-32), + OInt64: proto.Int64(-6400000000), + OUint32: proto.Uint32(32), + OUint64: proto.Uint64(6400000000), + OSint32: proto.Int32(-13), + OSint64: proto.Int64(-2600000000), + OFloat: proto.Float32(3.14), + ODouble: proto.Float64(6.02214179e23), + OBool: proto.Bool(true), + OString: proto.String("hello \"there\""), + OBytes: []byte("beep boop"), + } + + simpleObjectJSON = `{` + + `"o_bool":true,` + + `"o_int32":-32,` + + `"o_int64":"-6400000000",` + + `"o_uint32":32,` + + `"o_uint64":"6400000000",` + + `"o_sint32":-13,` + + `"o_sint64":"-2600000000",` + + `"o_float":3.14,` + + `"o_double":6.02214179e+23,` + + `"o_string":"hello \"there\"",` + + `"o_bytes":"YmVlcCBib29w"` + + `}` + + simpleObjectPrettyJSON = `{ + "o_bool": true, + "o_int32": -32, + "o_int64": "-6400000000", + "o_uint32": 32, + "o_uint64": "6400000000", + "o_sint32": -13, + "o_sint64": "-2600000000", + "o_float": 3.14, + "o_double": 6.02214179e+23, + "o_string": "hello \"there\"", + "o_bytes": "YmVlcCBib29w" +}` + + repeatsObject = &pb.Repeats{ + RBool: []bool{true, false, true}, + RInt32: []int32{-3, -4, -5}, + RInt64: []int64{-123456789, -987654321}, + RUint32: []uint32{1, 2, 3}, + RUint64: []uint64{6789012345, 3456789012}, + RSint32: []int32{-1, -2, -3}, + RSint64: []int64{-6789012345, -3456789012}, + RFloat: []float32{3.14, 6.28}, + RDouble: []float64{299792458, 6.62606957e-34}, + RString: []string{"happy", "days"}, + RBytes: [][]byte{[]byte("skittles"), []byte("m&m's")}, + } + + repeatsObjectJSON = `{` + + `"r_bool":[true,false,true],` + + `"r_int32":[-3,-4,-5],` + + `"r_int64":["-123456789","-987654321"],` + + `"r_uint32":[1,2,3],` + + `"r_uint64":["6789012345","3456789012"],` + + `"r_sint32":[-1,-2,-3],` + + `"r_sint64":["-6789012345","-3456789012"],` + + `"r_float":[3.14,6.28],` + + `"r_double":[2.99792458e+08,6.62606957e-34],` + + `"r_string":["happy","days"],` + + `"r_bytes":["c2tpdHRsZXM=","bSZtJ3M="]` + + `}` + + repeatsObjectPrettyJSON = `{ + "r_bool": [ + true, + false, + true + ], + "r_int32": [ + -3, + -4, + -5 + ], + "r_int64": [ + "-123456789", + "-987654321" + ], + "r_uint32": [ + 1, + 2, + 3 + ], + "r_uint64": [ + "6789012345", + "3456789012" + ], + "r_sint32": [ + -1, + -2, + -3 + ], + "r_sint64": [ + "-6789012345", + "-3456789012" + ], + "r_float": [ + 3.14, + 6.28 + ], + "r_double": [ + 2.99792458e+08, + 6.62606957e-34 + ], + "r_string": [ + "happy", + "days" + ], + "r_bytes": [ + "c2tpdHRsZXM=", + "bSZtJ3M=" + ] +}` + + innerSimple = &pb.Simple{OInt32: proto.Int32(-32)} + innerSimple2 = &pb.Simple{OInt64: proto.Int64(25)} + innerRepeats = &pb.Repeats{RString: []string{"roses", "red"}} + innerRepeats2 = &pb.Repeats{RString: []string{"violets", "blue"}} + complexObject = &pb.Widget{ + Color: pb.Widget_GREEN.Enum(), + RColor: []pb.Widget_Color{pb.Widget_RED, pb.Widget_GREEN, pb.Widget_BLUE}, + Simple: innerSimple, + RSimple: []*pb.Simple{innerSimple, innerSimple2}, + Repeats: innerRepeats, + RRepeats: []*pb.Repeats{innerRepeats, innerRepeats2}, + } + + complexObjectJSON = `{"color":"GREEN",` + + `"r_color":["RED","GREEN","BLUE"],` + + `"simple":{"o_int32":-32},` + + `"r_simple":[{"o_int32":-32},{"o_int64":"25"}],` + + `"repeats":{"r_string":["roses","red"]},` + + `"r_repeats":[{"r_string":["roses","red"]},{"r_string":["violets","blue"]}]` + + `}` + + complexObjectPrettyJSON = `{ + "color": "GREEN", + "r_color": [ + "RED", + "GREEN", + "BLUE" + ], + "simple": { + "o_int32": -32 + }, + "r_simple": [ + { + "o_int32": -32 + }, + { + "o_int64": "25" + } + ], + "repeats": { + "r_string": [ + "roses", + "red" + ] + }, + "r_repeats": [ + { + "r_string": [ + "roses", + "red" + ] + }, + { + "r_string": [ + "violets", + "blue" + ] + } + ] +}` + + colorPrettyJSON = `{ + "color": 2 +}` + + colorListPrettyJSON = `{ + "color": 1000, + "r_color": [ + "RED" + ] +}` + + nummyPrettyJSON = `{ + "nummy": { + "1": 2, + "3": 4 + } +}` + + objjyPrettyJSON = `{ + "objjy": { + "1": { + "dub": 1 + } + } +}` + realNumber = &pb.Real{Value: proto.Float64(3.14159265359)} + realNumberName = "Pi" + complexNumber = &pb.Complex{Imaginary: proto.Float64(0.5772156649)} + realNumberJSON = `{` + + `"value":3.14159265359,` + + `"[jsonpb.Complex.real_extension]":{"imaginary":0.5772156649},` + + `"[jsonpb.name]":"Pi"` + + `}` +) + +func init() { + if err := proto.SetExtension(realNumber, pb.E_Name, &realNumberName); err != nil { + panic(err) + } + if err := proto.SetExtension(realNumber, pb.E_Complex_RealExtension, complexNumber); err != nil { + panic(err) + } +} + +var marshalingTests = []struct { + desc string + marshaler Marshaler + pb proto.Message + json string +}{ + {"simple flat object", marshaler, simpleObject, simpleObjectJSON}, + {"simple pretty object", marshalerAllOptions, simpleObject, simpleObjectPrettyJSON}, + {"repeated fields flat object", marshaler, repeatsObject, repeatsObjectJSON}, + {"repeated fields pretty object", marshalerAllOptions, repeatsObject, repeatsObjectPrettyJSON}, + {"nested message/enum flat object", marshaler, complexObject, complexObjectJSON}, + {"nested message/enum pretty object", marshalerAllOptions, complexObject, complexObjectPrettyJSON}, + {"enum-string flat object", Marshaler{}, + &pb.Widget{Color: pb.Widget_BLUE.Enum()}, `{"color":"BLUE"}`}, + {"enum-value pretty object", Marshaler{EnumsAsInts: true, Indent: " "}, + &pb.Widget{Color: pb.Widget_BLUE.Enum()}, colorPrettyJSON}, + {"unknown enum value object", marshalerAllOptions, + &pb.Widget{Color: pb.Widget_Color(1000).Enum(), RColor: []pb.Widget_Color{pb.Widget_RED}}, colorListPrettyJSON}, + {"empty value", marshaler, &pb.Simple3{}, `{}`}, + {"empty value emitted", Marshaler{EmitDefaults: true}, &pb.Simple3{}, `{"dub":0}`}, + {"map", marshaler, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, `{"nummy":{"1":2,"3":4}}`}, + {"map", marshalerAllOptions, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}, nummyPrettyJSON}, + {"map", marshaler, + &pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}, + `{"strry":{"\"one\"":"two","three":"four"}}`}, + {"map", marshaler, + &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: &pb.Simple3{Dub: 1}}}, `{"objjy":{"1":{"dub":1}}}`}, + {"map", marshalerAllOptions, + &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: &pb.Simple3{Dub: 1}}}, objjyPrettyJSON}, + {"map", marshaler, &pb.Mappy{Buggy: map[int64]string{1234: "yup"}}, + `{"buggy":{"1234":"yup"}}`}, + {"map", marshaler, &pb.Mappy{Booly: map[bool]bool{false: true}}, `{"booly":{"false":true}}`}, + {"proto2 map", marshaler, &pb.Maps{MInt64Str: map[int64]string{213: "cat"}}, + `{"m_int64_str":{"213":"cat"}}`}, + {"proto2 map", marshaler, + &pb.Maps{MBoolSimple: map[bool]*pb.Simple{true: &pb.Simple{OInt32: proto.Int32(1)}}}, + `{"m_bool_simple":{"true":{"o_int32":1}}}`}, + {"oneof, not set", marshaler, &pb.MsgWithOneof{}, `{}`}, + {"oneof, set", marshaler, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Title{"Grand Poobah"}}, `{"title":"Grand Poobah"}`}, + {"proto2 extension", marshaler, realNumber, realNumberJSON}, +} + +func TestMarshaling(t *testing.T) { + for _, tt := range marshalingTests { + json, err := tt.marshaler.MarshalToString(tt.pb) + if err != nil { + t.Errorf("%s: marshaling error: %v", tt.desc, err) + } else if tt.json != json { + t.Errorf("%s: got [%v] want [%v]", tt.desc, json, tt.json) + } + } +} + +var unmarshalingTests = []struct { + desc string + json string + pb proto.Message +}{ + {"simple flat object", simpleObjectJSON, simpleObject}, + {"simple pretty object", simpleObjectPrettyJSON, simpleObject}, + {"repeated fields flat object", repeatsObjectJSON, repeatsObject}, + {"repeated fields pretty object", repeatsObjectPrettyJSON, repeatsObject}, + {"nested message/enum flat object", complexObjectJSON, complexObject}, + {"nested message/enum pretty object", complexObjectPrettyJSON, complexObject}, + {"enum-string object", `{"color":"BLUE"}`, &pb.Widget{Color: pb.Widget_BLUE.Enum()}}, + {"enum-value object", "{\n \"color\": 2\n}", &pb.Widget{Color: pb.Widget_BLUE.Enum()}}, + {"proto3 enum string", `{"hilarity":"PUNS"}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}}, + {"proto3 enum value", `{"hilarity":1}`, &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}}, + {"unknown enum value object", + "{\n \"color\": 1000,\n \"r_color\": [\n \"RED\"\n ]\n}", + &pb.Widget{Color: pb.Widget_Color(1000).Enum(), RColor: []pb.Widget_Color{pb.Widget_RED}}}, + {"unquoted int64 object", `{"o_int64":-314}`, &pb.Simple{OInt64: proto.Int64(-314)}}, + {"unquoted uint64 object", `{"o_uint64":123}`, &pb.Simple{OUint64: proto.Uint64(123)}}, + {"map", `{"nummy":{"1":2,"3":4}}`, &pb.Mappy{Nummy: map[int64]int32{1: 2, 3: 4}}}, + {"map", `{"strry":{"\"one\"":"two","three":"four"}}`, &pb.Mappy{Strry: map[string]string{`"one"`: "two", "three": "four"}}}, + {"map", `{"objjy":{"1":{"dub":1}}}`, &pb.Mappy{Objjy: map[int32]*pb.Simple3{1: &pb.Simple3{Dub: 1}}}}, + {"oneof", `{"salary":31000}`, &pb.MsgWithOneof{Union: &pb.MsgWithOneof_Salary{31000}}}, +} + +func TestUnmarshaling(t *testing.T) { + for _, tt := range unmarshalingTests { + // Make a new instance of the type of our expected object. + p := reflect.New(reflect.TypeOf(tt.pb).Elem()).Interface().(proto.Message) + + err := UnmarshalString(tt.json, p) + if err != nil { + t.Error(err) + continue + } + + // For easier diffs, compare text strings of the protos. + exp := proto.MarshalTextString(tt.pb) + act := proto.MarshalTextString(p) + if string(exp) != string(act) { + t.Errorf("%s: got [%s] want [%s]", tt.desc, act, exp) + } + } +} + +var unmarshalingShouldError = []struct { + desc string + in string + pb proto.Message +}{ + {"a value", "666", new(pb.Simple)}, + {"gibberish", "{adskja123;l23=-=", new(pb.Simple)}, + {"unknown enum name", `{"hilarity":"DAVE"}`, new(proto3pb.Message)}, +} + +func TestUnmarshalingBadInput(t *testing.T) { + for _, tt := range unmarshalingShouldError { + err := UnmarshalString(tt.in, tt.pb) + if err == nil { + t.Errorf("an error was expected when parsing %q instead of an object", tt.desc) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/Makefile new file mode 100644 index 00000000..e53e6a69 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/Makefile @@ -0,0 +1,33 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2015 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +regenerate: + protoc --go_out=. *.proto diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.pb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.pb.go new file mode 100644 index 00000000..5548ae4c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.pb.go @@ -0,0 +1,119 @@ +// Code generated by protoc-gen-go. +// source: more_test_objects.proto +// DO NOT EDIT! + +/* +Package jsonpb is a generated protocol buffer package. + +It is generated from these files: + more_test_objects.proto + test_objects.proto + +It has these top-level messages: + Simple3 + Mappy + Simple + Repeats + Widget + Maps + MsgWithOneof + Real + Complex +*/ +package jsonpb + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +const _ = proto.ProtoPackageIsVersion1 + +type Simple3 struct { + Dub float64 `protobuf:"fixed64,1,opt,name=dub" json:"dub,omitempty"` +} + +func (m *Simple3) Reset() { *m = Simple3{} } +func (m *Simple3) String() string { return proto.CompactTextString(m) } +func (*Simple3) ProtoMessage() {} +func (*Simple3) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +type Mappy struct { + Nummy map[int64]int32 `protobuf:"bytes,1,rep,name=nummy" json:"nummy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + Strry map[string]string `protobuf:"bytes,2,rep,name=strry" json:"strry,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Objjy map[int32]*Simple3 `protobuf:"bytes,3,rep,name=objjy" json:"objjy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Buggy map[int64]string `protobuf:"bytes,4,rep,name=buggy" json:"buggy,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Booly map[bool]bool `protobuf:"bytes,5,rep,name=booly" json:"booly,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` +} + +func (m *Mappy) Reset() { *m = Mappy{} } +func (m *Mappy) String() string { return proto.CompactTextString(m) } +func (*Mappy) ProtoMessage() {} +func (*Mappy) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *Mappy) GetNummy() map[int64]int32 { + if m != nil { + return m.Nummy + } + return nil +} + +func (m *Mappy) GetStrry() map[string]string { + if m != nil { + return m.Strry + } + return nil +} + +func (m *Mappy) GetObjjy() map[int32]*Simple3 { + if m != nil { + return m.Objjy + } + return nil +} + +func (m *Mappy) GetBuggy() map[int64]string { + if m != nil { + return m.Buggy + } + return nil +} + +func (m *Mappy) GetBooly() map[bool]bool { + if m != nil { + return m.Booly + } + return nil +} + +func init() { + proto.RegisterType((*Simple3)(nil), "jsonpb.Simple3") + proto.RegisterType((*Mappy)(nil), "jsonpb.Mappy") +} + +var fileDescriptor0 = []byte{ + // 261 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0xd1, 0xc1, 0x4a, 0xc3, 0x30, + 0x1c, 0x06, 0x70, 0xb2, 0x98, 0xb9, 0xfe, 0x8b, 0x08, 0x39, 0x68, 0xf0, 0x20, 0xb2, 0x8b, 0x3d, + 0x48, 0x0f, 0xdb, 0x45, 0x04, 0x2f, 0x82, 0x47, 0xf5, 0xb0, 0x07, 0x18, 0x8b, 0x86, 0x61, 0x6d, + 0x9b, 0x90, 0xa6, 0x42, 0x9e, 0xd1, 0x97, 0xb2, 0x89, 0xae, 0xfe, 0x0b, 0xf1, 0xfc, 0xfd, 0x42, + 0xbe, 0x2f, 0x81, 0xf3, 0x46, 0x5b, 0xb5, 0x75, 0xaa, 0x73, 0x5b, 0x2d, 0x2b, 0xf5, 0xea, 0xba, + 0xd2, 0x58, 0xed, 0x34, 0x9f, 0x57, 0x9d, 0x6e, 0x8d, 0x5c, 0x9e, 0xc1, 0xf1, 0xe6, 0xbd, 0x31, + 0xb5, 0x5a, 0xf3, 0x1c, 0xe8, 0x5b, 0x2f, 0x05, 0xb9, 0x22, 0x05, 0x59, 0x7e, 0x51, 0x60, 0x4f, + 0x3b, 0x63, 0x3c, 0xbf, 0x06, 0xd6, 0xf6, 0x4d, 0xe3, 0x87, 0x80, 0x16, 0xf9, 0x4a, 0x94, 0x3f, + 0x27, 0xcb, 0x98, 0x96, 0xcf, 0x21, 0x7a, 0x6c, 0x9d, 0x8d, 0xb0, 0x73, 0xd6, 0x7a, 0x31, 0x4b, + 0xc1, 0x4d, 0x88, 0x46, 0x38, 0x94, 0xa9, 0xbc, 0xa0, 0x29, 0xf8, 0x12, 0xa2, 0x11, 0xca, 0x7e, + 0xbf, 0xf7, 0xe2, 0x28, 0x05, 0x1f, 0x42, 0xf4, 0x07, 0xb5, 0xae, 0xbd, 0x60, 0x49, 0x18, 0xa2, + 0x08, 0x2f, 0x6e, 0x00, 0x50, 0xe3, 0x61, 0xf1, 0x87, 0xf2, 0x71, 0x31, 0xe5, 0x27, 0xc0, 0x3e, + 0x77, 0x75, 0xaf, 0x86, 0xfa, 0xa4, 0x60, 0x77, 0xb3, 0x5b, 0x12, 0x34, 0xaa, 0x8d, 0x74, 0x36, + 0xd5, 0x59, 0xd4, 0xf7, 0x00, 0xa8, 0x3b, 0xd2, 0x8c, 0x5f, 0x62, 0x9d, 0xaf, 0x4e, 0x0f, 0xfd, + 0x7e, 0x9f, 0xfe, 0x70, 0x19, 0x5a, 0xf4, 0x7f, 0xb5, 0x6c, 0xd4, 0xe3, 0x2c, 0xac, 0x17, 0x53, + 0xbd, 0x08, 0x5a, 0xce, 0xe3, 0xa7, 0xaf, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0xd5, 0x3b, 0xe8, + 0xea, 0x0f, 0x02, 0x00, 0x00, +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.proto new file mode 100644 index 00000000..65357916 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/more_test_objects.proto @@ -0,0 +1,46 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto3"; + +package jsonpb; + +message Simple3 { + double dub = 1; +} + +message Mappy { + map nummy = 1; + map strry = 2; + map objjy = 3; + map buggy = 4; + map booly = 5; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.pb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.pb.go new file mode 100644 index 00000000..a9f50c37 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.pb.go @@ -0,0 +1,578 @@ +// Code generated by protoc-gen-go. +// source: test_objects.proto +// DO NOT EDIT! + +package jsonpb + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +type Widget_Color int32 + +const ( + Widget_RED Widget_Color = 0 + Widget_GREEN Widget_Color = 1 + Widget_BLUE Widget_Color = 2 +) + +var Widget_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var Widget_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Widget_Color) Enum() *Widget_Color { + p := new(Widget_Color) + *p = x + return p +} +func (x Widget_Color) String() string { + return proto.EnumName(Widget_Color_name, int32(x)) +} +func (x *Widget_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Widget_Color_value, data, "Widget_Color") + if err != nil { + return err + } + *x = Widget_Color(value) + return nil +} +func (Widget_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor1, []int{2, 0} } + +// Test message for holding primitive types. +type Simple struct { + OBool *bool `protobuf:"varint,1,opt,name=o_bool" json:"o_bool,omitempty"` + OInt32 *int32 `protobuf:"varint,2,opt,name=o_int32" json:"o_int32,omitempty"` + OInt64 *int64 `protobuf:"varint,3,opt,name=o_int64" json:"o_int64,omitempty"` + OUint32 *uint32 `protobuf:"varint,4,opt,name=o_uint32" json:"o_uint32,omitempty"` + OUint64 *uint64 `protobuf:"varint,5,opt,name=o_uint64" json:"o_uint64,omitempty"` + OSint32 *int32 `protobuf:"zigzag32,6,opt,name=o_sint32" json:"o_sint32,omitempty"` + OSint64 *int64 `protobuf:"zigzag64,7,opt,name=o_sint64" json:"o_sint64,omitempty"` + OFloat *float32 `protobuf:"fixed32,8,opt,name=o_float" json:"o_float,omitempty"` + ODouble *float64 `protobuf:"fixed64,9,opt,name=o_double" json:"o_double,omitempty"` + OString *string `protobuf:"bytes,10,opt,name=o_string" json:"o_string,omitempty"` + OBytes []byte `protobuf:"bytes,11,opt,name=o_bytes" json:"o_bytes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Simple) Reset() { *m = Simple{} } +func (m *Simple) String() string { return proto.CompactTextString(m) } +func (*Simple) ProtoMessage() {} +func (*Simple) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{0} } + +func (m *Simple) GetOBool() bool { + if m != nil && m.OBool != nil { + return *m.OBool + } + return false +} + +func (m *Simple) GetOInt32() int32 { + if m != nil && m.OInt32 != nil { + return *m.OInt32 + } + return 0 +} + +func (m *Simple) GetOInt64() int64 { + if m != nil && m.OInt64 != nil { + return *m.OInt64 + } + return 0 +} + +func (m *Simple) GetOUint32() uint32 { + if m != nil && m.OUint32 != nil { + return *m.OUint32 + } + return 0 +} + +func (m *Simple) GetOUint64() uint64 { + if m != nil && m.OUint64 != nil { + return *m.OUint64 + } + return 0 +} + +func (m *Simple) GetOSint32() int32 { + if m != nil && m.OSint32 != nil { + return *m.OSint32 + } + return 0 +} + +func (m *Simple) GetOSint64() int64 { + if m != nil && m.OSint64 != nil { + return *m.OSint64 + } + return 0 +} + +func (m *Simple) GetOFloat() float32 { + if m != nil && m.OFloat != nil { + return *m.OFloat + } + return 0 +} + +func (m *Simple) GetODouble() float64 { + if m != nil && m.ODouble != nil { + return *m.ODouble + } + return 0 +} + +func (m *Simple) GetOString() string { + if m != nil && m.OString != nil { + return *m.OString + } + return "" +} + +func (m *Simple) GetOBytes() []byte { + if m != nil { + return m.OBytes + } + return nil +} + +// Test message for holding repeated primitives. +type Repeats struct { + RBool []bool `protobuf:"varint,1,rep,name=r_bool" json:"r_bool,omitempty"` + RInt32 []int32 `protobuf:"varint,2,rep,name=r_int32" json:"r_int32,omitempty"` + RInt64 []int64 `protobuf:"varint,3,rep,name=r_int64" json:"r_int64,omitempty"` + RUint32 []uint32 `protobuf:"varint,4,rep,name=r_uint32" json:"r_uint32,omitempty"` + RUint64 []uint64 `protobuf:"varint,5,rep,name=r_uint64" json:"r_uint64,omitempty"` + RSint32 []int32 `protobuf:"zigzag32,6,rep,name=r_sint32" json:"r_sint32,omitempty"` + RSint64 []int64 `protobuf:"zigzag64,7,rep,name=r_sint64" json:"r_sint64,omitempty"` + RFloat []float32 `protobuf:"fixed32,8,rep,name=r_float" json:"r_float,omitempty"` + RDouble []float64 `protobuf:"fixed64,9,rep,name=r_double" json:"r_double,omitempty"` + RString []string `protobuf:"bytes,10,rep,name=r_string" json:"r_string,omitempty"` + RBytes [][]byte `protobuf:"bytes,11,rep,name=r_bytes" json:"r_bytes,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Repeats) Reset() { *m = Repeats{} } +func (m *Repeats) String() string { return proto.CompactTextString(m) } +func (*Repeats) ProtoMessage() {} +func (*Repeats) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{1} } + +func (m *Repeats) GetRBool() []bool { + if m != nil { + return m.RBool + } + return nil +} + +func (m *Repeats) GetRInt32() []int32 { + if m != nil { + return m.RInt32 + } + return nil +} + +func (m *Repeats) GetRInt64() []int64 { + if m != nil { + return m.RInt64 + } + return nil +} + +func (m *Repeats) GetRUint32() []uint32 { + if m != nil { + return m.RUint32 + } + return nil +} + +func (m *Repeats) GetRUint64() []uint64 { + if m != nil { + return m.RUint64 + } + return nil +} + +func (m *Repeats) GetRSint32() []int32 { + if m != nil { + return m.RSint32 + } + return nil +} + +func (m *Repeats) GetRSint64() []int64 { + if m != nil { + return m.RSint64 + } + return nil +} + +func (m *Repeats) GetRFloat() []float32 { + if m != nil { + return m.RFloat + } + return nil +} + +func (m *Repeats) GetRDouble() []float64 { + if m != nil { + return m.RDouble + } + return nil +} + +func (m *Repeats) GetRString() []string { + if m != nil { + return m.RString + } + return nil +} + +func (m *Repeats) GetRBytes() [][]byte { + if m != nil { + return m.RBytes + } + return nil +} + +// Test message for holding enums and nested messages. +type Widget struct { + Color *Widget_Color `protobuf:"varint,1,opt,name=color,enum=jsonpb.Widget_Color" json:"color,omitempty"` + RColor []Widget_Color `protobuf:"varint,2,rep,name=r_color,enum=jsonpb.Widget_Color" json:"r_color,omitempty"` + Simple *Simple `protobuf:"bytes,10,opt,name=simple" json:"simple,omitempty"` + RSimple []*Simple `protobuf:"bytes,11,rep,name=r_simple" json:"r_simple,omitempty"` + Repeats *Repeats `protobuf:"bytes,20,opt,name=repeats" json:"repeats,omitempty"` + RRepeats []*Repeats `protobuf:"bytes,21,rep,name=r_repeats" json:"r_repeats,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Widget) Reset() { *m = Widget{} } +func (m *Widget) String() string { return proto.CompactTextString(m) } +func (*Widget) ProtoMessage() {} +func (*Widget) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{2} } + +func (m *Widget) GetColor() Widget_Color { + if m != nil && m.Color != nil { + return *m.Color + } + return Widget_RED +} + +func (m *Widget) GetRColor() []Widget_Color { + if m != nil { + return m.RColor + } + return nil +} + +func (m *Widget) GetSimple() *Simple { + if m != nil { + return m.Simple + } + return nil +} + +func (m *Widget) GetRSimple() []*Simple { + if m != nil { + return m.RSimple + } + return nil +} + +func (m *Widget) GetRepeats() *Repeats { + if m != nil { + return m.Repeats + } + return nil +} + +func (m *Widget) GetRRepeats() []*Repeats { + if m != nil { + return m.RRepeats + } + return nil +} + +type Maps struct { + MInt64Str map[int64]string `protobuf:"bytes,1,rep,name=m_int64_str" json:"m_int64_str,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + MBoolSimple map[bool]*Simple `protobuf:"bytes,2,rep,name=m_bool_simple" json:"m_bool_simple,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Maps) Reset() { *m = Maps{} } +func (m *Maps) String() string { return proto.CompactTextString(m) } +func (*Maps) ProtoMessage() {} +func (*Maps) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{3} } + +func (m *Maps) GetMInt64Str() map[int64]string { + if m != nil { + return m.MInt64Str + } + return nil +} + +func (m *Maps) GetMBoolSimple() map[bool]*Simple { + if m != nil { + return m.MBoolSimple + } + return nil +} + +type MsgWithOneof struct { + // Types that are valid to be assigned to Union: + // *MsgWithOneof_Title + // *MsgWithOneof_Salary + Union isMsgWithOneof_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MsgWithOneof) Reset() { *m = MsgWithOneof{} } +func (m *MsgWithOneof) String() string { return proto.CompactTextString(m) } +func (*MsgWithOneof) ProtoMessage() {} +func (*MsgWithOneof) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{4} } + +type isMsgWithOneof_Union interface { + isMsgWithOneof_Union() +} + +type MsgWithOneof_Title struct { + Title string `protobuf:"bytes,1,opt,name=title,oneof"` +} +type MsgWithOneof_Salary struct { + Salary int64 `protobuf:"varint,2,opt,name=salary,oneof"` +} + +func (*MsgWithOneof_Title) isMsgWithOneof_Union() {} +func (*MsgWithOneof_Salary) isMsgWithOneof_Union() {} + +func (m *MsgWithOneof) GetUnion() isMsgWithOneof_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *MsgWithOneof) GetTitle() string { + if x, ok := m.GetUnion().(*MsgWithOneof_Title); ok { + return x.Title + } + return "" +} + +func (m *MsgWithOneof) GetSalary() int64 { + if x, ok := m.GetUnion().(*MsgWithOneof_Salary); ok { + return x.Salary + } + return 0 +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*MsgWithOneof) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _MsgWithOneof_OneofMarshaler, _MsgWithOneof_OneofUnmarshaler, _MsgWithOneof_OneofSizer, []interface{}{ + (*MsgWithOneof_Title)(nil), + (*MsgWithOneof_Salary)(nil), + } +} + +func _MsgWithOneof_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*MsgWithOneof) + // union + switch x := m.Union.(type) { + case *MsgWithOneof_Title: + b.EncodeVarint(1<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Title) + case *MsgWithOneof_Salary: + b.EncodeVarint(2<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Salary)) + case nil: + default: + return fmt.Errorf("MsgWithOneof.Union has unexpected type %T", x) + } + return nil +} + +func _MsgWithOneof_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*MsgWithOneof) + switch tag { + case 1: // union.title + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Union = &MsgWithOneof_Title{x} + return true, err + case 2: // union.salary + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &MsgWithOneof_Salary{int64(x)} + return true, err + default: + return false, nil + } +} + +func _MsgWithOneof_OneofSizer(msg proto.Message) (n int) { + m := msg.(*MsgWithOneof) + // union + switch x := m.Union.(type) { + case *MsgWithOneof_Title: + n += proto.SizeVarint(1<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Title))) + n += len(x.Title) + case *MsgWithOneof_Salary: + n += proto.SizeVarint(2<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Salary)) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +type Real struct { + Value *float64 `protobuf:"fixed64,1,opt,name=value" json:"value,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Real) Reset() { *m = Real{} } +func (m *Real) String() string { return proto.CompactTextString(m) } +func (*Real) ProtoMessage() {} +func (*Real) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{5} } + +var extRange_Real = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*Real) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_Real +} +func (m *Real) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *Real) GetValue() float64 { + if m != nil && m.Value != nil { + return *m.Value + } + return 0 +} + +type Complex struct { + Imaginary *float64 `protobuf:"fixed64,1,opt,name=imaginary" json:"imaginary,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Complex) Reset() { *m = Complex{} } +func (m *Complex) String() string { return proto.CompactTextString(m) } +func (*Complex) ProtoMessage() {} +func (*Complex) Descriptor() ([]byte, []int) { return fileDescriptor1, []int{6} } + +var extRange_Complex = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*Complex) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_Complex +} +func (m *Complex) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *Complex) GetImaginary() float64 { + if m != nil && m.Imaginary != nil { + return *m.Imaginary + } + return 0 +} + +var E_Complex_RealExtension = &proto.ExtensionDesc{ + ExtendedType: (*Real)(nil), + ExtensionType: (*Complex)(nil), + Field: 123, + Name: "jsonpb.Complex.real_extension", + Tag: "bytes,123,opt,name=real_extension", +} + +var E_Name = &proto.ExtensionDesc{ + ExtendedType: (*Real)(nil), + ExtensionType: (*string)(nil), + Field: 124, + Name: "jsonpb.name", + Tag: "bytes,124,opt,name=name", +} + +func init() { + proto.RegisterType((*Simple)(nil), "jsonpb.Simple") + proto.RegisterType((*Repeats)(nil), "jsonpb.Repeats") + proto.RegisterType((*Widget)(nil), "jsonpb.Widget") + proto.RegisterType((*Maps)(nil), "jsonpb.Maps") + proto.RegisterType((*MsgWithOneof)(nil), "jsonpb.MsgWithOneof") + proto.RegisterType((*Real)(nil), "jsonpb.Real") + proto.RegisterType((*Complex)(nil), "jsonpb.Complex") + proto.RegisterEnum("jsonpb.Widget_Color", Widget_Color_name, Widget_Color_value) + proto.RegisterExtension(E_Complex_RealExtension) + proto.RegisterExtension(E_Name) +} + +var fileDescriptor1 = []byte{ + // 598 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x93, 0x5f, 0x6b, 0x13, 0x4d, + 0x14, 0xc6, 0xbb, 0x3b, 0xfb, 0xf7, 0xa4, 0x4d, 0xb7, 0x43, 0x5f, 0x58, 0xfa, 0x52, 0x2d, 0x2b, + 0x05, 0xf1, 0x22, 0x94, 0x58, 0x45, 0x72, 0x99, 0x1a, 0xac, 0x60, 0x14, 0x52, 0xa4, 0x57, 0xb2, + 0x6c, 0x9a, 0x69, 0xdc, 0xba, 0xd9, 0x09, 0xb3, 0x13, 0x69, 0xd0, 0x0b, 0xc1, 0x2f, 0xa7, 0xdf, + 0xc3, 0x0f, 0xe2, 0xcc, 0x9c, 0x6c, 0xb6, 0x8d, 0x9a, 0xcb, 0x67, 0x9e, 0xf3, 0xe4, 0xfc, 0xce, + 0x39, 0x0b, 0x54, 0xb2, 0x4a, 0xa6, 0x7c, 0x7c, 0xc3, 0xae, 0x64, 0xd5, 0x99, 0x0b, 0x2e, 0x39, + 0xf5, 0x6e, 0x2a, 0x5e, 0xce, 0xc7, 0xc9, 0x0f, 0x0b, 0xbc, 0x8b, 0x7c, 0x36, 0x2f, 0x18, 0x6d, + 0x83, 0xc7, 0xd3, 0x31, 0xe7, 0x45, 0x6c, 0x1d, 0x59, 0x8f, 0x03, 0xba, 0x0b, 0x3e, 0x4f, 0xf3, + 0x52, 0x3e, 0xed, 0xc6, 0xb6, 0x12, 0xdc, 0xb5, 0xf0, 0xfc, 0x34, 0x26, 0x4a, 0x20, 0x34, 0x82, + 0x80, 0xa7, 0x0b, 0xb4, 0x38, 0x4a, 0xd9, 0x69, 0x14, 0xe5, 0x71, 0x95, 0xe2, 0xa0, 0x52, 0xa1, + 0xc7, 0x53, 0xca, 0x5e, 0xa3, 0x28, 0x8f, 0xaf, 0x14, 0x8a, 0xc1, 0xd7, 0x05, 0xcf, 0x64, 0x1c, + 0x28, 0xc1, 0x46, 0xcb, 0x84, 0x2f, 0xc6, 0x05, 0x8b, 0x43, 0xa5, 0x58, 0xab, 0x22, 0x29, 0xf2, + 0x72, 0x1a, 0x83, 0x52, 0x42, 0x2c, 0x1a, 0x2f, 0x15, 0x5b, 0xdc, 0x52, 0xc2, 0x76, 0xf2, 0xd3, + 0x02, 0x7f, 0xc4, 0xe6, 0x2c, 0x93, 0x95, 0x66, 0x11, 0x35, 0x0b, 0x41, 0x16, 0xb1, 0x66, 0x21, + 0xc8, 0x22, 0xd6, 0x2c, 0x04, 0x59, 0x44, 0xc3, 0x42, 0x90, 0x45, 0x34, 0x2c, 0x04, 0x59, 0x44, + 0xc3, 0x42, 0x90, 0x45, 0x34, 0x2c, 0x04, 0x59, 0xc4, 0x9a, 0x85, 0x20, 0x8b, 0x68, 0x58, 0x08, + 0xb2, 0x88, 0x86, 0x85, 0x20, 0x8b, 0x58, 0xb3, 0x10, 0xc5, 0xf2, 0xdd, 0x06, 0xef, 0x32, 0x9f, + 0x4c, 0x99, 0xa4, 0x8f, 0xc0, 0xbd, 0xe2, 0x05, 0x17, 0x66, 0x2b, 0xed, 0xee, 0x7e, 0x07, 0x37, + 0xd7, 0xc1, 0xe7, 0xce, 0x99, 0x7e, 0xa3, 0xc7, 0x3a, 0x00, 0x6d, 0x9a, 0xef, 0x5f, 0xb6, 0x07, + 0xe0, 0x55, 0x66, 0xd9, 0x66, 0x86, 0xad, 0x6e, 0xbb, 0x76, 0xad, 0x4e, 0xe0, 0x08, 0x71, 0x8c, + 0x43, 0x37, 0xf2, 0x37, 0x87, 0x2f, 0x70, 0xc6, 0xf1, 0xbe, 0x89, 0xd8, 0xad, 0x0d, 0xf5, 0xe8, + 0x13, 0x08, 0x45, 0x5a, 0x7b, 0xfe, 0x33, 0x21, 0x9b, 0x9e, 0xe4, 0x18, 0x5c, 0x6c, 0xc8, 0x07, + 0x32, 0x1a, 0xbc, 0x8c, 0xb6, 0x68, 0x08, 0xee, 0xab, 0xd1, 0x60, 0xf0, 0x36, 0xb2, 0x68, 0x00, + 0x4e, 0xff, 0xcd, 0xfb, 0x41, 0x64, 0x27, 0xbf, 0x2c, 0x70, 0x86, 0xd9, 0xbc, 0xa2, 0x27, 0xd0, + 0x9a, 0xe1, 0xb6, 0xf4, 0xdc, 0xcc, 0x4e, 0x5b, 0xdd, 0xff, 0xeb, 0x54, 0x6d, 0xe9, 0x0c, 0x5f, + 0xeb, 0xe7, 0x0b, 0x29, 0x06, 0xa5, 0x14, 0x4b, 0x7a, 0x0a, 0x3b, 0x33, 0x73, 0x00, 0x35, 0x8e, + 0x6d, 0x6a, 0x0e, 0xef, 0xd7, 0xf4, 0x95, 0x01, 0xc1, 0x4c, 0xd5, 0xc1, 0x09, 0xb4, 0x37, 0x72, + 0x5a, 0x40, 0x3e, 0xb1, 0xa5, 0x99, 0x3d, 0xa1, 0x3b, 0xe0, 0x7e, 0xce, 0x8a, 0x05, 0x33, 0xdf, + 0x43, 0xd8, 0xb3, 0x5f, 0x58, 0x07, 0x7d, 0x88, 0x36, 0x53, 0xee, 0xd6, 0x04, 0xf4, 0xf0, 0x6e, + 0xcd, 0x1f, 0xf3, 0xd4, 0x19, 0x49, 0x0f, 0xb6, 0x87, 0xd5, 0xf4, 0x32, 0x97, 0x1f, 0xdf, 0x95, + 0x8c, 0x5f, 0xab, 0x6b, 0x70, 0x65, 0x2e, 0x55, 0xcf, 0x3a, 0x21, 0x3c, 0xdf, 0x52, 0x07, 0xe3, + 0x55, 0x59, 0x91, 0x89, 0xa5, 0x09, 0x21, 0xe7, 0x5b, 0x7d, 0x1f, 0xdc, 0x45, 0x99, 0xf3, 0x32, + 0x79, 0x08, 0xce, 0x88, 0x65, 0x45, 0xd3, 0x9a, 0xae, 0xb1, 0x9e, 0x04, 0xc1, 0x24, 0xfa, 0xa6, + 0x7e, 0x76, 0xf2, 0x01, 0xfc, 0x33, 0xae, 0xff, 0xea, 0x96, 0xee, 0x41, 0x98, 0xcf, 0xb2, 0x69, + 0x5e, 0xea, 0xa4, 0x0d, 0x5f, 0xf7, 0x19, 0xb4, 0x85, 0x0a, 0x4a, 0xd9, 0xad, 0x64, 0x65, 0xa5, + 0xa2, 0xe9, 0x76, 0xb3, 0xb5, 0xac, 0x88, 0xbf, 0xdc, 0xdf, 0xf6, 0x2a, 0xb3, 0x77, 0x00, 0x4e, + 0x99, 0xcd, 0xd8, 0x86, 0xf9, 0xab, 0x6e, 0xfc, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xc2, + 0xb2, 0xf6, 0x78, 0x04, 0x00, 0x00, +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.proto new file mode 100644 index 00000000..77f7fba9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/jsonpb/jsonpb_test_proto/test_objects.proto @@ -0,0 +1,110 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package jsonpb; + +// Test message for holding primitive types. +message Simple { + optional bool o_bool = 1; + optional int32 o_int32 = 2; + optional int64 o_int64 = 3; + optional uint32 o_uint32 = 4; + optional uint64 o_uint64 = 5; + optional sint32 o_sint32 = 6; + optional sint64 o_sint64 = 7; + optional float o_float = 8; + optional double o_double = 9; + optional string o_string = 10; + optional bytes o_bytes = 11; +} + +// Test message for holding repeated primitives. +message Repeats { + repeated bool r_bool = 1; + repeated int32 r_int32 = 2; + repeated int64 r_int64 = 3; + repeated uint32 r_uint32 = 4; + repeated uint64 r_uint64 = 5; + repeated sint32 r_sint32 = 6; + repeated sint64 r_sint64 = 7; + repeated float r_float = 8; + repeated double r_double = 9; + repeated string r_string = 10; + repeated bytes r_bytes = 11; +} + +// Test message for holding enums and nested messages. +message Widget { + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + }; + optional Color color = 1; + repeated Color r_color = 2; + + optional Simple simple = 10; + repeated Simple r_simple = 11; + + optional Repeats repeats = 20; + repeated Repeats r_repeats = 21; +} + +message Maps { + map m_int64_str = 1; + map m_bool_simple = 2; +} + +message MsgWithOneof { + oneof union { + string title = 1; + int64 salary = 2; + } +} + +message Real { + optional double value = 1; + extensions 100 to max; +} + +extend Real { + optional string name = 124; +} + +message Complex { + extend Real { + optional Complex real_extension = 123; + } + optional double imaginary = 1; + extensions 100 to max; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/Makefile new file mode 100644 index 00000000..f1f06564 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/Makefile @@ -0,0 +1,43 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +install: + go install + +test: install generate-test-pbs + go test + + +generate-test-pbs: + make install + make -C testdata + protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto + make diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/all_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/all_test.go new file mode 100644 index 00000000..f68f913d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/all_test.go @@ -0,0 +1,2169 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "math" + "math/rand" + "reflect" + "runtime/debug" + "strings" + "testing" + "time" + + . "github.com/golang/protobuf/proto" + . "github.com/golang/protobuf/proto/testdata" +) + +var globalO *Buffer + +func old() *Buffer { + if globalO == nil { + globalO = NewBuffer(nil) + } + globalO.Reset() + return globalO +} + +func equalbytes(b1, b2 []byte, t *testing.T) { + if len(b1) != len(b2) { + t.Errorf("wrong lengths: 2*%d != %d", len(b1), len(b2)) + return + } + for i := 0; i < len(b1); i++ { + if b1[i] != b2[i] { + t.Errorf("bad byte[%d]:%x %x: %s %s", i, b1[i], b2[i], b1, b2) + } + } +} + +func initGoTestField() *GoTestField { + f := new(GoTestField) + f.Label = String("label") + f.Type = String("type") + return f +} + +// These are all structurally equivalent but the tag numbers differ. +// (It's remarkable that required, optional, and repeated all have +// 8 letters.) +func initGoTest_RequiredGroup() *GoTest_RequiredGroup { + return &GoTest_RequiredGroup{ + RequiredField: String("required"), + } +} + +func initGoTest_OptionalGroup() *GoTest_OptionalGroup { + return &GoTest_OptionalGroup{ + RequiredField: String("optional"), + } +} + +func initGoTest_RepeatedGroup() *GoTest_RepeatedGroup { + return &GoTest_RepeatedGroup{ + RequiredField: String("repeated"), + } +} + +func initGoTest(setdefaults bool) *GoTest { + pb := new(GoTest) + if setdefaults { + pb.F_BoolDefaulted = Bool(Default_GoTest_F_BoolDefaulted) + pb.F_Int32Defaulted = Int32(Default_GoTest_F_Int32Defaulted) + pb.F_Int64Defaulted = Int64(Default_GoTest_F_Int64Defaulted) + pb.F_Fixed32Defaulted = Uint32(Default_GoTest_F_Fixed32Defaulted) + pb.F_Fixed64Defaulted = Uint64(Default_GoTest_F_Fixed64Defaulted) + pb.F_Uint32Defaulted = Uint32(Default_GoTest_F_Uint32Defaulted) + pb.F_Uint64Defaulted = Uint64(Default_GoTest_F_Uint64Defaulted) + pb.F_FloatDefaulted = Float32(Default_GoTest_F_FloatDefaulted) + pb.F_DoubleDefaulted = Float64(Default_GoTest_F_DoubleDefaulted) + pb.F_StringDefaulted = String(Default_GoTest_F_StringDefaulted) + pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted + pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted) + pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted) + } + + pb.Kind = GoTest_TIME.Enum() + pb.RequiredField = initGoTestField() + pb.F_BoolRequired = Bool(true) + pb.F_Int32Required = Int32(3) + pb.F_Int64Required = Int64(6) + pb.F_Fixed32Required = Uint32(32) + pb.F_Fixed64Required = Uint64(64) + pb.F_Uint32Required = Uint32(3232) + pb.F_Uint64Required = Uint64(6464) + pb.F_FloatRequired = Float32(3232) + pb.F_DoubleRequired = Float64(6464) + pb.F_StringRequired = String("string") + pb.F_BytesRequired = []byte("bytes") + pb.F_Sint32Required = Int32(-32) + pb.F_Sint64Required = Int64(-64) + pb.Requiredgroup = initGoTest_RequiredGroup() + + return pb +} + +func fail(msg string, b *bytes.Buffer, s string, t *testing.T) { + data := b.Bytes() + ld := len(data) + ls := len(s) / 2 + + fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls) + + // find the interesting spot - n + n := ls + if ld < ls { + n = ld + } + j := 0 + for i := 0; i < n; i++ { + bs := hex(s[j])*16 + hex(s[j+1]) + j += 2 + if data[i] == bs { + continue + } + n = i + break + } + l := n - 10 + if l < 0 { + l = 0 + } + h := n + 10 + + // find the interesting spot - n + fmt.Printf("is[%d]:", l) + for i := l; i < h; i++ { + if i >= ld { + fmt.Printf(" --") + continue + } + fmt.Printf(" %.2x", data[i]) + } + fmt.Printf("\n") + + fmt.Printf("sb[%d]:", l) + for i := l; i < h; i++ { + if i >= ls { + fmt.Printf(" --") + continue + } + bs := hex(s[j])*16 + hex(s[j+1]) + j += 2 + fmt.Printf(" %.2x", bs) + } + fmt.Printf("\n") + + t.Fail() + + // t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes()) + // Print the output in a partially-decoded format; can + // be helpful when updating the test. It produces the output + // that is pasted, with minor edits, into the argument to verify(). + // data := b.Bytes() + // nesting := 0 + // for b.Len() > 0 { + // start := len(data) - b.Len() + // var u uint64 + // u, err := DecodeVarint(b) + // if err != nil { + // fmt.Printf("decode error on varint:", err) + // return + // } + // wire := u & 0x7 + // tag := u >> 3 + // switch wire { + // case WireVarint: + // v, err := DecodeVarint(b) + // if err != nil { + // fmt.Printf("decode error on varint:", err) + // return + // } + // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n", + // data[start:len(data)-b.Len()], tag, wire, v) + // case WireFixed32: + // v, err := DecodeFixed32(b) + // if err != nil { + // fmt.Printf("decode error on fixed32:", err) + // return + // } + // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n", + // data[start:len(data)-b.Len()], tag, wire, v) + // case WireFixed64: + // v, err := DecodeFixed64(b) + // if err != nil { + // fmt.Printf("decode error on fixed64:", err) + // return + // } + // fmt.Printf("\t\t\"%x\" // field %d, encoding %d, value %d\n", + // data[start:len(data)-b.Len()], tag, wire, v) + // case WireBytes: + // nb, err := DecodeVarint(b) + // if err != nil { + // fmt.Printf("decode error on bytes:", err) + // return + // } + // after_tag := len(data) - b.Len() + // str := make([]byte, nb) + // _, err = b.Read(str) + // if err != nil { + // fmt.Printf("decode error on bytes:", err) + // return + // } + // fmt.Printf("\t\t\"%x\" \"%x\" // field %d, encoding %d (FIELD)\n", + // data[start:after_tag], str, tag, wire) + // case WireStartGroup: + // nesting++ + // fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n", + // data[start:len(data)-b.Len()], tag, nesting) + // case WireEndGroup: + // fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n", + // data[start:len(data)-b.Len()], tag, nesting) + // nesting-- + // default: + // fmt.Printf("unrecognized wire type %d\n", wire) + // return + // } + // } +} + +func hex(c uint8) uint8 { + if '0' <= c && c <= '9' { + return c - '0' + } + if 'a' <= c && c <= 'f' { + return 10 + c - 'a' + } + if 'A' <= c && c <= 'F' { + return 10 + c - 'A' + } + return 0 +} + +func equal(b []byte, s string, t *testing.T) bool { + if 2*len(b) != len(s) { + // fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t) + fmt.Printf("wrong lengths: 2*%d != %d\n", len(b), len(s)) + return false + } + for i, j := 0, 0; i < len(b); i, j = i+1, j+2 { + x := hex(s[j])*16 + hex(s[j+1]) + if b[i] != x { + // fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t) + fmt.Printf("bad byte[%d]:%x %x", i, b[i], x) + return false + } + } + return true +} + +func overify(t *testing.T, pb *GoTest, expected string) { + o := old() + err := o.Marshal(pb) + if err != nil { + fmt.Printf("overify marshal-1 err = %v", err) + o.DebugPrint("", o.Bytes()) + t.Fatalf("expected = %s", expected) + } + if !equal(o.Bytes(), expected, t) { + o.DebugPrint("overify neq 1", o.Bytes()) + t.Fatalf("expected = %s", expected) + } + + // Now test Unmarshal by recreating the original buffer. + pbd := new(GoTest) + err = o.Unmarshal(pbd) + if err != nil { + t.Fatalf("overify unmarshal err = %v", err) + o.DebugPrint("", o.Bytes()) + t.Fatalf("string = %s", expected) + } + o.Reset() + err = o.Marshal(pbd) + if err != nil { + t.Errorf("overify marshal-2 err = %v", err) + o.DebugPrint("", o.Bytes()) + t.Fatalf("string = %s", expected) + } + if !equal(o.Bytes(), expected, t) { + o.DebugPrint("overify neq 2", o.Bytes()) + t.Fatalf("string = %s", expected) + } +} + +// Simple tests for numeric encode/decode primitives (varint, etc.) +func TestNumericPrimitives(t *testing.T) { + for i := uint64(0); i < 1e6; i += 111 { + o := old() + if o.EncodeVarint(i) != nil { + t.Error("EncodeVarint") + break + } + x, e := o.DecodeVarint() + if e != nil { + t.Fatal("DecodeVarint") + } + if x != i { + t.Fatal("varint decode fail:", i, x) + } + + o = old() + if o.EncodeFixed32(i) != nil { + t.Fatal("encFixed32") + } + x, e = o.DecodeFixed32() + if e != nil { + t.Fatal("decFixed32") + } + if x != i { + t.Fatal("fixed32 decode fail:", i, x) + } + + o = old() + if o.EncodeFixed64(i*1234567) != nil { + t.Error("encFixed64") + break + } + x, e = o.DecodeFixed64() + if e != nil { + t.Error("decFixed64") + break + } + if x != i*1234567 { + t.Error("fixed64 decode fail:", i*1234567, x) + break + } + + o = old() + i32 := int32(i - 12345) + if o.EncodeZigzag32(uint64(i32)) != nil { + t.Fatal("EncodeZigzag32") + } + x, e = o.DecodeZigzag32() + if e != nil { + t.Fatal("DecodeZigzag32") + } + if x != uint64(uint32(i32)) { + t.Fatal("zigzag32 decode fail:", i32, x) + } + + o = old() + i64 := int64(i - 12345) + if o.EncodeZigzag64(uint64(i64)) != nil { + t.Fatal("EncodeZigzag64") + } + x, e = o.DecodeZigzag64() + if e != nil { + t.Fatal("DecodeZigzag64") + } + if x != uint64(i64) { + t.Fatal("zigzag64 decode fail:", i64, x) + } + } +} + +// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces. +type fakeMarshaler struct { + b []byte + err error +} + +func (f *fakeMarshaler) Marshal() ([]byte, error) { return f.b, f.err } +func (f *fakeMarshaler) String() string { return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err) } +func (f *fakeMarshaler) ProtoMessage() {} +func (f *fakeMarshaler) Reset() {} + +type msgWithFakeMarshaler struct { + M *fakeMarshaler `protobuf:"bytes,1,opt,name=fake"` +} + +func (m *msgWithFakeMarshaler) String() string { return CompactTextString(m) } +func (m *msgWithFakeMarshaler) ProtoMessage() {} +func (m *msgWithFakeMarshaler) Reset() {} + +// Simple tests for proto messages that implement the Marshaler interface. +func TestMarshalerEncoding(t *testing.T) { + tests := []struct { + name string + m Message + want []byte + wantErr error + }{ + { + name: "Marshaler that fails", + m: &fakeMarshaler{ + err: errors.New("some marshal err"), + b: []byte{5, 6, 7}, + }, + // Since there's an error, nothing should be written to buffer. + want: nil, + wantErr: errors.New("some marshal err"), + }, + { + name: "Marshaler that fails with RequiredNotSetError", + m: &msgWithFakeMarshaler{ + M: &fakeMarshaler{ + err: &RequiredNotSetError{}, + b: []byte{5, 6, 7}, + }, + }, + // Since there's an error that can be continued after, + // the buffer should be written. + want: []byte{ + 10, 3, // for &msgWithFakeMarshaler + 5, 6, 7, // for &fakeMarshaler + }, + wantErr: &RequiredNotSetError{}, + }, + { + name: "Marshaler that succeeds", + m: &fakeMarshaler{ + b: []byte{0, 1, 2, 3, 4, 127, 255}, + }, + want: []byte{0, 1, 2, 3, 4, 127, 255}, + wantErr: nil, + }, + } + for _, test := range tests { + b := NewBuffer(nil) + err := b.Marshal(test.m) + if _, ok := err.(*RequiredNotSetError); ok { + // We're not in package proto, so we can only assert the type in this case. + err = &RequiredNotSetError{} + } + if !reflect.DeepEqual(test.wantErr, err) { + t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr) + } + if !reflect.DeepEqual(test.want, b.Bytes()) { + t.Errorf("%s: got bytes %v wanted %v", test.name, b.Bytes(), test.want) + } + } +} + +// Simple tests for bytes +func TestBytesPrimitives(t *testing.T) { + o := old() + bytes := []byte{'n', 'o', 'w', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 't', 'i', 'm', 'e'} + if o.EncodeRawBytes(bytes) != nil { + t.Error("EncodeRawBytes") + } + decb, e := o.DecodeRawBytes(false) + if e != nil { + t.Error("DecodeRawBytes") + } + equalbytes(bytes, decb, t) +} + +// Simple tests for strings +func TestStringPrimitives(t *testing.T) { + o := old() + s := "now is the time" + if o.EncodeStringBytes(s) != nil { + t.Error("enc_string") + } + decs, e := o.DecodeStringBytes() + if e != nil { + t.Error("dec_string") + } + if s != decs { + t.Error("string encode/decode fail:", s, decs) + } +} + +// Do we catch the "required bit not set" case? +func TestRequiredBit(t *testing.T) { + o := old() + pb := new(GoTest) + err := o.Marshal(pb) + if err == nil { + t.Error("did not catch missing required fields") + } else if strings.Index(err.Error(), "Kind") < 0 { + t.Error("wrong error type:", err) + } +} + +// Check that all fields are nil. +// Clearly silly, and a residue from a more interesting test with an earlier, +// different initialization property, but it once caught a compiler bug so +// it lives. +func checkInitialized(pb *GoTest, t *testing.T) { + if pb.F_BoolDefaulted != nil { + t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted) + } + if pb.F_Int32Defaulted != nil { + t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted) + } + if pb.F_Int64Defaulted != nil { + t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted) + } + if pb.F_Fixed32Defaulted != nil { + t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted) + } + if pb.F_Fixed64Defaulted != nil { + t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted) + } + if pb.F_Uint32Defaulted != nil { + t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted) + } + if pb.F_Uint64Defaulted != nil { + t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted) + } + if pb.F_FloatDefaulted != nil { + t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted) + } + if pb.F_DoubleDefaulted != nil { + t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted) + } + if pb.F_StringDefaulted != nil { + t.Error("New or Reset did not set string:", *pb.F_StringDefaulted) + } + if pb.F_BytesDefaulted != nil { + t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted)) + } + if pb.F_Sint32Defaulted != nil { + t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted) + } + if pb.F_Sint64Defaulted != nil { + t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted) + } +} + +// Does Reset() reset? +func TestReset(t *testing.T) { + pb := initGoTest(true) + // muck with some values + pb.F_BoolDefaulted = Bool(false) + pb.F_Int32Defaulted = Int32(237) + pb.F_Int64Defaulted = Int64(12346) + pb.F_Fixed32Defaulted = Uint32(32000) + pb.F_Fixed64Defaulted = Uint64(666) + pb.F_Uint32Defaulted = Uint32(323232) + pb.F_Uint64Defaulted = nil + pb.F_FloatDefaulted = nil + pb.F_DoubleDefaulted = Float64(0) + pb.F_StringDefaulted = String("gotcha") + pb.F_BytesDefaulted = []byte("asdfasdf") + pb.F_Sint32Defaulted = Int32(123) + pb.F_Sint64Defaulted = Int64(789) + pb.Reset() + checkInitialized(pb, t) +} + +// All required fields set, no defaults provided. +func TestEncodeDecode1(t *testing.T) { + pb := initGoTest(false) + overify(t, pb, + "0807"+ // field 1, encoding 0, value 7 + "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) + "5001"+ // field 10, encoding 0, value 1 + "5803"+ // field 11, encoding 0, value 3 + "6006"+ // field 12, encoding 0, value 6 + "6d20000000"+ // field 13, encoding 5, value 0x20 + "714000000000000000"+ // field 14, encoding 1, value 0x40 + "78a019"+ // field 15, encoding 0, value 0xca0 = 3232 + "8001c032"+ // field 16, encoding 0, value 0x1940 = 6464 + "8d0100004a45"+ // field 17, encoding 5, value 3232.0 + "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 + "9a0106"+"737472696e67"+ // field 19, encoding 2, string "string" + "b304"+ // field 70, encoding 3, start group + "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" + "b404"+ // field 70, encoding 4, end group + "aa0605"+"6279746573"+ // field 101, encoding 2, string "bytes" + "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 + "b8067f") // field 103, encoding 0, 0x7f zigzag64 +} + +// All required fields set, defaults provided. +func TestEncodeDecode2(t *testing.T) { + pb := initGoTest(true) + overify(t, pb, + "0807"+ // field 1, encoding 0, value 7 + "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) + "5001"+ // field 10, encoding 0, value 1 + "5803"+ // field 11, encoding 0, value 3 + "6006"+ // field 12, encoding 0, value 6 + "6d20000000"+ // field 13, encoding 5, value 32 + "714000000000000000"+ // field 14, encoding 1, value 64 + "78a019"+ // field 15, encoding 0, value 3232 + "8001c032"+ // field 16, encoding 0, value 6464 + "8d0100004a45"+ // field 17, encoding 5, value 3232.0 + "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 + "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" + "c00201"+ // field 40, encoding 0, value 1 + "c80220"+ // field 41, encoding 0, value 32 + "d00240"+ // field 42, encoding 0, value 64 + "dd0240010000"+ // field 43, encoding 5, value 320 + "e1028002000000000000"+ // field 44, encoding 1, value 640 + "e8028019"+ // field 45, encoding 0, value 3200 + "f0028032"+ // field 46, encoding 0, value 6400 + "fd02e0659948"+ // field 47, encoding 5, value 314159.0 + "81030000000050971041"+ // field 48, encoding 1, value 271828.0 + "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" + "b304"+ // start group field 70 level 1 + "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" + "b404"+ // end group field 70 level 1 + "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" + "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 + "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 + "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" + "90193f"+ // field 402, encoding 0, value 63 + "98197f") // field 403, encoding 0, value 127 + +} + +// All default fields set to their default value by hand +func TestEncodeDecode3(t *testing.T) { + pb := initGoTest(false) + pb.F_BoolDefaulted = Bool(true) + pb.F_Int32Defaulted = Int32(32) + pb.F_Int64Defaulted = Int64(64) + pb.F_Fixed32Defaulted = Uint32(320) + pb.F_Fixed64Defaulted = Uint64(640) + pb.F_Uint32Defaulted = Uint32(3200) + pb.F_Uint64Defaulted = Uint64(6400) + pb.F_FloatDefaulted = Float32(314159) + pb.F_DoubleDefaulted = Float64(271828) + pb.F_StringDefaulted = String("hello, \"world!\"\n") + pb.F_BytesDefaulted = []byte("Bignose") + pb.F_Sint32Defaulted = Int32(-32) + pb.F_Sint64Defaulted = Int64(-64) + + overify(t, pb, + "0807"+ // field 1, encoding 0, value 7 + "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) + "5001"+ // field 10, encoding 0, value 1 + "5803"+ // field 11, encoding 0, value 3 + "6006"+ // field 12, encoding 0, value 6 + "6d20000000"+ // field 13, encoding 5, value 32 + "714000000000000000"+ // field 14, encoding 1, value 64 + "78a019"+ // field 15, encoding 0, value 3232 + "8001c032"+ // field 16, encoding 0, value 6464 + "8d0100004a45"+ // field 17, encoding 5, value 3232.0 + "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 + "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" + "c00201"+ // field 40, encoding 0, value 1 + "c80220"+ // field 41, encoding 0, value 32 + "d00240"+ // field 42, encoding 0, value 64 + "dd0240010000"+ // field 43, encoding 5, value 320 + "e1028002000000000000"+ // field 44, encoding 1, value 640 + "e8028019"+ // field 45, encoding 0, value 3200 + "f0028032"+ // field 46, encoding 0, value 6400 + "fd02e0659948"+ // field 47, encoding 5, value 314159.0 + "81030000000050971041"+ // field 48, encoding 1, value 271828.0 + "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" + "b304"+ // start group field 70 level 1 + "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" + "b404"+ // end group field 70 level 1 + "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" + "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 + "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 + "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" + "90193f"+ // field 402, encoding 0, value 63 + "98197f") // field 403, encoding 0, value 127 + +} + +// All required fields set, defaults provided, all non-defaulted optional fields have values. +func TestEncodeDecode4(t *testing.T) { + pb := initGoTest(true) + pb.Table = String("hello") + pb.Param = Int32(7) + pb.OptionalField = initGoTestField() + pb.F_BoolOptional = Bool(true) + pb.F_Int32Optional = Int32(32) + pb.F_Int64Optional = Int64(64) + pb.F_Fixed32Optional = Uint32(3232) + pb.F_Fixed64Optional = Uint64(6464) + pb.F_Uint32Optional = Uint32(323232) + pb.F_Uint64Optional = Uint64(646464) + pb.F_FloatOptional = Float32(32.) + pb.F_DoubleOptional = Float64(64.) + pb.F_StringOptional = String("hello") + pb.F_BytesOptional = []byte("Bignose") + pb.F_Sint32Optional = Int32(-32) + pb.F_Sint64Optional = Int64(-64) + pb.Optionalgroup = initGoTest_OptionalGroup() + + overify(t, pb, + "0807"+ // field 1, encoding 0, value 7 + "1205"+"68656c6c6f"+ // field 2, encoding 2, string "hello" + "1807"+ // field 3, encoding 0, value 7 + "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) + "320d"+"0a056c6162656c120474797065"+ // field 6, encoding 2 (GoTestField) + "5001"+ // field 10, encoding 0, value 1 + "5803"+ // field 11, encoding 0, value 3 + "6006"+ // field 12, encoding 0, value 6 + "6d20000000"+ // field 13, encoding 5, value 32 + "714000000000000000"+ // field 14, encoding 1, value 64 + "78a019"+ // field 15, encoding 0, value 3232 + "8001c032"+ // field 16, encoding 0, value 6464 + "8d0100004a45"+ // field 17, encoding 5, value 3232.0 + "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 + "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" + "f00101"+ // field 30, encoding 0, value 1 + "f80120"+ // field 31, encoding 0, value 32 + "800240"+ // field 32, encoding 0, value 64 + "8d02a00c0000"+ // field 33, encoding 5, value 3232 + "91024019000000000000"+ // field 34, encoding 1, value 6464 + "9802a0dd13"+ // field 35, encoding 0, value 323232 + "a002c0ba27"+ // field 36, encoding 0, value 646464 + "ad0200000042"+ // field 37, encoding 5, value 32.0 + "b1020000000000005040"+ // field 38, encoding 1, value 64.0 + "ba0205"+"68656c6c6f"+ // field 39, encoding 2, string "hello" + "c00201"+ // field 40, encoding 0, value 1 + "c80220"+ // field 41, encoding 0, value 32 + "d00240"+ // field 42, encoding 0, value 64 + "dd0240010000"+ // field 43, encoding 5, value 320 + "e1028002000000000000"+ // field 44, encoding 1, value 640 + "e8028019"+ // field 45, encoding 0, value 3200 + "f0028032"+ // field 46, encoding 0, value 6400 + "fd02e0659948"+ // field 47, encoding 5, value 314159.0 + "81030000000050971041"+ // field 48, encoding 1, value 271828.0 + "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" + "b304"+ // start group field 70 level 1 + "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" + "b404"+ // end group field 70 level 1 + "d305"+ // start group field 90 level 1 + "da0508"+"6f7074696f6e616c"+ // field 91, encoding 2, string "optional" + "d405"+ // end group field 90 level 1 + "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" + "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 + "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 + "ea1207"+"4269676e6f7365"+ // field 301, encoding 2, string "Bignose" + "f0123f"+ // field 302, encoding 0, value 63 + "f8127f"+ // field 303, encoding 0, value 127 + "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" + "90193f"+ // field 402, encoding 0, value 63 + "98197f") // field 403, encoding 0, value 127 + +} + +// All required fields set, defaults provided, all repeated fields given two values. +func TestEncodeDecode5(t *testing.T) { + pb := initGoTest(true) + pb.RepeatedField = []*GoTestField{initGoTestField(), initGoTestField()} + pb.F_BoolRepeated = []bool{false, true} + pb.F_Int32Repeated = []int32{32, 33} + pb.F_Int64Repeated = []int64{64, 65} + pb.F_Fixed32Repeated = []uint32{3232, 3333} + pb.F_Fixed64Repeated = []uint64{6464, 6565} + pb.F_Uint32Repeated = []uint32{323232, 333333} + pb.F_Uint64Repeated = []uint64{646464, 656565} + pb.F_FloatRepeated = []float32{32., 33.} + pb.F_DoubleRepeated = []float64{64., 65.} + pb.F_StringRepeated = []string{"hello", "sailor"} + pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")} + pb.F_Sint32Repeated = []int32{32, -32} + pb.F_Sint64Repeated = []int64{64, -64} + pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()} + + overify(t, pb, + "0807"+ // field 1, encoding 0, value 7 + "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) + "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField) + "2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField) + "5001"+ // field 10, encoding 0, value 1 + "5803"+ // field 11, encoding 0, value 3 + "6006"+ // field 12, encoding 0, value 6 + "6d20000000"+ // field 13, encoding 5, value 32 + "714000000000000000"+ // field 14, encoding 1, value 64 + "78a019"+ // field 15, encoding 0, value 3232 + "8001c032"+ // field 16, encoding 0, value 6464 + "8d0100004a45"+ // field 17, encoding 5, value 3232.0 + "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 + "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" + "a00100"+ // field 20, encoding 0, value 0 + "a00101"+ // field 20, encoding 0, value 1 + "a80120"+ // field 21, encoding 0, value 32 + "a80121"+ // field 21, encoding 0, value 33 + "b00140"+ // field 22, encoding 0, value 64 + "b00141"+ // field 22, encoding 0, value 65 + "bd01a00c0000"+ // field 23, encoding 5, value 3232 + "bd01050d0000"+ // field 23, encoding 5, value 3333 + "c1014019000000000000"+ // field 24, encoding 1, value 6464 + "c101a519000000000000"+ // field 24, encoding 1, value 6565 + "c801a0dd13"+ // field 25, encoding 0, value 323232 + "c80195ac14"+ // field 25, encoding 0, value 333333 + "d001c0ba27"+ // field 26, encoding 0, value 646464 + "d001b58928"+ // field 26, encoding 0, value 656565 + "dd0100000042"+ // field 27, encoding 5, value 32.0 + "dd0100000442"+ // field 27, encoding 5, value 33.0 + "e1010000000000005040"+ // field 28, encoding 1, value 64.0 + "e1010000000000405040"+ // field 28, encoding 1, value 65.0 + "ea0105"+"68656c6c6f"+ // field 29, encoding 2, string "hello" + "ea0106"+"7361696c6f72"+ // field 29, encoding 2, string "sailor" + "c00201"+ // field 40, encoding 0, value 1 + "c80220"+ // field 41, encoding 0, value 32 + "d00240"+ // field 42, encoding 0, value 64 + "dd0240010000"+ // field 43, encoding 5, value 320 + "e1028002000000000000"+ // field 44, encoding 1, value 640 + "e8028019"+ // field 45, encoding 0, value 3200 + "f0028032"+ // field 46, encoding 0, value 6400 + "fd02e0659948"+ // field 47, encoding 5, value 314159.0 + "81030000000050971041"+ // field 48, encoding 1, value 271828.0 + "8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n" + "b304"+ // start group field 70 level 1 + "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" + "b404"+ // end group field 70 level 1 + "8305"+ // start group field 80 level 1 + "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated" + "8405"+ // end group field 80 level 1 + "8305"+ // start group field 80 level 1 + "8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated" + "8405"+ // end group field 80 level 1 + "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" + "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 + "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 + "ca0c03"+"626967"+ // field 201, encoding 2, string "big" + "ca0c04"+"6e6f7365"+ // field 201, encoding 2, string "nose" + "d00c40"+ // field 202, encoding 0, value 32 + "d00c3f"+ // field 202, encoding 0, value -32 + "d80c8001"+ // field 203, encoding 0, value 64 + "d80c7f"+ // field 203, encoding 0, value -64 + "8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose" + "90193f"+ // field 402, encoding 0, value 63 + "98197f") // field 403, encoding 0, value 127 + +} + +// All required fields set, all packed repeated fields given two values. +func TestEncodeDecode6(t *testing.T) { + pb := initGoTest(false) + pb.F_BoolRepeatedPacked = []bool{false, true} + pb.F_Int32RepeatedPacked = []int32{32, 33} + pb.F_Int64RepeatedPacked = []int64{64, 65} + pb.F_Fixed32RepeatedPacked = []uint32{3232, 3333} + pb.F_Fixed64RepeatedPacked = []uint64{6464, 6565} + pb.F_Uint32RepeatedPacked = []uint32{323232, 333333} + pb.F_Uint64RepeatedPacked = []uint64{646464, 656565} + pb.F_FloatRepeatedPacked = []float32{32., 33.} + pb.F_DoubleRepeatedPacked = []float64{64., 65.} + pb.F_Sint32RepeatedPacked = []int32{32, -32} + pb.F_Sint64RepeatedPacked = []int64{64, -64} + + overify(t, pb, + "0807"+ // field 1, encoding 0, value 7 + "220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField) + "5001"+ // field 10, encoding 0, value 1 + "5803"+ // field 11, encoding 0, value 3 + "6006"+ // field 12, encoding 0, value 6 + "6d20000000"+ // field 13, encoding 5, value 32 + "714000000000000000"+ // field 14, encoding 1, value 64 + "78a019"+ // field 15, encoding 0, value 3232 + "8001c032"+ // field 16, encoding 0, value 6464 + "8d0100004a45"+ // field 17, encoding 5, value 3232.0 + "9101000000000040b940"+ // field 18, encoding 1, value 6464.0 + "9a0106"+"737472696e67"+ // field 19, encoding 2 string "string" + "9203020001"+ // field 50, encoding 2, 2 bytes, value 0, value 1 + "9a03022021"+ // field 51, encoding 2, 2 bytes, value 32, value 33 + "a203024041"+ // field 52, encoding 2, 2 bytes, value 64, value 65 + "aa0308"+ // field 53, encoding 2, 8 bytes + "a00c0000050d0000"+ // value 3232, value 3333 + "b20310"+ // field 54, encoding 2, 16 bytes + "4019000000000000a519000000000000"+ // value 6464, value 6565 + "ba0306"+ // field 55, encoding 2, 6 bytes + "a0dd1395ac14"+ // value 323232, value 333333 + "c20306"+ // field 56, encoding 2, 6 bytes + "c0ba27b58928"+ // value 646464, value 656565 + "ca0308"+ // field 57, encoding 2, 8 bytes + "0000004200000442"+ // value 32.0, value 33.0 + "d20310"+ // field 58, encoding 2, 16 bytes + "00000000000050400000000000405040"+ // value 64.0, value 65.0 + "b304"+ // start group field 70 level 1 + "ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required" + "b404"+ // end group field 70 level 1 + "aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes" + "b0063f"+ // field 102, encoding 0, 0x3f zigzag32 + "b8067f"+ // field 103, encoding 0, 0x7f zigzag64 + "b21f02"+ // field 502, encoding 2, 2 bytes + "403f"+ // value 32, value -32 + "ba1f03"+ // field 503, encoding 2, 3 bytes + "80017f") // value 64, value -64 +} + +// Test that we can encode empty bytes fields. +func TestEncodeDecodeBytes1(t *testing.T) { + pb := initGoTest(false) + + // Create our bytes + pb.F_BytesRequired = []byte{} + pb.F_BytesRepeated = [][]byte{{}} + pb.F_BytesOptional = []byte{} + + d, err := Marshal(pb) + if err != nil { + t.Error(err) + } + + pbd := new(GoTest) + if err := Unmarshal(d, pbd); err != nil { + t.Error(err) + } + + if pbd.F_BytesRequired == nil || len(pbd.F_BytesRequired) != 0 { + t.Error("required empty bytes field is incorrect") + } + if pbd.F_BytesRepeated == nil || len(pbd.F_BytesRepeated) == 1 && pbd.F_BytesRepeated[0] == nil { + t.Error("repeated empty bytes field is incorrect") + } + if pbd.F_BytesOptional == nil || len(pbd.F_BytesOptional) != 0 { + t.Error("optional empty bytes field is incorrect") + } +} + +// Test that we encode nil-valued fields of a repeated bytes field correctly. +// Since entries in a repeated field cannot be nil, nil must mean empty value. +func TestEncodeDecodeBytes2(t *testing.T) { + pb := initGoTest(false) + + // Create our bytes + pb.F_BytesRepeated = [][]byte{nil} + + d, err := Marshal(pb) + if err != nil { + t.Error(err) + } + + pbd := new(GoTest) + if err := Unmarshal(d, pbd); err != nil { + t.Error(err) + } + + if len(pbd.F_BytesRepeated) != 1 || pbd.F_BytesRepeated[0] == nil { + t.Error("Unexpected value for repeated bytes field") + } +} + +// All required fields set, defaults provided, all repeated fields given two values. +func TestSkippingUnrecognizedFields(t *testing.T) { + o := old() + pb := initGoTestField() + + // Marshal it normally. + o.Marshal(pb) + + // Now new a GoSkipTest record. + skip := &GoSkipTest{ + SkipInt32: Int32(32), + SkipFixed32: Uint32(3232), + SkipFixed64: Uint64(6464), + SkipString: String("skipper"), + Skipgroup: &GoSkipTest_SkipGroup{ + GroupInt32: Int32(75), + GroupString: String("wxyz"), + }, + } + + // Marshal it into same buffer. + o.Marshal(skip) + + pbd := new(GoTestField) + o.Unmarshal(pbd) + + // The __unrecognized field should be a marshaling of GoSkipTest + skipd := new(GoSkipTest) + + o.SetBuf(pbd.XXX_unrecognized) + o.Unmarshal(skipd) + + if *skipd.SkipInt32 != *skip.SkipInt32 { + t.Error("skip int32", skipd.SkipInt32) + } + if *skipd.SkipFixed32 != *skip.SkipFixed32 { + t.Error("skip fixed32", skipd.SkipFixed32) + } + if *skipd.SkipFixed64 != *skip.SkipFixed64 { + t.Error("skip fixed64", skipd.SkipFixed64) + } + if *skipd.SkipString != *skip.SkipString { + t.Error("skip string", *skipd.SkipString) + } + if *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32 { + t.Error("skip group int32", skipd.Skipgroup.GroupInt32) + } + if *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString { + t.Error("skip group string", *skipd.Skipgroup.GroupString) + } +} + +// Check that unrecognized fields of a submessage are preserved. +func TestSubmessageUnrecognizedFields(t *testing.T) { + nm := &NewMessage{ + Nested: &NewMessage_Nested{ + Name: String("Nigel"), + FoodGroup: String("carbs"), + }, + } + b, err := Marshal(nm) + if err != nil { + t.Fatalf("Marshal of NewMessage: %v", err) + } + + // Unmarshal into an OldMessage. + om := new(OldMessage) + if err := Unmarshal(b, om); err != nil { + t.Fatalf("Unmarshal to OldMessage: %v", err) + } + exp := &OldMessage{ + Nested: &OldMessage_Nested{ + Name: String("Nigel"), + // normal protocol buffer users should not do this + XXX_unrecognized: []byte("\x12\x05carbs"), + }, + } + if !Equal(om, exp) { + t.Errorf("om = %v, want %v", om, exp) + } + + // Clone the OldMessage. + om = Clone(om).(*OldMessage) + if !Equal(om, exp) { + t.Errorf("Clone(om) = %v, want %v", om, exp) + } + + // Marshal the OldMessage, then unmarshal it into an empty NewMessage. + if b, err = Marshal(om); err != nil { + t.Fatalf("Marshal of OldMessage: %v", err) + } + t.Logf("Marshal(%v) -> %q", om, b) + nm2 := new(NewMessage) + if err := Unmarshal(b, nm2); err != nil { + t.Fatalf("Unmarshal to NewMessage: %v", err) + } + if !Equal(nm, nm2) { + t.Errorf("NewMessage round-trip: %v => %v", nm, nm2) + } +} + +// Check that an int32 field can be upgraded to an int64 field. +func TestNegativeInt32(t *testing.T) { + om := &OldMessage{ + Num: Int32(-1), + } + b, err := Marshal(om) + if err != nil { + t.Fatalf("Marshal of OldMessage: %v", err) + } + + // Check the size. It should be 11 bytes; + // 1 for the field/wire type, and 10 for the negative number. + if len(b) != 11 { + t.Errorf("%v marshaled as %q, wanted 11 bytes", om, b) + } + + // Unmarshal into a NewMessage. + nm := new(NewMessage) + if err := Unmarshal(b, nm); err != nil { + t.Fatalf("Unmarshal to NewMessage: %v", err) + } + want := &NewMessage{ + Num: Int64(-1), + } + if !Equal(nm, want) { + t.Errorf("nm = %v, want %v", nm, want) + } +} + +// Check that we can grow an array (repeated field) to have many elements. +// This test doesn't depend only on our encoding; for variety, it makes sure +// we create, encode, and decode the correct contents explicitly. It's therefore +// a bit messier. +// This test also uses (and hence tests) the Marshal/Unmarshal functions +// instead of the methods. +func TestBigRepeated(t *testing.T) { + pb := initGoTest(true) + + // Create the arrays + const N = 50 // Internally the library starts much smaller. + pb.Repeatedgroup = make([]*GoTest_RepeatedGroup, N) + pb.F_Sint64Repeated = make([]int64, N) + pb.F_Sint32Repeated = make([]int32, N) + pb.F_BytesRepeated = make([][]byte, N) + pb.F_StringRepeated = make([]string, N) + pb.F_DoubleRepeated = make([]float64, N) + pb.F_FloatRepeated = make([]float32, N) + pb.F_Uint64Repeated = make([]uint64, N) + pb.F_Uint32Repeated = make([]uint32, N) + pb.F_Fixed64Repeated = make([]uint64, N) + pb.F_Fixed32Repeated = make([]uint32, N) + pb.F_Int64Repeated = make([]int64, N) + pb.F_Int32Repeated = make([]int32, N) + pb.F_BoolRepeated = make([]bool, N) + pb.RepeatedField = make([]*GoTestField, N) + + // Fill in the arrays with checkable values. + igtf := initGoTestField() + igtrg := initGoTest_RepeatedGroup() + for i := 0; i < N; i++ { + pb.Repeatedgroup[i] = igtrg + pb.F_Sint64Repeated[i] = int64(i) + pb.F_Sint32Repeated[i] = int32(i) + s := fmt.Sprint(i) + pb.F_BytesRepeated[i] = []byte(s) + pb.F_StringRepeated[i] = s + pb.F_DoubleRepeated[i] = float64(i) + pb.F_FloatRepeated[i] = float32(i) + pb.F_Uint64Repeated[i] = uint64(i) + pb.F_Uint32Repeated[i] = uint32(i) + pb.F_Fixed64Repeated[i] = uint64(i) + pb.F_Fixed32Repeated[i] = uint32(i) + pb.F_Int64Repeated[i] = int64(i) + pb.F_Int32Repeated[i] = int32(i) + pb.F_BoolRepeated[i] = i%2 == 0 + pb.RepeatedField[i] = igtf + } + + // Marshal. + buf, _ := Marshal(pb) + + // Now test Unmarshal by recreating the original buffer. + pbd := new(GoTest) + Unmarshal(buf, pbd) + + // Check the checkable values + for i := uint64(0); i < N; i++ { + if pbd.Repeatedgroup[i] == nil { // TODO: more checking? + t.Error("pbd.Repeatedgroup bad") + } + var x uint64 + x = uint64(pbd.F_Sint64Repeated[i]) + if x != i { + t.Error("pbd.F_Sint64Repeated bad", x, i) + } + x = uint64(pbd.F_Sint32Repeated[i]) + if x != i { + t.Error("pbd.F_Sint32Repeated bad", x, i) + } + s := fmt.Sprint(i) + equalbytes(pbd.F_BytesRepeated[i], []byte(s), t) + if pbd.F_StringRepeated[i] != s { + t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i) + } + x = uint64(pbd.F_DoubleRepeated[i]) + if x != i { + t.Error("pbd.F_DoubleRepeated bad", x, i) + } + x = uint64(pbd.F_FloatRepeated[i]) + if x != i { + t.Error("pbd.F_FloatRepeated bad", x, i) + } + x = pbd.F_Uint64Repeated[i] + if x != i { + t.Error("pbd.F_Uint64Repeated bad", x, i) + } + x = uint64(pbd.F_Uint32Repeated[i]) + if x != i { + t.Error("pbd.F_Uint32Repeated bad", x, i) + } + x = pbd.F_Fixed64Repeated[i] + if x != i { + t.Error("pbd.F_Fixed64Repeated bad", x, i) + } + x = uint64(pbd.F_Fixed32Repeated[i]) + if x != i { + t.Error("pbd.F_Fixed32Repeated bad", x, i) + } + x = uint64(pbd.F_Int64Repeated[i]) + if x != i { + t.Error("pbd.F_Int64Repeated bad", x, i) + } + x = uint64(pbd.F_Int32Repeated[i]) + if x != i { + t.Error("pbd.F_Int32Repeated bad", x, i) + } + if pbd.F_BoolRepeated[i] != (i%2 == 0) { + t.Error("pbd.F_BoolRepeated bad", x, i) + } + if pbd.RepeatedField[i] == nil { // TODO: more checking? + t.Error("pbd.RepeatedField bad") + } + } +} + +// Verify we give a useful message when decoding to the wrong structure type. +func TestTypeMismatch(t *testing.T) { + pb1 := initGoTest(true) + + // Marshal + o := old() + o.Marshal(pb1) + + // Now Unmarshal it to the wrong type. + pb2 := initGoTestField() + err := o.Unmarshal(pb2) + if err == nil { + t.Error("expected error, got no error") + } else if !strings.Contains(err.Error(), "bad wiretype") { + t.Error("expected bad wiretype error, got", err) + } +} + +func encodeDecode(t *testing.T, in, out Message, msg string) { + buf, err := Marshal(in) + if err != nil { + t.Fatalf("failed marshaling %v: %v", msg, err) + } + if err := Unmarshal(buf, out); err != nil { + t.Fatalf("failed unmarshaling %v: %v", msg, err) + } +} + +func TestPackedNonPackedDecoderSwitching(t *testing.T) { + np, p := new(NonPackedTest), new(PackedTest) + + // non-packed -> packed + np.A = []int32{0, 1, 1, 2, 3, 5} + encodeDecode(t, np, p, "non-packed -> packed") + if !reflect.DeepEqual(np.A, p.B) { + t.Errorf("failed non-packed -> packed; np.A=%+v, p.B=%+v", np.A, p.B) + } + + // packed -> non-packed + np.Reset() + p.B = []int32{3, 1, 4, 1, 5, 9} + encodeDecode(t, p, np, "packed -> non-packed") + if !reflect.DeepEqual(p.B, np.A) { + t.Errorf("failed packed -> non-packed; p.B=%+v, np.A=%+v", p.B, np.A) + } +} + +func TestProto1RepeatedGroup(t *testing.T) { + pb := &MessageList{ + Message: []*MessageList_Message{ + { + Name: String("blah"), + Count: Int32(7), + }, + // NOTE: pb.Message[1] is a nil + nil, + }, + } + + o := old() + err := o.Marshal(pb) + if err == nil || !strings.Contains(err.Error(), "repeated field Message has nil") { + t.Fatalf("unexpected or no error when marshaling: %v", err) + } +} + +// Test that enums work. Checks for a bug introduced by making enums +// named types instead of int32: newInt32FromUint64 would crash with +// a type mismatch in reflect.PointTo. +func TestEnum(t *testing.T) { + pb := new(GoEnum) + pb.Foo = FOO_FOO1.Enum() + o := old() + if err := o.Marshal(pb); err != nil { + t.Fatal("error encoding enum:", err) + } + pb1 := new(GoEnum) + if err := o.Unmarshal(pb1); err != nil { + t.Fatal("error decoding enum:", err) + } + if *pb1.Foo != FOO_FOO1 { + t.Error("expected 7 but got ", *pb1.Foo) + } +} + +// Enum types have String methods. Check that enum fields can be printed. +// We don't care what the value actually is, just as long as it doesn't crash. +func TestPrintingNilEnumFields(t *testing.T) { + pb := new(GoEnum) + fmt.Sprintf("%+v", pb) +} + +// Verify that absent required fields cause Marshal/Unmarshal to return errors. +func TestRequiredFieldEnforcement(t *testing.T) { + pb := new(GoTestField) + _, err := Marshal(pb) + if err == nil { + t.Error("marshal: expected error, got nil") + } else if strings.Index(err.Error(), "Label") < 0 { + t.Errorf("marshal: bad error type: %v", err) + } + + // A slightly sneaky, yet valid, proto. It encodes the same required field twice, + // so simply counting the required fields is insufficient. + // field 1, encoding 2, value "hi" + buf := []byte("\x0A\x02hi\x0A\x02hi") + err = Unmarshal(buf, pb) + if err == nil { + t.Error("unmarshal: expected error, got nil") + } else if strings.Index(err.Error(), "{Unknown}") < 0 { + t.Errorf("unmarshal: bad error type: %v", err) + } +} + +func TestTypedNilMarshal(t *testing.T) { + // A typed nil should return ErrNil and not crash. + _, err := Marshal((*GoEnum)(nil)) + if err != ErrNil { + t.Errorf("Marshal: got err %v, want ErrNil", err) + } +} + +// A type that implements the Marshaler interface, but is not nillable. +type nonNillableInt uint64 + +func (nni nonNillableInt) Marshal() ([]byte, error) { + return EncodeVarint(uint64(nni)), nil +} + +type NNIMessage struct { + nni nonNillableInt +} + +func (*NNIMessage) Reset() {} +func (*NNIMessage) String() string { return "" } +func (*NNIMessage) ProtoMessage() {} + +// A type that implements the Marshaler interface and is nillable. +type nillableMessage struct { + x uint64 +} + +func (nm *nillableMessage) Marshal() ([]byte, error) { + return EncodeVarint(nm.x), nil +} + +type NMMessage struct { + nm *nillableMessage +} + +func (*NMMessage) Reset() {} +func (*NMMessage) String() string { return "" } +func (*NMMessage) ProtoMessage() {} + +// Verify a type that uses the Marshaler interface, but has a nil pointer. +func TestNilMarshaler(t *testing.T) { + // Try a struct with a Marshaler field that is nil. + // It should be directly marshable. + nmm := new(NMMessage) + if _, err := Marshal(nmm); err != nil { + t.Error("unexpected error marshaling nmm: ", err) + } + + // Try a struct with a Marshaler field that is not nillable. + nnim := new(NNIMessage) + nnim.nni = 7 + var _ Marshaler = nnim.nni // verify it is truly a Marshaler + if _, err := Marshal(nnim); err != nil { + t.Error("unexpected error marshaling nnim: ", err) + } +} + +func TestAllSetDefaults(t *testing.T) { + // Exercise SetDefaults with all scalar field types. + m := &Defaults{ + // NaN != NaN, so override that here. + F_Nan: Float32(1.7), + } + expected := &Defaults{ + F_Bool: Bool(true), + F_Int32: Int32(32), + F_Int64: Int64(64), + F_Fixed32: Uint32(320), + F_Fixed64: Uint64(640), + F_Uint32: Uint32(3200), + F_Uint64: Uint64(6400), + F_Float: Float32(314159), + F_Double: Float64(271828), + F_String: String(`hello, "world!"` + "\n"), + F_Bytes: []byte("Bignose"), + F_Sint32: Int32(-32), + F_Sint64: Int64(-64), + F_Enum: Defaults_GREEN.Enum(), + F_Pinf: Float32(float32(math.Inf(1))), + F_Ninf: Float32(float32(math.Inf(-1))), + F_Nan: Float32(1.7), + StrZero: String(""), + } + SetDefaults(m) + if !Equal(m, expected) { + t.Errorf("SetDefaults failed\n got %v\nwant %v", m, expected) + } +} + +func TestSetDefaultsWithSetField(t *testing.T) { + // Check that a set value is not overridden. + m := &Defaults{ + F_Int32: Int32(12), + } + SetDefaults(m) + if v := m.GetF_Int32(); v != 12 { + t.Errorf("m.FInt32 = %v, want 12", v) + } +} + +func TestSetDefaultsWithSubMessage(t *testing.T) { + m := &OtherMessage{ + Key: Int64(123), + Inner: &InnerMessage{ + Host: String("gopher"), + }, + } + expected := &OtherMessage{ + Key: Int64(123), + Inner: &InnerMessage{ + Host: String("gopher"), + Port: Int32(4000), + }, + } + SetDefaults(m) + if !Equal(m, expected) { + t.Errorf("\n got %v\nwant %v", m, expected) + } +} + +func TestSetDefaultsWithRepeatedSubMessage(t *testing.T) { + m := &MyMessage{ + RepInner: []*InnerMessage{{}}, + } + expected := &MyMessage{ + RepInner: []*InnerMessage{{ + Port: Int32(4000), + }}, + } + SetDefaults(m) + if !Equal(m, expected) { + t.Errorf("\n got %v\nwant %v", m, expected) + } +} + +func TestSetDefaultWithRepeatedNonMessage(t *testing.T) { + m := &MyMessage{ + Pet: []string{"turtle", "wombat"}, + } + expected := Clone(m) + SetDefaults(m) + if !Equal(m, expected) { + t.Errorf("\n got %v\nwant %v", m, expected) + } +} + +func TestMaximumTagNumber(t *testing.T) { + m := &MaxTag{ + LastField: String("natural goat essence"), + } + buf, err := Marshal(m) + if err != nil { + t.Fatalf("proto.Marshal failed: %v", err) + } + m2 := new(MaxTag) + if err := Unmarshal(buf, m2); err != nil { + t.Fatalf("proto.Unmarshal failed: %v", err) + } + if got, want := m2.GetLastField(), *m.LastField; got != want { + t.Errorf("got %q, want %q", got, want) + } +} + +func TestJSON(t *testing.T) { + m := &MyMessage{ + Count: Int32(4), + Pet: []string{"bunny", "kitty"}, + Inner: &InnerMessage{ + Host: String("cauchy"), + }, + Bikeshed: MyMessage_GREEN.Enum(), + } + const expected = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}` + + b, err := json.Marshal(m) + if err != nil { + t.Fatalf("json.Marshal failed: %v", err) + } + s := string(b) + if s != expected { + t.Errorf("got %s\nwant %s", s, expected) + } + + received := new(MyMessage) + if err := json.Unmarshal(b, received); err != nil { + t.Fatalf("json.Unmarshal failed: %v", err) + } + if !Equal(received, m) { + t.Fatalf("got %s, want %s", received, m) + } + + // Test unmarshalling of JSON with symbolic enum name. + const old = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}` + received.Reset() + if err := json.Unmarshal([]byte(old), received); err != nil { + t.Fatalf("json.Unmarshal failed: %v", err) + } + if !Equal(received, m) { + t.Fatalf("got %s, want %s", received, m) + } +} + +func TestBadWireType(t *testing.T) { + b := []byte{7<<3 | 6} // field 7, wire type 6 + pb := new(OtherMessage) + if err := Unmarshal(b, pb); err == nil { + t.Errorf("Unmarshal did not fail") + } else if !strings.Contains(err.Error(), "unknown wire type") { + t.Errorf("wrong error: %v", err) + } +} + +func TestBytesWithInvalidLength(t *testing.T) { + // If a byte sequence has an invalid (negative) length, Unmarshal should not panic. + b := []byte{2<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0} + Unmarshal(b, new(MyMessage)) +} + +func TestLengthOverflow(t *testing.T) { + // Overflowing a length should not panic. + b := []byte{2<<3 | WireBytes, 1, 1, 3<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01} + Unmarshal(b, new(MyMessage)) +} + +func TestVarintOverflow(t *testing.T) { + // Overflowing a 64-bit length should not be allowed. + b := []byte{1<<3 | WireVarint, 0x01, 3<<3 | WireBytes, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01} + if err := Unmarshal(b, new(MyMessage)); err == nil { + t.Fatalf("Overflowed uint64 length without error") + } +} + +func TestUnmarshalFuzz(t *testing.T) { + const N = 1000 + seed := time.Now().UnixNano() + t.Logf("RNG seed is %d", seed) + rng := rand.New(rand.NewSource(seed)) + buf := make([]byte, 20) + for i := 0; i < N; i++ { + for j := range buf { + buf[j] = byte(rng.Intn(256)) + } + fuzzUnmarshal(t, buf) + } +} + +func TestMergeMessages(t *testing.T) { + pb := &MessageList{Message: []*MessageList_Message{{Name: String("x"), Count: Int32(1)}}} + data, err := Marshal(pb) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + pb1 := new(MessageList) + if err := Unmarshal(data, pb1); err != nil { + t.Fatalf("first Unmarshal: %v", err) + } + if err := Unmarshal(data, pb1); err != nil { + t.Fatalf("second Unmarshal: %v", err) + } + if len(pb1.Message) != 1 { + t.Errorf("two Unmarshals produced %d Messages, want 1", len(pb1.Message)) + } + + pb2 := new(MessageList) + if err := UnmarshalMerge(data, pb2); err != nil { + t.Fatalf("first UnmarshalMerge: %v", err) + } + if err := UnmarshalMerge(data, pb2); err != nil { + t.Fatalf("second UnmarshalMerge: %v", err) + } + if len(pb2.Message) != 2 { + t.Errorf("two UnmarshalMerges produced %d Messages, want 2", len(pb2.Message)) + } +} + +func TestExtensionMarshalOrder(t *testing.T) { + m := &MyMessage{Count: Int(123)} + if err := SetExtension(m, E_Ext_More, &Ext{Data: String("alpha")}); err != nil { + t.Fatalf("SetExtension: %v", err) + } + if err := SetExtension(m, E_Ext_Text, String("aleph")); err != nil { + t.Fatalf("SetExtension: %v", err) + } + if err := SetExtension(m, E_Ext_Number, Int32(1)); err != nil { + t.Fatalf("SetExtension: %v", err) + } + + // Serialize m several times, and check we get the same bytes each time. + var orig []byte + for i := 0; i < 100; i++ { + b, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if i == 0 { + orig = b + continue + } + if !bytes.Equal(b, orig) { + t.Errorf("Bytes differ on attempt #%d", i) + } + } +} + +// Many extensions, because small maps might not iterate differently on each iteration. +var exts = []*ExtensionDesc{ + E_X201, + E_X202, + E_X203, + E_X204, + E_X205, + E_X206, + E_X207, + E_X208, + E_X209, + E_X210, + E_X211, + E_X212, + E_X213, + E_X214, + E_X215, + E_X216, + E_X217, + E_X218, + E_X219, + E_X220, + E_X221, + E_X222, + E_X223, + E_X224, + E_X225, + E_X226, + E_X227, + E_X228, + E_X229, + E_X230, + E_X231, + E_X232, + E_X233, + E_X234, + E_X235, + E_X236, + E_X237, + E_X238, + E_X239, + E_X240, + E_X241, + E_X242, + E_X243, + E_X244, + E_X245, + E_X246, + E_X247, + E_X248, + E_X249, + E_X250, +} + +func TestMessageSetMarshalOrder(t *testing.T) { + m := &MyMessageSet{} + for _, x := range exts { + if err := SetExtension(m, x, &Empty{}); err != nil { + t.Fatalf("SetExtension: %v", err) + } + } + + buf, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + // Serialize m several times, and check we get the same bytes each time. + for i := 0; i < 10; i++ { + b1, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + if !bytes.Equal(b1, buf) { + t.Errorf("Bytes differ on re-Marshal #%d", i) + } + + m2 := &MyMessageSet{} + if err := Unmarshal(buf, m2); err != nil { + t.Errorf("Unmarshal: %v", err) + } + b2, err := Marshal(m2) + if err != nil { + t.Errorf("re-Marshal: %v", err) + } + if !bytes.Equal(b2, buf) { + t.Errorf("Bytes differ on round-trip #%d", i) + } + } +} + +func TestUnmarshalMergesMessages(t *testing.T) { + // If a nested message occurs twice in the input, + // the fields should be merged when decoding. + a := &OtherMessage{ + Key: Int64(123), + Inner: &InnerMessage{ + Host: String("polhode"), + Port: Int32(1234), + }, + } + aData, err := Marshal(a) + if err != nil { + t.Fatalf("Marshal(a): %v", err) + } + b := &OtherMessage{ + Weight: Float32(1.2), + Inner: &InnerMessage{ + Host: String("herpolhode"), + Connected: Bool(true), + }, + } + bData, err := Marshal(b) + if err != nil { + t.Fatalf("Marshal(b): %v", err) + } + want := &OtherMessage{ + Key: Int64(123), + Weight: Float32(1.2), + Inner: &InnerMessage{ + Host: String("herpolhode"), + Port: Int32(1234), + Connected: Bool(true), + }, + } + got := new(OtherMessage) + if err := Unmarshal(append(aData, bData...), got); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if !Equal(got, want) { + t.Errorf("\n got %v\nwant %v", got, want) + } +} + +func TestEncodingSizes(t *testing.T) { + tests := []struct { + m Message + n int + }{ + {&Defaults{F_Int32: Int32(math.MaxInt32)}, 6}, + {&Defaults{F_Int32: Int32(math.MinInt32)}, 11}, + {&Defaults{F_Uint32: Uint32(uint32(math.MaxInt32) + 1)}, 6}, + {&Defaults{F_Uint32: Uint32(math.MaxUint32)}, 6}, + } + for _, test := range tests { + b, err := Marshal(test.m) + if err != nil { + t.Errorf("Marshal(%v): %v", test.m, err) + continue + } + if len(b) != test.n { + t.Errorf("Marshal(%v) yielded %d bytes, want %d bytes", test.m, len(b), test.n) + } + } +} + +func TestRequiredNotSetError(t *testing.T) { + pb := initGoTest(false) + pb.RequiredField.Label = nil + pb.F_Int32Required = nil + pb.F_Int64Required = nil + + expected := "0807" + // field 1, encoding 0, value 7 + "2206" + "120474797065" + // field 4, encoding 2 (GoTestField) + "5001" + // field 10, encoding 0, value 1 + "6d20000000" + // field 13, encoding 5, value 0x20 + "714000000000000000" + // field 14, encoding 1, value 0x40 + "78a019" + // field 15, encoding 0, value 0xca0 = 3232 + "8001c032" + // field 16, encoding 0, value 0x1940 = 6464 + "8d0100004a45" + // field 17, encoding 5, value 3232.0 + "9101000000000040b940" + // field 18, encoding 1, value 6464.0 + "9a0106" + "737472696e67" + // field 19, encoding 2, string "string" + "b304" + // field 70, encoding 3, start group + "ba0408" + "7265717569726564" + // field 71, encoding 2, string "required" + "b404" + // field 70, encoding 4, end group + "aa0605" + "6279746573" + // field 101, encoding 2, string "bytes" + "b0063f" + // field 102, encoding 0, 0x3f zigzag32 + "b8067f" // field 103, encoding 0, 0x7f zigzag64 + + o := old() + bytes, err := Marshal(pb) + if _, ok := err.(*RequiredNotSetError); !ok { + fmt.Printf("marshal-1 err = %v, want *RequiredNotSetError", err) + o.DebugPrint("", bytes) + t.Fatalf("expected = %s", expected) + } + if strings.Index(err.Error(), "RequiredField.Label") < 0 { + t.Errorf("marshal-1 wrong err msg: %v", err) + } + if !equal(bytes, expected, t) { + o.DebugPrint("neq 1", bytes) + t.Fatalf("expected = %s", expected) + } + + // Now test Unmarshal by recreating the original buffer. + pbd := new(GoTest) + err = Unmarshal(bytes, pbd) + if _, ok := err.(*RequiredNotSetError); !ok { + t.Fatalf("unmarshal err = %v, want *RequiredNotSetError", err) + o.DebugPrint("", bytes) + t.Fatalf("string = %s", expected) + } + if strings.Index(err.Error(), "RequiredField.{Unknown}") < 0 { + t.Errorf("unmarshal wrong err msg: %v", err) + } + bytes, err = Marshal(pbd) + if _, ok := err.(*RequiredNotSetError); !ok { + t.Errorf("marshal-2 err = %v, want *RequiredNotSetError", err) + o.DebugPrint("", bytes) + t.Fatalf("string = %s", expected) + } + if strings.Index(err.Error(), "RequiredField.Label") < 0 { + t.Errorf("marshal-2 wrong err msg: %v", err) + } + if !equal(bytes, expected, t) { + o.DebugPrint("neq 2", bytes) + t.Fatalf("string = %s", expected) + } +} + +func fuzzUnmarshal(t *testing.T, data []byte) { + defer func() { + if e := recover(); e != nil { + t.Errorf("These bytes caused a panic: %+v", data) + t.Logf("Stack:\n%s", debug.Stack()) + t.FailNow() + } + }() + + pb := new(MyMessage) + Unmarshal(data, pb) +} + +func TestMapFieldMarshal(t *testing.T) { + m := &MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Rob", + 4: "Ian", + 8: "Dave", + }, + } + b, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + + // b should be the concatenation of these three byte sequences in some order. + parts := []string{ + "\n\a\b\x01\x12\x03Rob", + "\n\a\b\x04\x12\x03Ian", + "\n\b\b\x08\x12\x04Dave", + } + ok := false + for i := range parts { + for j := range parts { + if j == i { + continue + } + for k := range parts { + if k == i || k == j { + continue + } + try := parts[i] + parts[j] + parts[k] + if bytes.Equal(b, []byte(try)) { + ok = true + break + } + } + } + } + if !ok { + t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2]) + } + t.Logf("FYI b: %q", b) + + (new(Buffer)).DebugPrint("Dump of b", b) +} + +func TestMapFieldRoundTrips(t *testing.T) { + m := &MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Rob", + 4: "Ian", + 8: "Dave", + }, + MsgMapping: map[int64]*FloatingPoint{ + 0x7001: &FloatingPoint{F: Float64(2.0)}, + }, + ByteMapping: map[bool][]byte{ + false: []byte("that's not right!"), + true: []byte("aye, 'tis true!"), + }, + } + b, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + t.Logf("FYI b: %q", b) + m2 := new(MessageWithMap) + if err := Unmarshal(b, m2); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + for _, pair := range [][2]interface{}{ + {m.NameMapping, m2.NameMapping}, + {m.MsgMapping, m2.MsgMapping}, + {m.ByteMapping, m2.ByteMapping}, + } { + if !reflect.DeepEqual(pair[0], pair[1]) { + t.Errorf("Map did not survive a round trip.\ninitial: %v\n final: %v", pair[0], pair[1]) + } + } +} + +func TestMapFieldWithNil(t *testing.T) { + m := &MessageWithMap{ + MsgMapping: map[int64]*FloatingPoint{ + 1: nil, + }, + } + b, err := Marshal(m) + if err == nil { + t.Fatalf("Marshal of bad map should have failed, got these bytes: %v", b) + } +} + +func TestOneof(t *testing.T) { + m := &Communique{} + b, err := Marshal(m) + if err != nil { + t.Fatalf("Marshal of empty message with oneof: %v", err) + } + if len(b) != 0 { + t.Errorf("Marshal of empty message yielded too many bytes: %v", b) + } + + m = &Communique{ + Union: &Communique_Name{"Barry"}, + } + + // Round-trip. + b, err = Marshal(m) + if err != nil { + t.Fatalf("Marshal of message with oneof: %v", err) + } + if len(b) != 7 { // name tag/wire (1) + name len (1) + name (5) + t.Errorf("Incorrect marshal of message with oneof: %v", b) + } + m.Reset() + if err := Unmarshal(b, m); err != nil { + t.Fatalf("Unmarshal of message with oneof: %v", err) + } + if x, ok := m.Union.(*Communique_Name); !ok || x.Name != "Barry" { + t.Errorf("After round trip, Union = %+v", m.Union) + } + if name := m.GetName(); name != "Barry" { + t.Errorf("After round trip, GetName = %q, want %q", name, "Barry") + } + + // Let's try with a message in the oneof. + m.Union = &Communique_Msg{&Strings{StringField: String("deep deep string")}} + b, err = Marshal(m) + if err != nil { + t.Fatalf("Marshal of message with oneof set to message: %v", err) + } + if len(b) != 20 { // msg tag/wire (1) + msg len (1) + msg (1 + 1 + 16) + t.Errorf("Incorrect marshal of message with oneof set to message: %v", b) + } + m.Reset() + if err := Unmarshal(b, m); err != nil { + t.Fatalf("Unmarshal of message with oneof set to message: %v", err) + } + ss, ok := m.Union.(*Communique_Msg) + if !ok || ss.Msg.GetStringField() != "deep deep string" { + t.Errorf("After round trip with oneof set to message, Union = %+v", m.Union) + } +} + +func TestInefficientPackedBool(t *testing.T) { + // https://github.com/golang/protobuf/issues/76 + inp := []byte{ + 0x12, 0x02, // 0x12 = 2<<3|2; 2 bytes + // Usually a bool should take a single byte, + // but it is permitted to be any varint. + 0xb9, 0x30, + } + if err := Unmarshal(inp, new(MoreRepeated)); err != nil { + t.Error(err) + } +} + +// Benchmarks + +func testMsg() *GoTest { + pb := initGoTest(true) + const N = 1000 // Internally the library starts much smaller. + pb.F_Int32Repeated = make([]int32, N) + pb.F_DoubleRepeated = make([]float64, N) + for i := 0; i < N; i++ { + pb.F_Int32Repeated[i] = int32(i) + pb.F_DoubleRepeated[i] = float64(i) + } + return pb +} + +func bytesMsg() *GoTest { + pb := initGoTest(true) + buf := make([]byte, 4000) + for i := range buf { + buf[i] = byte(i) + } + pb.F_BytesDefaulted = buf + return pb +} + +func benchmarkMarshal(b *testing.B, pb Message, marshal func(Message) ([]byte, error)) { + d, _ := marshal(pb) + b.SetBytes(int64(len(d))) + b.ResetTimer() + for i := 0; i < b.N; i++ { + marshal(pb) + } +} + +func benchmarkBufferMarshal(b *testing.B, pb Message) { + p := NewBuffer(nil) + benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) { + p.Reset() + err := p.Marshal(pb0) + return p.Bytes(), err + }) +} + +func benchmarkSize(b *testing.B, pb Message) { + benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) { + Size(pb) + return nil, nil + }) +} + +func newOf(pb Message) Message { + in := reflect.ValueOf(pb) + if in.IsNil() { + return pb + } + return reflect.New(in.Type().Elem()).Interface().(Message) +} + +func benchmarkUnmarshal(b *testing.B, pb Message, unmarshal func([]byte, Message) error) { + d, _ := Marshal(pb) + b.SetBytes(int64(len(d))) + pbd := newOf(pb) + + b.ResetTimer() + for i := 0; i < b.N; i++ { + unmarshal(d, pbd) + } +} + +func benchmarkBufferUnmarshal(b *testing.B, pb Message) { + p := NewBuffer(nil) + benchmarkUnmarshal(b, pb, func(d []byte, pb0 Message) error { + p.SetBuf(d) + return p.Unmarshal(pb0) + }) +} + +// Benchmark{Marshal,BufferMarshal,Size,Unmarshal,BufferUnmarshal}{,Bytes} + +func BenchmarkMarshal(b *testing.B) { + benchmarkMarshal(b, testMsg(), Marshal) +} + +func BenchmarkBufferMarshal(b *testing.B) { + benchmarkBufferMarshal(b, testMsg()) +} + +func BenchmarkSize(b *testing.B) { + benchmarkSize(b, testMsg()) +} + +func BenchmarkUnmarshal(b *testing.B) { + benchmarkUnmarshal(b, testMsg(), Unmarshal) +} + +func BenchmarkBufferUnmarshal(b *testing.B) { + benchmarkBufferUnmarshal(b, testMsg()) +} + +func BenchmarkMarshalBytes(b *testing.B) { + benchmarkMarshal(b, bytesMsg(), Marshal) +} + +func BenchmarkBufferMarshalBytes(b *testing.B) { + benchmarkBufferMarshal(b, bytesMsg()) +} + +func BenchmarkSizeBytes(b *testing.B) { + benchmarkSize(b, bytesMsg()) +} + +func BenchmarkUnmarshalBytes(b *testing.B) { + benchmarkUnmarshal(b, bytesMsg(), Unmarshal) +} + +func BenchmarkBufferUnmarshalBytes(b *testing.B) { + benchmarkBufferUnmarshal(b, bytesMsg()) +} + +func BenchmarkUnmarshalUnrecognizedFields(b *testing.B) { + b.StopTimer() + pb := initGoTestField() + skip := &GoSkipTest{ + SkipInt32: Int32(32), + SkipFixed32: Uint32(3232), + SkipFixed64: Uint64(6464), + SkipString: String("skipper"), + Skipgroup: &GoSkipTest_SkipGroup{ + GroupInt32: Int32(75), + GroupString: String("wxyz"), + }, + } + + pbd := new(GoTestField) + p := NewBuffer(nil) + p.Marshal(pb) + p.Marshal(skip) + p2 := NewBuffer(nil) + + b.StartTimer() + for i := 0; i < b.N; i++ { + p2.SetBuf(p.Bytes()) + p2.Unmarshal(pbd) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/clone.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/clone.go new file mode 100644 index 00000000..e98ddec9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/clone.go @@ -0,0 +1,223 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// Protocol buffer deep copy and merge. +// TODO: RawMessage. + +package proto + +import ( + "log" + "reflect" + "strings" +) + +// Clone returns a deep copy of a protocol buffer. +func Clone(pb Message) Message { + in := reflect.ValueOf(pb) + if in.IsNil() { + return pb + } + + out := reflect.New(in.Type().Elem()) + // out is empty so a merge is a deep copy. + mergeStruct(out.Elem(), in.Elem()) + return out.Interface().(Message) +} + +// Merge merges src into dst. +// Required and optional fields that are set in src will be set to that value in dst. +// Elements of repeated fields will be appended. +// Merge panics if src and dst are not the same type, or if dst is nil. +func Merge(dst, src Message) { + in := reflect.ValueOf(src) + out := reflect.ValueOf(dst) + if out.IsNil() { + panic("proto: nil destination") + } + if in.Type() != out.Type() { + // Explicit test prior to mergeStruct so that mistyped nils will fail + panic("proto: type mismatch") + } + if in.IsNil() { + // Merging nil into non-nil is a quiet no-op + return + } + mergeStruct(out.Elem(), in.Elem()) +} + +func mergeStruct(out, in reflect.Value) { + sprop := GetProperties(in.Type()) + for i := 0; i < in.NumField(); i++ { + f := in.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) + } + + if emIn, ok := in.Addr().Interface().(extendableProto); ok { + emOut := out.Addr().Interface().(extendableProto) + mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap()) + } + + uf := in.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return + } + uin := uf.Bytes() + if len(uin) > 0 { + out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) + } +} + +// mergeAny performs a merge between two values of the same type. +// viaPtr indicates whether the values were indirected through a pointer (implying proto2). +// prop is set if this is a struct field (it may be nil). +func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { + if in.Type() == protoMessageType { + if !in.IsNil() { + if out.IsNil() { + out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) + } else { + Merge(out.Interface().(Message), in.Interface().(Message)) + } + } + return + } + switch in.Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + if !viaPtr && isProto3Zero(in) { + return + } + out.Set(in) + case reflect.Interface: + // Probably a oneof field; copy non-nil values. + if in.IsNil() { + return + } + // Allocate destination if it is not set, or set to a different type. + // Otherwise we will merge as normal. + if out.IsNil() || out.Elem().Type() != in.Elem().Type() { + out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) + } + mergeAny(out.Elem(), in.Elem(), false, nil) + case reflect.Map: + if in.Len() == 0 { + return + } + if out.IsNil() { + out.Set(reflect.MakeMap(in.Type())) + } + // For maps with value types of *T or []byte we need to deep copy each value. + elemKind := in.Type().Elem().Kind() + for _, key := range in.MapKeys() { + var val reflect.Value + switch elemKind { + case reflect.Ptr: + val = reflect.New(in.Type().Elem().Elem()) + mergeAny(val, in.MapIndex(key), false, nil) + case reflect.Slice: + val = in.MapIndex(key) + val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) + default: + val = in.MapIndex(key) + } + out.SetMapIndex(key, val) + } + case reflect.Ptr: + if in.IsNil() { + return + } + if out.IsNil() { + out.Set(reflect.New(in.Elem().Type())) + } + mergeAny(out.Elem(), in.Elem(), true, nil) + case reflect.Slice: + if in.IsNil() { + return + } + if in.Type().Elem().Kind() == reflect.Uint8 { + // []byte is a scalar bytes field, not a repeated field. + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value, and should not + // be merged. + if prop != nil && prop.proto3 && in.Len() == 0 { + return + } + + // Make a deep copy. + // Append to []byte{} instead of []byte(nil) so that we never end up + // with a nil result. + out.SetBytes(append([]byte{}, in.Bytes()...)) + return + } + n := in.Len() + if out.IsNil() { + out.Set(reflect.MakeSlice(in.Type(), 0, n)) + } + switch in.Type().Elem().Kind() { + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, + reflect.String, reflect.Uint32, reflect.Uint64: + out.Set(reflect.AppendSlice(out, in)) + default: + for i := 0; i < n; i++ { + x := reflect.Indirect(reflect.New(in.Type().Elem())) + mergeAny(x, in.Index(i), false, nil) + out.Set(reflect.Append(out, x)) + } + } + case reflect.Struct: + mergeStruct(out, in) + default: + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to copy %v", in) + } +} + +func mergeExtension(out, in map[int32]Extension) { + for extNum, eIn := range in { + eOut := Extension{desc: eIn.desc} + if eIn.value != nil { + v := reflect.New(reflect.TypeOf(eIn.value)).Elem() + mergeAny(v, reflect.ValueOf(eIn.value), false, nil) + eOut.value = v.Interface() + } + if eIn.enc != nil { + eOut.enc = make([]byte, len(eIn.enc)) + copy(eOut.enc, eIn.enc) + } + + out[extNum] = eOut + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/clone_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/clone_test.go new file mode 100644 index 00000000..76720f18 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/clone_test.go @@ -0,0 +1,267 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "testing" + + "github.com/golang/protobuf/proto" + + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + pb "github.com/golang/protobuf/proto/testdata" +) + +var cloneTestMessage = &pb.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + Pet: []string{"bunny", "kitty", "horsey"}, + Inner: &pb.InnerMessage{ + Host: proto.String("niles"), + Port: proto.Int32(9099), + Connected: proto.Bool(true), + }, + Others: []*pb.OtherMessage{ + { + Value: []byte("some bytes"), + }, + }, + Somegroup: &pb.MyMessage_SomeGroup{ + GroupField: proto.Int32(6), + }, + RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, +} + +func init() { + ext := &pb.Ext{ + Data: proto.String("extension"), + } + if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil { + panic("SetExtension: " + err.Error()) + } +} + +func TestClone(t *testing.T) { + m := proto.Clone(cloneTestMessage).(*pb.MyMessage) + if !proto.Equal(m, cloneTestMessage) { + t.Errorf("Clone(%v) = %v", cloneTestMessage, m) + } + + // Verify it was a deep copy. + *m.Inner.Port++ + if proto.Equal(m, cloneTestMessage) { + t.Error("Mutating clone changed the original") + } + // Byte fields and repeated fields should be copied. + if &m.Pet[0] == &cloneTestMessage.Pet[0] { + t.Error("Pet: repeated field not copied") + } + if &m.Others[0] == &cloneTestMessage.Others[0] { + t.Error("Others: repeated field not copied") + } + if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] { + t.Error("Others[0].Value: bytes field not copied") + } + if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] { + t.Error("RepBytes: repeated field not copied") + } + if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] { + t.Error("RepBytes[0]: bytes field not copied") + } +} + +func TestCloneNil(t *testing.T) { + var m *pb.MyMessage + if c := proto.Clone(m); !proto.Equal(m, c) { + t.Errorf("Clone(%v) = %v", m, c) + } +} + +var mergeTests = []struct { + src, dst, want proto.Message +}{ + { + src: &pb.MyMessage{ + Count: proto.Int32(42), + }, + dst: &pb.MyMessage{ + Name: proto.String("Dave"), + }, + want: &pb.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + }, + }, + { + src: &pb.MyMessage{ + Inner: &pb.InnerMessage{ + Host: proto.String("hey"), + Connected: proto.Bool(true), + }, + Pet: []string{"horsey"}, + Others: []*pb.OtherMessage{ + { + Value: []byte("some bytes"), + }, + }, + }, + dst: &pb.MyMessage{ + Inner: &pb.InnerMessage{ + Host: proto.String("niles"), + Port: proto.Int32(9099), + }, + Pet: []string{"bunny", "kitty"}, + Others: []*pb.OtherMessage{ + { + Key: proto.Int64(31415926535), + }, + { + // Explicitly test a src=nil field + Inner: nil, + }, + }, + }, + want: &pb.MyMessage{ + Inner: &pb.InnerMessage{ + Host: proto.String("hey"), + Connected: proto.Bool(true), + Port: proto.Int32(9099), + }, + Pet: []string{"bunny", "kitty", "horsey"}, + Others: []*pb.OtherMessage{ + { + Key: proto.Int64(31415926535), + }, + {}, + { + Value: []byte("some bytes"), + }, + }, + }, + }, + { + src: &pb.MyMessage{ + RepBytes: [][]byte{[]byte("wow")}, + }, + dst: &pb.MyMessage{ + Somegroup: &pb.MyMessage_SomeGroup{ + GroupField: proto.Int32(6), + }, + RepBytes: [][]byte{[]byte("sham")}, + }, + want: &pb.MyMessage{ + Somegroup: &pb.MyMessage_SomeGroup{ + GroupField: proto.Int32(6), + }, + RepBytes: [][]byte{[]byte("sham"), []byte("wow")}, + }, + }, + // Check that a scalar bytes field replaces rather than appends. + { + src: &pb.OtherMessage{Value: []byte("foo")}, + dst: &pb.OtherMessage{Value: []byte("bar")}, + want: &pb.OtherMessage{Value: []byte("foo")}, + }, + { + src: &pb.MessageWithMap{ + NameMapping: map[int32]string{6: "Nigel"}, + MsgMapping: map[int64]*pb.FloatingPoint{ + 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)}, + }, + ByteMapping: map[bool][]byte{true: []byte("wowsa")}, + }, + dst: &pb.MessageWithMap{ + NameMapping: map[int32]string{ + 6: "Bruce", // should be overwritten + 7: "Andrew", + }, + }, + want: &pb.MessageWithMap{ + NameMapping: map[int32]string{ + 6: "Nigel", + 7: "Andrew", + }, + MsgMapping: map[int64]*pb.FloatingPoint{ + 0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)}, + }, + ByteMapping: map[bool][]byte{true: []byte("wowsa")}, + }, + }, + // proto3 shouldn't merge zero values, + // in the same way that proto2 shouldn't merge nils. + { + src: &proto3pb.Message{ + Name: "Aaron", + Data: []byte(""), // zero value, but not nil + }, + dst: &proto3pb.Message{ + HeightInCm: 176, + Data: []byte("texas!"), + }, + want: &proto3pb.Message{ + Name: "Aaron", + HeightInCm: 176, + Data: []byte("texas!"), + }, + }, + // Oneof fields should merge by assignment. + { + src: &pb.Communique{ + Union: &pb.Communique_Number{41}, + }, + dst: &pb.Communique{ + Union: &pb.Communique_Name{"Bobby Tables"}, + }, + want: &pb.Communique{ + Union: &pb.Communique_Number{41}, + }, + }, + // Oneof nil is the same as not set. + { + src: &pb.Communique{}, + dst: &pb.Communique{ + Union: &pb.Communique_Name{"Bobby Tables"}, + }, + want: &pb.Communique{ + Union: &pb.Communique_Name{"Bobby Tables"}, + }, + }, +} + +func TestMerge(t *testing.T) { + for _, m := range mergeTests { + got := proto.Clone(m.dst) + proto.Merge(got, m.src) + if !proto.Equal(got, m.want) { + t.Errorf("Merge(%v, %v)\n got %v\nwant %v\n", m.dst, m.src, got, m.want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/decode.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/decode.go new file mode 100644 index 00000000..5810782f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/decode.go @@ -0,0 +1,867 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +/* + * Routines for decoding protocol buffer data to construct in-memory representations. + */ + +import ( + "errors" + "fmt" + "io" + "os" + "reflect" +) + +// errOverflow is returned when an integer is too large to be represented. +var errOverflow = errors.New("proto: integer overflow") + +// ErrInternalBadWireType is returned by generated code when an incorrect +// wire type is encountered. It does not get returned to user code. +var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") + +// The fundamental decoders that interpret bytes on the wire. +// Those that take integer types all return uint64 and are +// therefore of type valueDecoder. + +// DecodeVarint reads a varint-encoded integer from the slice. +// It returns the integer and the number of bytes consumed, or +// zero if there is not enough. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func DecodeVarint(buf []byte) (x uint64, n int) { + // x, n already 0 + for shift := uint(0); shift < 64; shift += 7 { + if n >= len(buf) { + return 0, 0 + } + b := uint64(buf[n]) + n++ + x |= (b & 0x7F) << shift + if (b & 0x80) == 0 { + return x, n + } + } + + // The number is too large to represent in a 64-bit value. + return 0, 0 +} + +// DecodeVarint reads a varint-encoded integer from the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) DecodeVarint() (x uint64, err error) { + // x, err already 0 + + i := p.index + l := len(p.buf) + + for shift := uint(0); shift < 64; shift += 7 { + if i >= l { + err = io.ErrUnexpectedEOF + return + } + b := p.buf[i] + i++ + x |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + p.index = i + return + } + } + + // The number is too large to represent in a 64-bit value. + err = errOverflow + return +} + +// DecodeFixed64 reads a 64-bit integer from the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) DecodeFixed64() (x uint64, err error) { + // x, err already 0 + i := p.index + 8 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-8]) + x |= uint64(p.buf[i-7]) << 8 + x |= uint64(p.buf[i-6]) << 16 + x |= uint64(p.buf[i-5]) << 24 + x |= uint64(p.buf[i-4]) << 32 + x |= uint64(p.buf[i-3]) << 40 + x |= uint64(p.buf[i-2]) << 48 + x |= uint64(p.buf[i-1]) << 56 + return +} + +// DecodeFixed32 reads a 32-bit integer from the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) DecodeFixed32() (x uint64, err error) { + // x, err already 0 + i := p.index + 4 + if i < 0 || i > len(p.buf) { + err = io.ErrUnexpectedEOF + return + } + p.index = i + + x = uint64(p.buf[i-4]) + x |= uint64(p.buf[i-3]) << 8 + x |= uint64(p.buf[i-2]) << 16 + x |= uint64(p.buf[i-1]) << 24 + return +} + +// DecodeZigzag64 reads a zigzag-encoded 64-bit integer +// from the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) DecodeZigzag64() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) + return +} + +// DecodeZigzag32 reads a zigzag-encoded 32-bit integer +// from the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) DecodeZigzag32() (x uint64, err error) { + x, err = p.DecodeVarint() + if err != nil { + return + } + x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) + return +} + +// These are not ValueDecoders: they produce an array of bytes or a string. +// bytes, embedded messages + +// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { + n, err := p.DecodeVarint() + if err != nil { + return nil, err + } + + nb := int(n) + if nb < 0 { + return nil, fmt.Errorf("proto: bad byte length %d", nb) + } + end := p.index + nb + if end < p.index || end > len(p.buf) { + return nil, io.ErrUnexpectedEOF + } + + if !alloc { + // todo: check if can get more uses of alloc=false + buf = p.buf[p.index:end] + p.index += nb + return + } + + buf = make([]byte, nb) + copy(buf, p.buf[p.index:]) + p.index += nb + return +} + +// DecodeStringBytes reads an encoded string from the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) DecodeStringBytes() (s string, err error) { + buf, err := p.DecodeRawBytes(false) + if err != nil { + return + } + return string(buf), nil +} + +// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. +// If the protocol buffer has extensions, and the field matches, add it as an extension. +// Otherwise, if the XXX_unrecognized field exists, append the skipped data there. +func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error { + oi := o.index + + err := o.skip(t, tag, wire) + if err != nil { + return err + } + + if !unrecField.IsValid() { + return nil + } + + ptr := structPointer_Bytes(base, unrecField) + + // Add the skipped field to struct field + obuf := o.buf + + o.buf = *ptr + o.EncodeVarint(uint64(tag<<3 | wire)) + *ptr = append(o.buf, obuf[oi:o.index]...) + + o.buf = obuf + + return nil +} + +// Skip the next item in the buffer. Its wire type is decoded and presented as an argument. +func (o *Buffer) skip(t reflect.Type, tag, wire int) error { + + var u uint64 + var err error + + switch wire { + case WireVarint: + _, err = o.DecodeVarint() + case WireFixed64: + _, err = o.DecodeFixed64() + case WireBytes: + _, err = o.DecodeRawBytes(false) + case WireFixed32: + _, err = o.DecodeFixed32() + case WireStartGroup: + for { + u, err = o.DecodeVarint() + if err != nil { + break + } + fwire := int(u & 0x7) + if fwire == WireEndGroup { + break + } + ftag := int(u >> 3) + err = o.skip(t, ftag, fwire) + if err != nil { + break + } + } + default: + err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t) + } + return err +} + +// Unmarshaler is the interface representing objects that can +// unmarshal themselves. The method should reset the receiver before +// decoding starts. The argument points to data that may be +// overwritten, so implementations should not keep references to the +// buffer. +type Unmarshaler interface { + Unmarshal([]byte) error +} + +// Unmarshal parses the protocol buffer representation in buf and places the +// decoded result in pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// Unmarshal resets pb before starting to unmarshal, so any +// existing data in pb is always removed. Use UnmarshalMerge +// to preserve and append to existing data. +func Unmarshal(buf []byte, pb Message) error { + pb.Reset() + return UnmarshalMerge(buf, pb) +} + +// UnmarshalMerge parses the protocol buffer representation in buf and +// writes the decoded result to pb. If the struct underlying pb does not match +// the data in buf, the results can be unpredictable. +// +// UnmarshalMerge merges into existing data in pb. +// Most code should use Unmarshal instead. +func UnmarshalMerge(buf []byte, pb Message) error { + // If the object can unmarshal itself, let it. + if u, ok := pb.(Unmarshaler); ok { + return u.Unmarshal(buf) + } + return NewBuffer(buf).Unmarshal(pb) +} + +// DecodeMessage reads a count-delimited message from the Buffer. +func (p *Buffer) DecodeMessage(pb Message) error { + enc, err := p.DecodeRawBytes(false) + if err != nil { + return err + } + return NewBuffer(enc).Unmarshal(pb) +} + +// DecodeGroup reads a tag-delimited group from the Buffer. +func (p *Buffer) DecodeGroup(pb Message) error { + typ, base, err := getbase(pb) + if err != nil { + return err + } + return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base) +} + +// Unmarshal parses the protocol buffer representation in the +// Buffer and places the decoded result in pb. If the struct +// underlying pb does not match the data in the buffer, the results can be +// unpredictable. +func (p *Buffer) Unmarshal(pb Message) error { + // If the object can unmarshal itself, let it. + if u, ok := pb.(Unmarshaler); ok { + err := u.Unmarshal(p.buf[p.index:]) + p.index = len(p.buf) + return err + } + + typ, base, err := getbase(pb) + if err != nil { + return err + } + + err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base) + + if collectStats { + stats.Decode++ + } + + return err +} + +// unmarshalType does the work of unmarshaling a structure. +func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error { + var state errorState + required, reqFields := prop.reqCount, uint64(0) + + var err error + for err == nil && o.index < len(o.buf) { + oi := o.index + var u uint64 + u, err = o.DecodeVarint() + if err != nil { + break + } + wire := int(u & 0x7) + if wire == WireEndGroup { + if is_group { + return nil // input is satisfied + } + return fmt.Errorf("proto: %s: wiretype end group for non-group", st) + } + tag := int(u >> 3) + if tag <= 0 { + return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire) + } + fieldnum, ok := prop.decoderTags.get(tag) + if !ok { + // Maybe it's an extension? + if prop.extendable { + if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) { + if err = o.skip(st, tag, wire); err == nil { + ext := e.ExtensionMap()[int32(tag)] // may be missing + ext.enc = append(ext.enc, o.buf[oi:o.index]...) + e.ExtensionMap()[int32(tag)] = ext + } + continue + } + } + // Maybe it's a oneof? + if prop.oneofUnmarshaler != nil { + m := structPointer_Interface(base, st).(Message) + // First return value indicates whether tag is a oneof field. + ok, err = prop.oneofUnmarshaler(m, tag, wire, o) + if err == ErrInternalBadWireType { + // Map the error to something more descriptive. + // Do the formatting here to save generated code space. + err = fmt.Errorf("bad wiretype for oneof field in %T", m) + } + if ok { + continue + } + } + err = o.skipAndSave(st, tag, wire, base, prop.unrecField) + continue + } + p := prop.Prop[fieldnum] + + if p.dec == nil { + fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name) + continue + } + dec := p.dec + if wire != WireStartGroup && wire != p.WireType { + if wire == WireBytes && p.packedDec != nil { + // a packable field + dec = p.packedDec + } else { + err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType) + continue + } + } + decErr := dec(o, p, base) + if decErr != nil && !state.shouldContinue(decErr, p) { + err = decErr + } + if err == nil && p.Required { + // Successfully decoded a required field. + if tag <= 64 { + // use bitmap for fields 1-64 to catch field reuse. + var mask uint64 = 1 << uint64(tag-1) + if reqFields&mask == 0 { + // new required field + reqFields |= mask + required-- + } + } else { + // This is imprecise. It can be fooled by a required field + // with a tag > 64 that is encoded twice; that's very rare. + // A fully correct implementation would require allocating + // a data structure, which we would like to avoid. + required-- + } + } + } + if err == nil { + if is_group { + return io.ErrUnexpectedEOF + } + if state.err != nil { + return state.err + } + if required > 0 { + // Not enough information to determine the exact field. If we use extra + // CPU, we could determine the field only if the missing required field + // has a tag <= 64 and we check reqFields. + return &RequiredNotSetError{"{Unknown}"} + } + } + return err +} + +// Individual type decoders +// For each, +// u is the decoded value, +// v is a pointer to the field (pointer) in the struct + +// Sizes of the pools to allocate inside the Buffer. +// The goal is modest amortization and allocation +// on at least 16-byte boundaries. +const ( + boolPoolSize = 16 + uint32PoolSize = 8 + uint64PoolSize = 4 +) + +// Decode a bool. +func (o *Buffer) dec_bool(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + if len(o.bools) == 0 { + o.bools = make([]bool, boolPoolSize) + } + o.bools[0] = u != 0 + *structPointer_Bool(base, p.field) = &o.bools[0] + o.bools = o.bools[1:] + return nil +} + +func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + *structPointer_BoolVal(base, p.field) = u != 0 + return nil +} + +// Decode an int32. +func (o *Buffer) dec_int32(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word32_Set(structPointer_Word32(base, p.field), o, uint32(u)) + return nil +} + +func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u)) + return nil +} + +// Decode an int64. +func (o *Buffer) dec_int64(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word64_Set(structPointer_Word64(base, p.field), o, u) + return nil +} + +func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + word64Val_Set(structPointer_Word64Val(base, p.field), o, u) + return nil +} + +// Decode a string. +func (o *Buffer) dec_string(p *Properties, base structPointer) error { + s, err := o.DecodeStringBytes() + if err != nil { + return err + } + *structPointer_String(base, p.field) = &s + return nil +} + +func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error { + s, err := o.DecodeStringBytes() + if err != nil { + return err + } + *structPointer_StringVal(base, p.field) = s + return nil +} + +// Decode a slice of bytes ([]byte). +func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error { + b, err := o.DecodeRawBytes(true) + if err != nil { + return err + } + *structPointer_Bytes(base, p.field) = b + return nil +} + +// Decode a slice of bools ([]bool). +func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + v := structPointer_BoolSlice(base, p.field) + *v = append(*v, u != 0) + return nil +} + +// Decode a slice of bools ([]bool) in packed format. +func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error { + v := structPointer_BoolSlice(base, p.field) + + nn, err := o.DecodeVarint() + if err != nil { + return err + } + nb := int(nn) // number of bytes of encoded bools + fin := o.index + nb + if fin < o.index { + return errOverflow + } + + y := *v + for o.index < fin { + u, err := p.valDec(o) + if err != nil { + return err + } + y = append(y, u != 0) + } + + *v = y + return nil +} + +// Decode a slice of int32s ([]int32). +func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + structPointer_Word32Slice(base, p.field).Append(uint32(u)) + return nil +} + +// Decode a slice of int32s ([]int32) in packed format. +func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error { + v := structPointer_Word32Slice(base, p.field) + + nn, err := o.DecodeVarint() + if err != nil { + return err + } + nb := int(nn) // number of bytes of encoded int32s + + fin := o.index + nb + if fin < o.index { + return errOverflow + } + for o.index < fin { + u, err := p.valDec(o) + if err != nil { + return err + } + v.Append(uint32(u)) + } + return nil +} + +// Decode a slice of int64s ([]int64). +func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error { + u, err := p.valDec(o) + if err != nil { + return err + } + + structPointer_Word64Slice(base, p.field).Append(u) + return nil +} + +// Decode a slice of int64s ([]int64) in packed format. +func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error { + v := structPointer_Word64Slice(base, p.field) + + nn, err := o.DecodeVarint() + if err != nil { + return err + } + nb := int(nn) // number of bytes of encoded int64s + + fin := o.index + nb + if fin < o.index { + return errOverflow + } + for o.index < fin { + u, err := p.valDec(o) + if err != nil { + return err + } + v.Append(u) + } + return nil +} + +// Decode a slice of strings ([]string). +func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error { + s, err := o.DecodeStringBytes() + if err != nil { + return err + } + v := structPointer_StringSlice(base, p.field) + *v = append(*v, s) + return nil +} + +// Decode a slice of slice of bytes ([][]byte). +func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error { + b, err := o.DecodeRawBytes(true) + if err != nil { + return err + } + v := structPointer_BytesSlice(base, p.field) + *v = append(*v, b) + return nil +} + +// Decode a map field. +func (o *Buffer) dec_new_map(p *Properties, base structPointer) error { + raw, err := o.DecodeRawBytes(false) + if err != nil { + return err + } + oi := o.index // index at the end of this map entry + o.index -= len(raw) // move buffer back to start of map entry + + mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V + if mptr.Elem().IsNil() { + mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem())) + } + v := mptr.Elem() // map[K]V + + // Prepare addressable doubly-indirect placeholders for the key and value types. + // See enc_new_map for why. + keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K + keybase := toStructPointer(keyptr.Addr()) // **K + + var valbase structPointer + var valptr reflect.Value + switch p.mtype.Elem().Kind() { + case reflect.Slice: + // []byte + var dummy []byte + valptr = reflect.ValueOf(&dummy) // *[]byte + valbase = toStructPointer(valptr) // *[]byte + case reflect.Ptr: + // message; valptr is **Msg; need to allocate the intermediate pointer + valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V + valptr.Set(reflect.New(valptr.Type().Elem())) + valbase = toStructPointer(valptr) + default: + // everything else + valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V + valbase = toStructPointer(valptr.Addr()) // **V + } + + // Decode. + // This parses a restricted wire format, namely the encoding of a message + // with two fields. See enc_new_map for the format. + for o.index < oi { + // tagcode for key and value properties are always a single byte + // because they have tags 1 and 2. + tagcode := o.buf[o.index] + o.index++ + switch tagcode { + case p.mkeyprop.tagcode[0]: + if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil { + return err + } + case p.mvalprop.tagcode[0]: + if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil { + return err + } + default: + // TODO: Should we silently skip this instead? + return fmt.Errorf("proto: bad map data tag %d", raw[0]) + } + } + keyelem, valelem := keyptr.Elem(), valptr.Elem() + if !keyelem.IsValid() || !valelem.IsValid() { + // We did not decode the key or the value in the map entry. + // Either way, it's an invalid map entry. + return fmt.Errorf("proto: bad map data: missing key/val") + } + + v.SetMapIndex(keyelem, valelem) + return nil +} + +// Decode a group. +func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error { + bas := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(bas) { + // allocate new nested message + bas = toStructPointer(reflect.New(p.stype)) + structPointer_SetStructPointer(base, p.field, bas) + } + return o.unmarshalType(p.stype, p.sprop, true, bas) +} + +// Decode an embedded message. +func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) { + raw, e := o.DecodeRawBytes(false) + if e != nil { + return e + } + + bas := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(bas) { + // allocate new nested message + bas = toStructPointer(reflect.New(p.stype)) + structPointer_SetStructPointer(base, p.field, bas) + } + + // If the object can unmarshal itself, let it. + if p.isUnmarshaler { + iv := structPointer_Interface(bas, p.stype) + return iv.(Unmarshaler).Unmarshal(raw) + } + + obuf := o.buf + oi := o.index + o.buf = raw + o.index = 0 + + err = o.unmarshalType(p.stype, p.sprop, false, bas) + o.buf = obuf + o.index = oi + + return err +} + +// Decode a slice of embedded messages. +func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error { + return o.dec_slice_struct(p, false, base) +} + +// Decode a slice of embedded groups. +func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error { + return o.dec_slice_struct(p, true, base) +} + +// Decode a slice of structs ([]*struct). +func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error { + v := reflect.New(p.stype) + bas := toStructPointer(v) + structPointer_StructPointerSlice(base, p.field).Append(bas) + + if is_group { + err := o.unmarshalType(p.stype, p.sprop, is_group, bas) + return err + } + + raw, err := o.DecodeRawBytes(false) + if err != nil { + return err + } + + // If the object can unmarshal itself, let it. + if p.isUnmarshaler { + iv := v.Interface() + return iv.(Unmarshaler).Unmarshal(raw) + } + + obuf := o.buf + oi := o.index + o.buf = raw + o.index = 0 + + err = o.unmarshalType(p.stype, p.sprop, is_group, bas) + + o.buf = obuf + o.index = oi + + return err +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/encode.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/encode.go new file mode 100644 index 00000000..231b0740 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/encode.go @@ -0,0 +1,1325 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "errors" + "fmt" + "reflect" + "sort" +) + +// RequiredNotSetError is the error returned if Marshal is called with +// a protocol buffer struct whose required fields have not +// all been initialized. It is also the error returned if Unmarshal is +// called with an encoded protocol buffer that does not include all the +// required fields. +// +// When printed, RequiredNotSetError reports the first unset required field in a +// message. If the field cannot be precisely determined, it is reported as +// "{Unknown}". +type RequiredNotSetError struct { + field string +} + +func (e *RequiredNotSetError) Error() string { + return fmt.Sprintf("proto: required field %q not set", e.field) +} + +var ( + // errRepeatedHasNil is the error returned if Marshal is called with + // a struct with a repeated field containing a nil element. + errRepeatedHasNil = errors.New("proto: repeated field has nil element") + + // ErrNil is the error returned if Marshal is called with nil. + ErrNil = errors.New("proto: Marshal called with nil") +) + +// The fundamental encoders that put bytes on the wire. +// Those that take integer types all accept uint64 and are +// therefore of type valueEncoder. + +const maxVarintBytes = 10 // maximum length of a varint + +// EncodeVarint returns the varint encoding of x. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +// Not used by the package itself, but helpful to clients +// wishing to use the same encoding. +func EncodeVarint(x uint64) []byte { + var buf [maxVarintBytes]byte + var n int + for n = 0; x > 127; n++ { + buf[n] = 0x80 | uint8(x&0x7F) + x >>= 7 + } + buf[n] = uint8(x) + n++ + return buf[0:n] +} + +// EncodeVarint writes a varint-encoded integer to the Buffer. +// This is the format for the +// int32, int64, uint32, uint64, bool, and enum +// protocol buffer types. +func (p *Buffer) EncodeVarint(x uint64) error { + for x >= 1<<7 { + p.buf = append(p.buf, uint8(x&0x7f|0x80)) + x >>= 7 + } + p.buf = append(p.buf, uint8(x)) + return nil +} + +// SizeVarint returns the varint encoding size of an integer. +func SizeVarint(x uint64) int { + return sizeVarint(x) +} + +func sizeVarint(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} + +// EncodeFixed64 writes a 64-bit integer to the Buffer. +// This is the format for the +// fixed64, sfixed64, and double protocol buffer types. +func (p *Buffer) EncodeFixed64(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24), + uint8(x>>32), + uint8(x>>40), + uint8(x>>48), + uint8(x>>56)) + return nil +} + +func sizeFixed64(x uint64) int { + return 8 +} + +// EncodeFixed32 writes a 32-bit integer to the Buffer. +// This is the format for the +// fixed32, sfixed32, and float protocol buffer types. +func (p *Buffer) EncodeFixed32(x uint64) error { + p.buf = append(p.buf, + uint8(x), + uint8(x>>8), + uint8(x>>16), + uint8(x>>24)) + return nil +} + +func sizeFixed32(x uint64) int { + return 4 +} + +// EncodeZigzag64 writes a zigzag-encoded 64-bit integer +// to the Buffer. +// This is the format used for the sint64 protocol buffer type. +func (p *Buffer) EncodeZigzag64(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +func sizeZigzag64(x uint64) int { + return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} + +// EncodeZigzag32 writes a zigzag-encoded 32-bit integer +// to the Buffer. +// This is the format used for the sint32 protocol buffer type. +func (p *Buffer) EncodeZigzag32(x uint64) error { + // use signed number to get arithmetic right shift. + return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) +} + +func sizeZigzag32(x uint64) int { + return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) +} + +// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. +// This is the format used for the bytes protocol buffer +// type and for embedded messages. +func (p *Buffer) EncodeRawBytes(b []byte) error { + p.EncodeVarint(uint64(len(b))) + p.buf = append(p.buf, b...) + return nil +} + +func sizeRawBytes(b []byte) int { + return sizeVarint(uint64(len(b))) + + len(b) +} + +// EncodeStringBytes writes an encoded string to the Buffer. +// This is the format used for the proto2 string type. +func (p *Buffer) EncodeStringBytes(s string) error { + p.EncodeVarint(uint64(len(s))) + p.buf = append(p.buf, s...) + return nil +} + +func sizeStringBytes(s string) int { + return sizeVarint(uint64(len(s))) + + len(s) +} + +// Marshaler is the interface representing objects that can marshal themselves. +type Marshaler interface { + Marshal() ([]byte, error) +} + +// Marshal takes the protocol buffer +// and encodes it into the wire format, returning the data. +func Marshal(pb Message) ([]byte, error) { + // Can the object marshal itself? + if m, ok := pb.(Marshaler); ok { + return m.Marshal() + } + p := NewBuffer(nil) + err := p.Marshal(pb) + var state errorState + if err != nil && !state.shouldContinue(err, nil) { + return nil, err + } + if p.buf == nil && err == nil { + // Return a non-nil slice on success. + return []byte{}, nil + } + return p.buf, err +} + +// EncodeMessage writes the protocol buffer to the Buffer, +// prefixed by a varint-encoded length. +func (p *Buffer) EncodeMessage(pb Message) error { + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return ErrNil + } + if err == nil { + var state errorState + err = p.enc_len_struct(GetProperties(t.Elem()), base, &state) + } + return err +} + +// Marshal takes the protocol buffer +// and encodes it into the wire format, writing the result to the +// Buffer. +func (p *Buffer) Marshal(pb Message) error { + // Can the object marshal itself? + if m, ok := pb.(Marshaler); ok { + data, err := m.Marshal() + if err != nil { + return err + } + p.buf = append(p.buf, data...) + return nil + } + + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return ErrNil + } + if err == nil { + err = p.enc_struct(GetProperties(t.Elem()), base) + } + + if collectStats { + stats.Encode++ + } + + return err +} + +// Size returns the encoded size of a protocol buffer. +func Size(pb Message) (n int) { + // Can the object marshal itself? If so, Size is slow. + // TODO: add Size to Marshaler, or add a Sizer interface. + if m, ok := pb.(Marshaler); ok { + b, _ := m.Marshal() + return len(b) + } + + t, base, err := getbase(pb) + if structPointer_IsNil(base) { + return 0 + } + if err == nil { + n = size_struct(GetProperties(t.Elem()), base) + } + + if collectStats { + stats.Size++ + } + + return +} + +// Individual type encoders. + +// Encode a bool. +func (o *Buffer) enc_bool(p *Properties, base structPointer) error { + v := *structPointer_Bool(base, p.field) + if v == nil { + return ErrNil + } + x := 0 + if *v { + x = 1 + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error { + v := *structPointer_BoolVal(base, p.field) + if !v { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, 1) + return nil +} + +func size_bool(p *Properties, base structPointer) int { + v := *structPointer_Bool(base, p.field) + if v == nil { + return 0 + } + return len(p.tagcode) + 1 // each bool takes exactly one byte +} + +func size_proto3_bool(p *Properties, base structPointer) int { + v := *structPointer_BoolVal(base, p.field) + if !v && !p.oneof { + return 0 + } + return len(p.tagcode) + 1 // each bool takes exactly one byte +} + +// Encode an int32. +func (o *Buffer) enc_int32(p *Properties, base structPointer) error { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return ErrNil + } + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error { + v := structPointer_Word32Val(base, p.field) + x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func size_int32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return 0 + } + x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +func size_proto3_int32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32Val(base, p.field) + x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range + if x == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +// Encode a uint32. +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_uint32(p *Properties, base structPointer) error { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return ErrNil + } + x := word32_Get(v) + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error { + v := structPointer_Word32Val(base, p.field) + x := word32Val_Get(v) + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, uint64(x)) + return nil +} + +func size_uint32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32(base, p.field) + if word32_IsNil(v) { + return 0 + } + x := word32_Get(v) + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +func size_proto3_uint32(p *Properties, base structPointer) (n int) { + v := structPointer_Word32Val(base, p.field) + x := word32Val_Get(v) + if x == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += p.valSize(uint64(x)) + return +} + +// Encode an int64. +func (o *Buffer) enc_int64(p *Properties, base structPointer) error { + v := structPointer_Word64(base, p.field) + if word64_IsNil(v) { + return ErrNil + } + x := word64_Get(v) + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, x) + return nil +} + +func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error { + v := structPointer_Word64Val(base, p.field) + x := word64Val_Get(v) + if x == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, x) + return nil +} + +func size_int64(p *Properties, base structPointer) (n int) { + v := structPointer_Word64(base, p.field) + if word64_IsNil(v) { + return 0 + } + x := word64_Get(v) + n += len(p.tagcode) + n += p.valSize(x) + return +} + +func size_proto3_int64(p *Properties, base structPointer) (n int) { + v := structPointer_Word64Val(base, p.field) + x := word64Val_Get(v) + if x == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += p.valSize(x) + return +} + +// Encode a string. +func (o *Buffer) enc_string(p *Properties, base structPointer) error { + v := *structPointer_String(base, p.field) + if v == nil { + return ErrNil + } + x := *v + o.buf = append(o.buf, p.tagcode...) + o.EncodeStringBytes(x) + return nil +} + +func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error { + v := *structPointer_StringVal(base, p.field) + if v == "" { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeStringBytes(v) + return nil +} + +func size_string(p *Properties, base structPointer) (n int) { + v := *structPointer_String(base, p.field) + if v == nil { + return 0 + } + x := *v + n += len(p.tagcode) + n += sizeStringBytes(x) + return +} + +func size_proto3_string(p *Properties, base structPointer) (n int) { + v := *structPointer_StringVal(base, p.field) + if v == "" && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += sizeStringBytes(v) + return +} + +// All protocol buffer fields are nillable, but be careful. +func isNil(v reflect.Value) bool { + switch v.Kind() { + case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: + return v.IsNil() + } + return false +} + +// Encode a message struct. +func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error { + var state errorState + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return ErrNil + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, err := m.Marshal() + if err != nil && !state.shouldContinue(err, nil) { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + return state.err + } + + o.buf = append(o.buf, p.tagcode...) + return o.enc_len_struct(p.sprop, structp, &state) +} + +func size_struct_message(p *Properties, base structPointer) int { + structp := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(structp) { + return 0 + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, _ := m.Marshal() + n0 := len(p.tagcode) + n1 := sizeRawBytes(data) + return n0 + n1 + } + + n0 := len(p.tagcode) + n1 := size_struct(p.sprop, structp) + n2 := sizeVarint(uint64(n1)) // size of encoded length + return n0 + n1 + n2 +} + +// Encode a group struct. +func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error { + var state errorState + b := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(b) { + return ErrNil + } + + o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) + err := o.enc_struct(p.sprop, b) + if err != nil && !state.shouldContinue(err, nil) { + return err + } + o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) + return state.err +} + +func size_struct_group(p *Properties, base structPointer) (n int) { + b := structPointer_GetStructPointer(base, p.field) + if structPointer_IsNil(b) { + return 0 + } + + n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup)) + n += size_struct(p.sprop, b) + n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup)) + return +} + +// Encode a slice of bools ([]bool). +func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return ErrNil + } + for _, x := range s { + o.buf = append(o.buf, p.tagcode...) + v := uint64(0) + if x { + v = 1 + } + p.valEnc(o, v) + } + return nil +} + +func size_slice_bool(p *Properties, base structPointer) int { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return 0 + } + return l * (len(p.tagcode) + 1) // each bool takes exactly one byte +} + +// Encode a slice of bools ([]bool) in packed format. +func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(l)) // each bool takes exactly one byte + for _, x := range s { + v := uint64(0) + if x { + v = 1 + } + p.valEnc(o, v) + } + return nil +} + +func size_slice_packed_bool(p *Properties, base structPointer) (n int) { + s := *structPointer_BoolSlice(base, p.field) + l := len(s) + if l == 0 { + return 0 + } + n += len(p.tagcode) + n += sizeVarint(uint64(l)) + n += l // each bool takes exactly one byte + return +} + +// Encode a slice of bytes ([]byte). +func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error { + s := *structPointer_Bytes(base, p.field) + if s == nil { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(s) + return nil +} + +func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error { + s := *structPointer_Bytes(base, p.field) + if len(s) == 0 { + return ErrNil + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(s) + return nil +} + +func size_slice_byte(p *Properties, base structPointer) (n int) { + s := *structPointer_Bytes(base, p.field) + if s == nil && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += sizeRawBytes(s) + return +} + +func size_proto3_slice_byte(p *Properties, base structPointer) (n int) { + s := *structPointer_Bytes(base, p.field) + if len(s) == 0 && !p.oneof { + return 0 + } + n += len(p.tagcode) + n += sizeRawBytes(s) + return +} + +// Encode a slice of int32s ([]int32). +func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + p.valEnc(o, uint64(x)) + } + return nil +} + +func size_slice_int32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + n += p.valSize(uint64(x)) + } + return +} + +// Encode a slice of int32s ([]int32) in packed format. +func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + // TODO: Reuse a Buffer. + buf := NewBuffer(nil) + for i := 0; i < l; i++ { + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + p.valEnc(buf, uint64(x)) + } + + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(len(buf.buf))) + o.buf = append(o.buf, buf.buf...) + return nil +} + +func size_slice_packed_int32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + x := int32(s.Index(i)) // permit sign extension to use full 64-bit range + bufSize += p.valSize(uint64(x)) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + +// Encode a slice of uint32s ([]uint32). +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + x := s.Index(i) + p.valEnc(o, uint64(x)) + } + return nil +} + +func size_slice_uint32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + x := s.Index(i) + n += p.valSize(uint64(x)) + } + return +} + +// Encode a slice of uint32s ([]uint32) in packed format. +// Exactly the same as int32, except for no sign extension. +func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + // TODO: Reuse a Buffer. + buf := NewBuffer(nil) + for i := 0; i < l; i++ { + p.valEnc(buf, uint64(s.Index(i))) + } + + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(len(buf.buf))) + o.buf = append(o.buf, buf.buf...) + return nil +} + +func size_slice_packed_uint32(p *Properties, base structPointer) (n int) { + s := structPointer_Word32Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + bufSize += p.valSize(uint64(s.Index(i))) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + +// Encode a slice of int64s ([]int64). +func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + p.valEnc(o, s.Index(i)) + } + return nil +} + +func size_slice_int64(p *Properties, base structPointer) (n int) { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + for i := 0; i < l; i++ { + n += len(p.tagcode) + n += p.valSize(s.Index(i)) + } + return +} + +// Encode a slice of int64s ([]int64) in packed format. +func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return ErrNil + } + // TODO: Reuse a Buffer. + buf := NewBuffer(nil) + for i := 0; i < l; i++ { + p.valEnc(buf, s.Index(i)) + } + + o.buf = append(o.buf, p.tagcode...) + o.EncodeVarint(uint64(len(buf.buf))) + o.buf = append(o.buf, buf.buf...) + return nil +} + +func size_slice_packed_int64(p *Properties, base structPointer) (n int) { + s := structPointer_Word64Slice(base, p.field) + l := s.Len() + if l == 0 { + return 0 + } + var bufSize int + for i := 0; i < l; i++ { + bufSize += p.valSize(s.Index(i)) + } + + n += len(p.tagcode) + n += sizeVarint(uint64(bufSize)) + n += bufSize + return +} + +// Encode a slice of slice of bytes ([][]byte). +func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error { + ss := *structPointer_BytesSlice(base, p.field) + l := len(ss) + if l == 0 { + return ErrNil + } + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(ss[i]) + } + return nil +} + +func size_slice_slice_byte(p *Properties, base structPointer) (n int) { + ss := *structPointer_BytesSlice(base, p.field) + l := len(ss) + if l == 0 { + return 0 + } + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + n += sizeRawBytes(ss[i]) + } + return +} + +// Encode a slice of strings ([]string). +func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error { + ss := *structPointer_StringSlice(base, p.field) + l := len(ss) + for i := 0; i < l; i++ { + o.buf = append(o.buf, p.tagcode...) + o.EncodeStringBytes(ss[i]) + } + return nil +} + +func size_slice_string(p *Properties, base structPointer) (n int) { + ss := *structPointer_StringSlice(base, p.field) + l := len(ss) + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + n += sizeStringBytes(ss[i]) + } + return +} + +// Encode a slice of message structs ([]*struct). +func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error { + var state errorState + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + + for i := 0; i < l; i++ { + structp := s.Index(i) + if structPointer_IsNil(structp) { + return errRepeatedHasNil + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, err := m.Marshal() + if err != nil && !state.shouldContinue(err, nil) { + return err + } + o.buf = append(o.buf, p.tagcode...) + o.EncodeRawBytes(data) + continue + } + + o.buf = append(o.buf, p.tagcode...) + err := o.enc_len_struct(p.sprop, structp, &state) + if err != nil && !state.shouldContinue(err, nil) { + if err == ErrNil { + return errRepeatedHasNil + } + return err + } + } + return state.err +} + +func size_slice_struct_message(p *Properties, base structPointer) (n int) { + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + n += l * len(p.tagcode) + for i := 0; i < l; i++ { + structp := s.Index(i) + if structPointer_IsNil(structp) { + return // return the size up to this point + } + + // Can the object marshal itself? + if p.isMarshaler { + m := structPointer_Interface(structp, p.stype).(Marshaler) + data, _ := m.Marshal() + n += len(p.tagcode) + n += sizeRawBytes(data) + continue + } + + n0 := size_struct(p.sprop, structp) + n1 := sizeVarint(uint64(n0)) // size of encoded length + n += n0 + n1 + } + return +} + +// Encode a slice of group structs ([]*struct). +func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error { + var state errorState + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + + for i := 0; i < l; i++ { + b := s.Index(i) + if structPointer_IsNil(b) { + return errRepeatedHasNil + } + + o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup)) + + err := o.enc_struct(p.sprop, b) + + if err != nil && !state.shouldContinue(err, nil) { + if err == ErrNil { + return errRepeatedHasNil + } + return err + } + + o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup)) + } + return state.err +} + +func size_slice_struct_group(p *Properties, base structPointer) (n int) { + s := structPointer_StructPointerSlice(base, p.field) + l := s.Len() + + n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup)) + n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup)) + for i := 0; i < l; i++ { + b := s.Index(i) + if structPointer_IsNil(b) { + return // return size up to this point + } + + n += size_struct(p.sprop, b) + } + return +} + +// Encode an extension map. +func (o *Buffer) enc_map(p *Properties, base structPointer) error { + v := *structPointer_ExtMap(base, p.field) + if err := encodeExtensionMap(v); err != nil { + return err + } + // Fast-path for common cases: zero or one extensions. + if len(v) <= 1 { + for _, e := range v { + o.buf = append(o.buf, e.enc...) + } + return nil + } + + // Sort keys to provide a deterministic encoding. + keys := make([]int, 0, len(v)) + for k := range v { + keys = append(keys, int(k)) + } + sort.Ints(keys) + + for _, k := range keys { + o.buf = append(o.buf, v[int32(k)].enc...) + } + return nil +} + +func size_map(p *Properties, base structPointer) int { + v := *structPointer_ExtMap(base, p.field) + return sizeExtensionMap(v) +} + +// Encode a map field. +func (o *Buffer) enc_new_map(p *Properties, base structPointer) error { + var state errorState // XXX: or do we need to plumb this through? + + /* + A map defined as + map map_field = N; + is encoded in the same way as + message MapFieldEntry { + key_type key = 1; + value_type value = 2; + } + repeated MapFieldEntry map_field = N; + */ + + v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V + if v.Len() == 0 { + return nil + } + + keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) + + enc := func() error { + if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil { + return err + } + if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil { + return err + } + return nil + } + + // Don't sort map keys. It is not required by the spec, and C++ doesn't do it. + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + + // The only illegal map entry values are nil message pointers. + if val.Kind() == reflect.Ptr && val.IsNil() { + return errors.New("proto: map has nil element") + } + + keycopy.Set(key) + valcopy.Set(val) + + o.buf = append(o.buf, p.tagcode...) + if err := o.enc_len_thing(enc, &state); err != nil { + return err + } + } + return nil +} + +func size_new_map(p *Properties, base structPointer) int { + v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V + + keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype) + + n := 0 + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + keycopy.Set(key) + valcopy.Set(val) + + // Tag codes for key and val are the responsibility of the sub-sizer. + keysize := p.mkeyprop.size(p.mkeyprop, keybase) + valsize := p.mvalprop.size(p.mvalprop, valbase) + entry := keysize + valsize + // Add on tag code and length of map entry itself. + n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry + } + return n +} + +// mapEncodeScratch returns a new reflect.Value matching the map's value type, +// and a structPointer suitable for passing to an encoder or sizer. +func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) { + // Prepare addressable doubly-indirect placeholders for the key and value types. + // This is needed because the element-type encoders expect **T, but the map iteration produces T. + + keycopy = reflect.New(mapType.Key()).Elem() // addressable K + keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K + keyptr.Set(keycopy.Addr()) // + keybase = toStructPointer(keyptr.Addr()) // **K + + // Value types are more varied and require special handling. + switch mapType.Elem().Kind() { + case reflect.Slice: + // []byte + var dummy []byte + valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte + valbase = toStructPointer(valcopy.Addr()) + case reflect.Ptr: + // message; the generated field type is map[K]*Msg (so V is *Msg), + // so we only need one level of indirection. + valcopy = reflect.New(mapType.Elem()).Elem() // addressable V + valbase = toStructPointer(valcopy.Addr()) + default: + // everything else + valcopy = reflect.New(mapType.Elem()).Elem() // addressable V + valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V + valptr.Set(valcopy.Addr()) // + valbase = toStructPointer(valptr.Addr()) // **V + } + return +} + +// Encode a struct. +func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error { + var state errorState + // Encode fields in tag order so that decoders may use optimizations + // that depend on the ordering. + // https://developers.google.com/protocol-buffers/docs/encoding#order + for _, i := range prop.order { + p := prop.Prop[i] + if p.enc != nil { + err := p.enc(o, p, base) + if err != nil { + if err == ErrNil { + if p.Required && state.err == nil { + state.err = &RequiredNotSetError{p.Name} + } + } else if err == errRepeatedHasNil { + // Give more context to nil values in repeated fields. + return errors.New("repeated field " + p.OrigName + " has nil element") + } else if !state.shouldContinue(err, p) { + return err + } + } + } + } + + // Do oneof fields. + if prop.oneofMarshaler != nil { + m := structPointer_Interface(base, prop.stype).(Message) + if err := prop.oneofMarshaler(m, o); err != nil { + return err + } + } + + // Add unrecognized fields at the end. + if prop.unrecField.IsValid() { + v := *structPointer_Bytes(base, prop.unrecField) + if len(v) > 0 { + o.buf = append(o.buf, v...) + } + } + + return state.err +} + +func size_struct(prop *StructProperties, base structPointer) (n int) { + for _, i := range prop.order { + p := prop.Prop[i] + if p.size != nil { + n += p.size(p, base) + } + } + + // Add unrecognized fields at the end. + if prop.unrecField.IsValid() { + v := *structPointer_Bytes(base, prop.unrecField) + n += len(v) + } + + // Factor in any oneof fields. + if prop.oneofSizer != nil { + m := structPointer_Interface(base, prop.stype).(Message) + n += prop.oneofSizer(m) + } + + return +} + +var zeroes [20]byte // longer than any conceivable sizeVarint + +// Encode a struct, preceded by its encoded length (as a varint). +func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error { + return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state) +} + +// Encode something, preceded by its encoded length (as a varint). +func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error { + iLen := len(o.buf) + o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length + iMsg := len(o.buf) + err := enc() + if err != nil && !state.shouldContinue(err, nil) { + return err + } + lMsg := len(o.buf) - iMsg + lLen := sizeVarint(uint64(lMsg)) + switch x := lLen - (iMsg - iLen); { + case x > 0: // actual length is x bytes larger than the space we reserved + // Move msg x bytes right. + o.buf = append(o.buf, zeroes[:x]...) + copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) + case x < 0: // actual length is x bytes smaller than the space we reserved + // Move msg x bytes left. + copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg]) + o.buf = o.buf[:len(o.buf)+x] // x is negative + } + // Encode the length in the reserved space. + o.buf = o.buf[:iLen] + o.EncodeVarint(uint64(lMsg)) + o.buf = o.buf[:len(o.buf)+lMsg] + return state.err +} + +// errorState maintains the first error that occurs and updates that error +// with additional context. +type errorState struct { + err error +} + +// shouldContinue reports whether encoding should continue upon encountering the +// given error. If the error is RequiredNotSetError, shouldContinue returns true +// and, if this is the first appearance of that error, remembers it for future +// reporting. +// +// If prop is not nil, it may update any error with additional context about the +// field with the error. +func (s *errorState) shouldContinue(err error, prop *Properties) bool { + // Ignore unset required fields. + reqNotSet, ok := err.(*RequiredNotSetError) + if !ok { + return false + } + if s.err == nil { + if prop != nil { + err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field} + } + s.err = err + } + return true +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/equal.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/equal.go new file mode 100644 index 00000000..f5db1def --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/equal.go @@ -0,0 +1,276 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// Protocol buffer comparison. + +package proto + +import ( + "bytes" + "log" + "reflect" + "strings" +) + +/* +Equal returns true iff protocol buffers a and b are equal. +The arguments must both be pointers to protocol buffer structs. + +Equality is defined in this way: + - Two messages are equal iff they are the same type, + corresponding fields are equal, unknown field sets + are equal, and extensions sets are equal. + - Two set scalar fields are equal iff their values are equal. + If the fields are of a floating-point type, remember that + NaN != x for all x, including NaN. If the message is defined + in a proto3 .proto file, fields are not "set"; specifically, + zero length proto3 "bytes" fields are equal (nil == {}). + - Two repeated fields are equal iff their lengths are the same, + and their corresponding elements are equal (a "bytes" field, + although represented by []byte, is not a repeated field) + - Two unset fields are equal. + - Two unknown field sets are equal if their current + encoded state is equal. + - Two extension sets are equal iff they have corresponding + elements that are pairwise equal. + - Every other combination of things are not equal. + +The return value is undefined if a and b are not protocol buffers. +*/ +func Equal(a, b Message) bool { + if a == nil || b == nil { + return a == b + } + v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) + if v1.Type() != v2.Type() { + return false + } + if v1.Kind() == reflect.Ptr { + if v1.IsNil() { + return v2.IsNil() + } + if v2.IsNil() { + return false + } + v1, v2 = v1.Elem(), v2.Elem() + } + if v1.Kind() != reflect.Struct { + return false + } + return equalStruct(v1, v2) +} + +// v1 and v2 are known to have the same type. +func equalStruct(v1, v2 reflect.Value) bool { + sprop := GetProperties(v1.Type()) + for i := 0; i < v1.NumField(); i++ { + f := v1.Type().Field(i) + if strings.HasPrefix(f.Name, "XXX_") { + continue + } + f1, f2 := v1.Field(i), v2.Field(i) + if f.Type.Kind() == reflect.Ptr { + if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { + // both unset + continue + } else if n1 != n2 { + // set/unset mismatch + return false + } + b1, ok := f1.Interface().(raw) + if ok { + b2 := f2.Interface().(raw) + // RawMessage + if !bytes.Equal(b1.Bytes(), b2.Bytes()) { + return false + } + continue + } + f1, f2 = f1.Elem(), f2.Elem() + } + if !equalAny(f1, f2, sprop.Prop[i]) { + return false + } + } + + if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { + em2 := v2.FieldByName("XXX_extensions") + if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { + return false + } + } + + uf := v1.FieldByName("XXX_unrecognized") + if !uf.IsValid() { + return true + } + + u1 := uf.Bytes() + u2 := v2.FieldByName("XXX_unrecognized").Bytes() + if !bytes.Equal(u1, u2) { + return false + } + + return true +} + +// v1 and v2 are known to have the same type. +// prop may be nil. +func equalAny(v1, v2 reflect.Value, prop *Properties) bool { + if v1.Type() == protoMessageType { + m1, _ := v1.Interface().(Message) + m2, _ := v2.Interface().(Message) + return Equal(m1, m2) + } + switch v1.Kind() { + case reflect.Bool: + return v1.Bool() == v2.Bool() + case reflect.Float32, reflect.Float64: + return v1.Float() == v2.Float() + case reflect.Int32, reflect.Int64: + return v1.Int() == v2.Int() + case reflect.Interface: + // Probably a oneof field; compare the inner values. + n1, n2 := v1.IsNil(), v2.IsNil() + if n1 || n2 { + return n1 == n2 + } + e1, e2 := v1.Elem(), v2.Elem() + if e1.Type() != e2.Type() { + return false + } + return equalAny(e1, e2, nil) + case reflect.Map: + if v1.Len() != v2.Len() { + return false + } + for _, key := range v1.MapKeys() { + val2 := v2.MapIndex(key) + if !val2.IsValid() { + // This key was not found in the second map. + return false + } + if !equalAny(v1.MapIndex(key), val2, nil) { + return false + } + } + return true + case reflect.Ptr: + return equalAny(v1.Elem(), v2.Elem(), prop) + case reflect.Slice: + if v1.Type().Elem().Kind() == reflect.Uint8 { + // short circuit: []byte + + // Edge case: if this is in a proto3 message, a zero length + // bytes field is considered the zero value. + if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { + return true + } + if v1.IsNil() != v2.IsNil() { + return false + } + return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) + } + + if v1.Len() != v2.Len() { + return false + } + for i := 0; i < v1.Len(); i++ { + if !equalAny(v1.Index(i), v2.Index(i), prop) { + return false + } + } + return true + case reflect.String: + return v1.Interface().(string) == v2.Interface().(string) + case reflect.Struct: + return equalStruct(v1, v2) + case reflect.Uint32, reflect.Uint64: + return v1.Uint() == v2.Uint() + } + + // unknown type, so not a protocol buffer + log.Printf("proto: don't know how to compare %v", v1) + return false +} + +// base is the struct type that the extensions are based on. +// em1 and em2 are extension maps. +func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool { + if len(em1) != len(em2) { + return false + } + + for extNum, e1 := range em1 { + e2, ok := em2[extNum] + if !ok { + return false + } + + m1, m2 := e1.value, e2.value + + if m1 != nil && m2 != nil { + // Both are unencoded. + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + continue + } + + // At least one is encoded. To do a semantically correct comparison + // we need to unmarshal them first. + var desc *ExtensionDesc + if m := extensionMaps[base]; m != nil { + desc = m[extNum] + } + if desc == nil { + log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) + continue + } + var err error + if m1 == nil { + m1, err = decodeExtension(e1.enc, desc) + } + if m2 == nil && err == nil { + m2, err = decodeExtension(e2.enc, desc) + } + if err != nil { + // The encoded form is invalid. + log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) + return false + } + if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { + return false + } + } + + return true +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/equal_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/equal_test.go new file mode 100644 index 00000000..7b45eaa6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/equal_test.go @@ -0,0 +1,212 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "testing" + + . "github.com/golang/protobuf/proto" + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + pb "github.com/golang/protobuf/proto/testdata" +) + +// Four identical base messages. +// The init function adds extensions to some of them. +var messageWithoutExtension = &pb.MyMessage{Count: Int32(7)} +var messageWithExtension1a = &pb.MyMessage{Count: Int32(7)} +var messageWithExtension1b = &pb.MyMessage{Count: Int32(7)} +var messageWithExtension2 = &pb.MyMessage{Count: Int32(7)} + +// Two messages with non-message extensions. +var messageWithInt32Extension1 = &pb.MyMessage{Count: Int32(8)} +var messageWithInt32Extension2 = &pb.MyMessage{Count: Int32(8)} + +func init() { + ext1 := &pb.Ext{Data: String("Kirk")} + ext2 := &pb.Ext{Data: String("Picard")} + + // messageWithExtension1a has ext1, but never marshals it. + if err := SetExtension(messageWithExtension1a, pb.E_Ext_More, ext1); err != nil { + panic("SetExtension on 1a failed: " + err.Error()) + } + + // messageWithExtension1b is the unmarshaled form of messageWithExtension1a. + if err := SetExtension(messageWithExtension1b, pb.E_Ext_More, ext1); err != nil { + panic("SetExtension on 1b failed: " + err.Error()) + } + buf, err := Marshal(messageWithExtension1b) + if err != nil { + panic("Marshal of 1b failed: " + err.Error()) + } + messageWithExtension1b.Reset() + if err := Unmarshal(buf, messageWithExtension1b); err != nil { + panic("Unmarshal of 1b failed: " + err.Error()) + } + + // messageWithExtension2 has ext2. + if err := SetExtension(messageWithExtension2, pb.E_Ext_More, ext2); err != nil { + panic("SetExtension on 2 failed: " + err.Error()) + } + + if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(23)); err != nil { + panic("SetExtension on Int32-1 failed: " + err.Error()) + } + if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(24)); err != nil { + panic("SetExtension on Int32-2 failed: " + err.Error()) + } +} + +var EqualTests = []struct { + desc string + a, b Message + exp bool +}{ + {"different types", &pb.GoEnum{}, &pb.GoTestField{}, false}, + {"equal empty", &pb.GoEnum{}, &pb.GoEnum{}, true}, + {"nil vs nil", nil, nil, true}, + {"typed nil vs typed nil", (*pb.GoEnum)(nil), (*pb.GoEnum)(nil), true}, + {"typed nil vs empty", (*pb.GoEnum)(nil), &pb.GoEnum{}, false}, + {"different typed nil", (*pb.GoEnum)(nil), (*pb.GoTestField)(nil), false}, + + {"one set field, one unset field", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{}, false}, + {"one set field zero, one unset field", &pb.GoTest{Param: Int32(0)}, &pb.GoTest{}, false}, + {"different set fields", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("bar")}, false}, + {"equal set", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("foo")}, true}, + + {"repeated, one set", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{}, false}, + {"repeated, different length", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{F_Int32Repeated: []int32{2}}, false}, + {"repeated, different value", &pb.GoTest{F_Int32Repeated: []int32{2}}, &pb.GoTest{F_Int32Repeated: []int32{3}}, false}, + {"repeated, equal", &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, true}, + {"repeated, nil equal nil", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: nil}, true}, + {"repeated, nil equal empty", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: []int32{}}, true}, + {"repeated, empty equal nil", &pb.GoTest{F_Int32Repeated: []int32{}}, &pb.GoTest{F_Int32Repeated: nil}, true}, + + { + "nested, different", + &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("foo")}}, + &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("bar")}}, + false, + }, + { + "nested, equal", + &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, + &pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}}, + true, + }, + + {"bytes", &pb.OtherMessage{Value: []byte("foo")}, &pb.OtherMessage{Value: []byte("foo")}, true}, + {"bytes, empty", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: []byte{}}, true}, + {"bytes, empty vs nil", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: nil}, false}, + { + "repeated bytes", + &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, + &pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}}, + true, + }, + // In proto3, []byte{} and []byte(nil) are equal. + {"proto3 bytes, empty vs nil", &proto3pb.Message{Data: []byte{}}, &proto3pb.Message{Data: nil}, true}, + + {"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false}, + {"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true}, + {"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false}, + + {"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true}, + {"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false}, + + { + "message with group", + &pb.MyMessage{ + Count: Int32(1), + Somegroup: &pb.MyMessage_SomeGroup{ + GroupField: Int32(5), + }, + }, + &pb.MyMessage{ + Count: Int32(1), + Somegroup: &pb.MyMessage_SomeGroup{ + GroupField: Int32(5), + }, + }, + true, + }, + + { + "map same", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + true, + }, + { + "map different entry", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}}, + false, + }, + { + "map different key only", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}}, + false, + }, + { + "map different value only", + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}}, + &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}}, + false, + }, + { + "oneof same", + &pb.Communique{Union: &pb.Communique_Number{41}}, + &pb.Communique{Union: &pb.Communique_Number{41}}, + true, + }, + { + "oneof one nil", + &pb.Communique{Union: &pb.Communique_Number{41}}, + &pb.Communique{}, + false, + }, + { + "oneof different", + &pb.Communique{Union: &pb.Communique_Number{41}}, + &pb.Communique{Union: &pb.Communique_Name{"Bobby Tables"}}, + false, + }, +} + +func TestEqual(t *testing.T) { + for _, tc := range EqualTests { + if res := Equal(tc.a, tc.b); res != tc.exp { + t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/extensions.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/extensions.go new file mode 100644 index 00000000..054f4f1d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/extensions.go @@ -0,0 +1,399 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +/* + * Types and routines for supporting protocol buffer extensions. + */ + +import ( + "errors" + "fmt" + "reflect" + "strconv" + "sync" +) + +// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. +var ErrMissingExtension = errors.New("proto: missing extension") + +// ExtensionRange represents a range of message extensions for a protocol buffer. +// Used in code generated by the protocol compiler. +type ExtensionRange struct { + Start, End int32 // both inclusive +} + +// extendableProto is an interface implemented by any protocol buffer that may be extended. +type extendableProto interface { + Message + ExtensionRangeArray() []ExtensionRange + ExtensionMap() map[int32]Extension +} + +var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem() + +// ExtensionDesc represents an extension specification. +// Used in generated code from the protocol compiler. +type ExtensionDesc struct { + ExtendedType Message // nil pointer to the type that is being extended + ExtensionType interface{} // nil pointer to the extension type + Field int32 // field number + Name string // fully-qualified name of extension, for text formatting + Tag string // protobuf tag style +} + +func (ed *ExtensionDesc) repeated() bool { + t := reflect.TypeOf(ed.ExtensionType) + return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 +} + +// Extension represents an extension in a message. +type Extension struct { + // When an extension is stored in a message using SetExtension + // only desc and value are set. When the message is marshaled + // enc will be set to the encoded form of the message. + // + // When a message is unmarshaled and contains extensions, each + // extension will have only enc set. When such an extension is + // accessed using GetExtension (or GetExtensions) desc and value + // will be set. + desc *ExtensionDesc + value interface{} + enc []byte +} + +// SetRawExtension is for testing only. +func SetRawExtension(base extendableProto, id int32, b []byte) { + base.ExtensionMap()[id] = Extension{enc: b} +} + +// isExtensionField returns true iff the given field number is in an extension range. +func isExtensionField(pb extendableProto, field int32) bool { + for _, er := range pb.ExtensionRangeArray() { + if er.Start <= field && field <= er.End { + return true + } + } + return false +} + +// checkExtensionTypes checks that the given extension is valid for pb. +func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { + // Check the extended type. + if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b { + return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String()) + } + // Check the range. + if !isExtensionField(pb, extension.Field) { + return errors.New("proto: bad extension number; not in declared ranges") + } + return nil +} + +// extPropKey is sufficient to uniquely identify an extension. +type extPropKey struct { + base reflect.Type + field int32 +} + +var extProp = struct { + sync.RWMutex + m map[extPropKey]*Properties +}{ + m: make(map[extPropKey]*Properties), +} + +func extensionProperties(ed *ExtensionDesc) *Properties { + key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} + + extProp.RLock() + if prop, ok := extProp.m[key]; ok { + extProp.RUnlock() + return prop + } + extProp.RUnlock() + + extProp.Lock() + defer extProp.Unlock() + // Check again. + if prop, ok := extProp.m[key]; ok { + return prop + } + + prop := new(Properties) + prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) + extProp.m[key] = prop + return prop +} + +// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m. +func encodeExtensionMap(m map[int32]Extension) error { + for k, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + et := reflect.TypeOf(e.desc.ExtensionType) + props := extensionProperties(e.desc) + + p := NewBuffer(nil) + // If e.value has type T, the encoder expects a *struct{ X T }. + // Pass a *T with a zero field and hope it all works out. + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(e.value)) + if err := props.enc(p, props, toStructPointer(x)); err != nil { + return err + } + e.enc = p.buf + m[k] = e + } + return nil +} + +func sizeExtensionMap(m map[int32]Extension) (n int) { + for _, e := range m { + if e.value == nil || e.desc == nil { + // Extension is only in its encoded form. + n += len(e.enc) + continue + } + + // We don't skip extensions that have an encoded form set, + // because the extension value may have been mutated after + // the last time this function was called. + + et := reflect.TypeOf(e.desc.ExtensionType) + props := extensionProperties(e.desc) + + // If e.value has type T, the encoder expects a *struct{ X T }. + // Pass a *T with a zero field and hope it all works out. + x := reflect.New(et) + x.Elem().Set(reflect.ValueOf(e.value)) + n += props.size(props, toStructPointer(x)) + } + return +} + +// HasExtension returns whether the given extension is present in pb. +func HasExtension(pb extendableProto, extension *ExtensionDesc) bool { + // TODO: Check types, field numbers, etc.? + _, ok := pb.ExtensionMap()[extension.Field] + return ok +} + +// ClearExtension removes the given extension from pb. +func ClearExtension(pb extendableProto, extension *ExtensionDesc) { + // TODO: Check types, field numbers, etc.? + delete(pb.ExtensionMap(), extension.Field) +} + +// GetExtension parses and returns the given extension of pb. +// If the extension is not present and has no default value it returns ErrMissingExtension. +func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) { + if err := checkExtensionTypes(pb, extension); err != nil { + return nil, err + } + + emap := pb.ExtensionMap() + e, ok := emap[extension.Field] + if !ok { + // defaultExtensionValue returns the default value or + // ErrMissingExtension if there is no default. + return defaultExtensionValue(extension) + } + + if e.value != nil { + // Already decoded. Check the descriptor, though. + if e.desc != extension { + // This shouldn't happen. If it does, it means that + // GetExtension was called twice with two different + // descriptors with the same field number. + return nil, errors.New("proto: descriptor conflict") + } + return e.value, nil + } + + v, err := decodeExtension(e.enc, extension) + if err != nil { + return nil, err + } + + // Remember the decoded version and drop the encoded version. + // That way it is safe to mutate what we return. + e.value = v + e.desc = extension + e.enc = nil + emap[extension.Field] = e + return e.value, nil +} + +// defaultExtensionValue returns the default value for extension. +// If no default for an extension is defined ErrMissingExtension is returned. +func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { + t := reflect.TypeOf(extension.ExtensionType) + props := extensionProperties(extension) + + sf, _, err := fieldDefault(t, props) + if err != nil { + return nil, err + } + + if sf == nil || sf.value == nil { + // There is no default value. + return nil, ErrMissingExtension + } + + if t.Kind() != reflect.Ptr { + // We do not need to return a Ptr, we can directly return sf.value. + return sf.value, nil + } + + // We need to return an interface{} that is a pointer to sf.value. + value := reflect.New(t).Elem() + value.Set(reflect.New(value.Type().Elem())) + if sf.kind == reflect.Int32 { + // We may have an int32 or an enum, but the underlying data is int32. + // Since we can't set an int32 into a non int32 reflect.value directly + // set it as a int32. + value.Elem().SetInt(int64(sf.value.(int32))) + } else { + value.Elem().Set(reflect.ValueOf(sf.value)) + } + return value.Interface(), nil +} + +// decodeExtension decodes an extension encoded in b. +func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { + o := NewBuffer(b) + + t := reflect.TypeOf(extension.ExtensionType) + + props := extensionProperties(extension) + + // t is a pointer to a struct, pointer to basic type or a slice. + // Allocate a "field" to store the pointer/slice itself; the + // pointer/slice will be stored here. We pass + // the address of this field to props.dec. + // This passes a zero field and a *t and lets props.dec + // interpret it as a *struct{ x t }. + value := reflect.New(t).Elem() + + for { + // Discard wire type and field number varint. It isn't needed. + if _, err := o.DecodeVarint(); err != nil { + return nil, err + } + + if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil { + return nil, err + } + + if o.index >= len(o.buf) { + break + } + } + return value.Interface(), nil +} + +// GetExtensions returns a slice of the extensions present in pb that are also listed in es. +// The returned slice has the same length as es; missing extensions will appear as nil elements. +func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { + epb, ok := pb.(extendableProto) + if !ok { + err = errors.New("proto: not an extendable proto") + return + } + extensions = make([]interface{}, len(es)) + for i, e := range es { + extensions[i], err = GetExtension(epb, e) + if err == ErrMissingExtension { + err = nil + } + if err != nil { + return + } + } + return +} + +// SetExtension sets the specified extension of pb to the specified value. +func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error { + if err := checkExtensionTypes(pb, extension); err != nil { + return err + } + typ := reflect.TypeOf(extension.ExtensionType) + if typ != reflect.TypeOf(value) { + return errors.New("proto: bad extension value type") + } + // nil extension values need to be caught early, because the + // encoder can't distinguish an ErrNil due to a nil extension + // from an ErrNil due to a missing field. Extensions are + // always optional, so the encoder would just swallow the error + // and drop all the extensions from the encoded message. + if reflect.ValueOf(value).IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) + } + + pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value} + return nil +} + +// A global registry of extensions. +// The generated code will register the generated descriptors by calling RegisterExtension. + +var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) + +// RegisterExtension is called from the generated code. +func RegisterExtension(desc *ExtensionDesc) { + st := reflect.TypeOf(desc.ExtendedType).Elem() + m := extensionMaps[st] + if m == nil { + m = make(map[int32]*ExtensionDesc) + extensionMaps[st] = m + } + if _, ok := m[desc.Field]; ok { + panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) + } + m[desc.Field] = desc +} + +// RegisteredExtensions returns a map of the registered extensions of a +// protocol buffer struct, indexed by the extension number. +// The argument pb should be a nil pointer to the struct type. +func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { + return extensionMaps[reflect.TypeOf(pb).Elem()] +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/extensions_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/extensions_test.go new file mode 100644 index 00000000..80122108 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/extensions_test.go @@ -0,0 +1,430 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "bytes" + "fmt" + "reflect" + "testing" + + "github.com/golang/protobuf/proto" + pb "github.com/golang/protobuf/proto/testdata" +) + +func TestGetExtensionsWithMissingExtensions(t *testing.T) { + msg := &pb.MyMessage{} + ext1 := &pb.Ext{} + if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { + t.Fatalf("Could not set ext1: %s", ext1) + } + exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{ + pb.E_Ext_More, + pb.E_Ext_Text, + }) + if err != nil { + t.Fatalf("GetExtensions() failed: %s", err) + } + if exts[0] != ext1 { + t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0]) + } + if exts[1] != nil { + t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1]) + } +} + +func TestGetExtensionStability(t *testing.T) { + check := func(m *pb.MyMessage) bool { + ext1, err := proto.GetExtension(m, pb.E_Ext_More) + if err != nil { + t.Fatalf("GetExtension() failed: %s", err) + } + ext2, err := proto.GetExtension(m, pb.E_Ext_More) + if err != nil { + t.Fatalf("GetExtension() failed: %s", err) + } + return ext1 == ext2 + } + msg := &pb.MyMessage{Count: proto.Int32(4)} + ext0 := &pb.Ext{} + if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil { + t.Fatalf("Could not set ext1: %s", ext0) + } + if !check(msg) { + t.Errorf("GetExtension() not stable before marshaling") + } + bb, err := proto.Marshal(msg) + if err != nil { + t.Fatalf("Marshal() failed: %s", err) + } + msg1 := &pb.MyMessage{} + err = proto.Unmarshal(bb, msg1) + if err != nil { + t.Fatalf("Unmarshal() failed: %s", err) + } + if !check(msg1) { + t.Errorf("GetExtension() not stable after unmarshaling") + } +} + +func TestGetExtensionDefaults(t *testing.T) { + var setFloat64 float64 = 1 + var setFloat32 float32 = 2 + var setInt32 int32 = 3 + var setInt64 int64 = 4 + var setUint32 uint32 = 5 + var setUint64 uint64 = 6 + var setBool = true + var setBool2 = false + var setString = "Goodnight string" + var setBytes = []byte("Goodnight bytes") + var setEnum = pb.DefaultsMessage_TWO + + type testcase struct { + ext *proto.ExtensionDesc // Extension we are testing. + want interface{} // Expected value of extension, or nil (meaning that GetExtension will fail). + def interface{} // Expected value of extension after ClearExtension(). + } + tests := []testcase{ + {pb.E_NoDefaultDouble, setFloat64, nil}, + {pb.E_NoDefaultFloat, setFloat32, nil}, + {pb.E_NoDefaultInt32, setInt32, nil}, + {pb.E_NoDefaultInt64, setInt64, nil}, + {pb.E_NoDefaultUint32, setUint32, nil}, + {pb.E_NoDefaultUint64, setUint64, nil}, + {pb.E_NoDefaultSint32, setInt32, nil}, + {pb.E_NoDefaultSint64, setInt64, nil}, + {pb.E_NoDefaultFixed32, setUint32, nil}, + {pb.E_NoDefaultFixed64, setUint64, nil}, + {pb.E_NoDefaultSfixed32, setInt32, nil}, + {pb.E_NoDefaultSfixed64, setInt64, nil}, + {pb.E_NoDefaultBool, setBool, nil}, + {pb.E_NoDefaultBool, setBool2, nil}, + {pb.E_NoDefaultString, setString, nil}, + {pb.E_NoDefaultBytes, setBytes, nil}, + {pb.E_NoDefaultEnum, setEnum, nil}, + {pb.E_DefaultDouble, setFloat64, float64(3.1415)}, + {pb.E_DefaultFloat, setFloat32, float32(3.14)}, + {pb.E_DefaultInt32, setInt32, int32(42)}, + {pb.E_DefaultInt64, setInt64, int64(43)}, + {pb.E_DefaultUint32, setUint32, uint32(44)}, + {pb.E_DefaultUint64, setUint64, uint64(45)}, + {pb.E_DefaultSint32, setInt32, int32(46)}, + {pb.E_DefaultSint64, setInt64, int64(47)}, + {pb.E_DefaultFixed32, setUint32, uint32(48)}, + {pb.E_DefaultFixed64, setUint64, uint64(49)}, + {pb.E_DefaultSfixed32, setInt32, int32(50)}, + {pb.E_DefaultSfixed64, setInt64, int64(51)}, + {pb.E_DefaultBool, setBool, true}, + {pb.E_DefaultBool, setBool2, true}, + {pb.E_DefaultString, setString, "Hello, string"}, + {pb.E_DefaultBytes, setBytes, []byte("Hello, bytes")}, + {pb.E_DefaultEnum, setEnum, pb.DefaultsMessage_ONE}, + } + + checkVal := func(test testcase, msg *pb.DefaultsMessage, valWant interface{}) error { + val, err := proto.GetExtension(msg, test.ext) + if err != nil { + if valWant != nil { + return fmt.Errorf("GetExtension(): %s", err) + } + if want := proto.ErrMissingExtension; err != want { + return fmt.Errorf("Unexpected error: got %v, want %v", err, want) + } + return nil + } + + // All proto2 extension values are either a pointer to a value or a slice of values. + ty := reflect.TypeOf(val) + tyWant := reflect.TypeOf(test.ext.ExtensionType) + if got, want := ty, tyWant; got != want { + return fmt.Errorf("unexpected reflect.TypeOf(): got %v want %v", got, want) + } + tye := ty.Elem() + tyeWant := tyWant.Elem() + if got, want := tye, tyeWant; got != want { + return fmt.Errorf("unexpected reflect.TypeOf().Elem(): got %v want %v", got, want) + } + + // Check the name of the type of the value. + // If it is an enum it will be type int32 with the name of the enum. + if got, want := tye.Name(), tye.Name(); got != want { + return fmt.Errorf("unexpected reflect.TypeOf().Elem().Name(): got %v want %v", got, want) + } + + // Check that value is what we expect. + // If we have a pointer in val, get the value it points to. + valExp := val + if ty.Kind() == reflect.Ptr { + valExp = reflect.ValueOf(val).Elem().Interface() + } + if got, want := valExp, valWant; !reflect.DeepEqual(got, want) { + return fmt.Errorf("unexpected reflect.DeepEqual(): got %v want %v", got, want) + } + + return nil + } + + setTo := func(test testcase) interface{} { + setTo := reflect.ValueOf(test.want) + if typ := reflect.TypeOf(test.ext.ExtensionType); typ.Kind() == reflect.Ptr { + setTo = reflect.New(typ).Elem() + setTo.Set(reflect.New(setTo.Type().Elem())) + setTo.Elem().Set(reflect.ValueOf(test.want)) + } + return setTo.Interface() + } + + for _, test := range tests { + msg := &pb.DefaultsMessage{} + name := test.ext.Name + + // Check the initial value. + if err := checkVal(test, msg, test.def); err != nil { + t.Errorf("%s: %v", name, err) + } + + // Set the per-type value and check value. + name = fmt.Sprintf("%s (set to %T %v)", name, test.want, test.want) + if err := proto.SetExtension(msg, test.ext, setTo(test)); err != nil { + t.Errorf("%s: SetExtension(): %v", name, err) + continue + } + if err := checkVal(test, msg, test.want); err != nil { + t.Errorf("%s: %v", name, err) + continue + } + + // Set and check the value. + name += " (cleared)" + proto.ClearExtension(msg, test.ext) + if err := checkVal(test, msg, test.def); err != nil { + t.Errorf("%s: %v", name, err) + } + } +} + +func TestExtensionsRoundTrip(t *testing.T) { + msg := &pb.MyMessage{} + ext1 := &pb.Ext{ + Data: proto.String("hi"), + } + ext2 := &pb.Ext{ + Data: proto.String("there"), + } + exists := proto.HasExtension(msg, pb.E_Ext_More) + if exists { + t.Error("Extension More present unexpectedly") + } + if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil { + t.Error(err) + } + if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil { + t.Error(err) + } + e, err := proto.GetExtension(msg, pb.E_Ext_More) + if err != nil { + t.Error(err) + } + x, ok := e.(*pb.Ext) + if !ok { + t.Errorf("e has type %T, expected testdata.Ext", e) + } else if *x.Data != "there" { + t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x) + } + proto.ClearExtension(msg, pb.E_Ext_More) + if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension { + t.Errorf("got %v, expected ErrMissingExtension", e) + } + if _, err := proto.GetExtension(msg, pb.E_X215); err == nil { + t.Error("expected bad extension error, got nil") + } + if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil { + t.Error("expected extension err") + } + if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil { + t.Error("expected some sort of type mismatch error, got nil") + } +} + +func TestNilExtension(t *testing.T) { + msg := &pb.MyMessage{ + Count: proto.Int32(1), + } + if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil { + t.Fatal(err) + } + if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil { + t.Error("expected SetExtension to fail due to a nil extension") + } else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want { + t.Errorf("expected error %v, got %v", want, err) + } + // Note: if the behavior of Marshal is ever changed to ignore nil extensions, update + // this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal. +} + +func TestMarshalUnmarshalRepeatedExtension(t *testing.T) { + // Add a repeated extension to the result. + tests := []struct { + name string + ext []*pb.ComplexExtension + }{ + { + "two fields", + []*pb.ComplexExtension{ + {First: proto.Int32(7)}, + {Second: proto.Int32(11)}, + }, + }, + { + "repeated field", + []*pb.ComplexExtension{ + {Third: []int32{1000}}, + {Third: []int32{2000}}, + }, + }, + { + "two fields and repeated field", + []*pb.ComplexExtension{ + {Third: []int32{1000}}, + {First: proto.Int32(9)}, + {Second: proto.Int32(21)}, + {Third: []int32{2000}}, + }, + }, + } + for _, test := range tests { + // Marshal message with a repeated extension. + msg1 := new(pb.OtherMessage) + err := proto.SetExtension(msg1, pb.E_RComplex, test.ext) + if err != nil { + t.Fatalf("[%s] Error setting extension: %v", test.name, err) + } + b, err := proto.Marshal(msg1) + if err != nil { + t.Fatalf("[%s] Error marshaling message: %v", test.name, err) + } + + // Unmarshal and read the merged proto. + msg2 := new(pb.OtherMessage) + err = proto.Unmarshal(b, msg2) + if err != nil { + t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err) + } + e, err := proto.GetExtension(msg2, pb.E_RComplex) + if err != nil { + t.Fatalf("[%s] Error getting extension: %v", test.name, err) + } + ext := e.([]*pb.ComplexExtension) + if ext == nil { + t.Fatalf("[%s] Invalid extension", test.name) + } + if !reflect.DeepEqual(ext, test.ext) { + t.Errorf("[%s] Wrong value for ComplexExtension: got: %v want: %v\n", test.name, ext, test.ext) + } + } +} + +func TestUnmarshalRepeatingNonRepeatedExtension(t *testing.T) { + // We may see multiple instances of the same extension in the wire + // format. For example, the proto compiler may encode custom options in + // this way. Here, we verify that we merge the extensions together. + tests := []struct { + name string + ext []*pb.ComplexExtension + }{ + { + "two fields", + []*pb.ComplexExtension{ + {First: proto.Int32(7)}, + {Second: proto.Int32(11)}, + }, + }, + { + "repeated field", + []*pb.ComplexExtension{ + {Third: []int32{1000}}, + {Third: []int32{2000}}, + }, + }, + { + "two fields and repeated field", + []*pb.ComplexExtension{ + {Third: []int32{1000}}, + {First: proto.Int32(9)}, + {Second: proto.Int32(21)}, + {Third: []int32{2000}}, + }, + }, + } + for _, test := range tests { + var buf bytes.Buffer + var want pb.ComplexExtension + + // Generate a serialized representation of a repeated extension + // by catenating bytes together. + for i, e := range test.ext { + // Merge to create the wanted proto. + proto.Merge(&want, e) + + // serialize the message + msg := new(pb.OtherMessage) + err := proto.SetExtension(msg, pb.E_Complex, e) + if err != nil { + t.Fatalf("[%s] Error setting extension %d: %v", test.name, i, err) + } + b, err := proto.Marshal(msg) + if err != nil { + t.Fatalf("[%s] Error marshaling message %d: %v", test.name, i, err) + } + buf.Write(b) + } + + // Unmarshal and read the merged proto. + msg2 := new(pb.OtherMessage) + err := proto.Unmarshal(buf.Bytes(), msg2) + if err != nil { + t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err) + } + e, err := proto.GetExtension(msg2, pb.E_Complex) + if err != nil { + t.Fatalf("[%s] Error getting extension: %v", test.name, err) + } + ext := e.(*pb.ComplexExtension) + if ext == nil { + t.Fatalf("[%s] Invalid extension", test.name) + } + if !reflect.DeepEqual(*ext, want) { + t.Errorf("[%s] Wrong value for ComplexExtension: got: %s want: %s\n", test.name, ext, want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/lib.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/lib.go new file mode 100644 index 00000000..0de8f8df --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/lib.go @@ -0,0 +1,894 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +/* +Package proto converts data structures to and from the wire format of +protocol buffers. It works in concert with the Go source code generated +for .proto files by the protocol compiler. + +A summary of the properties of the protocol buffer interface +for a protocol buffer variable v: + + - Names are turned from camel_case to CamelCase for export. + - There are no methods on v to set fields; just treat + them as structure fields. + - There are getters that return a field's value if set, + and return the field's default value if unset. + The getters work even if the receiver is a nil message. + - The zero value for a struct is its correct initialization state. + All desired fields must be set before marshaling. + - A Reset() method will restore a protobuf struct to its zero state. + - Non-repeated fields are pointers to the values; nil means unset. + That is, optional or required field int32 f becomes F *int32. + - Repeated fields are slices. + - Helper functions are available to aid the setting of fields. + msg.Foo = proto.String("hello") // set field + - Constants are defined to hold the default values of all fields that + have them. They have the form Default_StructName_FieldName. + Because the getter methods handle defaulted values, + direct use of these constants should be rare. + - Enums are given type names and maps from names to values. + Enum values are prefixed by the enclosing message's name, or by the + enum's type name if it is a top-level enum. Enum types have a String + method, and a Enum method to assist in message construction. + - Nested messages, groups and enums have type names prefixed with the name of + the surrounding message type. + - Extensions are given descriptor names that start with E_, + followed by an underscore-delimited list of the nested messages + that contain it (if any) followed by the CamelCased name of the + extension field itself. HasExtension, ClearExtension, GetExtension + and SetExtension are functions for manipulating extensions. + - Oneof field sets are given a single field in their message, + with distinguished wrapper types for each possible field value. + - Marshal and Unmarshal are functions to encode and decode the wire format. + +When the .proto file specifies `syntax="proto3"`, there are some differences: + + - Non-repeated fields of non-message type are values instead of pointers. + - Getters are only generated for message and oneof fields. + - Enum types do not get an Enum method. + +The simplest way to describe this is to see an example. +Given file test.proto, containing + + package example; + + enum FOO { X = 17; } + + message Test { + required string label = 1; + optional int32 type = 2 [default=77]; + repeated int64 reps = 3; + optional group OptionalGroup = 4 { + required string RequiredField = 5; + } + oneof union { + int32 number = 6; + string name = 7; + } + } + +The resulting file, test.pb.go, is: + + package example + + import proto "github.com/golang/protobuf/proto" + import math "math" + + type FOO int32 + const ( + FOO_X FOO = 17 + ) + var FOO_name = map[int32]string{ + 17: "X", + } + var FOO_value = map[string]int32{ + "X": 17, + } + + func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p + } + func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) + } + func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data) + if err != nil { + return err + } + *x = FOO(value) + return nil + } + + type Test struct { + Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` + Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` + Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` + Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + // Types that are valid to be assigned to Union: + // *Test_Number + // *Test_Name + Union isTest_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` + } + func (m *Test) Reset() { *m = Test{} } + func (m *Test) String() string { return proto.CompactTextString(m) } + func (*Test) ProtoMessage() {} + + type isTest_Union interface { + isTest_Union() + } + + type Test_Number struct { + Number int32 `protobuf:"varint,6,opt,name=number"` + } + type Test_Name struct { + Name string `protobuf:"bytes,7,opt,name=name"` + } + + func (*Test_Number) isTest_Union() {} + func (*Test_Name) isTest_Union() {} + + func (m *Test) GetUnion() isTest_Union { + if m != nil { + return m.Union + } + return nil + } + const Default_Test_Type int32 = 77 + + func (m *Test) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" + } + + func (m *Test) GetType() int32 { + if m != nil && m.Type != nil { + return *m.Type + } + return Default_Test_Type + } + + func (m *Test) GetOptionalgroup() *Test_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil + } + + type Test_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` + } + func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } + func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } + + func (m *Test_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" + } + + func (m *Test) GetNumber() int32 { + if x, ok := m.GetUnion().(*Test_Number); ok { + return x.Number + } + return 0 + } + + func (m *Test) GetName() string { + if x, ok := m.GetUnion().(*Test_Name); ok { + return x.Name + } + return "" + } + + func init() { + proto.RegisterEnum("example.FOO", FOO_name, FOO_value) + } + +To create and play with a Test object: + + package main + + import ( + "log" + + "github.com/golang/protobuf/proto" + pb "./example.pb" + ) + + func main() { + test := &pb.Test{ + Label: proto.String("hello"), + Type: proto.Int32(17), + Reps: []int64{1, 2, 3}, + Optionalgroup: &pb.Test_OptionalGroup{ + RequiredField: proto.String("good bye"), + }, + Union: &pb.Test_Name{"fred"}, + } + data, err := proto.Marshal(test) + if err != nil { + log.Fatal("marshaling error: ", err) + } + newTest := &pb.Test{} + err = proto.Unmarshal(data, newTest) + if err != nil { + log.Fatal("unmarshaling error: ", err) + } + // Now test and newTest contain the same data. + if test.GetLabel() != newTest.GetLabel() { + log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) + } + // Use a type switch to determine which oneof was set. + switch u := test.Union.(type) { + case *pb.Test_Number: // u.Number contains the number. + case *pb.Test_Name: // u.Name contains the string. + } + // etc. + } +*/ +package proto + +import ( + "encoding/json" + "fmt" + "log" + "reflect" + "sort" + "strconv" + "sync" +) + +// Message is implemented by generated protocol buffer messages. +type Message interface { + Reset() + String() string + ProtoMessage() +} + +// Stats records allocation details about the protocol buffer encoders +// and decoders. Useful for tuning the library itself. +type Stats struct { + Emalloc uint64 // mallocs in encode + Dmalloc uint64 // mallocs in decode + Encode uint64 // number of encodes + Decode uint64 // number of decodes + Chit uint64 // number of cache hits + Cmiss uint64 // number of cache misses + Size uint64 // number of sizes +} + +// Set to true to enable stats collection. +const collectStats = false + +var stats Stats + +// GetStats returns a copy of the global Stats structure. +func GetStats() Stats { return stats } + +// A Buffer is a buffer manager for marshaling and unmarshaling +// protocol buffers. It may be reused between invocations to +// reduce memory usage. It is not necessary to use a Buffer; +// the global functions Marshal and Unmarshal create a +// temporary Buffer and are fine for most applications. +type Buffer struct { + buf []byte // encode/decode byte stream + index int // write point + + // pools of basic types to amortize allocation. + bools []bool + uint32s []uint32 + uint64s []uint64 + + // extra pools, only used with pointer_reflect.go + int32s []int32 + int64s []int64 + float32s []float32 + float64s []float64 +} + +// NewBuffer allocates a new Buffer and initializes its internal data to +// the contents of the argument slice. +func NewBuffer(e []byte) *Buffer { + return &Buffer{buf: e} +} + +// Reset resets the Buffer, ready for marshaling a new protocol buffer. +func (p *Buffer) Reset() { + p.buf = p.buf[0:0] // for reading/writing + p.index = 0 // for reading +} + +// SetBuf replaces the internal buffer with the slice, +// ready for unmarshaling the contents of the slice. +func (p *Buffer) SetBuf(s []byte) { + p.buf = s + p.index = 0 +} + +// Bytes returns the contents of the Buffer. +func (p *Buffer) Bytes() []byte { return p.buf } + +/* + * Helper routines for simplifying the creation of optional fields of basic type. + */ + +// Bool is a helper routine that allocates a new bool value +// to store v and returns a pointer to it. +func Bool(v bool) *bool { + return &v +} + +// Int32 is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it. +func Int32(v int32) *int32 { + return &v +} + +// Int is a helper routine that allocates a new int32 value +// to store v and returns a pointer to it, but unlike Int32 +// its argument value is an int. +func Int(v int) *int32 { + p := new(int32) + *p = int32(v) + return p +} + +// Int64 is a helper routine that allocates a new int64 value +// to store v and returns a pointer to it. +func Int64(v int64) *int64 { + return &v +} + +// Float32 is a helper routine that allocates a new float32 value +// to store v and returns a pointer to it. +func Float32(v float32) *float32 { + return &v +} + +// Float64 is a helper routine that allocates a new float64 value +// to store v and returns a pointer to it. +func Float64(v float64) *float64 { + return &v +} + +// Uint32 is a helper routine that allocates a new uint32 value +// to store v and returns a pointer to it. +func Uint32(v uint32) *uint32 { + return &v +} + +// Uint64 is a helper routine that allocates a new uint64 value +// to store v and returns a pointer to it. +func Uint64(v uint64) *uint64 { + return &v +} + +// String is a helper routine that allocates a new string value +// to store v and returns a pointer to it. +func String(v string) *string { + return &v +} + +// EnumName is a helper function to simplify printing protocol buffer enums +// by name. Given an enum map and a value, it returns a useful string. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// UnmarshalJSONEnum is a helper function to simplify recovering enum int values +// from their JSON-encoded representation. Given a map from the enum's symbolic +// names to its int values, and a byte buffer containing the JSON-encoded +// value, it returns an int32 that can be cast to the enum type by the caller. +// +// The function can deal with both JSON representations, numeric and symbolic. +func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { + if data[0] == '"' { + // New style: enums are strings. + var repr string + if err := json.Unmarshal(data, &repr); err != nil { + return -1, err + } + val, ok := m[repr] + if !ok { + return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) + } + return val, nil + } + // Old style: enums are ints. + var val int32 + if err := json.Unmarshal(data, &val); err != nil { + return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) + } + return val, nil +} + +// DebugPrint dumps the encoded data in b in a debugging format with a header +// including the string s. Used in testing but made available for general debugging. +func (p *Buffer) DebugPrint(s string, b []byte) { + var u uint64 + + obuf := p.buf + index := p.index + p.buf = b + p.index = 0 + depth := 0 + + fmt.Printf("\n--- %s ---\n", s) + +out: + for { + for i := 0; i < depth; i++ { + fmt.Print(" ") + } + + index := p.index + if index == len(p.buf) { + break + } + + op, err := p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: fetching op err %v\n", index, err) + break out + } + tag := op >> 3 + wire := op & 7 + + switch wire { + default: + fmt.Printf("%3d: t=%3d unknown wire=%d\n", + index, tag, wire) + break out + + case WireBytes: + var r []byte + + r, err = p.DecodeRawBytes(false) + if err != nil { + break out + } + fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) + if len(r) <= 6 { + for i := 0; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } else { + for i := 0; i < 3; i++ { + fmt.Printf(" %.2x", r[i]) + } + fmt.Printf(" ..") + for i := len(r) - 3; i < len(r); i++ { + fmt.Printf(" %.2x", r[i]) + } + } + fmt.Printf("\n") + + case WireFixed32: + u, err = p.DecodeFixed32() + if err != nil { + fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) + + case WireFixed64: + u, err = p.DecodeFixed64() + if err != nil { + fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) + + case WireVarint: + u, err = p.DecodeVarint() + if err != nil { + fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) + break out + } + fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) + + case WireStartGroup: + fmt.Printf("%3d: t=%3d start\n", index, tag) + depth++ + + case WireEndGroup: + depth-- + fmt.Printf("%3d: t=%3d end\n", index, tag) + } + } + + if depth != 0 { + fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) + } + fmt.Printf("\n") + + p.buf = obuf + p.index = index +} + +// SetDefaults sets unset protocol buffer fields to their default values. +// It only modifies fields that are both unset and have defined defaults. +// It recursively sets default values in any non-nil sub-messages. +func SetDefaults(pb Message) { + setDefaults(reflect.ValueOf(pb), true, false) +} + +// v is a pointer to a struct. +func setDefaults(v reflect.Value, recur, zeros bool) { + v = v.Elem() + + defaultMu.RLock() + dm, ok := defaults[v.Type()] + defaultMu.RUnlock() + if !ok { + dm = buildDefaultMessage(v.Type()) + defaultMu.Lock() + defaults[v.Type()] = dm + defaultMu.Unlock() + } + + for _, sf := range dm.scalars { + f := v.Field(sf.index) + if !f.IsNil() { + // field already set + continue + } + dv := sf.value + if dv == nil && !zeros { + // no explicit default, and don't want to set zeros + continue + } + fptr := f.Addr().Interface() // **T + // TODO: Consider batching the allocations we do here. + switch sf.kind { + case reflect.Bool: + b := new(bool) + if dv != nil { + *b = dv.(bool) + } + *(fptr.(**bool)) = b + case reflect.Float32: + f := new(float32) + if dv != nil { + *f = dv.(float32) + } + *(fptr.(**float32)) = f + case reflect.Float64: + f := new(float64) + if dv != nil { + *f = dv.(float64) + } + *(fptr.(**float64)) = f + case reflect.Int32: + // might be an enum + if ft := f.Type(); ft != int32PtrType { + // enum + f.Set(reflect.New(ft.Elem())) + if dv != nil { + f.Elem().SetInt(int64(dv.(int32))) + } + } else { + // int32 field + i := new(int32) + if dv != nil { + *i = dv.(int32) + } + *(fptr.(**int32)) = i + } + case reflect.Int64: + i := new(int64) + if dv != nil { + *i = dv.(int64) + } + *(fptr.(**int64)) = i + case reflect.String: + s := new(string) + if dv != nil { + *s = dv.(string) + } + *(fptr.(**string)) = s + case reflect.Uint8: + // exceptional case: []byte + var b []byte + if dv != nil { + db := dv.([]byte) + b = make([]byte, len(db)) + copy(b, db) + } else { + b = []byte{} + } + *(fptr.(*[]byte)) = b + case reflect.Uint32: + u := new(uint32) + if dv != nil { + *u = dv.(uint32) + } + *(fptr.(**uint32)) = u + case reflect.Uint64: + u := new(uint64) + if dv != nil { + *u = dv.(uint64) + } + *(fptr.(**uint64)) = u + default: + log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) + } + } + + for _, ni := range dm.nested { + f := v.Field(ni) + // f is *T or []*T or map[T]*T + switch f.Kind() { + case reflect.Ptr: + if f.IsNil() { + continue + } + setDefaults(f, recur, zeros) + + case reflect.Slice: + for i := 0; i < f.Len(); i++ { + e := f.Index(i) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + + case reflect.Map: + for _, k := range f.MapKeys() { + e := f.MapIndex(k) + if e.IsNil() { + continue + } + setDefaults(e, recur, zeros) + } + } + } +} + +var ( + // defaults maps a protocol buffer struct type to a slice of the fields, + // with its scalar fields set to their proto-declared non-zero default values. + defaultMu sync.RWMutex + defaults = make(map[reflect.Type]defaultMessage) + + int32PtrType = reflect.TypeOf((*int32)(nil)) +) + +// defaultMessage represents information about the default values of a message. +type defaultMessage struct { + scalars []scalarField + nested []int // struct field index of nested messages +} + +type scalarField struct { + index int // struct field index + kind reflect.Kind // element type (the T in *T or []T) + value interface{} // the proto-declared default value, or nil +} + +// t is a struct type. +func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { + sprop := GetProperties(t) + for _, prop := range sprop.Prop { + fi, ok := sprop.decoderTags.get(prop.Tag) + if !ok { + // XXX_unrecognized + continue + } + ft := t.Field(fi).Type + + sf, nested, err := fieldDefault(ft, prop) + switch { + case err != nil: + log.Print(err) + case nested: + dm.nested = append(dm.nested, fi) + case sf != nil: + sf.index = fi + dm.scalars = append(dm.scalars, *sf) + } + } + + return dm +} + +// fieldDefault returns the scalarField for field type ft. +// sf will be nil if the field can not have a default. +// nestedMessage will be true if this is a nested message. +// Note that sf.index is not set on return. +func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { + var canHaveDefault bool + switch ft.Kind() { + case reflect.Ptr: + if ft.Elem().Kind() == reflect.Struct { + nestedMessage = true + } else { + canHaveDefault = true // proto2 scalar field + } + + case reflect.Slice: + switch ft.Elem().Kind() { + case reflect.Ptr: + nestedMessage = true // repeated message + case reflect.Uint8: + canHaveDefault = true // bytes field + } + + case reflect.Map: + if ft.Elem().Kind() == reflect.Ptr { + nestedMessage = true // map with message values + } + } + + if !canHaveDefault { + if nestedMessage { + return nil, true, nil + } + return nil, false, nil + } + + // We now know that ft is a pointer or slice. + sf = &scalarField{kind: ft.Elem().Kind()} + + // scalar fields without defaults + if !prop.HasDefault { + return sf, false, nil + } + + // a scalar field: either *T or []byte + switch ft.Elem().Kind() { + case reflect.Bool: + x, err := strconv.ParseBool(prop.Default) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Float32: + x, err := strconv.ParseFloat(prop.Default, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) + } + sf.value = float32(x) + case reflect.Float64: + x, err := strconv.ParseFloat(prop.Default, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.Int32: + x, err := strconv.ParseInt(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) + } + sf.value = int32(x) + case reflect.Int64: + x, err := strconv.ParseInt(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) + } + sf.value = x + case reflect.String: + sf.value = prop.Default + case reflect.Uint8: + // []byte (not *uint8) + sf.value = []byte(prop.Default) + case reflect.Uint32: + x, err := strconv.ParseUint(prop.Default, 10, 32) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) + } + sf.value = uint32(x) + case reflect.Uint64: + x, err := strconv.ParseUint(prop.Default, 10, 64) + if err != nil { + return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) + } + sf.value = x + default: + return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) + } + + return sf, false, nil +} + +// Map fields may have key types of non-float scalars, strings and enums. +// The easiest way to sort them in some deterministic order is to use fmt. +// If this turns out to be inefficient we can always consider other options, +// such as doing a Schwartzian transform. + +func mapKeys(vs []reflect.Value) sort.Interface { + s := mapKeySorter{ + vs: vs, + // default Less function: textual comparison + less: func(a, b reflect.Value) bool { + return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface()) + }, + } + + // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps; + // numeric keys are sorted numerically. + if len(vs) == 0 { + return s + } + switch vs[0].Kind() { + case reflect.Int32, reflect.Int64: + s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } + case reflect.Uint32, reflect.Uint64: + s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } + } + + return s +} + +type mapKeySorter struct { + vs []reflect.Value + less func(a, b reflect.Value) bool +} + +func (s mapKeySorter) Len() int { return len(s.vs) } +func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } +func (s mapKeySorter) Less(i, j int) bool { + return s.less(s.vs[i], s.vs[j]) +} + +// isProto3Zero reports whether v is a zero proto3 value. +func isProto3Zero(v reflect.Value) bool { + switch v.Kind() { + case reflect.Bool: + return !v.Bool() + case reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint32, reflect.Uint64: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.String: + return v.String() == "" + } + return false +} + +// ProtoPackageIsVersion1 is referenced from generated protocol buffer files +// to assert that that code is compatible with this version of the proto package. +const ProtoPackageIsVersion1 = true diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/message_set.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/message_set.go new file mode 100644 index 00000000..e25e01e6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/message_set.go @@ -0,0 +1,280 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +/* + * Support for message sets. + */ + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "reflect" + "sort" +) + +// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. +// A message type ID is required for storing a protocol buffer in a message set. +var errNoMessageTypeID = errors.New("proto does not have a message type ID") + +// The first two types (_MessageSet_Item and messageSet) +// model what the protocol compiler produces for the following protocol message: +// message MessageSet { +// repeated group Item = 1 { +// required int32 type_id = 2; +// required string message = 3; +// }; +// } +// That is the MessageSet wire format. We can't use a proto to generate these +// because that would introduce a circular dependency between it and this package. + +type _MessageSet_Item struct { + TypeId *int32 `protobuf:"varint,2,req,name=type_id"` + Message []byte `protobuf:"bytes,3,req,name=message"` +} + +type messageSet struct { + Item []*_MessageSet_Item `protobuf:"group,1,rep"` + XXX_unrecognized []byte + // TODO: caching? +} + +// Make sure messageSet is a Message. +var _ Message = (*messageSet)(nil) + +// messageTypeIder is an interface satisfied by a protocol buffer type +// that may be stored in a MessageSet. +type messageTypeIder interface { + MessageTypeId() int32 +} + +func (ms *messageSet) find(pb Message) *_MessageSet_Item { + mti, ok := pb.(messageTypeIder) + if !ok { + return nil + } + id := mti.MessageTypeId() + for _, item := range ms.Item { + if *item.TypeId == id { + return item + } + } + return nil +} + +func (ms *messageSet) Has(pb Message) bool { + if ms.find(pb) != nil { + return true + } + return false +} + +func (ms *messageSet) Unmarshal(pb Message) error { + if item := ms.find(pb); item != nil { + return Unmarshal(item.Message, pb) + } + if _, ok := pb.(messageTypeIder); !ok { + return errNoMessageTypeID + } + return nil // TODO: return error instead? +} + +func (ms *messageSet) Marshal(pb Message) error { + msg, err := Marshal(pb) + if err != nil { + return err + } + if item := ms.find(pb); item != nil { + // reuse existing item + item.Message = msg + return nil + } + + mti, ok := pb.(messageTypeIder) + if !ok { + return errNoMessageTypeID + } + + mtid := mti.MessageTypeId() + ms.Item = append(ms.Item, &_MessageSet_Item{ + TypeId: &mtid, + Message: msg, + }) + return nil +} + +func (ms *messageSet) Reset() { *ms = messageSet{} } +func (ms *messageSet) String() string { return CompactTextString(ms) } +func (*messageSet) ProtoMessage() {} + +// Support for the message_set_wire_format message option. + +func skipVarint(buf []byte) []byte { + i := 0 + for ; buf[i]&0x80 != 0; i++ { + } + return buf[i+1:] +} + +// MarshalMessageSet encodes the extension map represented by m in the message set wire format. +// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option. +func MarshalMessageSet(m map[int32]Extension) ([]byte, error) { + if err := encodeExtensionMap(m); err != nil { + return nil, err + } + + // Sort extension IDs to provide a deterministic encoding. + // See also enc_map in encode.go. + ids := make([]int, 0, len(m)) + for id := range m { + ids = append(ids, int(id)) + } + sort.Ints(ids) + + ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))} + for _, id := range ids { + e := m[int32(id)] + // Remove the wire type and field number varint, as well as the length varint. + msg := skipVarint(skipVarint(e.enc)) + + ms.Item = append(ms.Item, &_MessageSet_Item{ + TypeId: Int32(int32(id)), + Message: msg, + }) + } + return Marshal(ms) +} + +// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. +// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option. +func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error { + ms := new(messageSet) + if err := Unmarshal(buf, ms); err != nil { + return err + } + for _, item := range ms.Item { + id := *item.TypeId + msg := item.Message + + // Restore wire type and field number varint, plus length varint. + // Be careful to preserve duplicate items. + b := EncodeVarint(uint64(id)<<3 | WireBytes) + if ext, ok := m[id]; ok { + // Existing data; rip off the tag and length varint + // so we join the new data correctly. + // We can assume that ext.enc is set because we are unmarshaling. + o := ext.enc[len(b):] // skip wire type and field number + _, n := DecodeVarint(o) // calculate length of length varint + o = o[n:] // skip length varint + msg = append(o, msg...) // join old data and new data + } + b = append(b, EncodeVarint(uint64(len(msg)))...) + b = append(b, msg...) + + m[id] = Extension{enc: b} + } + return nil +} + +// MarshalMessageSetJSON encodes the extension map represented by m in JSON format. +// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) { + var b bytes.Buffer + b.WriteByte('{') + + // Process the map in key order for deterministic output. + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) // int32Slice defined in text.go + + for i, id := range ids { + ext := m[id] + if i > 0 { + b.WriteByte(',') + } + + msd, ok := messageSetMap[id] + if !ok { + // Unknown type; we can't render it, so skip it. + continue + } + fmt.Fprintf(&b, `"[%s]":`, msd.name) + + x := ext.value + if x == nil { + x = reflect.New(msd.t.Elem()).Interface() + if err := Unmarshal(ext.enc, x.(Message)); err != nil { + return nil, err + } + } + d, err := json.Marshal(x) + if err != nil { + return nil, err + } + b.Write(d) + } + b.WriteByte('}') + return b.Bytes(), nil +} + +// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format. +// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option. +func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error { + // Common-case fast path. + if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) { + return nil + } + + // This is fairly tricky, and it's not clear that it is needed. + return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented") +} + +// A global registry of types that can be used in a MessageSet. + +var messageSetMap = make(map[int32]messageSetDesc) + +type messageSetDesc struct { + t reflect.Type // pointer to struct + name string +} + +// RegisterMessageSetType is called from the generated code. +func RegisterMessageSetType(m Message, fieldNum int32, name string) { + messageSetMap[fieldNum] = messageSetDesc{ + t: reflect.TypeOf(m), + name: name, + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/message_set_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/message_set_test.go new file mode 100644 index 00000000..ab8ac2f0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/message_set_test.go @@ -0,0 +1,66 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +import ( + "bytes" + "testing" +) + +func TestUnmarshalMessageSetWithDuplicate(t *testing.T) { + // Check that a repeated message set entry will be concatenated. + in := &messageSet{ + Item: []*_MessageSet_Item{ + {TypeId: Int32(12345), Message: []byte("hoo")}, + {TypeId: Int32(12345), Message: []byte("hah")}, + }, + } + b, err := Marshal(in) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + t.Logf("Marshaled bytes: %q", b) + + m := make(map[int32]Extension) + if err := UnmarshalMessageSet(b, m); err != nil { + t.Fatalf("UnmarshalMessageSet: %v", err) + } + ext, ok := m[12345] + if !ok { + t.Fatalf("Didn't retrieve extension 12345; map is %v", m) + } + // Skip wire type/field number and length varints. + got := skipVarint(skipVarint(ext.enc)) + if want := []byte("hoohah"); !bytes.Equal(got, want) { + t.Errorf("Combined extension is %q, want %q", got, want) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/pointer_reflect.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/pointer_reflect.go new file mode 100644 index 00000000..749919d2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/pointer_reflect.go @@ -0,0 +1,479 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// +build appengine + +// This file contains an implementation of proto field accesses using package reflect. +// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can +// be used on App Engine. + +package proto + +import ( + "math" + "reflect" +) + +// A structPointer is a pointer to a struct. +type structPointer struct { + v reflect.Value +} + +// toStructPointer returns a structPointer equivalent to the given reflect value. +// The reflect value must itself be a pointer to a struct. +func toStructPointer(v reflect.Value) structPointer { + return structPointer{v} +} + +// IsNil reports whether p is nil. +func structPointer_IsNil(p structPointer) bool { + return p.v.IsNil() +} + +// Interface returns the struct pointer as an interface value. +func structPointer_Interface(p structPointer, _ reflect.Type) interface{} { + return p.v.Interface() +} + +// A field identifies a field in a struct, accessible from a structPointer. +// In this implementation, a field is identified by the sequence of field indices +// passed to reflect's FieldByIndex. +type field []int + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return f.Index +} + +// invalidField is an invalid field identifier. +var invalidField = field(nil) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { return f != nil } + +// field returns the given field in the struct as a reflect value. +func structPointer_field(p structPointer, f field) reflect.Value { + // Special case: an extension map entry with a value of type T + // passes a *T to the struct-handling code with a zero field, + // expecting that it will be treated as equivalent to *struct{ X T }, + // which has the same memory layout. We have to handle that case + // specially, because reflect will panic if we call FieldByIndex on a + // non-struct. + if f == nil { + return p.v.Elem() + } + + return p.v.Elem().FieldByIndex(f) +} + +// ifield returns the given field in the struct as an interface value. +func structPointer_ifield(p structPointer, f field) interface{} { + return structPointer_field(p, f).Addr().Interface() +} + +// Bytes returns the address of a []byte field in the struct. +func structPointer_Bytes(p structPointer, f field) *[]byte { + return structPointer_ifield(p, f).(*[]byte) +} + +// BytesSlice returns the address of a [][]byte field in the struct. +func structPointer_BytesSlice(p structPointer, f field) *[][]byte { + return structPointer_ifield(p, f).(*[][]byte) +} + +// Bool returns the address of a *bool field in the struct. +func structPointer_Bool(p structPointer, f field) **bool { + return structPointer_ifield(p, f).(**bool) +} + +// BoolVal returns the address of a bool field in the struct. +func structPointer_BoolVal(p structPointer, f field) *bool { + return structPointer_ifield(p, f).(*bool) +} + +// BoolSlice returns the address of a []bool field in the struct. +func structPointer_BoolSlice(p structPointer, f field) *[]bool { + return structPointer_ifield(p, f).(*[]bool) +} + +// String returns the address of a *string field in the struct. +func structPointer_String(p structPointer, f field) **string { + return structPointer_ifield(p, f).(**string) +} + +// StringVal returns the address of a string field in the struct. +func structPointer_StringVal(p structPointer, f field) *string { + return structPointer_ifield(p, f).(*string) +} + +// StringSlice returns the address of a []string field in the struct. +func structPointer_StringSlice(p structPointer, f field) *[]string { + return structPointer_ifield(p, f).(*[]string) +} + +// ExtMap returns the address of an extension map field in the struct. +func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { + return structPointer_ifield(p, f).(*map[int32]Extension) +} + +// NewAt returns the reflect.Value for a pointer to a field in the struct. +func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { + return structPointer_field(p, f).Addr() +} + +// SetStructPointer writes a *struct field in the struct. +func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { + structPointer_field(p, f).Set(q.v) +} + +// GetStructPointer reads a *struct field in the struct. +func structPointer_GetStructPointer(p structPointer, f field) structPointer { + return structPointer{structPointer_field(p, f)} +} + +// StructPointerSlice the address of a []*struct field in the struct. +func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice { + return structPointerSlice{structPointer_field(p, f)} +} + +// A structPointerSlice represents the address of a slice of pointers to structs +// (themselves messages or groups). That is, v.Type() is *[]*struct{...}. +type structPointerSlice struct { + v reflect.Value +} + +func (p structPointerSlice) Len() int { return p.v.Len() } +func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} } +func (p structPointerSlice) Append(q structPointer) { + p.v.Set(reflect.Append(p.v, q.v)) +} + +var ( + int32Type = reflect.TypeOf(int32(0)) + uint32Type = reflect.TypeOf(uint32(0)) + float32Type = reflect.TypeOf(float32(0)) + int64Type = reflect.TypeOf(int64(0)) + uint64Type = reflect.TypeOf(uint64(0)) + float64Type = reflect.TypeOf(float64(0)) +) + +// A word32 represents a field of type *int32, *uint32, *float32, or *enum. +// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable. +type word32 struct { + v reflect.Value +} + +// IsNil reports whether p is nil. +func word32_IsNil(p word32) bool { + return p.v.IsNil() +} + +// Set sets p to point at a newly allocated word with bits set to x. +func word32_Set(p word32, o *Buffer, x uint32) { + t := p.v.Type().Elem() + switch t { + case int32Type: + if len(o.int32s) == 0 { + o.int32s = make([]int32, uint32PoolSize) + } + o.int32s[0] = int32(x) + p.v.Set(reflect.ValueOf(&o.int32s[0])) + o.int32s = o.int32s[1:] + return + case uint32Type: + if len(o.uint32s) == 0 { + o.uint32s = make([]uint32, uint32PoolSize) + } + o.uint32s[0] = x + p.v.Set(reflect.ValueOf(&o.uint32s[0])) + o.uint32s = o.uint32s[1:] + return + case float32Type: + if len(o.float32s) == 0 { + o.float32s = make([]float32, uint32PoolSize) + } + o.float32s[0] = math.Float32frombits(x) + p.v.Set(reflect.ValueOf(&o.float32s[0])) + o.float32s = o.float32s[1:] + return + } + + // must be enum + p.v.Set(reflect.New(t)) + p.v.Elem().SetInt(int64(int32(x))) +} + +// Get gets the bits pointed at by p, as a uint32. +func word32_Get(p word32) uint32 { + elem := p.v.Elem() + switch elem.Kind() { + case reflect.Int32: + return uint32(elem.Int()) + case reflect.Uint32: + return uint32(elem.Uint()) + case reflect.Float32: + return math.Float32bits(float32(elem.Float())) + } + panic("unreachable") +} + +// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct. +func structPointer_Word32(p structPointer, f field) word32 { + return word32{structPointer_field(p, f)} +} + +// A word32Val represents a field of type int32, uint32, float32, or enum. +// That is, v.Type() is int32, uint32, float32, or enum and v is assignable. +type word32Val struct { + v reflect.Value +} + +// Set sets *p to x. +func word32Val_Set(p word32Val, x uint32) { + switch p.v.Type() { + case int32Type: + p.v.SetInt(int64(x)) + return + case uint32Type: + p.v.SetUint(uint64(x)) + return + case float32Type: + p.v.SetFloat(float64(math.Float32frombits(x))) + return + } + + // must be enum + p.v.SetInt(int64(int32(x))) +} + +// Get gets the bits pointed at by p, as a uint32. +func word32Val_Get(p word32Val) uint32 { + elem := p.v + switch elem.Kind() { + case reflect.Int32: + return uint32(elem.Int()) + case reflect.Uint32: + return uint32(elem.Uint()) + case reflect.Float32: + return math.Float32bits(float32(elem.Float())) + } + panic("unreachable") +} + +// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct. +func structPointer_Word32Val(p structPointer, f field) word32Val { + return word32Val{structPointer_field(p, f)} +} + +// A word32Slice is a slice of 32-bit values. +// That is, v.Type() is []int32, []uint32, []float32, or []enum. +type word32Slice struct { + v reflect.Value +} + +func (p word32Slice) Append(x uint32) { + n, m := p.v.Len(), p.v.Cap() + if n < m { + p.v.SetLen(n + 1) + } else { + t := p.v.Type().Elem() + p.v.Set(reflect.Append(p.v, reflect.Zero(t))) + } + elem := p.v.Index(n) + switch elem.Kind() { + case reflect.Int32: + elem.SetInt(int64(int32(x))) + case reflect.Uint32: + elem.SetUint(uint64(x)) + case reflect.Float32: + elem.SetFloat(float64(math.Float32frombits(x))) + } +} + +func (p word32Slice) Len() int { + return p.v.Len() +} + +func (p word32Slice) Index(i int) uint32 { + elem := p.v.Index(i) + switch elem.Kind() { + case reflect.Int32: + return uint32(elem.Int()) + case reflect.Uint32: + return uint32(elem.Uint()) + case reflect.Float32: + return math.Float32bits(float32(elem.Float())) + } + panic("unreachable") +} + +// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct. +func structPointer_Word32Slice(p structPointer, f field) word32Slice { + return word32Slice{structPointer_field(p, f)} +} + +// word64 is like word32 but for 64-bit values. +type word64 struct { + v reflect.Value +} + +func word64_Set(p word64, o *Buffer, x uint64) { + t := p.v.Type().Elem() + switch t { + case int64Type: + if len(o.int64s) == 0 { + o.int64s = make([]int64, uint64PoolSize) + } + o.int64s[0] = int64(x) + p.v.Set(reflect.ValueOf(&o.int64s[0])) + o.int64s = o.int64s[1:] + return + case uint64Type: + if len(o.uint64s) == 0 { + o.uint64s = make([]uint64, uint64PoolSize) + } + o.uint64s[0] = x + p.v.Set(reflect.ValueOf(&o.uint64s[0])) + o.uint64s = o.uint64s[1:] + return + case float64Type: + if len(o.float64s) == 0 { + o.float64s = make([]float64, uint64PoolSize) + } + o.float64s[0] = math.Float64frombits(x) + p.v.Set(reflect.ValueOf(&o.float64s[0])) + o.float64s = o.float64s[1:] + return + } + panic("unreachable") +} + +func word64_IsNil(p word64) bool { + return p.v.IsNil() +} + +func word64_Get(p word64) uint64 { + elem := p.v.Elem() + switch elem.Kind() { + case reflect.Int64: + return uint64(elem.Int()) + case reflect.Uint64: + return elem.Uint() + case reflect.Float64: + return math.Float64bits(elem.Float()) + } + panic("unreachable") +} + +func structPointer_Word64(p structPointer, f field) word64 { + return word64{structPointer_field(p, f)} +} + +// word64Val is like word32Val but for 64-bit values. +type word64Val struct { + v reflect.Value +} + +func word64Val_Set(p word64Val, o *Buffer, x uint64) { + switch p.v.Type() { + case int64Type: + p.v.SetInt(int64(x)) + return + case uint64Type: + p.v.SetUint(x) + return + case float64Type: + p.v.SetFloat(math.Float64frombits(x)) + return + } + panic("unreachable") +} + +func word64Val_Get(p word64Val) uint64 { + elem := p.v + switch elem.Kind() { + case reflect.Int64: + return uint64(elem.Int()) + case reflect.Uint64: + return elem.Uint() + case reflect.Float64: + return math.Float64bits(elem.Float()) + } + panic("unreachable") +} + +func structPointer_Word64Val(p structPointer, f field) word64Val { + return word64Val{structPointer_field(p, f)} +} + +type word64Slice struct { + v reflect.Value +} + +func (p word64Slice) Append(x uint64) { + n, m := p.v.Len(), p.v.Cap() + if n < m { + p.v.SetLen(n + 1) + } else { + t := p.v.Type().Elem() + p.v.Set(reflect.Append(p.v, reflect.Zero(t))) + } + elem := p.v.Index(n) + switch elem.Kind() { + case reflect.Int64: + elem.SetInt(int64(int64(x))) + case reflect.Uint64: + elem.SetUint(uint64(x)) + case reflect.Float64: + elem.SetFloat(float64(math.Float64frombits(x))) + } +} + +func (p word64Slice) Len() int { + return p.v.Len() +} + +func (p word64Slice) Index(i int) uint64 { + elem := p.v.Index(i) + switch elem.Kind() { + case reflect.Int64: + return uint64(elem.Int()) + case reflect.Uint64: + return uint64(elem.Uint()) + case reflect.Float64: + return math.Float64bits(float64(elem.Float())) + } + panic("unreachable") +} + +func structPointer_Word64Slice(p structPointer, f field) word64Slice { + return word64Slice{structPointer_field(p, f)} +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/pointer_unsafe.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/pointer_unsafe.go new file mode 100644 index 00000000..e9be0fe9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/pointer_unsafe.go @@ -0,0 +1,266 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// +build !appengine + +// This file contains the implementation of the proto field accesses using package unsafe. + +package proto + +import ( + "reflect" + "unsafe" +) + +// NOTE: These type_Foo functions would more idiomatically be methods, +// but Go does not allow methods on pointer types, and we must preserve +// some pointer type for the garbage collector. We use these +// funcs with clunky names as our poor approximation to methods. +// +// An alternative would be +// type structPointer struct { p unsafe.Pointer } +// but that does not registerize as well. + +// A structPointer is a pointer to a struct. +type structPointer unsafe.Pointer + +// toStructPointer returns a structPointer equivalent to the given reflect value. +func toStructPointer(v reflect.Value) structPointer { + return structPointer(unsafe.Pointer(v.Pointer())) +} + +// IsNil reports whether p is nil. +func structPointer_IsNil(p structPointer) bool { + return p == nil +} + +// Interface returns the struct pointer, assumed to have element type t, +// as an interface value. +func structPointer_Interface(p structPointer, t reflect.Type) interface{} { + return reflect.NewAt(t, unsafe.Pointer(p)).Interface() +} + +// A field identifies a field in a struct, accessible from a structPointer. +// In this implementation, a field is identified by its byte offset from the start of the struct. +type field uintptr + +// toField returns a field equivalent to the given reflect field. +func toField(f *reflect.StructField) field { + return field(f.Offset) +} + +// invalidField is an invalid field identifier. +const invalidField = ^field(0) + +// IsValid reports whether the field identifier is valid. +func (f field) IsValid() bool { + return f != ^field(0) +} + +// Bytes returns the address of a []byte field in the struct. +func structPointer_Bytes(p structPointer, f field) *[]byte { + return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// BytesSlice returns the address of a [][]byte field in the struct. +func structPointer_BytesSlice(p structPointer, f field) *[][]byte { + return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// Bool returns the address of a *bool field in the struct. +func structPointer_Bool(p structPointer, f field) **bool { + return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// BoolVal returns the address of a bool field in the struct. +func structPointer_BoolVal(p structPointer, f field) *bool { + return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// BoolSlice returns the address of a []bool field in the struct. +func structPointer_BoolSlice(p structPointer, f field) *[]bool { + return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// String returns the address of a *string field in the struct. +func structPointer_String(p structPointer, f field) **string { + return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// StringVal returns the address of a string field in the struct. +func structPointer_StringVal(p structPointer, f field) *string { + return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// StringSlice returns the address of a []string field in the struct. +func structPointer_StringSlice(p structPointer, f field) *[]string { + return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// ExtMap returns the address of an extension map field in the struct. +func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension { + return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// NewAt returns the reflect.Value for a pointer to a field in the struct. +func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value { + return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) +} + +// SetStructPointer writes a *struct field in the struct. +func structPointer_SetStructPointer(p structPointer, f field, q structPointer) { + *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q +} + +// GetStructPointer reads a *struct field in the struct. +func structPointer_GetStructPointer(p structPointer, f field) structPointer { + return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// StructPointerSlice the address of a []*struct field in the struct. +func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice { + return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups). +type structPointerSlice []structPointer + +func (v *structPointerSlice) Len() int { return len(*v) } +func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] } +func (v *structPointerSlice) Append(p structPointer) { *v = append(*v, p) } + +// A word32 is the address of a "pointer to 32-bit value" field. +type word32 **uint32 + +// IsNil reports whether *v is nil. +func word32_IsNil(p word32) bool { + return *p == nil +} + +// Set sets *v to point at a newly allocated word set to x. +func word32_Set(p word32, o *Buffer, x uint32) { + if len(o.uint32s) == 0 { + o.uint32s = make([]uint32, uint32PoolSize) + } + o.uint32s[0] = x + *p = &o.uint32s[0] + o.uint32s = o.uint32s[1:] +} + +// Get gets the value pointed at by *v. +func word32_Get(p word32) uint32 { + return **p +} + +// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct. +func structPointer_Word32(p structPointer, f field) word32 { + return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// A word32Val is the address of a 32-bit value field. +type word32Val *uint32 + +// Set sets *p to x. +func word32Val_Set(p word32Val, x uint32) { + *p = x +} + +// Get gets the value pointed at by p. +func word32Val_Get(p word32Val) uint32 { + return *p +} + +// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct. +func structPointer_Word32Val(p structPointer, f field) word32Val { + return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// A word32Slice is a slice of 32-bit values. +type word32Slice []uint32 + +func (v *word32Slice) Append(x uint32) { *v = append(*v, x) } +func (v *word32Slice) Len() int { return len(*v) } +func (v *word32Slice) Index(i int) uint32 { return (*v)[i] } + +// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct. +func structPointer_Word32Slice(p structPointer, f field) *word32Slice { + return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} + +// word64 is like word32 but for 64-bit values. +type word64 **uint64 + +func word64_Set(p word64, o *Buffer, x uint64) { + if len(o.uint64s) == 0 { + o.uint64s = make([]uint64, uint64PoolSize) + } + o.uint64s[0] = x + *p = &o.uint64s[0] + o.uint64s = o.uint64s[1:] +} + +func word64_IsNil(p word64) bool { + return *p == nil +} + +func word64_Get(p word64) uint64 { + return **p +} + +func structPointer_Word64(p structPointer, f field) word64 { + return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// word64Val is like word32Val but for 64-bit values. +type word64Val *uint64 + +func word64Val_Set(p word64Val, o *Buffer, x uint64) { + *p = x +} + +func word64Val_Get(p word64Val) uint64 { + return *p +} + +func structPointer_Word64Val(p structPointer, f field) word64Val { + return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f)))) +} + +// word64Slice is like word32Slice but for 64-bit values. +type word64Slice []uint64 + +func (v *word64Slice) Append(x uint64) { *v = append(*v, x) } +func (v *word64Slice) Len() int { return len(*v) } +func (v *word64Slice) Index(i int) uint64 { return (*v)[i] } + +func structPointer_Word64Slice(p structPointer, f field) *word64Slice { + return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f))) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/properties.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/properties.go new file mode 100644 index 00000000..d4531c05 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/properties.go @@ -0,0 +1,842 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +/* + * Routines for encoding data into the wire format for protocol buffers. + */ + +import ( + "fmt" + "log" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" +) + +const debug bool = false + +// Constants that identify the encoding of a value on the wire. +const ( + WireVarint = 0 + WireFixed64 = 1 + WireBytes = 2 + WireStartGroup = 3 + WireEndGroup = 4 + WireFixed32 = 5 +) + +const startSize = 10 // initial slice/string sizes + +// Encoders are defined in encode.go +// An encoder outputs the full representation of a field, including its +// tag and encoder type. +type encoder func(p *Buffer, prop *Properties, base structPointer) error + +// A valueEncoder encodes a single integer in a particular encoding. +type valueEncoder func(o *Buffer, x uint64) error + +// Sizers are defined in encode.go +// A sizer returns the encoded size of a field, including its tag and encoder +// type. +type sizer func(prop *Properties, base structPointer) int + +// A valueSizer returns the encoded size of a single integer in a particular +// encoding. +type valueSizer func(x uint64) int + +// Decoders are defined in decode.go +// A decoder creates a value from its wire representation. +// Unrecognized subelements are saved in unrec. +type decoder func(p *Buffer, prop *Properties, base structPointer) error + +// A valueDecoder decodes a single integer in a particular encoding. +type valueDecoder func(o *Buffer) (x uint64, err error) + +// A oneofMarshaler does the marshaling for all oneof fields in a message. +type oneofMarshaler func(Message, *Buffer) error + +// A oneofUnmarshaler does the unmarshaling for a oneof field in a message. +type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error) + +// A oneofSizer does the sizing for all oneof fields in a message. +type oneofSizer func(Message) int + +// tagMap is an optimization over map[int]int for typical protocol buffer +// use-cases. Encoded protocol buffers are often in tag order with small tag +// numbers. +type tagMap struct { + fastTags []int + slowTags map[int]int +} + +// tagMapFastLimit is the upper bound on the tag number that will be stored in +// the tagMap slice rather than its map. +const tagMapFastLimit = 1024 + +func (p *tagMap) get(t int) (int, bool) { + if t > 0 && t < tagMapFastLimit { + if t >= len(p.fastTags) { + return 0, false + } + fi := p.fastTags[t] + return fi, fi >= 0 + } + fi, ok := p.slowTags[t] + return fi, ok +} + +func (p *tagMap) put(t int, fi int) { + if t > 0 && t < tagMapFastLimit { + for len(p.fastTags) < t+1 { + p.fastTags = append(p.fastTags, -1) + } + p.fastTags[t] = fi + return + } + if p.slowTags == nil { + p.slowTags = make(map[int]int) + } + p.slowTags[t] = fi +} + +// StructProperties represents properties for all the fields of a struct. +// decoderTags and decoderOrigNames should only be used by the decoder. +type StructProperties struct { + Prop []*Properties // properties for each field + reqCount int // required count + decoderTags tagMap // map from proto tag to struct field number + decoderOrigNames map[string]int // map from original name to struct field number + order []int // list of struct field numbers in tag order + unrecField field // field id of the XXX_unrecognized []byte field + extendable bool // is this an extendable proto + + oneofMarshaler oneofMarshaler + oneofUnmarshaler oneofUnmarshaler + oneofSizer oneofSizer + stype reflect.Type + + // OneofTypes contains information about the oneof fields in this message. + // It is keyed by the original name of a field. + OneofTypes map[string]*OneofProperties +} + +// OneofProperties represents information about a specific field in a oneof. +type OneofProperties struct { + Type reflect.Type // pointer to generated struct type for this oneof field + Field int // struct field number of the containing oneof in the message + Prop *Properties +} + +// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. +// See encode.go, (*Buffer).enc_struct. + +func (sp *StructProperties) Len() int { return len(sp.order) } +func (sp *StructProperties) Less(i, j int) bool { + return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag +} +func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } + +// Properties represents the protocol-specific behavior of a single struct field. +type Properties struct { + Name string // name of the field, for error messages + OrigName string // original name before protocol compiler (always set) + Wire string + WireType int + Tag int + Required bool + Optional bool + Repeated bool + Packed bool // relevant for repeated primitives only + Enum string // set for enum types only + proto3 bool // whether this is known to be a proto3 field; set for []byte only + oneof bool // whether this is a oneof field + + Default string // default value + HasDefault bool // whether an explicit default was provided + def_uint64 uint64 + + enc encoder + valEnc valueEncoder // set for bool and numeric types only + field field + tagcode []byte // encoding of EncodeVarint((Tag<<3)|WireType) + tagbuf [8]byte + stype reflect.Type // set for struct types only + sprop *StructProperties // set for struct types only + isMarshaler bool + isUnmarshaler bool + + mtype reflect.Type // set for map types only + mkeyprop *Properties // set for map types only + mvalprop *Properties // set for map types only + + size sizer + valSize valueSizer // set for bool and numeric types only + + dec decoder + valDec valueDecoder // set for bool and numeric types only + + // If this is a packable field, this will be the decoder for the packed version of the field. + packedDec decoder +} + +// String formats the properties in the protobuf struct field tag style. +func (p *Properties) String() string { + s := p.Wire + s = "," + s += strconv.Itoa(p.Tag) + if p.Required { + s += ",req" + } + if p.Optional { + s += ",opt" + } + if p.Repeated { + s += ",rep" + } + if p.Packed { + s += ",packed" + } + if p.OrigName != p.Name { + s += ",name=" + p.OrigName + } + if p.proto3 { + s += ",proto3" + } + if p.oneof { + s += ",oneof" + } + if len(p.Enum) > 0 { + s += ",enum=" + p.Enum + } + if p.HasDefault { + s += ",def=" + p.Default + } + return s +} + +// Parse populates p by parsing a string in the protobuf struct field tag style. +func (p *Properties) Parse(s string) { + // "bytes,49,opt,name=foo,def=hello!" + fields := strings.Split(s, ",") // breaks def=, but handled below. + if len(fields) < 2 { + fmt.Fprintf(os.Stderr, "proto: tag has too few fields: %q\n", s) + return + } + + p.Wire = fields[0] + switch p.Wire { + case "varint": + p.WireType = WireVarint + p.valEnc = (*Buffer).EncodeVarint + p.valDec = (*Buffer).DecodeVarint + p.valSize = sizeVarint + case "fixed32": + p.WireType = WireFixed32 + p.valEnc = (*Buffer).EncodeFixed32 + p.valDec = (*Buffer).DecodeFixed32 + p.valSize = sizeFixed32 + case "fixed64": + p.WireType = WireFixed64 + p.valEnc = (*Buffer).EncodeFixed64 + p.valDec = (*Buffer).DecodeFixed64 + p.valSize = sizeFixed64 + case "zigzag32": + p.WireType = WireVarint + p.valEnc = (*Buffer).EncodeZigzag32 + p.valDec = (*Buffer).DecodeZigzag32 + p.valSize = sizeZigzag32 + case "zigzag64": + p.WireType = WireVarint + p.valEnc = (*Buffer).EncodeZigzag64 + p.valDec = (*Buffer).DecodeZigzag64 + p.valSize = sizeZigzag64 + case "bytes", "group": + p.WireType = WireBytes + // no numeric converter for non-numeric types + default: + fmt.Fprintf(os.Stderr, "proto: tag has unknown wire type: %q\n", s) + return + } + + var err error + p.Tag, err = strconv.Atoi(fields[1]) + if err != nil { + return + } + + for i := 2; i < len(fields); i++ { + f := fields[i] + switch { + case f == "req": + p.Required = true + case f == "opt": + p.Optional = true + case f == "rep": + p.Repeated = true + case f == "packed": + p.Packed = true + case strings.HasPrefix(f, "name="): + p.OrigName = f[5:] + case strings.HasPrefix(f, "enum="): + p.Enum = f[5:] + case f == "proto3": + p.proto3 = true + case f == "oneof": + p.oneof = true + case strings.HasPrefix(f, "def="): + p.HasDefault = true + p.Default = f[4:] // rest of string + if i+1 < len(fields) { + // Commas aren't escaped, and def is always last. + p.Default += "," + strings.Join(fields[i+1:], ",") + break + } + } + } +} + +func logNoSliceEnc(t1, t2 reflect.Type) { + fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2) +} + +var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() + +// Initialize the fields for encoding and decoding. +func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { + p.enc = nil + p.dec = nil + p.size = nil + + switch t1 := typ; t1.Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1) + + // proto3 scalar types + + case reflect.Bool: + p.enc = (*Buffer).enc_proto3_bool + p.dec = (*Buffer).dec_proto3_bool + p.size = size_proto3_bool + case reflect.Int32: + p.enc = (*Buffer).enc_proto3_int32 + p.dec = (*Buffer).dec_proto3_int32 + p.size = size_proto3_int32 + case reflect.Uint32: + p.enc = (*Buffer).enc_proto3_uint32 + p.dec = (*Buffer).dec_proto3_int32 // can reuse + p.size = size_proto3_uint32 + case reflect.Int64, reflect.Uint64: + p.enc = (*Buffer).enc_proto3_int64 + p.dec = (*Buffer).dec_proto3_int64 + p.size = size_proto3_int64 + case reflect.Float32: + p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits + p.dec = (*Buffer).dec_proto3_int32 + p.size = size_proto3_uint32 + case reflect.Float64: + p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits + p.dec = (*Buffer).dec_proto3_int64 + p.size = size_proto3_int64 + case reflect.String: + p.enc = (*Buffer).enc_proto3_string + p.dec = (*Buffer).dec_proto3_string + p.size = size_proto3_string + + case reflect.Ptr: + switch t2 := t1.Elem(); t2.Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2) + break + case reflect.Bool: + p.enc = (*Buffer).enc_bool + p.dec = (*Buffer).dec_bool + p.size = size_bool + case reflect.Int32: + p.enc = (*Buffer).enc_int32 + p.dec = (*Buffer).dec_int32 + p.size = size_int32 + case reflect.Uint32: + p.enc = (*Buffer).enc_uint32 + p.dec = (*Buffer).dec_int32 // can reuse + p.size = size_uint32 + case reflect.Int64, reflect.Uint64: + p.enc = (*Buffer).enc_int64 + p.dec = (*Buffer).dec_int64 + p.size = size_int64 + case reflect.Float32: + p.enc = (*Buffer).enc_uint32 // can just treat them as bits + p.dec = (*Buffer).dec_int32 + p.size = size_uint32 + case reflect.Float64: + p.enc = (*Buffer).enc_int64 // can just treat them as bits + p.dec = (*Buffer).dec_int64 + p.size = size_int64 + case reflect.String: + p.enc = (*Buffer).enc_string + p.dec = (*Buffer).dec_string + p.size = size_string + case reflect.Struct: + p.stype = t1.Elem() + p.isMarshaler = isMarshaler(t1) + p.isUnmarshaler = isUnmarshaler(t1) + if p.Wire == "bytes" { + p.enc = (*Buffer).enc_struct_message + p.dec = (*Buffer).dec_struct_message + p.size = size_struct_message + } else { + p.enc = (*Buffer).enc_struct_group + p.dec = (*Buffer).dec_struct_group + p.size = size_struct_group + } + } + + case reflect.Slice: + switch t2 := t1.Elem(); t2.Kind() { + default: + logNoSliceEnc(t1, t2) + break + case reflect.Bool: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_bool + p.size = size_slice_packed_bool + } else { + p.enc = (*Buffer).enc_slice_bool + p.size = size_slice_bool + } + p.dec = (*Buffer).dec_slice_bool + p.packedDec = (*Buffer).dec_slice_packed_bool + case reflect.Int32: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int32 + p.size = size_slice_packed_int32 + } else { + p.enc = (*Buffer).enc_slice_int32 + p.size = size_slice_int32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case reflect.Uint32: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_uint32 + p.size = size_slice_packed_uint32 + } else { + p.enc = (*Buffer).enc_slice_uint32 + p.size = size_slice_uint32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case reflect.Int64, reflect.Uint64: + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int64 + p.size = size_slice_packed_int64 + } else { + p.enc = (*Buffer).enc_slice_int64 + p.size = size_slice_int64 + } + p.dec = (*Buffer).dec_slice_int64 + p.packedDec = (*Buffer).dec_slice_packed_int64 + case reflect.Uint8: + p.enc = (*Buffer).enc_slice_byte + p.dec = (*Buffer).dec_slice_byte + p.size = size_slice_byte + // This is a []byte, which is either a bytes field, + // or the value of a map field. In the latter case, + // we always encode an empty []byte, so we should not + // use the proto3 enc/size funcs. + // f == nil iff this is the key/value of a map field. + if p.proto3 && f != nil { + p.enc = (*Buffer).enc_proto3_slice_byte + p.size = size_proto3_slice_byte + } + case reflect.Float32, reflect.Float64: + switch t2.Bits() { + case 32: + // can just treat them as bits + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_uint32 + p.size = size_slice_packed_uint32 + } else { + p.enc = (*Buffer).enc_slice_uint32 + p.size = size_slice_uint32 + } + p.dec = (*Buffer).dec_slice_int32 + p.packedDec = (*Buffer).dec_slice_packed_int32 + case 64: + // can just treat them as bits + if p.Packed { + p.enc = (*Buffer).enc_slice_packed_int64 + p.size = size_slice_packed_int64 + } else { + p.enc = (*Buffer).enc_slice_int64 + p.size = size_slice_int64 + } + p.dec = (*Buffer).dec_slice_int64 + p.packedDec = (*Buffer).dec_slice_packed_int64 + default: + logNoSliceEnc(t1, t2) + break + } + case reflect.String: + p.enc = (*Buffer).enc_slice_string + p.dec = (*Buffer).dec_slice_string + p.size = size_slice_string + case reflect.Ptr: + switch t3 := t2.Elem(); t3.Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3) + break + case reflect.Struct: + p.stype = t2.Elem() + p.isMarshaler = isMarshaler(t2) + p.isUnmarshaler = isUnmarshaler(t2) + if p.Wire == "bytes" { + p.enc = (*Buffer).enc_slice_struct_message + p.dec = (*Buffer).dec_slice_struct_message + p.size = size_slice_struct_message + } else { + p.enc = (*Buffer).enc_slice_struct_group + p.dec = (*Buffer).dec_slice_struct_group + p.size = size_slice_struct_group + } + } + case reflect.Slice: + switch t2.Elem().Kind() { + default: + fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem()) + break + case reflect.Uint8: + p.enc = (*Buffer).enc_slice_slice_byte + p.dec = (*Buffer).dec_slice_slice_byte + p.size = size_slice_slice_byte + } + } + + case reflect.Map: + p.enc = (*Buffer).enc_new_map + p.dec = (*Buffer).dec_new_map + p.size = size_new_map + + p.mtype = t1 + p.mkeyprop = &Properties{} + p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) + p.mvalprop = &Properties{} + vtype := p.mtype.Elem() + if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { + // The value type is not a message (*T) or bytes ([]byte), + // so we need encoders for the pointer to this type. + vtype = reflect.PtrTo(vtype) + } + p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) + } + + // precalculate tag code + wire := p.WireType + if p.Packed { + wire = WireBytes + } + x := uint32(p.Tag)<<3 | uint32(wire) + i := 0 + for i = 0; x > 127; i++ { + p.tagbuf[i] = 0x80 | uint8(x&0x7F) + x >>= 7 + } + p.tagbuf[i] = uint8(x) + p.tagcode = p.tagbuf[0 : i+1] + + if p.stype != nil { + if lockGetProp { + p.sprop = GetProperties(p.stype) + } else { + p.sprop = getPropertiesLocked(p.stype) + } + } +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() + unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() +) + +// isMarshaler reports whether type t implements Marshaler. +func isMarshaler(t reflect.Type) bool { + // We're checking for (likely) pointer-receiver methods + // so if t is not a pointer, something is very wrong. + // The calls above only invoke isMarshaler on pointer types. + if t.Kind() != reflect.Ptr { + panic("proto: misuse of isMarshaler") + } + return t.Implements(marshalerType) +} + +// isUnmarshaler reports whether type t implements Unmarshaler. +func isUnmarshaler(t reflect.Type) bool { + // We're checking for (likely) pointer-receiver methods + // so if t is not a pointer, something is very wrong. + // The calls above only invoke isUnmarshaler on pointer types. + if t.Kind() != reflect.Ptr { + panic("proto: misuse of isUnmarshaler") + } + return t.Implements(unmarshalerType) +} + +// Init populates the properties from a protocol buffer struct tag. +func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { + p.init(typ, name, tag, f, true) +} + +func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { + // "bytes,49,opt,def=hello!" + p.Name = name + p.OrigName = name + if f != nil { + p.field = toField(f) + } + if tag == "" { + return + } + p.Parse(tag) + p.setEncAndDec(typ, f, lockGetProp) +} + +var ( + propertiesMu sync.RWMutex + propertiesMap = make(map[reflect.Type]*StructProperties) +) + +// GetProperties returns the list of properties for the type represented by t. +// t must represent a generated struct type of a protocol message. +func GetProperties(t reflect.Type) *StructProperties { + if t.Kind() != reflect.Struct { + panic("proto: type must have kind struct") + } + + // Most calls to GetProperties in a long-running program will be + // retrieving details for types we have seen before. + propertiesMu.RLock() + sprop, ok := propertiesMap[t] + propertiesMu.RUnlock() + if ok { + if collectStats { + stats.Chit++ + } + return sprop + } + + propertiesMu.Lock() + sprop = getPropertiesLocked(t) + propertiesMu.Unlock() + return sprop +} + +// getPropertiesLocked requires that propertiesMu is held. +func getPropertiesLocked(t reflect.Type) *StructProperties { + if prop, ok := propertiesMap[t]; ok { + if collectStats { + stats.Chit++ + } + return prop + } + if collectStats { + stats.Cmiss++ + } + + prop := new(StructProperties) + // in case of recursive protos, fill this in now. + propertiesMap[t] = prop + + // build properties + prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) + prop.unrecField = invalidField + prop.Prop = make([]*Properties, t.NumField()) + prop.order = make([]int, t.NumField()) + + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + p := new(Properties) + name := f.Name + p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) + + if f.Name == "XXX_extensions" { // special case + p.enc = (*Buffer).enc_map + p.dec = nil // not needed + p.size = size_map + } + if f.Name == "XXX_unrecognized" { // special case + prop.unrecField = toField(&f) + } + oneof := f.Tag.Get("protobuf_oneof") != "" // special case + prop.Prop[i] = p + prop.order[i] = i + if debug { + print(i, " ", f.Name, " ", t.String(), " ") + if p.Tag > 0 { + print(p.String()) + } + print("\n") + } + if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof { + fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]") + } + } + + // Re-order prop.order. + sort.Sort(prop) + + type oneofMessage interface { + XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) + } + if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok { + var oots []interface{} + prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs() + prop.stype = t + + // Interpret oneof metadata. + prop.OneofTypes = make(map[string]*OneofProperties) + for _, oot := range oots { + oop := &OneofProperties{ + Type: reflect.ValueOf(oot).Type(), // *T + Prop: new(Properties), + } + sft := oop.Type.Elem().Field(0) + oop.Prop.Name = sft.Name + oop.Prop.Parse(sft.Tag.Get("protobuf")) + // There will be exactly one interface field that + // this new value is assignable to. + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Type.Kind() != reflect.Interface { + continue + } + if !oop.Type.AssignableTo(f.Type) { + continue + } + oop.Field = i + break + } + prop.OneofTypes[oop.Prop.OrigName] = oop + } + } + + // build required counts + // build tags + reqCount := 0 + prop.decoderOrigNames = make(map[string]int) + for i, p := range prop.Prop { + if strings.HasPrefix(p.Name, "XXX_") { + // Internal fields should not appear in tags/origNames maps. + // They are handled specially when encoding and decoding. + continue + } + if p.Required { + reqCount++ + } + prop.decoderTags.put(p.Tag, i) + prop.decoderOrigNames[p.OrigName] = i + } + prop.reqCount = reqCount + + return prop +} + +// Return the Properties object for the x[0]'th field of the structure. +func propByIndex(t reflect.Type, x []int) *Properties { + if len(x) != 1 { + fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t) + return nil + } + prop := GetProperties(t) + return prop.Prop[x[0]] +} + +// Get the address and type of a pointer to a struct from an interface. +func getbase(pb Message) (t reflect.Type, b structPointer, err error) { + if pb == nil { + err = ErrNil + return + } + // get the reflect type of the pointer to the struct. + t = reflect.TypeOf(pb) + // get the address of the struct. + value := reflect.ValueOf(pb) + b = toStructPointer(value) + return +} + +// A global registry of enum types. +// The generated code will register the generated maps by calling RegisterEnum. + +var enumValueMaps = make(map[string]map[string]int32) + +// RegisterEnum is called from the generated code to install the enum descriptor +// maps into the global table to aid parsing text format protocol buffers. +func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { + if _, ok := enumValueMaps[typeName]; ok { + panic("proto: duplicate enum registered: " + typeName) + } + enumValueMaps[typeName] = valueMap +} + +// EnumValueMap returns the mapping from names to integers of the +// enum type enumType, or a nil if not found. +func EnumValueMap(enumType string) map[string]int32 { + return enumValueMaps[enumType] +} + +// A registry of all linked message types. +// The string is a fully-qualified proto name ("pkg.Message"). +var ( + protoTypes = make(map[string]reflect.Type) + revProtoTypes = make(map[reflect.Type]string) +) + +// RegisterType is called from generated code and maps from the fully qualified +// proto name to the type (pointer to struct) of the protocol buffer. +func RegisterType(x Message, name string) { + if _, ok := protoTypes[name]; ok { + // TODO: Some day, make this a panic. + log.Printf("proto: duplicate proto type registered: %s", name) + return + } + t := reflect.TypeOf(x) + protoTypes[name] = t + revProtoTypes[t] = name +} + +// MessageName returns the fully-qualified proto name for the given message type. +func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] } + +// MessageType returns the message type (pointer to struct) for a named message. +func MessageType(name string) reflect.Type { return protoTypes[name] } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go new file mode 100644 index 00000000..37c77820 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go @@ -0,0 +1,122 @@ +// Code generated by protoc-gen-go. +// source: proto3_proto/proto3.proto +// DO NOT EDIT! + +/* +Package proto3_proto is a generated protocol buffer package. + +It is generated from these files: + proto3_proto/proto3.proto + +It has these top-level messages: + Message + Nested + MessageWithMap +*/ +package proto3_proto + +import proto "github.com/golang/protobuf/proto" +import testdata "github.com/golang/protobuf/proto/testdata" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal + +type Message_Humour int32 + +const ( + Message_UNKNOWN Message_Humour = 0 + Message_PUNS Message_Humour = 1 + Message_SLAPSTICK Message_Humour = 2 + Message_BILL_BAILEY Message_Humour = 3 +) + +var Message_Humour_name = map[int32]string{ + 0: "UNKNOWN", + 1: "PUNS", + 2: "SLAPSTICK", + 3: "BILL_BAILEY", +} +var Message_Humour_value = map[string]int32{ + "UNKNOWN": 0, + "PUNS": 1, + "SLAPSTICK": 2, + "BILL_BAILEY": 3, +} + +func (x Message_Humour) String() string { + return proto.EnumName(Message_Humour_name, int32(x)) +} + +type Message struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Hilarity Message_Humour `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"` + HeightInCm uint32 `protobuf:"varint,3,opt,name=height_in_cm" json:"height_in_cm,omitempty"` + Data []byte `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + ResultCount int64 `protobuf:"varint,7,opt,name=result_count" json:"result_count,omitempty"` + TrueScotsman bool `protobuf:"varint,8,opt,name=true_scotsman" json:"true_scotsman,omitempty"` + Score float32 `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"` + Key []uint64 `protobuf:"varint,5,rep,name=key" json:"key,omitempty"` + Nested *Nested `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"` + Terrain map[string]*Nested `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Proto2Field *testdata.SubDefaults `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"` + Proto2Value map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` +} + +func (m *Message) Reset() { *m = Message{} } +func (m *Message) String() string { return proto.CompactTextString(m) } +func (*Message) ProtoMessage() {} + +func (m *Message) GetNested() *Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *Message) GetTerrain() map[string]*Nested { + if m != nil { + return m.Terrain + } + return nil +} + +func (m *Message) GetProto2Field() *testdata.SubDefaults { + if m != nil { + return m.Proto2Field + } + return nil +} + +func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults { + if m != nil { + return m.Proto2Value + } + return nil +} + +type Nested struct { + Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"` +} + +func (m *Nested) Reset() { *m = Nested{} } +func (m *Nested) String() string { return proto.CompactTextString(m) } +func (*Nested) ProtoMessage() {} + +type MessageWithMap struct { + ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func init() { + proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto new file mode 100644 index 00000000..e2311d92 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto @@ -0,0 +1,68 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto3"; + +import "testdata/test.proto"; + +package proto3_proto; + +message Message { + enum Humour { + UNKNOWN = 0; + PUNS = 1; + SLAPSTICK = 2; + BILL_BAILEY = 3; + } + + string name = 1; + Humour hilarity = 2; + uint32 height_in_cm = 3; + bytes data = 4; + int64 result_count = 7; + bool true_scotsman = 8; + float score = 9; + + repeated uint64 key = 5; + Nested nested = 6; + + map terrain = 10; + testdata.SubDefaults proto2_field = 11; + map proto2_value = 13; +} + +message Nested { + string bunny = 1; +} + +message MessageWithMap { + map byte_mapping = 1; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_test.go new file mode 100644 index 00000000..462f8055 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/proto3_test.go @@ -0,0 +1,125 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "testing" + + "github.com/golang/protobuf/proto" + pb "github.com/golang/protobuf/proto/proto3_proto" + tpb "github.com/golang/protobuf/proto/testdata" +) + +func TestProto3ZeroValues(t *testing.T) { + tests := []struct { + desc string + m proto.Message + }{ + {"zero message", &pb.Message{}}, + {"empty bytes field", &pb.Message{Data: []byte{}}}, + } + for _, test := range tests { + b, err := proto.Marshal(test.m) + if err != nil { + t.Errorf("%s: proto.Marshal: %v", test.desc, err) + continue + } + if len(b) > 0 { + t.Errorf("%s: Encoding is non-empty: %q", test.desc, b) + } + } +} + +func TestRoundTripProto3(t *testing.T) { + m := &pb.Message{ + Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" + Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01 + HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 + Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" + ResultCount: 47, // (0 | 7<<3): 0x38 0x2f + TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 + Score: 8.1, // (5 | 9<<3): 0x4d <8.1> + + Key: []uint64{1, 0xdeadbeef}, + Nested: &pb.Nested{ + Bunny: "Monty", + }, + } + t.Logf(" m: %v", m) + + b, err := proto.Marshal(m) + if err != nil { + t.Fatalf("proto.Marshal: %v", err) + } + t.Logf(" b: %q", b) + + m2 := new(pb.Message) + if err := proto.Unmarshal(b, m2); err != nil { + t.Fatalf("proto.Unmarshal: %v", err) + } + t.Logf("m2: %v", m2) + + if !proto.Equal(m, m2) { + t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) + } +} + +func TestProto3SetDefaults(t *testing.T) { + in := &pb.Message{ + Terrain: map[string]*pb.Nested{ + "meadow": new(pb.Nested), + }, + Proto2Field: new(tpb.SubDefaults), + Proto2Value: map[string]*tpb.SubDefaults{ + "badlands": new(tpb.SubDefaults), + }, + } + + got := proto.Clone(in).(*pb.Message) + proto.SetDefaults(got) + + // There are no defaults in proto3. Everything should be the zero value, but + // we need to remember to set defaults for nested proto2 messages. + want := &pb.Message{ + Terrain: map[string]*pb.Nested{ + "meadow": new(pb.Nested), + }, + Proto2Field: &tpb.SubDefaults{N: proto.Int64(7)}, + Proto2Value: map[string]*tpb.SubDefaults{ + "badlands": &tpb.SubDefaults{N: proto.Int64(7)}, + }, + } + + if !proto.Equal(got, want) { + t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/size2_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/size2_test.go new file mode 100644 index 00000000..a2729c39 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/size2_test.go @@ -0,0 +1,63 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +import ( + "testing" +) + +// This is a separate file and package from size_test.go because that one uses +// generated messages and thus may not be in package proto without having a circular +// dependency, whereas this file tests unexported details of size.go. + +func TestVarintSize(t *testing.T) { + // Check the edge cases carefully. + testCases := []struct { + n uint64 + size int + }{ + {0, 1}, + {1, 1}, + {127, 1}, + {128, 2}, + {16383, 2}, + {16384, 3}, + {1<<63 - 1, 9}, + {1 << 63, 10}, + } + for _, tc := range testCases { + size := sizeVarint(tc.n) + if size != tc.size { + t.Errorf("sizeVarint(%d) = %d, want %d", tc.n, size, tc.size) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/size_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/size_test.go new file mode 100644 index 00000000..af1034dc --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/size_test.go @@ -0,0 +1,164 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "log" + "strings" + "testing" + + . "github.com/golang/protobuf/proto" + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + pb "github.com/golang/protobuf/proto/testdata" +) + +var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)} + +// messageWithExtension2 is in equal_test.go. +var messageWithExtension3 = &pb.MyMessage{Count: Int32(8)} + +func init() { + if err := SetExtension(messageWithExtension1, pb.E_Ext_More, &pb.Ext{Data: String("Abbott")}); err != nil { + log.Panicf("SetExtension: %v", err) + } + if err := SetExtension(messageWithExtension3, pb.E_Ext_More, &pb.Ext{Data: String("Costello")}); err != nil { + log.Panicf("SetExtension: %v", err) + } + + // Force messageWithExtension3 to have the extension encoded. + Marshal(messageWithExtension3) + +} + +var SizeTests = []struct { + desc string + pb Message +}{ + {"empty", &pb.OtherMessage{}}, + // Basic types. + {"bool", &pb.Defaults{F_Bool: Bool(true)}}, + {"int32", &pb.Defaults{F_Int32: Int32(12)}}, + {"negative int32", &pb.Defaults{F_Int32: Int32(-1)}}, + {"small int64", &pb.Defaults{F_Int64: Int64(1)}}, + {"big int64", &pb.Defaults{F_Int64: Int64(1 << 20)}}, + {"negative int64", &pb.Defaults{F_Int64: Int64(-1)}}, + {"fixed32", &pb.Defaults{F_Fixed32: Uint32(71)}}, + {"fixed64", &pb.Defaults{F_Fixed64: Uint64(72)}}, + {"uint32", &pb.Defaults{F_Uint32: Uint32(123)}}, + {"uint64", &pb.Defaults{F_Uint64: Uint64(124)}}, + {"float", &pb.Defaults{F_Float: Float32(12.6)}}, + {"double", &pb.Defaults{F_Double: Float64(13.9)}}, + {"string", &pb.Defaults{F_String: String("niles")}}, + {"bytes", &pb.Defaults{F_Bytes: []byte("wowsa")}}, + {"bytes, empty", &pb.Defaults{F_Bytes: []byte{}}}, + {"sint32", &pb.Defaults{F_Sint32: Int32(65)}}, + {"sint64", &pb.Defaults{F_Sint64: Int64(67)}}, + {"enum", &pb.Defaults{F_Enum: pb.Defaults_BLUE.Enum()}}, + // Repeated. + {"empty repeated bool", &pb.MoreRepeated{Bools: []bool{}}}, + {"repeated bool", &pb.MoreRepeated{Bools: []bool{false, true, true, false}}}, + {"packed repeated bool", &pb.MoreRepeated{BoolsPacked: []bool{false, true, true, false, true, true, true}}}, + {"repeated int32", &pb.MoreRepeated{Ints: []int32{1, 12203, 1729, -1}}}, + {"repeated int32 packed", &pb.MoreRepeated{IntsPacked: []int32{1, 12203, 1729}}}, + {"repeated int64 packed", &pb.MoreRepeated{Int64SPacked: []int64{ + // Need enough large numbers to verify that the header is counting the number of bytes + // for the field, not the number of elements. + 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, + 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, 1 << 62, + }}}, + {"repeated string", &pb.MoreRepeated{Strings: []string{"r", "ken", "gri"}}}, + {"repeated fixed", &pb.MoreRepeated{Fixeds: []uint32{1, 2, 3, 4}}}, + // Nested. + {"nested", &pb.OldMessage{Nested: &pb.OldMessage_Nested{Name: String("whatever")}}}, + {"group", &pb.GroupOld{G: &pb.GroupOld_G{X: Int32(12345)}}}, + // Other things. + {"unrecognized", &pb.MoreRepeated{XXX_unrecognized: []byte{13<<3 | 0, 4}}}, + {"extension (unencoded)", messageWithExtension1}, + {"extension (encoded)", messageWithExtension3}, + // proto3 message + {"proto3 empty", &proto3pb.Message{}}, + {"proto3 bool", &proto3pb.Message{TrueScotsman: true}}, + {"proto3 int64", &proto3pb.Message{ResultCount: 1}}, + {"proto3 uint32", &proto3pb.Message{HeightInCm: 123}}, + {"proto3 float", &proto3pb.Message{Score: 12.6}}, + {"proto3 string", &proto3pb.Message{Name: "Snezana"}}, + {"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}}, + {"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}}, + {"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}}, + {"proto3 map field with empty bytes", &proto3pb.MessageWithMap{ByteMapping: map[bool][]byte{false: []byte{}}}}, + + {"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}}, + {"map field with message", &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{0x7001: &pb.FloatingPoint{F: Float64(2.0)}}}}, + {"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}}, + {"map field with empty bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte{}}}}, + + {"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}}, + {"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}}, + {"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}}, + + {"oneof not set", &pb.Oneof{}}, + {"oneof bool", &pb.Oneof{Union: &pb.Oneof_F_Bool{true}}}, + {"oneof zero int32", &pb.Oneof{Union: &pb.Oneof_F_Int32{0}}}, + {"oneof big int32", &pb.Oneof{Union: &pb.Oneof_F_Int32{1 << 20}}}, + {"oneof int64", &pb.Oneof{Union: &pb.Oneof_F_Int64{42}}}, + {"oneof fixed32", &pb.Oneof{Union: &pb.Oneof_F_Fixed32{43}}}, + {"oneof fixed64", &pb.Oneof{Union: &pb.Oneof_F_Fixed64{44}}}, + {"oneof uint32", &pb.Oneof{Union: &pb.Oneof_F_Uint32{45}}}, + {"oneof uint64", &pb.Oneof{Union: &pb.Oneof_F_Uint64{46}}}, + {"oneof float", &pb.Oneof{Union: &pb.Oneof_F_Float{47.1}}}, + {"oneof double", &pb.Oneof{Union: &pb.Oneof_F_Double{48.9}}}, + {"oneof string", &pb.Oneof{Union: &pb.Oneof_F_String{"Rhythmic Fman"}}}, + {"oneof bytes", &pb.Oneof{Union: &pb.Oneof_F_Bytes{[]byte("let go")}}}, + {"oneof sint32", &pb.Oneof{Union: &pb.Oneof_F_Sint32{50}}}, + {"oneof sint64", &pb.Oneof{Union: &pb.Oneof_F_Sint64{51}}}, + {"oneof enum", &pb.Oneof{Union: &pb.Oneof_F_Enum{pb.MyMessage_BLUE}}}, + {"message for oneof", &pb.GoTestField{Label: String("k"), Type: String("v")}}, + {"oneof message", &pb.Oneof{Union: &pb.Oneof_F_Message{&pb.GoTestField{Label: String("k"), Type: String("v")}}}}, + {"oneof group", &pb.Oneof{Union: &pb.Oneof_FGroup{&pb.Oneof_F_Group{X: Int32(52)}}}}, + {"oneof largest tag", &pb.Oneof{Union: &pb.Oneof_F_Largest_Tag{1}}}, + {"multiple oneofs", &pb.Oneof{Union: &pb.Oneof_F_Int32{1}, Tormato: &pb.Oneof_Value{2}}}, +} + +func TestSize(t *testing.T) { + for _, tc := range SizeTests { + size := Size(tc.pb) + b, err := Marshal(tc.pb) + if err != nil { + t.Errorf("%v: Marshal failed: %v", tc.desc, err) + continue + } + if size != len(b) { + t.Errorf("%v: Size(%v) = %d, want %d", tc.desc, tc.pb, size, len(b)) + t.Logf("%v: bytes: %#v", tc.desc, b) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/Makefile new file mode 100644 index 00000000..fc288628 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/Makefile @@ -0,0 +1,50 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + + +include ../../Make.protobuf + +all: regenerate + +regenerate: + rm -f test.pb.go + make test.pb.go + +# The following rules are just aids to development. Not needed for typical testing. + +diff: regenerate + git diff test.pb.go + +restore: + cp test.pb.go.golden test.pb.go + +preserve: + cp test.pb.go test.pb.go.golden diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/golden_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/golden_test.go new file mode 100644 index 00000000..7172d0e9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/golden_test.go @@ -0,0 +1,86 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// Verify that the compiler output for test.proto is unchanged. + +package testdata + +import ( + "crypto/sha1" + "fmt" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "testing" +) + +// sum returns in string form (for easy comparison) the SHA-1 hash of the named file. +func sum(t *testing.T, name string) string { + data, err := ioutil.ReadFile(name) + if err != nil { + t.Fatal(err) + } + t.Logf("sum(%q): length is %d", name, len(data)) + hash := sha1.New() + _, err = hash.Write(data) + if err != nil { + t.Fatal(err) + } + return fmt.Sprintf("% x", hash.Sum(nil)) +} + +func run(t *testing.T, name string, args ...string) { + cmd := exec.Command(name, args...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + err := cmd.Run() + if err != nil { + t.Fatal(err) + } +} + +func TestGolden(t *testing.T) { + // Compute the original checksum. + goldenSum := sum(t, "test.pb.go") + // Run the proto compiler. + run(t, "protoc", "--go_out="+os.TempDir(), "test.proto") + newFile := filepath.Join(os.TempDir(), "test.pb.go") + defer os.Remove(newFile) + // Compute the new checksum. + newSum := sum(t, newFile) + // Verify + if newSum != goldenSum { + run(t, "diff", "-u", "test.pb.go", newFile) + t.Fatal("Code generated by protoc-gen-go has changed; update test.pb.go") + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/test.pb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/test.pb.go new file mode 100644 index 00000000..e3c83fc1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/test.pb.go @@ -0,0 +1,3926 @@ +// Code generated by protoc-gen-go. +// source: test.proto +// DO NOT EDIT! + +/* +Package testdata is a generated protocol buffer package. + +It is generated from these files: + test.proto + +It has these top-level messages: + GoEnum + GoTestField + GoTest + GoSkipTest + NonPackedTest + PackedTest + MaxTag + OldMessage + NewMessage + InnerMessage + OtherMessage + MyMessage + Ext + ComplexExtension + DefaultsMessage + MyMessageSet + Empty + MessageList + Strings + Defaults + SubDefaults + RepeatedEnum + MoreRepeated + GroupOld + GroupNew + FloatingPoint + MessageWithMap + Oneof + Communique +*/ +package testdata + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +const _ = proto.ProtoPackageIsVersion1 + +type FOO int32 + +const ( + FOO_FOO1 FOO = 1 +) + +var FOO_name = map[int32]string{ + 1: "FOO1", +} +var FOO_value = map[string]int32{ + "FOO1": 1, +} + +func (x FOO) Enum() *FOO { + p := new(FOO) + *p = x + return p +} +func (x FOO) String() string { + return proto.EnumName(FOO_name, int32(x)) +} +func (x *FOO) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FOO_value, data, "FOO") + if err != nil { + return err + } + *x = FOO(value) + return nil +} +func (FOO) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +// An enum, for completeness. +type GoTest_KIND int32 + +const ( + GoTest_VOID GoTest_KIND = 0 + // Basic types + GoTest_BOOL GoTest_KIND = 1 + GoTest_BYTES GoTest_KIND = 2 + GoTest_FINGERPRINT GoTest_KIND = 3 + GoTest_FLOAT GoTest_KIND = 4 + GoTest_INT GoTest_KIND = 5 + GoTest_STRING GoTest_KIND = 6 + GoTest_TIME GoTest_KIND = 7 + // Groupings + GoTest_TUPLE GoTest_KIND = 8 + GoTest_ARRAY GoTest_KIND = 9 + GoTest_MAP GoTest_KIND = 10 + // Table types + GoTest_TABLE GoTest_KIND = 11 + // Functions + GoTest_FUNCTION GoTest_KIND = 12 +) + +var GoTest_KIND_name = map[int32]string{ + 0: "VOID", + 1: "BOOL", + 2: "BYTES", + 3: "FINGERPRINT", + 4: "FLOAT", + 5: "INT", + 6: "STRING", + 7: "TIME", + 8: "TUPLE", + 9: "ARRAY", + 10: "MAP", + 11: "TABLE", + 12: "FUNCTION", +} +var GoTest_KIND_value = map[string]int32{ + "VOID": 0, + "BOOL": 1, + "BYTES": 2, + "FINGERPRINT": 3, + "FLOAT": 4, + "INT": 5, + "STRING": 6, + "TIME": 7, + "TUPLE": 8, + "ARRAY": 9, + "MAP": 10, + "TABLE": 11, + "FUNCTION": 12, +} + +func (x GoTest_KIND) Enum() *GoTest_KIND { + p := new(GoTest_KIND) + *p = x + return p +} +func (x GoTest_KIND) String() string { + return proto.EnumName(GoTest_KIND_name, int32(x)) +} +func (x *GoTest_KIND) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(GoTest_KIND_value, data, "GoTest_KIND") + if err != nil { + return err + } + *x = GoTest_KIND(value) + return nil +} +func (GoTest_KIND) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2, 0} } + +type MyMessage_Color int32 + +const ( + MyMessage_RED MyMessage_Color = 0 + MyMessage_GREEN MyMessage_Color = 1 + MyMessage_BLUE MyMessage_Color = 2 +) + +var MyMessage_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var MyMessage_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x MyMessage_Color) Enum() *MyMessage_Color { + p := new(MyMessage_Color) + *p = x + return p +} +func (x MyMessage_Color) String() string { + return proto.EnumName(MyMessage_Color_name, int32(x)) +} +func (x *MyMessage_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(MyMessage_Color_value, data, "MyMessage_Color") + if err != nil { + return err + } + *x = MyMessage_Color(value) + return nil +} +func (MyMessage_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} } + +type DefaultsMessage_DefaultsEnum int32 + +const ( + DefaultsMessage_ZERO DefaultsMessage_DefaultsEnum = 0 + DefaultsMessage_ONE DefaultsMessage_DefaultsEnum = 1 + DefaultsMessage_TWO DefaultsMessage_DefaultsEnum = 2 +) + +var DefaultsMessage_DefaultsEnum_name = map[int32]string{ + 0: "ZERO", + 1: "ONE", + 2: "TWO", +} +var DefaultsMessage_DefaultsEnum_value = map[string]int32{ + "ZERO": 0, + "ONE": 1, + "TWO": 2, +} + +func (x DefaultsMessage_DefaultsEnum) Enum() *DefaultsMessage_DefaultsEnum { + p := new(DefaultsMessage_DefaultsEnum) + *p = x + return p +} +func (x DefaultsMessage_DefaultsEnum) String() string { + return proto.EnumName(DefaultsMessage_DefaultsEnum_name, int32(x)) +} +func (x *DefaultsMessage_DefaultsEnum) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(DefaultsMessage_DefaultsEnum_value, data, "DefaultsMessage_DefaultsEnum") + if err != nil { + return err + } + *x = DefaultsMessage_DefaultsEnum(value) + return nil +} +func (DefaultsMessage_DefaultsEnum) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{14, 0} +} + +type Defaults_Color int32 + +const ( + Defaults_RED Defaults_Color = 0 + Defaults_GREEN Defaults_Color = 1 + Defaults_BLUE Defaults_Color = 2 +) + +var Defaults_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var Defaults_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Defaults_Color) Enum() *Defaults_Color { + p := new(Defaults_Color) + *p = x + return p +} +func (x Defaults_Color) String() string { + return proto.EnumName(Defaults_Color_name, int32(x)) +} +func (x *Defaults_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Defaults_Color_value, data, "Defaults_Color") + if err != nil { + return err + } + *x = Defaults_Color(value) + return nil +} +func (Defaults_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{19, 0} } + +type RepeatedEnum_Color int32 + +const ( + RepeatedEnum_RED RepeatedEnum_Color = 1 +) + +var RepeatedEnum_Color_name = map[int32]string{ + 1: "RED", +} +var RepeatedEnum_Color_value = map[string]int32{ + "RED": 1, +} + +func (x RepeatedEnum_Color) Enum() *RepeatedEnum_Color { + p := new(RepeatedEnum_Color) + *p = x + return p +} +func (x RepeatedEnum_Color) String() string { + return proto.EnumName(RepeatedEnum_Color_name, int32(x)) +} +func (x *RepeatedEnum_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(RepeatedEnum_Color_value, data, "RepeatedEnum_Color") + if err != nil { + return err + } + *x = RepeatedEnum_Color(value) + return nil +} +func (RepeatedEnum_Color) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{21, 0} } + +type GoEnum struct { + Foo *FOO `protobuf:"varint,1,req,name=foo,enum=testdata.FOO" json:"foo,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoEnum) Reset() { *m = GoEnum{} } +func (m *GoEnum) String() string { return proto.CompactTextString(m) } +func (*GoEnum) ProtoMessage() {} +func (*GoEnum) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *GoEnum) GetFoo() FOO { + if m != nil && m.Foo != nil { + return *m.Foo + } + return FOO_FOO1 +} + +type GoTestField struct { + Label *string `protobuf:"bytes,1,req,name=Label" json:"Label,omitempty"` + Type *string `protobuf:"bytes,2,req,name=Type" json:"Type,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTestField) Reset() { *m = GoTestField{} } +func (m *GoTestField) String() string { return proto.CompactTextString(m) } +func (*GoTestField) ProtoMessage() {} +func (*GoTestField) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *GoTestField) GetLabel() string { + if m != nil && m.Label != nil { + return *m.Label + } + return "" +} + +func (m *GoTestField) GetType() string { + if m != nil && m.Type != nil { + return *m.Type + } + return "" +} + +type GoTest struct { + // Some typical parameters + Kind *GoTest_KIND `protobuf:"varint,1,req,name=Kind,enum=testdata.GoTest_KIND" json:"Kind,omitempty"` + Table *string `protobuf:"bytes,2,opt,name=Table" json:"Table,omitempty"` + Param *int32 `protobuf:"varint,3,opt,name=Param" json:"Param,omitempty"` + // Required, repeated and optional foreign fields. + RequiredField *GoTestField `protobuf:"bytes,4,req,name=RequiredField" json:"RequiredField,omitempty"` + RepeatedField []*GoTestField `protobuf:"bytes,5,rep,name=RepeatedField" json:"RepeatedField,omitempty"` + OptionalField *GoTestField `protobuf:"bytes,6,opt,name=OptionalField" json:"OptionalField,omitempty"` + // Required fields of all basic types + F_BoolRequired *bool `protobuf:"varint,10,req,name=F_Bool_required" json:"F_Bool_required,omitempty"` + F_Int32Required *int32 `protobuf:"varint,11,req,name=F_Int32_required" json:"F_Int32_required,omitempty"` + F_Int64Required *int64 `protobuf:"varint,12,req,name=F_Int64_required" json:"F_Int64_required,omitempty"` + F_Fixed32Required *uint32 `protobuf:"fixed32,13,req,name=F_Fixed32_required" json:"F_Fixed32_required,omitempty"` + F_Fixed64Required *uint64 `protobuf:"fixed64,14,req,name=F_Fixed64_required" json:"F_Fixed64_required,omitempty"` + F_Uint32Required *uint32 `protobuf:"varint,15,req,name=F_Uint32_required" json:"F_Uint32_required,omitempty"` + F_Uint64Required *uint64 `protobuf:"varint,16,req,name=F_Uint64_required" json:"F_Uint64_required,omitempty"` + F_FloatRequired *float32 `protobuf:"fixed32,17,req,name=F_Float_required" json:"F_Float_required,omitempty"` + F_DoubleRequired *float64 `protobuf:"fixed64,18,req,name=F_Double_required" json:"F_Double_required,omitempty"` + F_StringRequired *string `protobuf:"bytes,19,req,name=F_String_required" json:"F_String_required,omitempty"` + F_BytesRequired []byte `protobuf:"bytes,101,req,name=F_Bytes_required" json:"F_Bytes_required,omitempty"` + F_Sint32Required *int32 `protobuf:"zigzag32,102,req,name=F_Sint32_required" json:"F_Sint32_required,omitempty"` + F_Sint64Required *int64 `protobuf:"zigzag64,103,req,name=F_Sint64_required" json:"F_Sint64_required,omitempty"` + // Repeated fields of all basic types + F_BoolRepeated []bool `protobuf:"varint,20,rep,name=F_Bool_repeated" json:"F_Bool_repeated,omitempty"` + F_Int32Repeated []int32 `protobuf:"varint,21,rep,name=F_Int32_repeated" json:"F_Int32_repeated,omitempty"` + F_Int64Repeated []int64 `protobuf:"varint,22,rep,name=F_Int64_repeated" json:"F_Int64_repeated,omitempty"` + F_Fixed32Repeated []uint32 `protobuf:"fixed32,23,rep,name=F_Fixed32_repeated" json:"F_Fixed32_repeated,omitempty"` + F_Fixed64Repeated []uint64 `protobuf:"fixed64,24,rep,name=F_Fixed64_repeated" json:"F_Fixed64_repeated,omitempty"` + F_Uint32Repeated []uint32 `protobuf:"varint,25,rep,name=F_Uint32_repeated" json:"F_Uint32_repeated,omitempty"` + F_Uint64Repeated []uint64 `protobuf:"varint,26,rep,name=F_Uint64_repeated" json:"F_Uint64_repeated,omitempty"` + F_FloatRepeated []float32 `protobuf:"fixed32,27,rep,name=F_Float_repeated" json:"F_Float_repeated,omitempty"` + F_DoubleRepeated []float64 `protobuf:"fixed64,28,rep,name=F_Double_repeated" json:"F_Double_repeated,omitempty"` + F_StringRepeated []string `protobuf:"bytes,29,rep,name=F_String_repeated" json:"F_String_repeated,omitempty"` + F_BytesRepeated [][]byte `protobuf:"bytes,201,rep,name=F_Bytes_repeated" json:"F_Bytes_repeated,omitempty"` + F_Sint32Repeated []int32 `protobuf:"zigzag32,202,rep,name=F_Sint32_repeated" json:"F_Sint32_repeated,omitempty"` + F_Sint64Repeated []int64 `protobuf:"zigzag64,203,rep,name=F_Sint64_repeated" json:"F_Sint64_repeated,omitempty"` + // Optional fields of all basic types + F_BoolOptional *bool `protobuf:"varint,30,opt,name=F_Bool_optional" json:"F_Bool_optional,omitempty"` + F_Int32Optional *int32 `protobuf:"varint,31,opt,name=F_Int32_optional" json:"F_Int32_optional,omitempty"` + F_Int64Optional *int64 `protobuf:"varint,32,opt,name=F_Int64_optional" json:"F_Int64_optional,omitempty"` + F_Fixed32Optional *uint32 `protobuf:"fixed32,33,opt,name=F_Fixed32_optional" json:"F_Fixed32_optional,omitempty"` + F_Fixed64Optional *uint64 `protobuf:"fixed64,34,opt,name=F_Fixed64_optional" json:"F_Fixed64_optional,omitempty"` + F_Uint32Optional *uint32 `protobuf:"varint,35,opt,name=F_Uint32_optional" json:"F_Uint32_optional,omitempty"` + F_Uint64Optional *uint64 `protobuf:"varint,36,opt,name=F_Uint64_optional" json:"F_Uint64_optional,omitempty"` + F_FloatOptional *float32 `protobuf:"fixed32,37,opt,name=F_Float_optional" json:"F_Float_optional,omitempty"` + F_DoubleOptional *float64 `protobuf:"fixed64,38,opt,name=F_Double_optional" json:"F_Double_optional,omitempty"` + F_StringOptional *string `protobuf:"bytes,39,opt,name=F_String_optional" json:"F_String_optional,omitempty"` + F_BytesOptional []byte `protobuf:"bytes,301,opt,name=F_Bytes_optional" json:"F_Bytes_optional,omitempty"` + F_Sint32Optional *int32 `protobuf:"zigzag32,302,opt,name=F_Sint32_optional" json:"F_Sint32_optional,omitempty"` + F_Sint64Optional *int64 `protobuf:"zigzag64,303,opt,name=F_Sint64_optional" json:"F_Sint64_optional,omitempty"` + // Default-valued fields of all basic types + F_BoolDefaulted *bool `protobuf:"varint,40,opt,name=F_Bool_defaulted,def=1" json:"F_Bool_defaulted,omitempty"` + F_Int32Defaulted *int32 `protobuf:"varint,41,opt,name=F_Int32_defaulted,def=32" json:"F_Int32_defaulted,omitempty"` + F_Int64Defaulted *int64 `protobuf:"varint,42,opt,name=F_Int64_defaulted,def=64" json:"F_Int64_defaulted,omitempty"` + F_Fixed32Defaulted *uint32 `protobuf:"fixed32,43,opt,name=F_Fixed32_defaulted,def=320" json:"F_Fixed32_defaulted,omitempty"` + F_Fixed64Defaulted *uint64 `protobuf:"fixed64,44,opt,name=F_Fixed64_defaulted,def=640" json:"F_Fixed64_defaulted,omitempty"` + F_Uint32Defaulted *uint32 `protobuf:"varint,45,opt,name=F_Uint32_defaulted,def=3200" json:"F_Uint32_defaulted,omitempty"` + F_Uint64Defaulted *uint64 `protobuf:"varint,46,opt,name=F_Uint64_defaulted,def=6400" json:"F_Uint64_defaulted,omitempty"` + F_FloatDefaulted *float32 `protobuf:"fixed32,47,opt,name=F_Float_defaulted,def=314159" json:"F_Float_defaulted,omitempty"` + F_DoubleDefaulted *float64 `protobuf:"fixed64,48,opt,name=F_Double_defaulted,def=271828" json:"F_Double_defaulted,omitempty"` + F_StringDefaulted *string `protobuf:"bytes,49,opt,name=F_String_defaulted,def=hello, \"world!\"\n" json:"F_String_defaulted,omitempty"` + F_BytesDefaulted []byte `protobuf:"bytes,401,opt,name=F_Bytes_defaulted,def=Bignose" json:"F_Bytes_defaulted,omitempty"` + F_Sint32Defaulted *int32 `protobuf:"zigzag32,402,opt,name=F_Sint32_defaulted,def=-32" json:"F_Sint32_defaulted,omitempty"` + F_Sint64Defaulted *int64 `protobuf:"zigzag64,403,opt,name=F_Sint64_defaulted,def=-64" json:"F_Sint64_defaulted,omitempty"` + // Packed repeated fields (no string or bytes). + F_BoolRepeatedPacked []bool `protobuf:"varint,50,rep,packed,name=F_Bool_repeated_packed" json:"F_Bool_repeated_packed,omitempty"` + F_Int32RepeatedPacked []int32 `protobuf:"varint,51,rep,packed,name=F_Int32_repeated_packed" json:"F_Int32_repeated_packed,omitempty"` + F_Int64RepeatedPacked []int64 `protobuf:"varint,52,rep,packed,name=F_Int64_repeated_packed" json:"F_Int64_repeated_packed,omitempty"` + F_Fixed32RepeatedPacked []uint32 `protobuf:"fixed32,53,rep,packed,name=F_Fixed32_repeated_packed" json:"F_Fixed32_repeated_packed,omitempty"` + F_Fixed64RepeatedPacked []uint64 `protobuf:"fixed64,54,rep,packed,name=F_Fixed64_repeated_packed" json:"F_Fixed64_repeated_packed,omitempty"` + F_Uint32RepeatedPacked []uint32 `protobuf:"varint,55,rep,packed,name=F_Uint32_repeated_packed" json:"F_Uint32_repeated_packed,omitempty"` + F_Uint64RepeatedPacked []uint64 `protobuf:"varint,56,rep,packed,name=F_Uint64_repeated_packed" json:"F_Uint64_repeated_packed,omitempty"` + F_FloatRepeatedPacked []float32 `protobuf:"fixed32,57,rep,packed,name=F_Float_repeated_packed" json:"F_Float_repeated_packed,omitempty"` + F_DoubleRepeatedPacked []float64 `protobuf:"fixed64,58,rep,packed,name=F_Double_repeated_packed" json:"F_Double_repeated_packed,omitempty"` + F_Sint32RepeatedPacked []int32 `protobuf:"zigzag32,502,rep,packed,name=F_Sint32_repeated_packed" json:"F_Sint32_repeated_packed,omitempty"` + F_Sint64RepeatedPacked []int64 `protobuf:"zigzag64,503,rep,packed,name=F_Sint64_repeated_packed" json:"F_Sint64_repeated_packed,omitempty"` + Requiredgroup *GoTest_RequiredGroup `protobuf:"group,70,req,name=RequiredGroup" json:"requiredgroup,omitempty"` + Repeatedgroup []*GoTest_RepeatedGroup `protobuf:"group,80,rep,name=RepeatedGroup" json:"repeatedgroup,omitempty"` + Optionalgroup *GoTest_OptionalGroup `protobuf:"group,90,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest) Reset() { *m = GoTest{} } +func (m *GoTest) String() string { return proto.CompactTextString(m) } +func (*GoTest) ProtoMessage() {} +func (*GoTest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +const Default_GoTest_F_BoolDefaulted bool = true +const Default_GoTest_F_Int32Defaulted int32 = 32 +const Default_GoTest_F_Int64Defaulted int64 = 64 +const Default_GoTest_F_Fixed32Defaulted uint32 = 320 +const Default_GoTest_F_Fixed64Defaulted uint64 = 640 +const Default_GoTest_F_Uint32Defaulted uint32 = 3200 +const Default_GoTest_F_Uint64Defaulted uint64 = 6400 +const Default_GoTest_F_FloatDefaulted float32 = 314159 +const Default_GoTest_F_DoubleDefaulted float64 = 271828 +const Default_GoTest_F_StringDefaulted string = "hello, \"world!\"\n" + +var Default_GoTest_F_BytesDefaulted []byte = []byte("Bignose") + +const Default_GoTest_F_Sint32Defaulted int32 = -32 +const Default_GoTest_F_Sint64Defaulted int64 = -64 + +func (m *GoTest) GetKind() GoTest_KIND { + if m != nil && m.Kind != nil { + return *m.Kind + } + return GoTest_VOID +} + +func (m *GoTest) GetTable() string { + if m != nil && m.Table != nil { + return *m.Table + } + return "" +} + +func (m *GoTest) GetParam() int32 { + if m != nil && m.Param != nil { + return *m.Param + } + return 0 +} + +func (m *GoTest) GetRequiredField() *GoTestField { + if m != nil { + return m.RequiredField + } + return nil +} + +func (m *GoTest) GetRepeatedField() []*GoTestField { + if m != nil { + return m.RepeatedField + } + return nil +} + +func (m *GoTest) GetOptionalField() *GoTestField { + if m != nil { + return m.OptionalField + } + return nil +} + +func (m *GoTest) GetF_BoolRequired() bool { + if m != nil && m.F_BoolRequired != nil { + return *m.F_BoolRequired + } + return false +} + +func (m *GoTest) GetF_Int32Required() int32 { + if m != nil && m.F_Int32Required != nil { + return *m.F_Int32Required + } + return 0 +} + +func (m *GoTest) GetF_Int64Required() int64 { + if m != nil && m.F_Int64Required != nil { + return *m.F_Int64Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Required() uint32 { + if m != nil && m.F_Fixed32Required != nil { + return *m.F_Fixed32Required + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Required() uint64 { + if m != nil && m.F_Fixed64Required != nil { + return *m.F_Fixed64Required + } + return 0 +} + +func (m *GoTest) GetF_Uint32Required() uint32 { + if m != nil && m.F_Uint32Required != nil { + return *m.F_Uint32Required + } + return 0 +} + +func (m *GoTest) GetF_Uint64Required() uint64 { + if m != nil && m.F_Uint64Required != nil { + return *m.F_Uint64Required + } + return 0 +} + +func (m *GoTest) GetF_FloatRequired() float32 { + if m != nil && m.F_FloatRequired != nil { + return *m.F_FloatRequired + } + return 0 +} + +func (m *GoTest) GetF_DoubleRequired() float64 { + if m != nil && m.F_DoubleRequired != nil { + return *m.F_DoubleRequired + } + return 0 +} + +func (m *GoTest) GetF_StringRequired() string { + if m != nil && m.F_StringRequired != nil { + return *m.F_StringRequired + } + return "" +} + +func (m *GoTest) GetF_BytesRequired() []byte { + if m != nil { + return m.F_BytesRequired + } + return nil +} + +func (m *GoTest) GetF_Sint32Required() int32 { + if m != nil && m.F_Sint32Required != nil { + return *m.F_Sint32Required + } + return 0 +} + +func (m *GoTest) GetF_Sint64Required() int64 { + if m != nil && m.F_Sint64Required != nil { + return *m.F_Sint64Required + } + return 0 +} + +func (m *GoTest) GetF_BoolRepeated() []bool { + if m != nil { + return m.F_BoolRepeated + } + return nil +} + +func (m *GoTest) GetF_Int32Repeated() []int32 { + if m != nil { + return m.F_Int32Repeated + } + return nil +} + +func (m *GoTest) GetF_Int64Repeated() []int64 { + if m != nil { + return m.F_Int64Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed32Repeated() []uint32 { + if m != nil { + return m.F_Fixed32Repeated + } + return nil +} + +func (m *GoTest) GetF_Fixed64Repeated() []uint64 { + if m != nil { + return m.F_Fixed64Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint32Repeated() []uint32 { + if m != nil { + return m.F_Uint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Uint64Repeated() []uint64 { + if m != nil { + return m.F_Uint64Repeated + } + return nil +} + +func (m *GoTest) GetF_FloatRepeated() []float32 { + if m != nil { + return m.F_FloatRepeated + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeated() []float64 { + if m != nil { + return m.F_DoubleRepeated + } + return nil +} + +func (m *GoTest) GetF_StringRepeated() []string { + if m != nil { + return m.F_StringRepeated + } + return nil +} + +func (m *GoTest) GetF_BytesRepeated() [][]byte { + if m != nil { + return m.F_BytesRepeated + } + return nil +} + +func (m *GoTest) GetF_Sint32Repeated() []int32 { + if m != nil { + return m.F_Sint32Repeated + } + return nil +} + +func (m *GoTest) GetF_Sint64Repeated() []int64 { + if m != nil { + return m.F_Sint64Repeated + } + return nil +} + +func (m *GoTest) GetF_BoolOptional() bool { + if m != nil && m.F_BoolOptional != nil { + return *m.F_BoolOptional + } + return false +} + +func (m *GoTest) GetF_Int32Optional() int32 { + if m != nil && m.F_Int32Optional != nil { + return *m.F_Int32Optional + } + return 0 +} + +func (m *GoTest) GetF_Int64Optional() int64 { + if m != nil && m.F_Int64Optional != nil { + return *m.F_Int64Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed32Optional() uint32 { + if m != nil && m.F_Fixed32Optional != nil { + return *m.F_Fixed32Optional + } + return 0 +} + +func (m *GoTest) GetF_Fixed64Optional() uint64 { + if m != nil && m.F_Fixed64Optional != nil { + return *m.F_Fixed64Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint32Optional() uint32 { + if m != nil && m.F_Uint32Optional != nil { + return *m.F_Uint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Uint64Optional() uint64 { + if m != nil && m.F_Uint64Optional != nil { + return *m.F_Uint64Optional + } + return 0 +} + +func (m *GoTest) GetF_FloatOptional() float32 { + if m != nil && m.F_FloatOptional != nil { + return *m.F_FloatOptional + } + return 0 +} + +func (m *GoTest) GetF_DoubleOptional() float64 { + if m != nil && m.F_DoubleOptional != nil { + return *m.F_DoubleOptional + } + return 0 +} + +func (m *GoTest) GetF_StringOptional() string { + if m != nil && m.F_StringOptional != nil { + return *m.F_StringOptional + } + return "" +} + +func (m *GoTest) GetF_BytesOptional() []byte { + if m != nil { + return m.F_BytesOptional + } + return nil +} + +func (m *GoTest) GetF_Sint32Optional() int32 { + if m != nil && m.F_Sint32Optional != nil { + return *m.F_Sint32Optional + } + return 0 +} + +func (m *GoTest) GetF_Sint64Optional() int64 { + if m != nil && m.F_Sint64Optional != nil { + return *m.F_Sint64Optional + } + return 0 +} + +func (m *GoTest) GetF_BoolDefaulted() bool { + if m != nil && m.F_BoolDefaulted != nil { + return *m.F_BoolDefaulted + } + return Default_GoTest_F_BoolDefaulted +} + +func (m *GoTest) GetF_Int32Defaulted() int32 { + if m != nil && m.F_Int32Defaulted != nil { + return *m.F_Int32Defaulted + } + return Default_GoTest_F_Int32Defaulted +} + +func (m *GoTest) GetF_Int64Defaulted() int64 { + if m != nil && m.F_Int64Defaulted != nil { + return *m.F_Int64Defaulted + } + return Default_GoTest_F_Int64Defaulted +} + +func (m *GoTest) GetF_Fixed32Defaulted() uint32 { + if m != nil && m.F_Fixed32Defaulted != nil { + return *m.F_Fixed32Defaulted + } + return Default_GoTest_F_Fixed32Defaulted +} + +func (m *GoTest) GetF_Fixed64Defaulted() uint64 { + if m != nil && m.F_Fixed64Defaulted != nil { + return *m.F_Fixed64Defaulted + } + return Default_GoTest_F_Fixed64Defaulted +} + +func (m *GoTest) GetF_Uint32Defaulted() uint32 { + if m != nil && m.F_Uint32Defaulted != nil { + return *m.F_Uint32Defaulted + } + return Default_GoTest_F_Uint32Defaulted +} + +func (m *GoTest) GetF_Uint64Defaulted() uint64 { + if m != nil && m.F_Uint64Defaulted != nil { + return *m.F_Uint64Defaulted + } + return Default_GoTest_F_Uint64Defaulted +} + +func (m *GoTest) GetF_FloatDefaulted() float32 { + if m != nil && m.F_FloatDefaulted != nil { + return *m.F_FloatDefaulted + } + return Default_GoTest_F_FloatDefaulted +} + +func (m *GoTest) GetF_DoubleDefaulted() float64 { + if m != nil && m.F_DoubleDefaulted != nil { + return *m.F_DoubleDefaulted + } + return Default_GoTest_F_DoubleDefaulted +} + +func (m *GoTest) GetF_StringDefaulted() string { + if m != nil && m.F_StringDefaulted != nil { + return *m.F_StringDefaulted + } + return Default_GoTest_F_StringDefaulted +} + +func (m *GoTest) GetF_BytesDefaulted() []byte { + if m != nil && m.F_BytesDefaulted != nil { + return m.F_BytesDefaulted + } + return append([]byte(nil), Default_GoTest_F_BytesDefaulted...) +} + +func (m *GoTest) GetF_Sint32Defaulted() int32 { + if m != nil && m.F_Sint32Defaulted != nil { + return *m.F_Sint32Defaulted + } + return Default_GoTest_F_Sint32Defaulted +} + +func (m *GoTest) GetF_Sint64Defaulted() int64 { + if m != nil && m.F_Sint64Defaulted != nil { + return *m.F_Sint64Defaulted + } + return Default_GoTest_F_Sint64Defaulted +} + +func (m *GoTest) GetF_BoolRepeatedPacked() []bool { + if m != nil { + return m.F_BoolRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int32RepeatedPacked() []int32 { + if m != nil { + return m.F_Int32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Int64RepeatedPacked() []int64 { + if m != nil { + return m.F_Int64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Fixed32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Fixed64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Fixed64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint32RepeatedPacked() []uint32 { + if m != nil { + return m.F_Uint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Uint64RepeatedPacked() []uint64 { + if m != nil { + return m.F_Uint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_FloatRepeatedPacked() []float32 { + if m != nil { + return m.F_FloatRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_DoubleRepeatedPacked() []float64 { + if m != nil { + return m.F_DoubleRepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint32RepeatedPacked() []int32 { + if m != nil { + return m.F_Sint32RepeatedPacked + } + return nil +} + +func (m *GoTest) GetF_Sint64RepeatedPacked() []int64 { + if m != nil { + return m.F_Sint64RepeatedPacked + } + return nil +} + +func (m *GoTest) GetRequiredgroup() *GoTest_RequiredGroup { + if m != nil { + return m.Requiredgroup + } + return nil +} + +func (m *GoTest) GetRepeatedgroup() []*GoTest_RepeatedGroup { + if m != nil { + return m.Repeatedgroup + } + return nil +} + +func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup { + if m != nil { + return m.Optionalgroup + } + return nil +} + +// Required, repeated, and optional groups. +type GoTest_RequiredGroup struct { + RequiredField *string `protobuf:"bytes,71,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_RequiredGroup) Reset() { *m = GoTest_RequiredGroup{} } +func (m *GoTest_RequiredGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_RequiredGroup) ProtoMessage() {} + +func (m *GoTest_RequiredGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_RepeatedGroup struct { + RequiredField *string `protobuf:"bytes,81,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_RepeatedGroup) Reset() { *m = GoTest_RepeatedGroup{} } +func (m *GoTest_RepeatedGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_RepeatedGroup) ProtoMessage() {} + +func (m *GoTest_RepeatedGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +type GoTest_OptionalGroup struct { + RequiredField *string `protobuf:"bytes,91,req,name=RequiredField" json:"RequiredField,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoTest_OptionalGroup) Reset() { *m = GoTest_OptionalGroup{} } +func (m *GoTest_OptionalGroup) String() string { return proto.CompactTextString(m) } +func (*GoTest_OptionalGroup) ProtoMessage() {} + +func (m *GoTest_OptionalGroup) GetRequiredField() string { + if m != nil && m.RequiredField != nil { + return *m.RequiredField + } + return "" +} + +// For testing skipping of unrecognized fields. +// Numbers are all big, larger than tag numbers in GoTestField, +// the message used in the corresponding test. +type GoSkipTest struct { + SkipInt32 *int32 `protobuf:"varint,11,req,name=skip_int32" json:"skip_int32,omitempty"` + SkipFixed32 *uint32 `protobuf:"fixed32,12,req,name=skip_fixed32" json:"skip_fixed32,omitempty"` + SkipFixed64 *uint64 `protobuf:"fixed64,13,req,name=skip_fixed64" json:"skip_fixed64,omitempty"` + SkipString *string `protobuf:"bytes,14,req,name=skip_string" json:"skip_string,omitempty"` + Skipgroup *GoSkipTest_SkipGroup `protobuf:"group,15,req,name=SkipGroup" json:"skipgroup,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoSkipTest) Reset() { *m = GoSkipTest{} } +func (m *GoSkipTest) String() string { return proto.CompactTextString(m) } +func (*GoSkipTest) ProtoMessage() {} +func (*GoSkipTest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *GoSkipTest) GetSkipInt32() int32 { + if m != nil && m.SkipInt32 != nil { + return *m.SkipInt32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed32() uint32 { + if m != nil && m.SkipFixed32 != nil { + return *m.SkipFixed32 + } + return 0 +} + +func (m *GoSkipTest) GetSkipFixed64() uint64 { + if m != nil && m.SkipFixed64 != nil { + return *m.SkipFixed64 + } + return 0 +} + +func (m *GoSkipTest) GetSkipString() string { + if m != nil && m.SkipString != nil { + return *m.SkipString + } + return "" +} + +func (m *GoSkipTest) GetSkipgroup() *GoSkipTest_SkipGroup { + if m != nil { + return m.Skipgroup + } + return nil +} + +type GoSkipTest_SkipGroup struct { + GroupInt32 *int32 `protobuf:"varint,16,req,name=group_int32" json:"group_int32,omitempty"` + GroupString *string `protobuf:"bytes,17,req,name=group_string" json:"group_string,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GoSkipTest_SkipGroup) Reset() { *m = GoSkipTest_SkipGroup{} } +func (m *GoSkipTest_SkipGroup) String() string { return proto.CompactTextString(m) } +func (*GoSkipTest_SkipGroup) ProtoMessage() {} + +func (m *GoSkipTest_SkipGroup) GetGroupInt32() int32 { + if m != nil && m.GroupInt32 != nil { + return *m.GroupInt32 + } + return 0 +} + +func (m *GoSkipTest_SkipGroup) GetGroupString() string { + if m != nil && m.GroupString != nil { + return *m.GroupString + } + return "" +} + +// For testing packed/non-packed decoder switching. +// A serialized instance of one should be deserializable as the other. +type NonPackedTest struct { + A []int32 `protobuf:"varint,1,rep,name=a" json:"a,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NonPackedTest) Reset() { *m = NonPackedTest{} } +func (m *NonPackedTest) String() string { return proto.CompactTextString(m) } +func (*NonPackedTest) ProtoMessage() {} +func (*NonPackedTest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *NonPackedTest) GetA() []int32 { + if m != nil { + return m.A + } + return nil +} + +type PackedTest struct { + B []int32 `protobuf:"varint,1,rep,packed,name=b" json:"b,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *PackedTest) Reset() { *m = PackedTest{} } +func (m *PackedTest) String() string { return proto.CompactTextString(m) } +func (*PackedTest) ProtoMessage() {} +func (*PackedTest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *PackedTest) GetB() []int32 { + if m != nil { + return m.B + } + return nil +} + +type MaxTag struct { + // Maximum possible tag number. + LastField *string `protobuf:"bytes,536870911,opt,name=last_field" json:"last_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MaxTag) Reset() { *m = MaxTag{} } +func (m *MaxTag) String() string { return proto.CompactTextString(m) } +func (*MaxTag) ProtoMessage() {} +func (*MaxTag) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *MaxTag) GetLastField() string { + if m != nil && m.LastField != nil { + return *m.LastField + } + return "" +} + +type OldMessage struct { + Nested *OldMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + Num *int32 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldMessage) Reset() { *m = OldMessage{} } +func (m *OldMessage) String() string { return proto.CompactTextString(m) } +func (*OldMessage) ProtoMessage() {} +func (*OldMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *OldMessage) GetNested() *OldMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *OldMessage) GetNum() int32 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + +type OldMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldMessage_Nested) Reset() { *m = OldMessage_Nested{} } +func (m *OldMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*OldMessage_Nested) ProtoMessage() {} +func (*OldMessage_Nested) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7, 0} } + +func (m *OldMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +// NewMessage is wire compatible with OldMessage; +// imagine it as a future version. +type NewMessage struct { + Nested *NewMessage_Nested `protobuf:"bytes,1,opt,name=nested" json:"nested,omitempty"` + // This is an int32 in OldMessage. + Num *int64 `protobuf:"varint,2,opt,name=num" json:"num,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NewMessage) Reset() { *m = NewMessage{} } +func (m *NewMessage) String() string { return proto.CompactTextString(m) } +func (*NewMessage) ProtoMessage() {} +func (*NewMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +func (m *NewMessage) GetNested() *NewMessage_Nested { + if m != nil { + return m.Nested + } + return nil +} + +func (m *NewMessage) GetNum() int64 { + if m != nil && m.Num != nil { + return *m.Num + } + return 0 +} + +type NewMessage_Nested struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + FoodGroup *string `protobuf:"bytes,2,opt,name=food_group" json:"food_group,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *NewMessage_Nested) Reset() { *m = NewMessage_Nested{} } +func (m *NewMessage_Nested) String() string { return proto.CompactTextString(m) } +func (*NewMessage_Nested) ProtoMessage() {} +func (*NewMessage_Nested) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8, 0} } + +func (m *NewMessage_Nested) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *NewMessage_Nested) GetFoodGroup() string { + if m != nil && m.FoodGroup != nil { + return *m.FoodGroup + } + return "" +} + +type InnerMessage struct { + Host *string `protobuf:"bytes,1,req,name=host" json:"host,omitempty"` + Port *int32 `protobuf:"varint,2,opt,name=port,def=4000" json:"port,omitempty"` + Connected *bool `protobuf:"varint,3,opt,name=connected" json:"connected,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *InnerMessage) Reset() { *m = InnerMessage{} } +func (m *InnerMessage) String() string { return proto.CompactTextString(m) } +func (*InnerMessage) ProtoMessage() {} +func (*InnerMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } + +const Default_InnerMessage_Port int32 = 4000 + +func (m *InnerMessage) GetHost() string { + if m != nil && m.Host != nil { + return *m.Host + } + return "" +} + +func (m *InnerMessage) GetPort() int32 { + if m != nil && m.Port != nil { + return *m.Port + } + return Default_InnerMessage_Port +} + +func (m *InnerMessage) GetConnected() bool { + if m != nil && m.Connected != nil { + return *m.Connected + } + return false +} + +type OtherMessage struct { + Key *int64 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + Value []byte `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + Weight *float32 `protobuf:"fixed32,3,opt,name=weight" json:"weight,omitempty"` + Inner *InnerMessage `protobuf:"bytes,4,opt,name=inner" json:"inner,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherMessage) Reset() { *m = OtherMessage{} } +func (m *OtherMessage) String() string { return proto.CompactTextString(m) } +func (*OtherMessage) ProtoMessage() {} +func (*OtherMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +var extRange_OtherMessage = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*OtherMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OtherMessage +} +func (m *OtherMessage) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *OtherMessage) GetKey() int64 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + +func (m *OtherMessage) GetValue() []byte { + if m != nil { + return m.Value + } + return nil +} + +func (m *OtherMessage) GetWeight() float32 { + if m != nil && m.Weight != nil { + return *m.Weight + } + return 0 +} + +func (m *OtherMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +type MyMessage struct { + Count *int32 `protobuf:"varint,1,req,name=count" json:"count,omitempty"` + Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + Quote *string `protobuf:"bytes,3,opt,name=quote" json:"quote,omitempty"` + Pet []string `protobuf:"bytes,4,rep,name=pet" json:"pet,omitempty"` + Inner *InnerMessage `protobuf:"bytes,5,opt,name=inner" json:"inner,omitempty"` + Others []*OtherMessage `protobuf:"bytes,6,rep,name=others" json:"others,omitempty"` + RepInner []*InnerMessage `protobuf:"bytes,12,rep,name=rep_inner" json:"rep_inner,omitempty"` + Bikeshed *MyMessage_Color `protobuf:"varint,7,opt,name=bikeshed,enum=testdata.MyMessage_Color" json:"bikeshed,omitempty"` + Somegroup *MyMessage_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` + // This field becomes [][]byte in the generated code. + RepBytes [][]byte `protobuf:"bytes,10,rep,name=rep_bytes" json:"rep_bytes,omitempty"` + Bigfloat *float64 `protobuf:"fixed64,11,opt,name=bigfloat" json:"bigfloat,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessage) Reset() { *m = MyMessage{} } +func (m *MyMessage) String() string { return proto.CompactTextString(m) } +func (*MyMessage) ProtoMessage() {} +func (*MyMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } + +var extRange_MyMessage = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*MyMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MyMessage +} +func (m *MyMessage) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *MyMessage) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +func (m *MyMessage) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MyMessage) GetQuote() string { + if m != nil && m.Quote != nil { + return *m.Quote + } + return "" +} + +func (m *MyMessage) GetPet() []string { + if m != nil { + return m.Pet + } + return nil +} + +func (m *MyMessage) GetInner() *InnerMessage { + if m != nil { + return m.Inner + } + return nil +} + +func (m *MyMessage) GetOthers() []*OtherMessage { + if m != nil { + return m.Others + } + return nil +} + +func (m *MyMessage) GetRepInner() []*InnerMessage { + if m != nil { + return m.RepInner + } + return nil +} + +func (m *MyMessage) GetBikeshed() MyMessage_Color { + if m != nil && m.Bikeshed != nil { + return *m.Bikeshed + } + return MyMessage_RED +} + +func (m *MyMessage) GetSomegroup() *MyMessage_SomeGroup { + if m != nil { + return m.Somegroup + } + return nil +} + +func (m *MyMessage) GetRepBytes() [][]byte { + if m != nil { + return m.RepBytes + } + return nil +} + +func (m *MyMessage) GetBigfloat() float64 { + if m != nil && m.Bigfloat != nil { + return *m.Bigfloat + } + return 0 +} + +type MyMessage_SomeGroup struct { + GroupField *int32 `protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessage_SomeGroup) Reset() { *m = MyMessage_SomeGroup{} } +func (m *MyMessage_SomeGroup) String() string { return proto.CompactTextString(m) } +func (*MyMessage_SomeGroup) ProtoMessage() {} + +func (m *MyMessage_SomeGroup) GetGroupField() int32 { + if m != nil && m.GroupField != nil { + return *m.GroupField + } + return 0 +} + +type Ext struct { + Data *string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Ext) Reset() { *m = Ext{} } +func (m *Ext) String() string { return proto.CompactTextString(m) } +func (*Ext) ProtoMessage() {} +func (*Ext) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } + +func (m *Ext) GetData() string { + if m != nil && m.Data != nil { + return *m.Data + } + return "" +} + +var E_Ext_More = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*Ext)(nil), + Field: 103, + Name: "testdata.Ext.more", + Tag: "bytes,103,opt,name=more", +} + +var E_Ext_Text = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*string)(nil), + Field: 104, + Name: "testdata.Ext.text", + Tag: "bytes,104,opt,name=text", +} + +var E_Ext_Number = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 105, + Name: "testdata.Ext.number", + Tag: "varint,105,opt,name=number", +} + +type ComplexExtension struct { + First *int32 `protobuf:"varint,1,opt,name=first" json:"first,omitempty"` + Second *int32 `protobuf:"varint,2,opt,name=second" json:"second,omitempty"` + Third []int32 `protobuf:"varint,3,rep,name=third" json:"third,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ComplexExtension) Reset() { *m = ComplexExtension{} } +func (m *ComplexExtension) String() string { return proto.CompactTextString(m) } +func (*ComplexExtension) ProtoMessage() {} +func (*ComplexExtension) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } + +func (m *ComplexExtension) GetFirst() int32 { + if m != nil && m.First != nil { + return *m.First + } + return 0 +} + +func (m *ComplexExtension) GetSecond() int32 { + if m != nil && m.Second != nil { + return *m.Second + } + return 0 +} + +func (m *ComplexExtension) GetThird() []int32 { + if m != nil { + return m.Third + } + return nil +} + +type DefaultsMessage struct { + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DefaultsMessage) Reset() { *m = DefaultsMessage{} } +func (m *DefaultsMessage) String() string { return proto.CompactTextString(m) } +func (*DefaultsMessage) ProtoMessage() {} +func (*DefaultsMessage) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } + +var extRange_DefaultsMessage = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*DefaultsMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_DefaultsMessage +} +func (m *DefaultsMessage) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +type MyMessageSet struct { + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MyMessageSet) Reset() { *m = MyMessageSet{} } +func (m *MyMessageSet) String() string { return proto.CompactTextString(m) } +func (*MyMessageSet) ProtoMessage() {} +func (*MyMessageSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } + +func (m *MyMessageSet) Marshal() ([]byte, error) { + return proto.MarshalMessageSet(m.ExtensionMap()) +} +func (m *MyMessageSet) Unmarshal(buf []byte) error { + return proto.UnmarshalMessageSet(buf, m.ExtensionMap()) +} +func (m *MyMessageSet) MarshalJSON() ([]byte, error) { + return proto.MarshalMessageSetJSON(m.XXX_extensions) +} +func (m *MyMessageSet) UnmarshalJSON(buf []byte) error { + return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions) +} + +// ensure MyMessageSet satisfies proto.Marshaler and proto.Unmarshaler +var _ proto.Marshaler = (*MyMessageSet)(nil) +var _ proto.Unmarshaler = (*MyMessageSet)(nil) + +var extRange_MyMessageSet = []proto.ExtensionRange{ + {100, 2147483646}, +} + +func (*MyMessageSet) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MyMessageSet +} +func (m *MyMessageSet) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +type Empty struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *Empty) Reset() { *m = Empty{} } +func (m *Empty) String() string { return proto.CompactTextString(m) } +func (*Empty) ProtoMessage() {} +func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } + +type MessageList struct { + Message []*MessageList_Message `protobuf:"group,1,rep,name=Message" json:"message,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageList) Reset() { *m = MessageList{} } +func (m *MessageList) String() string { return proto.CompactTextString(m) } +func (*MessageList) ProtoMessage() {} +func (*MessageList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } + +func (m *MessageList) GetMessage() []*MessageList_Message { + if m != nil { + return m.Message + } + return nil +} + +type MessageList_Message struct { + Name *string `protobuf:"bytes,2,req,name=name" json:"name,omitempty"` + Count *int32 `protobuf:"varint,3,req,name=count" json:"count,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageList_Message) Reset() { *m = MessageList_Message{} } +func (m *MessageList_Message) String() string { return proto.CompactTextString(m) } +func (*MessageList_Message) ProtoMessage() {} + +func (m *MessageList_Message) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MessageList_Message) GetCount() int32 { + if m != nil && m.Count != nil { + return *m.Count + } + return 0 +} + +type Strings struct { + StringField *string `protobuf:"bytes,1,opt,name=string_field" json:"string_field,omitempty"` + BytesField []byte `protobuf:"bytes,2,opt,name=bytes_field" json:"bytes_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Strings) Reset() { *m = Strings{} } +func (m *Strings) String() string { return proto.CompactTextString(m) } +func (*Strings) ProtoMessage() {} +func (*Strings) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } + +func (m *Strings) GetStringField() string { + if m != nil && m.StringField != nil { + return *m.StringField + } + return "" +} + +func (m *Strings) GetBytesField() []byte { + if m != nil { + return m.BytesField + } + return nil +} + +type Defaults struct { + // Default-valued fields of all basic types. + // Same as GoTest, but copied here to make testing easier. + F_Bool *bool `protobuf:"varint,1,opt,name=F_Bool,def=1" json:"F_Bool,omitempty"` + F_Int32 *int32 `protobuf:"varint,2,opt,name=F_Int32,def=32" json:"F_Int32,omitempty"` + F_Int64 *int64 `protobuf:"varint,3,opt,name=F_Int64,def=64" json:"F_Int64,omitempty"` + F_Fixed32 *uint32 `protobuf:"fixed32,4,opt,name=F_Fixed32,def=320" json:"F_Fixed32,omitempty"` + F_Fixed64 *uint64 `protobuf:"fixed64,5,opt,name=F_Fixed64,def=640" json:"F_Fixed64,omitempty"` + F_Uint32 *uint32 `protobuf:"varint,6,opt,name=F_Uint32,def=3200" json:"F_Uint32,omitempty"` + F_Uint64 *uint64 `protobuf:"varint,7,opt,name=F_Uint64,def=6400" json:"F_Uint64,omitempty"` + F_Float *float32 `protobuf:"fixed32,8,opt,name=F_Float,def=314159" json:"F_Float,omitempty"` + F_Double *float64 `protobuf:"fixed64,9,opt,name=F_Double,def=271828" json:"F_Double,omitempty"` + F_String *string `protobuf:"bytes,10,opt,name=F_String,def=hello, \"world!\"\n" json:"F_String,omitempty"` + F_Bytes []byte `protobuf:"bytes,11,opt,name=F_Bytes,def=Bignose" json:"F_Bytes,omitempty"` + F_Sint32 *int32 `protobuf:"zigzag32,12,opt,name=F_Sint32,def=-32" json:"F_Sint32,omitempty"` + F_Sint64 *int64 `protobuf:"zigzag64,13,opt,name=F_Sint64,def=-64" json:"F_Sint64,omitempty"` + F_Enum *Defaults_Color `protobuf:"varint,14,opt,name=F_Enum,enum=testdata.Defaults_Color,def=1" json:"F_Enum,omitempty"` + // More fields with crazy defaults. + F_Pinf *float32 `protobuf:"fixed32,15,opt,name=F_Pinf,def=inf" json:"F_Pinf,omitempty"` + F_Ninf *float32 `protobuf:"fixed32,16,opt,name=F_Ninf,def=-inf" json:"F_Ninf,omitempty"` + F_Nan *float32 `protobuf:"fixed32,17,opt,name=F_Nan,def=nan" json:"F_Nan,omitempty"` + // Sub-message. + Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"` + // Redundant but explicit defaults. + StrZero *string `protobuf:"bytes,19,opt,name=str_zero,def=" json:"str_zero,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Defaults) Reset() { *m = Defaults{} } +func (m *Defaults) String() string { return proto.CompactTextString(m) } +func (*Defaults) ProtoMessage() {} +func (*Defaults) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } + +const Default_Defaults_F_Bool bool = true +const Default_Defaults_F_Int32 int32 = 32 +const Default_Defaults_F_Int64 int64 = 64 +const Default_Defaults_F_Fixed32 uint32 = 320 +const Default_Defaults_F_Fixed64 uint64 = 640 +const Default_Defaults_F_Uint32 uint32 = 3200 +const Default_Defaults_F_Uint64 uint64 = 6400 +const Default_Defaults_F_Float float32 = 314159 +const Default_Defaults_F_Double float64 = 271828 +const Default_Defaults_F_String string = "hello, \"world!\"\n" + +var Default_Defaults_F_Bytes []byte = []byte("Bignose") + +const Default_Defaults_F_Sint32 int32 = -32 +const Default_Defaults_F_Sint64 int64 = -64 +const Default_Defaults_F_Enum Defaults_Color = Defaults_GREEN + +var Default_Defaults_F_Pinf float32 = float32(math.Inf(1)) +var Default_Defaults_F_Ninf float32 = float32(math.Inf(-1)) +var Default_Defaults_F_Nan float32 = float32(math.NaN()) + +func (m *Defaults) GetF_Bool() bool { + if m != nil && m.F_Bool != nil { + return *m.F_Bool + } + return Default_Defaults_F_Bool +} + +func (m *Defaults) GetF_Int32() int32 { + if m != nil && m.F_Int32 != nil { + return *m.F_Int32 + } + return Default_Defaults_F_Int32 +} + +func (m *Defaults) GetF_Int64() int64 { + if m != nil && m.F_Int64 != nil { + return *m.F_Int64 + } + return Default_Defaults_F_Int64 +} + +func (m *Defaults) GetF_Fixed32() uint32 { + if m != nil && m.F_Fixed32 != nil { + return *m.F_Fixed32 + } + return Default_Defaults_F_Fixed32 +} + +func (m *Defaults) GetF_Fixed64() uint64 { + if m != nil && m.F_Fixed64 != nil { + return *m.F_Fixed64 + } + return Default_Defaults_F_Fixed64 +} + +func (m *Defaults) GetF_Uint32() uint32 { + if m != nil && m.F_Uint32 != nil { + return *m.F_Uint32 + } + return Default_Defaults_F_Uint32 +} + +func (m *Defaults) GetF_Uint64() uint64 { + if m != nil && m.F_Uint64 != nil { + return *m.F_Uint64 + } + return Default_Defaults_F_Uint64 +} + +func (m *Defaults) GetF_Float() float32 { + if m != nil && m.F_Float != nil { + return *m.F_Float + } + return Default_Defaults_F_Float +} + +func (m *Defaults) GetF_Double() float64 { + if m != nil && m.F_Double != nil { + return *m.F_Double + } + return Default_Defaults_F_Double +} + +func (m *Defaults) GetF_String() string { + if m != nil && m.F_String != nil { + return *m.F_String + } + return Default_Defaults_F_String +} + +func (m *Defaults) GetF_Bytes() []byte { + if m != nil && m.F_Bytes != nil { + return m.F_Bytes + } + return append([]byte(nil), Default_Defaults_F_Bytes...) +} + +func (m *Defaults) GetF_Sint32() int32 { + if m != nil && m.F_Sint32 != nil { + return *m.F_Sint32 + } + return Default_Defaults_F_Sint32 +} + +func (m *Defaults) GetF_Sint64() int64 { + if m != nil && m.F_Sint64 != nil { + return *m.F_Sint64 + } + return Default_Defaults_F_Sint64 +} + +func (m *Defaults) GetF_Enum() Defaults_Color { + if m != nil && m.F_Enum != nil { + return *m.F_Enum + } + return Default_Defaults_F_Enum +} + +func (m *Defaults) GetF_Pinf() float32 { + if m != nil && m.F_Pinf != nil { + return *m.F_Pinf + } + return Default_Defaults_F_Pinf +} + +func (m *Defaults) GetF_Ninf() float32 { + if m != nil && m.F_Ninf != nil { + return *m.F_Ninf + } + return Default_Defaults_F_Ninf +} + +func (m *Defaults) GetF_Nan() float32 { + if m != nil && m.F_Nan != nil { + return *m.F_Nan + } + return Default_Defaults_F_Nan +} + +func (m *Defaults) GetSub() *SubDefaults { + if m != nil { + return m.Sub + } + return nil +} + +func (m *Defaults) GetStrZero() string { + if m != nil && m.StrZero != nil { + return *m.StrZero + } + return "" +} + +type SubDefaults struct { + N *int64 `protobuf:"varint,1,opt,name=n,def=7" json:"n,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *SubDefaults) Reset() { *m = SubDefaults{} } +func (m *SubDefaults) String() string { return proto.CompactTextString(m) } +func (*SubDefaults) ProtoMessage() {} +func (*SubDefaults) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } + +const Default_SubDefaults_N int64 = 7 + +func (m *SubDefaults) GetN() int64 { + if m != nil && m.N != nil { + return *m.N + } + return Default_SubDefaults_N +} + +type RepeatedEnum struct { + Color []RepeatedEnum_Color `protobuf:"varint,1,rep,name=color,enum=testdata.RepeatedEnum_Color" json:"color,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *RepeatedEnum) Reset() { *m = RepeatedEnum{} } +func (m *RepeatedEnum) String() string { return proto.CompactTextString(m) } +func (*RepeatedEnum) ProtoMessage() {} +func (*RepeatedEnum) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } + +func (m *RepeatedEnum) GetColor() []RepeatedEnum_Color { + if m != nil { + return m.Color + } + return nil +} + +type MoreRepeated struct { + Bools []bool `protobuf:"varint,1,rep,name=bools" json:"bools,omitempty"` + BoolsPacked []bool `protobuf:"varint,2,rep,packed,name=bools_packed" json:"bools_packed,omitempty"` + Ints []int32 `protobuf:"varint,3,rep,name=ints" json:"ints,omitempty"` + IntsPacked []int32 `protobuf:"varint,4,rep,packed,name=ints_packed" json:"ints_packed,omitempty"` + Int64SPacked []int64 `protobuf:"varint,7,rep,packed,name=int64s_packed" json:"int64s_packed,omitempty"` + Strings []string `protobuf:"bytes,5,rep,name=strings" json:"strings,omitempty"` + Fixeds []uint32 `protobuf:"fixed32,6,rep,name=fixeds" json:"fixeds,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MoreRepeated) Reset() { *m = MoreRepeated{} } +func (m *MoreRepeated) String() string { return proto.CompactTextString(m) } +func (*MoreRepeated) ProtoMessage() {} +func (*MoreRepeated) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } + +func (m *MoreRepeated) GetBools() []bool { + if m != nil { + return m.Bools + } + return nil +} + +func (m *MoreRepeated) GetBoolsPacked() []bool { + if m != nil { + return m.BoolsPacked + } + return nil +} + +func (m *MoreRepeated) GetInts() []int32 { + if m != nil { + return m.Ints + } + return nil +} + +func (m *MoreRepeated) GetIntsPacked() []int32 { + if m != nil { + return m.IntsPacked + } + return nil +} + +func (m *MoreRepeated) GetInt64SPacked() []int64 { + if m != nil { + return m.Int64SPacked + } + return nil +} + +func (m *MoreRepeated) GetStrings() []string { + if m != nil { + return m.Strings + } + return nil +} + +func (m *MoreRepeated) GetFixeds() []uint32 { + if m != nil { + return m.Fixeds + } + return nil +} + +type GroupOld struct { + G *GroupOld_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupOld) Reset() { *m = GroupOld{} } +func (m *GroupOld) String() string { return proto.CompactTextString(m) } +func (*GroupOld) ProtoMessage() {} +func (*GroupOld) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } + +func (m *GroupOld) GetG() *GroupOld_G { + if m != nil { + return m.G + } + return nil +} + +type GroupOld_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupOld_G) Reset() { *m = GroupOld_G{} } +func (m *GroupOld_G) String() string { return proto.CompactTextString(m) } +func (*GroupOld_G) ProtoMessage() {} + +func (m *GroupOld_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +type GroupNew struct { + G *GroupNew_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupNew) Reset() { *m = GroupNew{} } +func (m *GroupNew) String() string { return proto.CompactTextString(m) } +func (*GroupNew) ProtoMessage() {} +func (*GroupNew) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } + +func (m *GroupNew) GetG() *GroupNew_G { + if m != nil { + return m.G + } + return nil +} + +type GroupNew_G struct { + X *int32 `protobuf:"varint,2,opt,name=x" json:"x,omitempty"` + Y *int32 `protobuf:"varint,3,opt,name=y" json:"y,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *GroupNew_G) Reset() { *m = GroupNew_G{} } +func (m *GroupNew_G) String() string { return proto.CompactTextString(m) } +func (*GroupNew_G) ProtoMessage() {} + +func (m *GroupNew_G) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +func (m *GroupNew_G) GetY() int32 { + if m != nil && m.Y != nil { + return *m.Y + } + return 0 +} + +type FloatingPoint struct { + F *float64 `protobuf:"fixed64,1,req,name=f" json:"f,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FloatingPoint) Reset() { *m = FloatingPoint{} } +func (m *FloatingPoint) String() string { return proto.CompactTextString(m) } +func (*FloatingPoint) ProtoMessage() {} +func (*FloatingPoint) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } + +func (m *FloatingPoint) GetF() float64 { + if m != nil && m.F != nil { + return *m.F + } + return 0 +} + +type MessageWithMap struct { + NameMapping map[int32]string `protobuf:"bytes,1,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + MsgMapping map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + ByteMapping map[bool][]byte `protobuf:"bytes,3,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + StrToStr map[string]string `protobuf:"bytes,4,rep,name=str_to_str" json:"str_to_str,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageWithMap) Reset() { *m = MessageWithMap{} } +func (m *MessageWithMap) String() string { return proto.CompactTextString(m) } +func (*MessageWithMap) ProtoMessage() {} +func (*MessageWithMap) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } + +func (m *MessageWithMap) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *MessageWithMap) GetMsgMapping() map[int64]*FloatingPoint { + if m != nil { + return m.MsgMapping + } + return nil +} + +func (m *MessageWithMap) GetByteMapping() map[bool][]byte { + if m != nil { + return m.ByteMapping + } + return nil +} + +func (m *MessageWithMap) GetStrToStr() map[string]string { + if m != nil { + return m.StrToStr + } + return nil +} + +type Oneof struct { + // Types that are valid to be assigned to Union: + // *Oneof_F_Bool + // *Oneof_F_Int32 + // *Oneof_F_Int64 + // *Oneof_F_Fixed32 + // *Oneof_F_Fixed64 + // *Oneof_F_Uint32 + // *Oneof_F_Uint64 + // *Oneof_F_Float + // *Oneof_F_Double + // *Oneof_F_String + // *Oneof_F_Bytes + // *Oneof_F_Sint32 + // *Oneof_F_Sint64 + // *Oneof_F_Enum + // *Oneof_F_Message + // *Oneof_FGroup + // *Oneof_F_Largest_Tag + Union isOneof_Union `protobuf_oneof:"union"` + // Types that are valid to be assigned to Tormato: + // *Oneof_Value + Tormato isOneof_Tormato `protobuf_oneof:"tormato"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Oneof) Reset() { *m = Oneof{} } +func (m *Oneof) String() string { return proto.CompactTextString(m) } +func (*Oneof) ProtoMessage() {} +func (*Oneof) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } + +type isOneof_Union interface { + isOneof_Union() +} +type isOneof_Tormato interface { + isOneof_Tormato() +} + +type Oneof_F_Bool struct { + F_Bool bool `protobuf:"varint,1,opt,name=F_Bool,oneof"` +} +type Oneof_F_Int32 struct { + F_Int32 int32 `protobuf:"varint,2,opt,name=F_Int32,oneof"` +} +type Oneof_F_Int64 struct { + F_Int64 int64 `protobuf:"varint,3,opt,name=F_Int64,oneof"` +} +type Oneof_F_Fixed32 struct { + F_Fixed32 uint32 `protobuf:"fixed32,4,opt,name=F_Fixed32,oneof"` +} +type Oneof_F_Fixed64 struct { + F_Fixed64 uint64 `protobuf:"fixed64,5,opt,name=F_Fixed64,oneof"` +} +type Oneof_F_Uint32 struct { + F_Uint32 uint32 `protobuf:"varint,6,opt,name=F_Uint32,oneof"` +} +type Oneof_F_Uint64 struct { + F_Uint64 uint64 `protobuf:"varint,7,opt,name=F_Uint64,oneof"` +} +type Oneof_F_Float struct { + F_Float float32 `protobuf:"fixed32,8,opt,name=F_Float,oneof"` +} +type Oneof_F_Double struct { + F_Double float64 `protobuf:"fixed64,9,opt,name=F_Double,oneof"` +} +type Oneof_F_String struct { + F_String string `protobuf:"bytes,10,opt,name=F_String,oneof"` +} +type Oneof_F_Bytes struct { + F_Bytes []byte `protobuf:"bytes,11,opt,name=F_Bytes,oneof"` +} +type Oneof_F_Sint32 struct { + F_Sint32 int32 `protobuf:"zigzag32,12,opt,name=F_Sint32,oneof"` +} +type Oneof_F_Sint64 struct { + F_Sint64 int64 `protobuf:"zigzag64,13,opt,name=F_Sint64,oneof"` +} +type Oneof_F_Enum struct { + F_Enum MyMessage_Color `protobuf:"varint,14,opt,name=F_Enum,enum=testdata.MyMessage_Color,oneof"` +} +type Oneof_F_Message struct { + F_Message *GoTestField `protobuf:"bytes,15,opt,name=F_Message,oneof"` +} +type Oneof_FGroup struct { + FGroup *Oneof_F_Group `protobuf:"group,16,opt,name=F_Group,oneof"` +} +type Oneof_F_Largest_Tag struct { + F_Largest_Tag int32 `protobuf:"varint,536870911,opt,name=F_Largest_Tag,oneof"` +} +type Oneof_Value struct { + Value int32 `protobuf:"varint,100,opt,name=value,oneof"` +} + +func (*Oneof_F_Bool) isOneof_Union() {} +func (*Oneof_F_Int32) isOneof_Union() {} +func (*Oneof_F_Int64) isOneof_Union() {} +func (*Oneof_F_Fixed32) isOneof_Union() {} +func (*Oneof_F_Fixed64) isOneof_Union() {} +func (*Oneof_F_Uint32) isOneof_Union() {} +func (*Oneof_F_Uint64) isOneof_Union() {} +func (*Oneof_F_Float) isOneof_Union() {} +func (*Oneof_F_Double) isOneof_Union() {} +func (*Oneof_F_String) isOneof_Union() {} +func (*Oneof_F_Bytes) isOneof_Union() {} +func (*Oneof_F_Sint32) isOneof_Union() {} +func (*Oneof_F_Sint64) isOneof_Union() {} +func (*Oneof_F_Enum) isOneof_Union() {} +func (*Oneof_F_Message) isOneof_Union() {} +func (*Oneof_FGroup) isOneof_Union() {} +func (*Oneof_F_Largest_Tag) isOneof_Union() {} +func (*Oneof_Value) isOneof_Tormato() {} + +func (m *Oneof) GetUnion() isOneof_Union { + if m != nil { + return m.Union + } + return nil +} +func (m *Oneof) GetTormato() isOneof_Tormato { + if m != nil { + return m.Tormato + } + return nil +} + +func (m *Oneof) GetF_Bool() bool { + if x, ok := m.GetUnion().(*Oneof_F_Bool); ok { + return x.F_Bool + } + return false +} + +func (m *Oneof) GetF_Int32() int32 { + if x, ok := m.GetUnion().(*Oneof_F_Int32); ok { + return x.F_Int32 + } + return 0 +} + +func (m *Oneof) GetF_Int64() int64 { + if x, ok := m.GetUnion().(*Oneof_F_Int64); ok { + return x.F_Int64 + } + return 0 +} + +func (m *Oneof) GetF_Fixed32() uint32 { + if x, ok := m.GetUnion().(*Oneof_F_Fixed32); ok { + return x.F_Fixed32 + } + return 0 +} + +func (m *Oneof) GetF_Fixed64() uint64 { + if x, ok := m.GetUnion().(*Oneof_F_Fixed64); ok { + return x.F_Fixed64 + } + return 0 +} + +func (m *Oneof) GetF_Uint32() uint32 { + if x, ok := m.GetUnion().(*Oneof_F_Uint32); ok { + return x.F_Uint32 + } + return 0 +} + +func (m *Oneof) GetF_Uint64() uint64 { + if x, ok := m.GetUnion().(*Oneof_F_Uint64); ok { + return x.F_Uint64 + } + return 0 +} + +func (m *Oneof) GetF_Float() float32 { + if x, ok := m.GetUnion().(*Oneof_F_Float); ok { + return x.F_Float + } + return 0 +} + +func (m *Oneof) GetF_Double() float64 { + if x, ok := m.GetUnion().(*Oneof_F_Double); ok { + return x.F_Double + } + return 0 +} + +func (m *Oneof) GetF_String() string { + if x, ok := m.GetUnion().(*Oneof_F_String); ok { + return x.F_String + } + return "" +} + +func (m *Oneof) GetF_Bytes() []byte { + if x, ok := m.GetUnion().(*Oneof_F_Bytes); ok { + return x.F_Bytes + } + return nil +} + +func (m *Oneof) GetF_Sint32() int32 { + if x, ok := m.GetUnion().(*Oneof_F_Sint32); ok { + return x.F_Sint32 + } + return 0 +} + +func (m *Oneof) GetF_Sint64() int64 { + if x, ok := m.GetUnion().(*Oneof_F_Sint64); ok { + return x.F_Sint64 + } + return 0 +} + +func (m *Oneof) GetF_Enum() MyMessage_Color { + if x, ok := m.GetUnion().(*Oneof_F_Enum); ok { + return x.F_Enum + } + return MyMessage_RED +} + +func (m *Oneof) GetF_Message() *GoTestField { + if x, ok := m.GetUnion().(*Oneof_F_Message); ok { + return x.F_Message + } + return nil +} + +func (m *Oneof) GetFGroup() *Oneof_F_Group { + if x, ok := m.GetUnion().(*Oneof_FGroup); ok { + return x.FGroup + } + return nil +} + +func (m *Oneof) GetF_Largest_Tag() int32 { + if x, ok := m.GetUnion().(*Oneof_F_Largest_Tag); ok { + return x.F_Largest_Tag + } + return 0 +} + +func (m *Oneof) GetValue() int32 { + if x, ok := m.GetTormato().(*Oneof_Value); ok { + return x.Value + } + return 0 +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Oneof) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Oneof_OneofMarshaler, _Oneof_OneofUnmarshaler, _Oneof_OneofSizer, []interface{}{ + (*Oneof_F_Bool)(nil), + (*Oneof_F_Int32)(nil), + (*Oneof_F_Int64)(nil), + (*Oneof_F_Fixed32)(nil), + (*Oneof_F_Fixed64)(nil), + (*Oneof_F_Uint32)(nil), + (*Oneof_F_Uint64)(nil), + (*Oneof_F_Float)(nil), + (*Oneof_F_Double)(nil), + (*Oneof_F_String)(nil), + (*Oneof_F_Bytes)(nil), + (*Oneof_F_Sint32)(nil), + (*Oneof_F_Sint64)(nil), + (*Oneof_F_Enum)(nil), + (*Oneof_F_Message)(nil), + (*Oneof_FGroup)(nil), + (*Oneof_F_Largest_Tag)(nil), + (*Oneof_Value)(nil), + } +} + +func _Oneof_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Oneof) + // union + switch x := m.Union.(type) { + case *Oneof_F_Bool: + t := uint64(0) + if x.F_Bool { + t = 1 + } + b.EncodeVarint(1<<3 | proto.WireVarint) + b.EncodeVarint(t) + case *Oneof_F_Int32: + b.EncodeVarint(2<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.F_Int32)) + case *Oneof_F_Int64: + b.EncodeVarint(3<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.F_Int64)) + case *Oneof_F_Fixed32: + b.EncodeVarint(4<<3 | proto.WireFixed32) + b.EncodeFixed32(uint64(x.F_Fixed32)) + case *Oneof_F_Fixed64: + b.EncodeVarint(5<<3 | proto.WireFixed64) + b.EncodeFixed64(uint64(x.F_Fixed64)) + case *Oneof_F_Uint32: + b.EncodeVarint(6<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.F_Uint32)) + case *Oneof_F_Uint64: + b.EncodeVarint(7<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.F_Uint64)) + case *Oneof_F_Float: + b.EncodeVarint(8<<3 | proto.WireFixed32) + b.EncodeFixed32(uint64(math.Float32bits(x.F_Float))) + case *Oneof_F_Double: + b.EncodeVarint(9<<3 | proto.WireFixed64) + b.EncodeFixed64(math.Float64bits(x.F_Double)) + case *Oneof_F_String: + b.EncodeVarint(10<<3 | proto.WireBytes) + b.EncodeStringBytes(x.F_String) + case *Oneof_F_Bytes: + b.EncodeVarint(11<<3 | proto.WireBytes) + b.EncodeRawBytes(x.F_Bytes) + case *Oneof_F_Sint32: + b.EncodeVarint(12<<3 | proto.WireVarint) + b.EncodeZigzag32(uint64(x.F_Sint32)) + case *Oneof_F_Sint64: + b.EncodeVarint(13<<3 | proto.WireVarint) + b.EncodeZigzag64(uint64(x.F_Sint64)) + case *Oneof_F_Enum: + b.EncodeVarint(14<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.F_Enum)) + case *Oneof_F_Message: + b.EncodeVarint(15<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.F_Message); err != nil { + return err + } + case *Oneof_FGroup: + b.EncodeVarint(16<<3 | proto.WireStartGroup) + if err := b.Marshal(x.FGroup); err != nil { + return err + } + b.EncodeVarint(16<<3 | proto.WireEndGroup) + case *Oneof_F_Largest_Tag: + b.EncodeVarint(536870911<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.F_Largest_Tag)) + case nil: + default: + return fmt.Errorf("Oneof.Union has unexpected type %T", x) + } + // tormato + switch x := m.Tormato.(type) { + case *Oneof_Value: + b.EncodeVarint(100<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Value)) + case nil: + default: + return fmt.Errorf("Oneof.Tormato has unexpected type %T", x) + } + return nil +} + +func _Oneof_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Oneof) + switch tag { + case 1: // union.F_Bool + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Oneof_F_Bool{x != 0} + return true, err + case 2: // union.F_Int32 + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Oneof_F_Int32{int32(x)} + return true, err + case 3: // union.F_Int64 + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Oneof_F_Int64{int64(x)} + return true, err + case 4: // union.F_Fixed32 + if wire != proto.WireFixed32 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed32() + m.Union = &Oneof_F_Fixed32{uint32(x)} + return true, err + case 5: // union.F_Fixed64 + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Union = &Oneof_F_Fixed64{x} + return true, err + case 6: // union.F_Uint32 + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Oneof_F_Uint32{uint32(x)} + return true, err + case 7: // union.F_Uint64 + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Oneof_F_Uint64{x} + return true, err + case 8: // union.F_Float + if wire != proto.WireFixed32 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed32() + m.Union = &Oneof_F_Float{math.Float32frombits(uint32(x))} + return true, err + case 9: // union.F_Double + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Union = &Oneof_F_Double{math.Float64frombits(x)} + return true, err + case 10: // union.F_String + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Union = &Oneof_F_String{x} + return true, err + case 11: // union.F_Bytes + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.Union = &Oneof_F_Bytes{x} + return true, err + case 12: // union.F_Sint32 + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeZigzag32() + m.Union = &Oneof_F_Sint32{int32(x)} + return true, err + case 13: // union.F_Sint64 + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeZigzag64() + m.Union = &Oneof_F_Sint64{int64(x)} + return true, err + case 14: // union.F_Enum + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Oneof_F_Enum{MyMessage_Color(x)} + return true, err + case 15: // union.F_Message + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(GoTestField) + err := b.DecodeMessage(msg) + m.Union = &Oneof_F_Message{msg} + return true, err + case 16: // union.f_group + if wire != proto.WireStartGroup { + return true, proto.ErrInternalBadWireType + } + msg := new(Oneof_F_Group) + err := b.DecodeGroup(msg) + m.Union = &Oneof_FGroup{msg} + return true, err + case 536870911: // union.F_Largest_Tag + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Oneof_F_Largest_Tag{int32(x)} + return true, err + case 100: // tormato.value + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Tormato = &Oneof_Value{int32(x)} + return true, err + default: + return false, nil + } +} + +func _Oneof_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Oneof) + // union + switch x := m.Union.(type) { + case *Oneof_F_Bool: + n += proto.SizeVarint(1<<3 | proto.WireVarint) + n += 1 + case *Oneof_F_Int32: + n += proto.SizeVarint(2<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.F_Int32)) + case *Oneof_F_Int64: + n += proto.SizeVarint(3<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.F_Int64)) + case *Oneof_F_Fixed32: + n += proto.SizeVarint(4<<3 | proto.WireFixed32) + n += 4 + case *Oneof_F_Fixed64: + n += proto.SizeVarint(5<<3 | proto.WireFixed64) + n += 8 + case *Oneof_F_Uint32: + n += proto.SizeVarint(6<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.F_Uint32)) + case *Oneof_F_Uint64: + n += proto.SizeVarint(7<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.F_Uint64)) + case *Oneof_F_Float: + n += proto.SizeVarint(8<<3 | proto.WireFixed32) + n += 4 + case *Oneof_F_Double: + n += proto.SizeVarint(9<<3 | proto.WireFixed64) + n += 8 + case *Oneof_F_String: + n += proto.SizeVarint(10<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.F_String))) + n += len(x.F_String) + case *Oneof_F_Bytes: + n += proto.SizeVarint(11<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.F_Bytes))) + n += len(x.F_Bytes) + case *Oneof_F_Sint32: + n += proto.SizeVarint(12<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64((uint32(x.F_Sint32) << 1) ^ uint32((int32(x.F_Sint32) >> 31)))) + case *Oneof_F_Sint64: + n += proto.SizeVarint(13<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(uint64(x.F_Sint64<<1) ^ uint64((int64(x.F_Sint64) >> 63)))) + case *Oneof_F_Enum: + n += proto.SizeVarint(14<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.F_Enum)) + case *Oneof_F_Message: + s := proto.Size(x.F_Message) + n += proto.SizeVarint(15<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *Oneof_FGroup: + n += proto.SizeVarint(16<<3 | proto.WireStartGroup) + n += proto.Size(x.FGroup) + n += proto.SizeVarint(16<<3 | proto.WireEndGroup) + case *Oneof_F_Largest_Tag: + n += proto.SizeVarint(536870911<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.F_Largest_Tag)) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + // tormato + switch x := m.Tormato.(type) { + case *Oneof_Value: + n += proto.SizeVarint(100<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Value)) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +type Oneof_F_Group struct { + X *int32 `protobuf:"varint,17,opt,name=x" json:"x,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Oneof_F_Group) Reset() { *m = Oneof_F_Group{} } +func (m *Oneof_F_Group) String() string { return proto.CompactTextString(m) } +func (*Oneof_F_Group) ProtoMessage() {} + +func (m *Oneof_F_Group) GetX() int32 { + if m != nil && m.X != nil { + return *m.X + } + return 0 +} + +type Communique struct { + MakeMeCry *bool `protobuf:"varint,1,opt,name=make_me_cry" json:"make_me_cry,omitempty"` + // This is a oneof, called "union". + // + // Types that are valid to be assigned to Union: + // *Communique_Number + // *Communique_Name + // *Communique_Data + // *Communique_TempC + // *Communique_Col + // *Communique_Msg + Union isCommunique_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique) Reset() { *m = Communique{} } +func (m *Communique) String() string { return proto.CompactTextString(m) } +func (*Communique) ProtoMessage() {} +func (*Communique) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } + +type isCommunique_Union interface { + isCommunique_Union() +} + +type Communique_Number struct { + Number int32 `protobuf:"varint,5,opt,name=number,oneof"` +} +type Communique_Name struct { + Name string `protobuf:"bytes,6,opt,name=name,oneof"` +} +type Communique_Data struct { + Data []byte `protobuf:"bytes,7,opt,name=data,oneof"` +} +type Communique_TempC struct { + TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"` +} +type Communique_Col struct { + Col MyMessage_Color `protobuf:"varint,9,opt,name=col,enum=testdata.MyMessage_Color,oneof"` +} +type Communique_Msg struct { + Msg *Strings `protobuf:"bytes,10,opt,name=msg,oneof"` +} + +func (*Communique_Number) isCommunique_Union() {} +func (*Communique_Name) isCommunique_Union() {} +func (*Communique_Data) isCommunique_Union() {} +func (*Communique_TempC) isCommunique_Union() {} +func (*Communique_Col) isCommunique_Union() {} +func (*Communique_Msg) isCommunique_Union() {} + +func (m *Communique) GetUnion() isCommunique_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *Communique) GetMakeMeCry() bool { + if m != nil && m.MakeMeCry != nil { + return *m.MakeMeCry + } + return false +} + +func (m *Communique) GetNumber() int32 { + if x, ok := m.GetUnion().(*Communique_Number); ok { + return x.Number + } + return 0 +} + +func (m *Communique) GetName() string { + if x, ok := m.GetUnion().(*Communique_Name); ok { + return x.Name + } + return "" +} + +func (m *Communique) GetData() []byte { + if x, ok := m.GetUnion().(*Communique_Data); ok { + return x.Data + } + return nil +} + +func (m *Communique) GetTempC() float64 { + if x, ok := m.GetUnion().(*Communique_TempC); ok { + return x.TempC + } + return 0 +} + +func (m *Communique) GetCol() MyMessage_Color { + if x, ok := m.GetUnion().(*Communique_Col); ok { + return x.Col + } + return MyMessage_RED +} + +func (m *Communique) GetMsg() *Strings { + if x, ok := m.GetUnion().(*Communique_Msg); ok { + return x.Msg + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Communique) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Communique_OneofMarshaler, _Communique_OneofUnmarshaler, _Communique_OneofSizer, []interface{}{ + (*Communique_Number)(nil), + (*Communique_Name)(nil), + (*Communique_Data)(nil), + (*Communique_TempC)(nil), + (*Communique_Col)(nil), + (*Communique_Msg)(nil), + } +} + +func _Communique_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Communique) + // union + switch x := m.Union.(type) { + case *Communique_Number: + b.EncodeVarint(5<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Number)) + case *Communique_Name: + b.EncodeVarint(6<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Name) + case *Communique_Data: + b.EncodeVarint(7<<3 | proto.WireBytes) + b.EncodeRawBytes(x.Data) + case *Communique_TempC: + b.EncodeVarint(8<<3 | proto.WireFixed64) + b.EncodeFixed64(math.Float64bits(x.TempC)) + case *Communique_Col: + b.EncodeVarint(9<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Col)) + case *Communique_Msg: + b.EncodeVarint(10<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Msg); err != nil { + return err + } + case nil: + default: + return fmt.Errorf("Communique.Union has unexpected type %T", x) + } + return nil +} + +func _Communique_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Communique) + switch tag { + case 5: // union.number + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Number{int32(x)} + return true, err + case 6: // union.name + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Union = &Communique_Name{x} + return true, err + case 7: // union.data + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.Union = &Communique_Data{x} + return true, err + case 8: // union.temp_c + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Union = &Communique_TempC{math.Float64frombits(x)} + return true, err + case 9: // union.col + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Col{MyMessage_Color(x)} + return true, err + case 10: // union.msg + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Strings) + err := b.DecodeMessage(msg) + m.Union = &Communique_Msg{msg} + return true, err + default: + return false, nil + } +} + +func _Communique_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Communique) + // union + switch x := m.Union.(type) { + case *Communique_Number: + n += proto.SizeVarint(5<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Number)) + case *Communique_Name: + n += proto.SizeVarint(6<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Name))) + n += len(x.Name) + case *Communique_Data: + n += proto.SizeVarint(7<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Data))) + n += len(x.Data) + case *Communique_TempC: + n += proto.SizeVarint(8<<3 | proto.WireFixed64) + n += 8 + case *Communique_Col: + n += proto.SizeVarint(9<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Col)) + case *Communique_Msg: + s := proto.Size(x.Msg) + n += proto.SizeVarint(10<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +var E_Greeting = &proto.ExtensionDesc{ + ExtendedType: (*MyMessage)(nil), + ExtensionType: ([]string)(nil), + Field: 106, + Name: "testdata.greeting", + Tag: "bytes,106,rep,name=greeting", +} + +var E_Complex = &proto.ExtensionDesc{ + ExtendedType: (*OtherMessage)(nil), + ExtensionType: (*ComplexExtension)(nil), + Field: 200, + Name: "testdata.complex", + Tag: "bytes,200,opt,name=complex", +} + +var E_RComplex = &proto.ExtensionDesc{ + ExtendedType: (*OtherMessage)(nil), + ExtensionType: ([]*ComplexExtension)(nil), + Field: 201, + Name: "testdata.r_complex", + Tag: "bytes,201,rep,name=r_complex", +} + +var E_NoDefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 101, + Name: "testdata.no_default_double", + Tag: "fixed64,101,opt,name=no_default_double", +} + +var E_NoDefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 102, + Name: "testdata.no_default_float", + Tag: "fixed32,102,opt,name=no_default_float", +} + +var E_NoDefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 103, + Name: "testdata.no_default_int32", + Tag: "varint,103,opt,name=no_default_int32", +} + +var E_NoDefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 104, + Name: "testdata.no_default_int64", + Tag: "varint,104,opt,name=no_default_int64", +} + +var E_NoDefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 105, + Name: "testdata.no_default_uint32", + Tag: "varint,105,opt,name=no_default_uint32", +} + +var E_NoDefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 106, + Name: "testdata.no_default_uint64", + Tag: "varint,106,opt,name=no_default_uint64", +} + +var E_NoDefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 107, + Name: "testdata.no_default_sint32", + Tag: "zigzag32,107,opt,name=no_default_sint32", +} + +var E_NoDefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 108, + Name: "testdata.no_default_sint64", + Tag: "zigzag64,108,opt,name=no_default_sint64", +} + +var E_NoDefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 109, + Name: "testdata.no_default_fixed32", + Tag: "fixed32,109,opt,name=no_default_fixed32", +} + +var E_NoDefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 110, + Name: "testdata.no_default_fixed64", + Tag: "fixed64,110,opt,name=no_default_fixed64", +} + +var E_NoDefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 111, + Name: "testdata.no_default_sfixed32", + Tag: "fixed32,111,opt,name=no_default_sfixed32", +} + +var E_NoDefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 112, + Name: "testdata.no_default_sfixed64", + Tag: "fixed64,112,opt,name=no_default_sfixed64", +} + +var E_NoDefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 113, + Name: "testdata.no_default_bool", + Tag: "varint,113,opt,name=no_default_bool", +} + +var E_NoDefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 114, + Name: "testdata.no_default_string", + Tag: "bytes,114,opt,name=no_default_string", +} + +var E_NoDefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 115, + Name: "testdata.no_default_bytes", + Tag: "bytes,115,opt,name=no_default_bytes", +} + +var E_NoDefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 116, + Name: "testdata.no_default_enum", + Tag: "varint,116,opt,name=no_default_enum,enum=testdata.DefaultsMessage_DefaultsEnum", +} + +var E_DefaultDouble = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float64)(nil), + Field: 201, + Name: "testdata.default_double", + Tag: "fixed64,201,opt,name=default_double,def=3.1415", +} + +var E_DefaultFloat = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*float32)(nil), + Field: 202, + Name: "testdata.default_float", + Tag: "fixed32,202,opt,name=default_float,def=3.14", +} + +var E_DefaultInt32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 203, + Name: "testdata.default_int32", + Tag: "varint,203,opt,name=default_int32,def=42", +} + +var E_DefaultInt64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 204, + Name: "testdata.default_int64", + Tag: "varint,204,opt,name=default_int64,def=43", +} + +var E_DefaultUint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 205, + Name: "testdata.default_uint32", + Tag: "varint,205,opt,name=default_uint32,def=44", +} + +var E_DefaultUint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 206, + Name: "testdata.default_uint64", + Tag: "varint,206,opt,name=default_uint64,def=45", +} + +var E_DefaultSint32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 207, + Name: "testdata.default_sint32", + Tag: "zigzag32,207,opt,name=default_sint32,def=46", +} + +var E_DefaultSint64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 208, + Name: "testdata.default_sint64", + Tag: "zigzag64,208,opt,name=default_sint64,def=47", +} + +var E_DefaultFixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint32)(nil), + Field: 209, + Name: "testdata.default_fixed32", + Tag: "fixed32,209,opt,name=default_fixed32,def=48", +} + +var E_DefaultFixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*uint64)(nil), + Field: 210, + Name: "testdata.default_fixed64", + Tag: "fixed64,210,opt,name=default_fixed64,def=49", +} + +var E_DefaultSfixed32 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int32)(nil), + Field: 211, + Name: "testdata.default_sfixed32", + Tag: "fixed32,211,opt,name=default_sfixed32,def=50", +} + +var E_DefaultSfixed64 = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*int64)(nil), + Field: 212, + Name: "testdata.default_sfixed64", + Tag: "fixed64,212,opt,name=default_sfixed64,def=51", +} + +var E_DefaultBool = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*bool)(nil), + Field: 213, + Name: "testdata.default_bool", + Tag: "varint,213,opt,name=default_bool,def=1", +} + +var E_DefaultString = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*string)(nil), + Field: 214, + Name: "testdata.default_string", + Tag: "bytes,214,opt,name=default_string,def=Hello, string", +} + +var E_DefaultBytes = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: ([]byte)(nil), + Field: 215, + Name: "testdata.default_bytes", + Tag: "bytes,215,opt,name=default_bytes,def=Hello, bytes", +} + +var E_DefaultEnum = &proto.ExtensionDesc{ + ExtendedType: (*DefaultsMessage)(nil), + ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil), + Field: 216, + Name: "testdata.default_enum", + Tag: "varint,216,opt,name=default_enum,enum=testdata.DefaultsMessage_DefaultsEnum,def=1", +} + +var E_X201 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 201, + Name: "testdata.x201", + Tag: "bytes,201,opt,name=x201", +} + +var E_X202 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 202, + Name: "testdata.x202", + Tag: "bytes,202,opt,name=x202", +} + +var E_X203 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 203, + Name: "testdata.x203", + Tag: "bytes,203,opt,name=x203", +} + +var E_X204 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 204, + Name: "testdata.x204", + Tag: "bytes,204,opt,name=x204", +} + +var E_X205 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 205, + Name: "testdata.x205", + Tag: "bytes,205,opt,name=x205", +} + +var E_X206 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 206, + Name: "testdata.x206", + Tag: "bytes,206,opt,name=x206", +} + +var E_X207 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 207, + Name: "testdata.x207", + Tag: "bytes,207,opt,name=x207", +} + +var E_X208 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 208, + Name: "testdata.x208", + Tag: "bytes,208,opt,name=x208", +} + +var E_X209 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 209, + Name: "testdata.x209", + Tag: "bytes,209,opt,name=x209", +} + +var E_X210 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 210, + Name: "testdata.x210", + Tag: "bytes,210,opt,name=x210", +} + +var E_X211 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 211, + Name: "testdata.x211", + Tag: "bytes,211,opt,name=x211", +} + +var E_X212 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 212, + Name: "testdata.x212", + Tag: "bytes,212,opt,name=x212", +} + +var E_X213 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 213, + Name: "testdata.x213", + Tag: "bytes,213,opt,name=x213", +} + +var E_X214 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 214, + Name: "testdata.x214", + Tag: "bytes,214,opt,name=x214", +} + +var E_X215 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 215, + Name: "testdata.x215", + Tag: "bytes,215,opt,name=x215", +} + +var E_X216 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 216, + Name: "testdata.x216", + Tag: "bytes,216,opt,name=x216", +} + +var E_X217 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 217, + Name: "testdata.x217", + Tag: "bytes,217,opt,name=x217", +} + +var E_X218 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 218, + Name: "testdata.x218", + Tag: "bytes,218,opt,name=x218", +} + +var E_X219 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 219, + Name: "testdata.x219", + Tag: "bytes,219,opt,name=x219", +} + +var E_X220 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 220, + Name: "testdata.x220", + Tag: "bytes,220,opt,name=x220", +} + +var E_X221 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 221, + Name: "testdata.x221", + Tag: "bytes,221,opt,name=x221", +} + +var E_X222 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 222, + Name: "testdata.x222", + Tag: "bytes,222,opt,name=x222", +} + +var E_X223 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 223, + Name: "testdata.x223", + Tag: "bytes,223,opt,name=x223", +} + +var E_X224 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 224, + Name: "testdata.x224", + Tag: "bytes,224,opt,name=x224", +} + +var E_X225 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 225, + Name: "testdata.x225", + Tag: "bytes,225,opt,name=x225", +} + +var E_X226 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 226, + Name: "testdata.x226", + Tag: "bytes,226,opt,name=x226", +} + +var E_X227 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 227, + Name: "testdata.x227", + Tag: "bytes,227,opt,name=x227", +} + +var E_X228 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 228, + Name: "testdata.x228", + Tag: "bytes,228,opt,name=x228", +} + +var E_X229 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 229, + Name: "testdata.x229", + Tag: "bytes,229,opt,name=x229", +} + +var E_X230 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 230, + Name: "testdata.x230", + Tag: "bytes,230,opt,name=x230", +} + +var E_X231 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 231, + Name: "testdata.x231", + Tag: "bytes,231,opt,name=x231", +} + +var E_X232 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 232, + Name: "testdata.x232", + Tag: "bytes,232,opt,name=x232", +} + +var E_X233 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 233, + Name: "testdata.x233", + Tag: "bytes,233,opt,name=x233", +} + +var E_X234 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 234, + Name: "testdata.x234", + Tag: "bytes,234,opt,name=x234", +} + +var E_X235 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 235, + Name: "testdata.x235", + Tag: "bytes,235,opt,name=x235", +} + +var E_X236 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 236, + Name: "testdata.x236", + Tag: "bytes,236,opt,name=x236", +} + +var E_X237 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 237, + Name: "testdata.x237", + Tag: "bytes,237,opt,name=x237", +} + +var E_X238 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 238, + Name: "testdata.x238", + Tag: "bytes,238,opt,name=x238", +} + +var E_X239 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 239, + Name: "testdata.x239", + Tag: "bytes,239,opt,name=x239", +} + +var E_X240 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 240, + Name: "testdata.x240", + Tag: "bytes,240,opt,name=x240", +} + +var E_X241 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 241, + Name: "testdata.x241", + Tag: "bytes,241,opt,name=x241", +} + +var E_X242 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 242, + Name: "testdata.x242", + Tag: "bytes,242,opt,name=x242", +} + +var E_X243 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 243, + Name: "testdata.x243", + Tag: "bytes,243,opt,name=x243", +} + +var E_X244 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 244, + Name: "testdata.x244", + Tag: "bytes,244,opt,name=x244", +} + +var E_X245 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 245, + Name: "testdata.x245", + Tag: "bytes,245,opt,name=x245", +} + +var E_X246 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 246, + Name: "testdata.x246", + Tag: "bytes,246,opt,name=x246", +} + +var E_X247 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 247, + Name: "testdata.x247", + Tag: "bytes,247,opt,name=x247", +} + +var E_X248 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 248, + Name: "testdata.x248", + Tag: "bytes,248,opt,name=x248", +} + +var E_X249 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 249, + Name: "testdata.x249", + Tag: "bytes,249,opt,name=x249", +} + +var E_X250 = &proto.ExtensionDesc{ + ExtendedType: (*MyMessageSet)(nil), + ExtensionType: (*Empty)(nil), + Field: 250, + Name: "testdata.x250", + Tag: "bytes,250,opt,name=x250", +} + +func init() { + proto.RegisterType((*GoEnum)(nil), "testdata.GoEnum") + proto.RegisterType((*GoTestField)(nil), "testdata.GoTestField") + proto.RegisterType((*GoTest)(nil), "testdata.GoTest") + proto.RegisterType((*GoTest_RequiredGroup)(nil), "testdata.GoTest.RequiredGroup") + proto.RegisterType((*GoTest_RepeatedGroup)(nil), "testdata.GoTest.RepeatedGroup") + proto.RegisterType((*GoTest_OptionalGroup)(nil), "testdata.GoTest.OptionalGroup") + proto.RegisterType((*GoSkipTest)(nil), "testdata.GoSkipTest") + proto.RegisterType((*GoSkipTest_SkipGroup)(nil), "testdata.GoSkipTest.SkipGroup") + proto.RegisterType((*NonPackedTest)(nil), "testdata.NonPackedTest") + proto.RegisterType((*PackedTest)(nil), "testdata.PackedTest") + proto.RegisterType((*MaxTag)(nil), "testdata.MaxTag") + proto.RegisterType((*OldMessage)(nil), "testdata.OldMessage") + proto.RegisterType((*OldMessage_Nested)(nil), "testdata.OldMessage.Nested") + proto.RegisterType((*NewMessage)(nil), "testdata.NewMessage") + proto.RegisterType((*NewMessage_Nested)(nil), "testdata.NewMessage.Nested") + proto.RegisterType((*InnerMessage)(nil), "testdata.InnerMessage") + proto.RegisterType((*OtherMessage)(nil), "testdata.OtherMessage") + proto.RegisterType((*MyMessage)(nil), "testdata.MyMessage") + proto.RegisterType((*MyMessage_SomeGroup)(nil), "testdata.MyMessage.SomeGroup") + proto.RegisterType((*Ext)(nil), "testdata.Ext") + proto.RegisterType((*ComplexExtension)(nil), "testdata.ComplexExtension") + proto.RegisterType((*DefaultsMessage)(nil), "testdata.DefaultsMessage") + proto.RegisterType((*MyMessageSet)(nil), "testdata.MyMessageSet") + proto.RegisterType((*Empty)(nil), "testdata.Empty") + proto.RegisterType((*MessageList)(nil), "testdata.MessageList") + proto.RegisterType((*MessageList_Message)(nil), "testdata.MessageList.Message") + proto.RegisterType((*Strings)(nil), "testdata.Strings") + proto.RegisterType((*Defaults)(nil), "testdata.Defaults") + proto.RegisterType((*SubDefaults)(nil), "testdata.SubDefaults") + proto.RegisterType((*RepeatedEnum)(nil), "testdata.RepeatedEnum") + proto.RegisterType((*MoreRepeated)(nil), "testdata.MoreRepeated") + proto.RegisterType((*GroupOld)(nil), "testdata.GroupOld") + proto.RegisterType((*GroupOld_G)(nil), "testdata.GroupOld.G") + proto.RegisterType((*GroupNew)(nil), "testdata.GroupNew") + proto.RegisterType((*GroupNew_G)(nil), "testdata.GroupNew.G") + proto.RegisterType((*FloatingPoint)(nil), "testdata.FloatingPoint") + proto.RegisterType((*MessageWithMap)(nil), "testdata.MessageWithMap") + proto.RegisterType((*Oneof)(nil), "testdata.Oneof") + proto.RegisterType((*Oneof_F_Group)(nil), "testdata.Oneof.F_Group") + proto.RegisterType((*Communique)(nil), "testdata.Communique") + proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value) + proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_value) + proto.RegisterEnum("testdata.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value) + proto.RegisterEnum("testdata.DefaultsMessage_DefaultsEnum", DefaultsMessage_DefaultsEnum_name, DefaultsMessage_DefaultsEnum_value) + proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_Color_value) + proto.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value) + proto.RegisterExtension(E_Ext_More) + proto.RegisterExtension(E_Ext_Text) + proto.RegisterExtension(E_Ext_Number) + proto.RegisterExtension(E_Greeting) + proto.RegisterExtension(E_Complex) + proto.RegisterExtension(E_RComplex) + proto.RegisterExtension(E_NoDefaultDouble) + proto.RegisterExtension(E_NoDefaultFloat) + proto.RegisterExtension(E_NoDefaultInt32) + proto.RegisterExtension(E_NoDefaultInt64) + proto.RegisterExtension(E_NoDefaultUint32) + proto.RegisterExtension(E_NoDefaultUint64) + proto.RegisterExtension(E_NoDefaultSint32) + proto.RegisterExtension(E_NoDefaultSint64) + proto.RegisterExtension(E_NoDefaultFixed32) + proto.RegisterExtension(E_NoDefaultFixed64) + proto.RegisterExtension(E_NoDefaultSfixed32) + proto.RegisterExtension(E_NoDefaultSfixed64) + proto.RegisterExtension(E_NoDefaultBool) + proto.RegisterExtension(E_NoDefaultString) + proto.RegisterExtension(E_NoDefaultBytes) + proto.RegisterExtension(E_NoDefaultEnum) + proto.RegisterExtension(E_DefaultDouble) + proto.RegisterExtension(E_DefaultFloat) + proto.RegisterExtension(E_DefaultInt32) + proto.RegisterExtension(E_DefaultInt64) + proto.RegisterExtension(E_DefaultUint32) + proto.RegisterExtension(E_DefaultUint64) + proto.RegisterExtension(E_DefaultSint32) + proto.RegisterExtension(E_DefaultSint64) + proto.RegisterExtension(E_DefaultFixed32) + proto.RegisterExtension(E_DefaultFixed64) + proto.RegisterExtension(E_DefaultSfixed32) + proto.RegisterExtension(E_DefaultSfixed64) + proto.RegisterExtension(E_DefaultBool) + proto.RegisterExtension(E_DefaultString) + proto.RegisterExtension(E_DefaultBytes) + proto.RegisterExtension(E_DefaultEnum) + proto.RegisterExtension(E_X201) + proto.RegisterExtension(E_X202) + proto.RegisterExtension(E_X203) + proto.RegisterExtension(E_X204) + proto.RegisterExtension(E_X205) + proto.RegisterExtension(E_X206) + proto.RegisterExtension(E_X207) + proto.RegisterExtension(E_X208) + proto.RegisterExtension(E_X209) + proto.RegisterExtension(E_X210) + proto.RegisterExtension(E_X211) + proto.RegisterExtension(E_X212) + proto.RegisterExtension(E_X213) + proto.RegisterExtension(E_X214) + proto.RegisterExtension(E_X215) + proto.RegisterExtension(E_X216) + proto.RegisterExtension(E_X217) + proto.RegisterExtension(E_X218) + proto.RegisterExtension(E_X219) + proto.RegisterExtension(E_X220) + proto.RegisterExtension(E_X221) + proto.RegisterExtension(E_X222) + proto.RegisterExtension(E_X223) + proto.RegisterExtension(E_X224) + proto.RegisterExtension(E_X225) + proto.RegisterExtension(E_X226) + proto.RegisterExtension(E_X227) + proto.RegisterExtension(E_X228) + proto.RegisterExtension(E_X229) + proto.RegisterExtension(E_X230) + proto.RegisterExtension(E_X231) + proto.RegisterExtension(E_X232) + proto.RegisterExtension(E_X233) + proto.RegisterExtension(E_X234) + proto.RegisterExtension(E_X235) + proto.RegisterExtension(E_X236) + proto.RegisterExtension(E_X237) + proto.RegisterExtension(E_X238) + proto.RegisterExtension(E_X239) + proto.RegisterExtension(E_X240) + proto.RegisterExtension(E_X241) + proto.RegisterExtension(E_X242) + proto.RegisterExtension(E_X243) + proto.RegisterExtension(E_X244) + proto.RegisterExtension(E_X245) + proto.RegisterExtension(E_X246) + proto.RegisterExtension(E_X247) + proto.RegisterExtension(E_X248) + proto.RegisterExtension(E_X249) + proto.RegisterExtension(E_X250) +} + +var fileDescriptor0 = []byte{ + // 3329 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x58, 0xd9, 0x73, 0x1b, 0xc7, + 0xf1, 0xd6, 0xe2, 0xc6, 0x00, 0x24, 0x96, 0x4b, 0x1d, 0x10, 0xe5, 0x83, 0x5a, 0xd9, 0xfa, 0xc9, + 0x92, 0x0d, 0x93, 0x20, 0x48, 0x49, 0xfb, 0xab, 0x94, 0x23, 0x4a, 0x00, 0xcd, 0x98, 0x24, 0x18, + 0x92, 0x8a, 0xcb, 0x4e, 0x25, 0x28, 0x90, 0x5c, 0x82, 0x30, 0x01, 0x2c, 0x04, 0x2c, 0x62, 0x31, + 0x4f, 0x79, 0xcd, 0x43, 0x1e, 0x92, 0x54, 0xaa, 0x5c, 0xf9, 0x1f, 0x92, 0xbc, 0xe7, 0x2f, 0x88, + 0xef, 0xfb, 0xc8, 0x7d, 0x39, 0xf7, 0xed, 0x24, 0x76, 0x92, 0x97, 0xa4, 0xbb, 0x67, 0x6f, 0x60, + 0x87, 0xb4, 0x1e, 0x6c, 0x70, 0xbe, 0xfe, 0x7a, 0x66, 0x7a, 0xba, 0x7b, 0xbe, 0x59, 0xc6, 0x4c, + 0xbd, 0x6f, 0x16, 0xba, 0x3d, 0xc3, 0x34, 0x94, 0x14, 0xfe, 0xde, 0xad, 0x9b, 0x75, 0xf5, 0x01, + 0x96, 0x58, 0x32, 0xca, 0x9d, 0x41, 0x5b, 0x99, 0x62, 0xd1, 0x3d, 0xc3, 0xc8, 0x4b, 0xd3, 0x91, + 0x4b, 0xe3, 0xc5, 0xb1, 0x82, 0x6d, 0x51, 0xa8, 0x54, 0xab, 0xea, 0x65, 0x96, 0x59, 0x32, 0xb6, + 0x60, 0xa4, 0xd2, 0xd4, 0x5b, 0xbb, 0xca, 0x18, 0x8b, 0xaf, 0xd4, 0xb7, 0xf5, 0x16, 0x19, 0xa7, + 0x95, 0x2c, 0x8b, 0x6d, 0x1d, 0x76, 0xf5, 0x7c, 0x04, 0xff, 0x52, 0xbf, 0x7c, 0x12, 0x5d, 0xa2, + 0xb1, 0x72, 0x81, 0xc5, 0x9e, 0x68, 0x76, 0x76, 0x2d, 0x9f, 0xa7, 0x5c, 0x9f, 0x1c, 0x2f, 0x3c, + 0xb1, 0xbc, 0x76, 0x0b, 0x9d, 0x6d, 0xd5, 0xb7, 0x5b, 0x48, 0x97, 0xc0, 0x19, 0xfc, 0xb9, 0x5e, + 0xef, 0xd5, 0xdb, 0xf9, 0x28, 0xfc, 0x19, 0x57, 0x1e, 0x66, 0x63, 0x1b, 0xfa, 0x9d, 0x41, 0xb3, + 0xa7, 0xef, 0xd2, 0xdc, 0xf9, 0x18, 0xf8, 0xca, 0x0c, 0xfb, 0xe2, 0x0b, 0x23, 0xeb, 0xae, 0x5e, + 0x37, 0x6d, 0xeb, 0xf8, 0x74, 0x54, 0x68, 0x5d, 0xed, 0x9a, 0x4d, 0xa3, 0x53, 0x6f, 0x71, 0xeb, + 0x04, 0x4c, 0x19, 0x6a, 0x7d, 0x86, 0xe5, 0x2a, 0xb5, 0x45, 0xc3, 0x68, 0xd5, 0x7a, 0xd6, 0x82, + 0xf2, 0x0c, 0xd6, 0x92, 0x52, 0xf2, 0x4c, 0xae, 0xd4, 0x96, 0x3b, 0xe6, 0x5c, 0xd1, 0x45, 0x32, + 0x80, 0xc4, 0x1d, 0x64, 0xa1, 0xe4, 0x22, 0x59, 0x40, 0xa2, 0x10, 0x6c, 0xa5, 0x52, 0xab, 0x34, + 0xef, 0xea, 0xbb, 0x5e, 0xd6, 0x18, 0x60, 0x49, 0x0f, 0xe6, 0xe5, 0x8d, 0x03, 0x96, 0x50, 0xce, + 0xb2, 0x89, 0x4a, 0xed, 0x76, 0xd3, 0x3f, 0x59, 0x0e, 0xa0, 0x31, 0x17, 0xf2, 0xb2, 0x64, 0x80, + 0x62, 0x7c, 0x1d, 0x95, 0x96, 0x51, 0x37, 0x5d, 0x64, 0x02, 0x90, 0x08, 0x27, 0xdd, 0x32, 0x06, + 0x10, 0x7f, 0x17, 0x52, 0x00, 0x92, 0x38, 0xb4, 0x69, 0xf6, 0x9a, 0x9d, 0x86, 0x0b, 0x4d, 0xd2, + 0x81, 0x93, 0xbf, 0xc5, 0x43, 0x08, 0x93, 0x8b, 0xe8, 0x80, 0x64, 0x2d, 0x52, 0x60, 0x7d, 0x7b, + 0x00, 0x4d, 0xb8, 0x90, 0x77, 0x7d, 0x0d, 0x80, 0x14, 0x5f, 0x68, 0xf9, 0xe9, 0xe5, 0x4f, 0xc2, + 0xc1, 0x05, 0x42, 0x6b, 0x21, 0xa7, 0x00, 0x09, 0x84, 0xd6, 0x42, 0x4e, 0x03, 0x32, 0x14, 0x5a, + 0x0b, 0x3b, 0x03, 0xd8, 0x50, 0x68, 0x2d, 0x2c, 0x0f, 0x58, 0x30, 0xb4, 0x16, 0x74, 0x16, 0xa0, + 0x60, 0x68, 0x2d, 0x68, 0x0a, 0xa0, 0x40, 0x68, 0x2d, 0xe4, 0x1c, 0x20, 0xc1, 0xd0, 0x5a, 0xd0, + 0x3d, 0x00, 0x05, 0x43, 0x6b, 0x41, 0xf7, 0x02, 0x94, 0x06, 0xc8, 0x13, 0x5a, 0x0b, 0x79, 0x5e, + 0x02, 0x28, 0x0b, 0x8b, 0xf7, 0xc6, 0xd6, 0xc2, 0x5e, 0x40, 0x6c, 0xc2, 0xc5, 0xbc, 0x2b, 0x7c, + 0x11, 0x31, 0x6f, 0x74, 0x0d, 0x2b, 0xdb, 0xf3, 0xf7, 0x41, 0xa2, 0xfb, 0xa2, 0xeb, 0x20, 0xf7, + 0x53, 0xd5, 0x79, 0xa2, 0xeb, 0x20, 0xd3, 0x80, 0x04, 0xa2, 0xeb, 0x60, 0xe7, 0x01, 0x0b, 0x44, + 0xd7, 0xc1, 0x54, 0xc0, 0xfc, 0xd1, 0x75, 0xa0, 0x0b, 0x00, 0xf9, 0xa3, 0xeb, 0x40, 0x0f, 0x00, + 0xe4, 0x8b, 0xae, 0x83, 0x3c, 0x08, 0x88, 0x3f, 0xba, 0x0e, 0x74, 0x11, 0x20, 0x7f, 0x74, 0x1d, + 0xe8, 0xff, 0xa8, 0xb9, 0x78, 0xa2, 0xeb, 0x20, 0xdf, 0xc2, 0xbe, 0xe3, 0x8f, 0xae, 0x83, 0x7d, + 0x1b, 0x31, 0x7f, 0x74, 0x1d, 0xec, 0x3b, 0x88, 0x29, 0xca, 0x7d, 0xe4, 0x12, 0xa3, 0xbb, 0xab, + 0xef, 0xd5, 0x07, 0x2d, 0x0c, 0xfc, 0x25, 0x0c, 0xaf, 0x16, 0x33, 0x7b, 0x03, 0x5d, 0xb9, 0x17, + 0xb9, 0x3c, 0xc8, 0xae, 0xc1, 0x43, 0x18, 0x65, 0x2d, 0x32, 0x57, 0x74, 0x60, 0xf0, 0xec, 0xc2, + 0x97, 0x31, 0xd4, 0x5a, 0x64, 0xa1, 0xa4, 0x4c, 0xb3, 0x49, 0x37, 0xdc, 0xae, 0xc1, 0x15, 0x8c, + 0xb7, 0x16, 0x9d, 0x2b, 0xce, 0x78, 0x2c, 0x7c, 0x2e, 0x1e, 0xc6, 0xa8, 0x6b, 0xd1, 0x85, 0x12, + 0x5a, 0x28, 0x4e, 0xe8, 0x5d, 0x83, 0x47, 0x30, 0xf6, 0x5a, 0x0c, 0x5c, 0x78, 0x2c, 0x7c, 0x2e, + 0x0a, 0x78, 0x04, 0x5a, 0x0c, 0x5c, 0xcc, 0x28, 0xe7, 0x71, 0x99, 0xfc, 0x20, 0x5c, 0x83, 0x47, + 0xf1, 0x24, 0xb4, 0xc4, 0xdc, 0x6c, 0x69, 0x76, 0xfe, 0xba, 0xa2, 0xa2, 0x13, 0xeb, 0x44, 0x5c, + 0x9b, 0x19, 0x3c, 0x12, 0x2d, 0x51, 0xbc, 0x3a, 0x7b, 0xad, 0x78, 0x0d, 0x3a, 0xae, 0xe2, 0x1c, + 0x8d, 0x6b, 0x33, 0x8b, 0x67, 0xa3, 0xc9, 0xfb, 0x7a, 0xab, 0x65, 0x3c, 0x3c, 0xad, 0x3e, 0x6b, + 0xf4, 0x5a, 0xbb, 0xe7, 0xc1, 0xdd, 0x05, 0x9c, 0x94, 0x9f, 0x96, 0x6b, 0xfc, 0x55, 0xbc, 0x17, + 0xb2, 0x5a, 0x72, 0xb1, 0xd9, 0xe8, 0x18, 0x7d, 0x9d, 0xaf, 0x7d, 0x33, 0xb8, 0xbb, 0xaf, 0xa1, + 0xd5, 0x84, 0x16, 0x7d, 0x04, 0x42, 0xec, 0x58, 0xf8, 0x76, 0xf7, 0x75, 0xb4, 0x50, 0xc0, 0x02, + 0xa2, 0xac, 0xb2, 0xd3, 0x81, 0xfe, 0x53, 0xeb, 0xd6, 0x77, 0x0e, 0xc0, 0xaa, 0x88, 0x6d, 0x68, + 0x31, 0x22, 0x4b, 0xb0, 0x98, 0x33, 0xc1, 0x56, 0x64, 0x1b, 0xcd, 0x61, 0x47, 0xf2, 0x19, 0x79, + 0xaa, 0xd0, 0x36, 0x2a, 0x61, 0x73, 0x22, 0xa3, 0x07, 0xd9, 0xd9, 0xe1, 0x06, 0x65, 0x9b, 0xcd, + 0x63, 0x9f, 0x0a, 0x98, 0x8d, 0xf0, 0xb6, 0x80, 0x2d, 0x8b, 0xcc, 0x1e, 0x60, 0xf9, 0xa1, 0xb6, + 0x65, 0x5b, 0x5d, 0xc5, 0xee, 0xe5, 0xb7, 0x1a, 0xe1, 0xeb, 0x1a, 0x36, 0x32, 0x77, 0xf9, 0xfe, + 0x66, 0x66, 0x1b, 0x5d, 0xc7, 0x9e, 0xe6, 0xba, 0x0a, 0xf4, 0x35, 0xdb, 0x4a, 0xc3, 0xf6, 0x66, + 0xad, 0x3e, 0x3f, 0xd4, 0xac, 0x6c, 0xab, 0x0f, 0xa3, 0xd8, 0xb3, 0xfc, 0x66, 0x23, 0xd6, 0xf5, + 0x11, 0x9a, 0x29, 0x64, 0x36, 0xcf, 0xc6, 0xec, 0x2b, 0xa3, 0xd1, 0x33, 0x06, 0xdd, 0x7c, 0x05, + 0xee, 0x0d, 0x56, 0xbc, 0x6f, 0x48, 0x51, 0xd8, 0x5a, 0x61, 0x09, 0xad, 0x38, 0x8d, 0x3b, 0xe5, + 0xb4, 0x75, 0xf0, 0x38, 0x9a, 0xc6, 0xad, 0x1c, 0x9a, 0x5d, 0xe5, 0x9c, 0xf6, 0x34, 0xa4, 0xca, + 0x28, 0x9a, 0xad, 0x1e, 0x88, 0x36, 0x75, 0xd1, 0x95, 0x2a, 0xdc, 0xcf, 0xa9, 0xa0, 0x76, 0x59, + 0xc2, 0xdb, 0x93, 0xdb, 0x79, 0xe7, 0x1b, 0xb2, 0xfb, 0xb4, 0x6d, 0xe7, 0x9b, 0x60, 0xd8, 0xee, + 0xb3, 0x24, 0xb8, 0x9e, 0x93, 0x40, 0x66, 0xa1, 0x92, 0x4a, 0xb1, 0xd8, 0x67, 0xaa, 0xcb, 0xb7, + 0xe4, 0x13, 0xf8, 0x6b, 0xb1, 0x5a, 0x5d, 0x81, 0xc8, 0xa5, 0x59, 0x7c, 0xf1, 0xa9, 0xad, 0xf2, + 0xa6, 0x1c, 0x51, 0x72, 0x2c, 0x53, 0x59, 0x5e, 0x5b, 0x2a, 0x6f, 0xac, 0x6f, 0x2c, 0xaf, 0x6d, + 0xc9, 0x51, 0xc4, 0x2a, 0x2b, 0xd5, 0x1b, 0x5b, 0x72, 0x4c, 0x49, 0xb2, 0x28, 0x8e, 0xc5, 0x15, + 0xc6, 0x12, 0x9b, 0x5b, 0x80, 0x2f, 0xc9, 0x09, 0xf4, 0xb2, 0xb5, 0xbc, 0x5a, 0x96, 0x93, 0x68, + 0xb9, 0x75, 0x7b, 0x7d, 0xa5, 0x2c, 0xa7, 0xf0, 0xe7, 0x8d, 0x8d, 0x8d, 0x1b, 0x4f, 0xc9, 0x69, + 0x24, 0xad, 0xde, 0x58, 0x97, 0x19, 0xc1, 0x37, 0x16, 0x01, 0xce, 0x80, 0x16, 0x4c, 0x55, 0x6e, + 0xaf, 0xdd, 0xdc, 0x5a, 0xae, 0xae, 0xc9, 0x59, 0xf5, 0x25, 0x89, 0xb1, 0x25, 0x63, 0xf3, 0xa0, + 0xd9, 0x25, 0x3d, 0x08, 0xde, 0xfb, 0xf0, 0xbb, 0x46, 0x69, 0x61, 0x69, 0xa4, 0x93, 0x2c, 0x4b, + 0x63, 0x7b, 0xbc, 0x20, 0x48, 0x1f, 0x25, 0xfd, 0xa3, 0x0b, 0x25, 0x52, 0x46, 0x09, 0x65, 0x92, + 0x65, 0x68, 0xb4, 0x4f, 0x1d, 0x84, 0x24, 0x51, 0x5a, 0x99, 0x65, 0x69, 0x1c, 0xe4, 0x27, 0x95, + 0x1b, 0xce, 0x0b, 0x7b, 0xf6, 0x02, 0xfe, 0xe0, 0x27, 0xb5, 0xc0, 0xd2, 0xce, 0x1f, 0xe8, 0x94, + 0xb8, 0xd6, 0xaa, 0x64, 0x7b, 0x55, 0x7c, 0xd0, 0x9a, 0x6a, 0x82, 0x22, 0x3d, 0xc5, 0xc6, 0xd6, + 0x8c, 0xce, 0x3a, 0xa5, 0x27, 0x6d, 0x28, 0xcd, 0xa4, 0x7a, 0x1e, 0x6f, 0xd9, 0xb8, 0x7a, 0x8e, + 0x31, 0x0f, 0x30, 0xc6, 0xa4, 0x6d, 0x0e, 0x60, 0xfe, 0xaa, 0xd3, 0x2c, 0xb1, 0x5a, 0xbf, 0xbb, + 0x55, 0x6f, 0x28, 0xa7, 0x19, 0x6b, 0xd5, 0xfb, 0x26, 0x6c, 0x0c, 0x0f, 0xf0, 0xbf, 0xf0, 0x4f, + 0xc2, 0xee, 0xa7, 0x7e, 0x9e, 0xb1, 0x6a, 0x6b, 0x77, 0x55, 0xef, 0xf7, 0xeb, 0x0d, 0x5d, 0xb9, + 0xc2, 0x12, 0x1d, 0x70, 0xa3, 0xa3, 0x74, 0x46, 0x49, 0x7a, 0xce, 0xdd, 0x90, 0x6b, 0x55, 0x58, + 0x23, 0x13, 0x25, 0xc3, 0xa2, 0xa0, 0xdf, 0x49, 0x3e, 0xc7, 0xa7, 0x4e, 0xb3, 0x84, 0x35, 0x0c, + 0xaa, 0xbc, 0x53, 0x6f, 0xeb, 0x79, 0xee, 0xbf, 0xc7, 0xd8, 0x9a, 0xfe, 0xec, 0x31, 0xfc, 0xbb, + 0x56, 0x23, 0xfc, 0x47, 0xa7, 0x2e, 0x8f, 0xf6, 0x8f, 0x47, 0x0b, 0xaf, 0x87, 0xdd, 0x1a, 0x3f, + 0x06, 0x92, 0xf2, 0xea, 0x4d, 0x96, 0x5d, 0xee, 0x74, 0xf4, 0x9e, 0x3d, 0x2b, 0x30, 0xf6, 0x8d, + 0xbe, 0x69, 0xbd, 0x1a, 0x14, 0x16, 0xeb, 0x1a, 0x3d, 0x93, 0xaf, 0x5b, 0x8b, 0xc1, 0x2d, 0x33, + 0xa3, 0x4c, 0xb0, 0xf4, 0x8e, 0x01, 0x94, 0x1d, 0x5c, 0x1a, 0x36, 0xe8, 0x94, 0x7a, 0xc0, 0xb2, + 0x55, 0x73, 0xdf, 0x75, 0x02, 0xab, 0x39, 0xd0, 0x0f, 0x69, 0xd6, 0x28, 0x3e, 0x16, 0xbe, 0x50, + 0x6f, 0x0d, 0xf8, 0xdb, 0x21, 0xab, 0x8c, 0xb3, 0xc4, 0xb3, 0x7a, 0xb3, 0xb1, 0x6f, 0x12, 0x37, + 0x02, 0xdd, 0x25, 0xde, 0xc4, 0x05, 0xc0, 0xa3, 0x01, 0x77, 0x79, 0xda, 0xdd, 0xa5, 0x77, 0x5d, + 0x97, 0x53, 0xa9, 0x5d, 0xf9, 0x4b, 0xf0, 0x2f, 0xa2, 0x7e, 0x23, 0xca, 0xd2, 0xab, 0x87, 0xf6, + 0x54, 0xe0, 0x7d, 0xc7, 0x18, 0x74, 0xf8, 0x82, 0xe3, 0xce, 0x86, 0x9d, 0x77, 0xca, 0x9d, 0x81, + 0x61, 0xea, 0x34, 0x55, 0x1a, 0x97, 0xd5, 0xd5, 0x4d, 0x98, 0x08, 0x45, 0x9c, 0x33, 0x6f, 0x5c, + 0x34, 0xaf, 0x72, 0x91, 0x25, 0x0c, 0xdc, 0x5a, 0x1f, 0x1e, 0x1e, 0x51, 0xbf, 0x9d, 0x6f, 0xcb, + 0x0f, 0xb1, 0x34, 0xb4, 0xb1, 0x1a, 0x77, 0x99, 0x0d, 0x9a, 0xfa, 0x5c, 0x5e, 0x61, 0xa9, 0xed, + 0xe6, 0x81, 0xde, 0xdf, 0x87, 0xf8, 0x25, 0x61, 0xf2, 0xf1, 0xe2, 0x59, 0xd7, 0xd2, 0xd9, 0x59, + 0xe1, 0xa6, 0xd1, 0x32, 0x7a, 0xca, 0x0c, 0x54, 0x8e, 0xd1, 0xd6, 0xf9, 0x91, 0xa5, 0xa8, 0xc7, + 0xdd, 0x3b, 0xca, 0x7a, 0x13, 0x8c, 0x78, 0xad, 0x4c, 0xf0, 0x95, 0x6c, 0xe3, 0x9d, 0x0c, 0xaf, + 0x1f, 0x54, 0xa5, 0x32, 0xce, 0xd8, 0xd8, 0xc3, 0x4b, 0x03, 0x2a, 0x1a, 0x2e, 0xfb, 0xa9, 0x69, + 0xa8, 0x2e, 0x87, 0xe1, 0x54, 0x17, 0x4f, 0xf8, 0x34, 0x1e, 0xb6, 0x0a, 0xf1, 0xe1, 0x2b, 0x80, + 0x0e, 0xb2, 0x51, 0xc6, 0x86, 0x05, 0x1d, 0x64, 0x69, 0xa3, 0x5c, 0x5e, 0x83, 0x8e, 0x85, 0xbd, + 0x6b, 0xe5, 0x76, 0x59, 0x8e, 0x78, 0xce, 0xe5, 0x2b, 0x12, 0x8b, 0x96, 0xef, 0x9a, 0x78, 0x04, + 0xb8, 0x36, 0x9e, 0x73, 0xc5, 0x19, 0x16, 0x6b, 0x1b, 0x3d, 0x5d, 0x99, 0x1c, 0xb1, 0x68, 0x78, + 0x59, 0x60, 0xe8, 0x3d, 0xef, 0x58, 0xe0, 0x17, 0xcf, 0xb3, 0x98, 0xa9, 0x83, 0x9f, 0x91, 0x8c, + 0x7d, 0x72, 0x7a, 0x01, 0x4a, 0x63, 0xd0, 0xde, 0xd6, 0x7b, 0xa3, 0x8d, 0x9a, 0xb4, 0x81, 0x4f, + 0x32, 0xf9, 0xa6, 0xd1, 0xee, 0xb6, 0xf4, 0xbb, 0xe0, 0x55, 0xef, 0xf4, 0xa1, 0x49, 0x63, 0x42, + 0xec, 0x35, 0x7b, 0x94, 0xde, 0x28, 0xa1, 0x21, 0x17, 0xfb, 0x3a, 0x24, 0xf3, 0x2e, 0x4f, 0x70, + 0x84, 0xcd, 0xfd, 0x66, 0x0f, 0xd3, 0x1a, 0xdb, 0xc5, 0x12, 0xcb, 0xdd, 0xe2, 0x5a, 0xa4, 0x6f, + 0xb9, 0x86, 0x47, 0x76, 0xd6, 0x1e, 0xa2, 0x07, 0x39, 0x04, 0xe2, 0xe9, 0xf2, 0x46, 0x15, 0xa2, + 0x03, 0x61, 0xaa, 0xae, 0x95, 0x21, 0x36, 0xf0, 0x63, 0xeb, 0xc9, 0xaa, 0x2f, 0x34, 0xf7, 0xb0, + 0xac, 0xb3, 0xba, 0x4d, 0xdd, 0x24, 0x04, 0xdb, 0x4a, 0x52, 0x8b, 0xa4, 0x24, 0x35, 0xc9, 0xe2, + 0xe5, 0x76, 0xd7, 0x3c, 0x54, 0x75, 0x96, 0xb1, 0x8c, 0x56, 0x9a, 0xd0, 0x9f, 0x0a, 0x2c, 0xd9, + 0xb6, 0x76, 0x24, 0xd1, 0x9d, 0xe8, 0x3d, 0x78, 0xd7, 0xce, 0xfe, 0x0d, 0x77, 0x51, 0xd2, 0x53, + 0xc5, 0x56, 0x19, 0x44, 0x78, 0x19, 0xf0, 0x1a, 0x89, 0x62, 0x8d, 0xa8, 0x25, 0x96, 0xe4, 0xf2, + 0xae, 0x4f, 0x2d, 0x9c, 0x2b, 0x3d, 0x7e, 0xf4, 0xbc, 0x4f, 0x40, 0x3e, 0x50, 0xf6, 0x58, 0x83, + 0x54, 0xb7, 0xea, 0x73, 0x31, 0x96, 0xb2, 0xb7, 0x0e, 0xbc, 0x04, 0x17, 0x63, 0xc4, 0xb0, 0x65, + 0xf4, 0x24, 0x4b, 0x5a, 0xf2, 0xcb, 0x6a, 0x18, 0x28, 0x9e, 0xed, 0x41, 0xb8, 0x20, 0xa2, 0x8e, + 0x64, 0x3e, 0xcd, 0xd2, 0x8e, 0xbc, 0xa2, 0xc2, 0xb7, 0x84, 0xb2, 0x3b, 0x0e, 0xe6, 0x71, 0x57, + 0x1e, 0x9f, 0x86, 0x1b, 0xcb, 0x12, 0x50, 0xf4, 0x01, 0xc0, 0x16, 0xc5, 0xce, 0x38, 0x98, 0x27, + 0x3d, 0x52, 0xf8, 0x0c, 0x4e, 0x4a, 0x22, 0x89, 0x6a, 0xc6, 0x15, 0xc0, 0x79, 0x24, 0x70, 0x61, + 0x44, 0x79, 0xee, 0xca, 0x5e, 0x15, 0x11, 0x1e, 0x17, 0xa8, 0x9a, 0xd1, 0x62, 0x37, 0x8f, 0x6e, + 0x49, 0xec, 0x52, 0x19, 0x79, 0x14, 0xee, 0x29, 0x62, 0xf3, 0x05, 0x66, 0x5d, 0x59, 0xeb, 0x0c, + 0xd3, 0xf5, 0xe8, 0x68, 0xd9, 0x47, 0x31, 0x7c, 0x98, 0x3f, 0x70, 0x3d, 0x62, 0xfd, 0xe7, 0xdd, + 0x83, 0xb5, 0x43, 0xcc, 0xcb, 0x5f, 0xe3, 0x15, 0x07, 0x41, 0x04, 0xc2, 0x7a, 0xb3, 0xb3, 0x07, + 0x97, 0x27, 0x6e, 0x27, 0x0a, 0x3f, 0xf9, 0x21, 0xac, 0xe1, 0xa0, 0x4c, 0x83, 0xb1, 0x47, 0x70, + 0x54, 0x01, 0xc1, 0x50, 0x5b, 0xab, 0x77, 0xe0, 0x3a, 0x24, 0xcb, 0x4e, 0xbd, 0x03, 0x7b, 0x8b, + 0xf6, 0x07, 0xdb, 0x79, 0x25, 0xf8, 0xe9, 0x64, 0x73, 0xb0, 0xed, 0x1c, 0xa9, 0xc2, 0x52, 0x90, + 0x0a, 0xb5, 0x2f, 0xea, 0x3d, 0x23, 0x3f, 0x49, 0xfb, 0x3f, 0x71, 0xcc, 0x1e, 0x00, 0xd7, 0x6a, + 0xc6, 0xeb, 0x29, 0xcb, 0xa4, 0x0e, 0xef, 0xfd, 0x9a, 0x74, 0x55, 0x5d, 0x65, 0x59, 0x5b, 0x49, + 0x51, 0xc5, 0x5c, 0xc1, 0x64, 0x04, 0x9f, 0x94, 0xd3, 0xe3, 0xc5, 0x7b, 0xdc, 0xd5, 0x78, 0xcd, + 0xf8, 0xf6, 0x55, 0x39, 0xb0, 0x00, 0x49, 0xfd, 0xa6, 0x04, 0xb5, 0x04, 0x0d, 0xc5, 0x36, 0xc6, + 0xe4, 0xde, 0x86, 0x44, 0xec, 0x93, 0x3f, 0x7c, 0x2f, 0x67, 0xe9, 0x4f, 0x5b, 0xa0, 0x46, 0x9c, + 0xc7, 0x01, 0xd4, 0x04, 0x1c, 0x44, 0x9f, 0xd7, 0x36, 0x64, 0x48, 0x06, 0xff, 0xb2, 0xcd, 0x62, + 0xce, 0xf3, 0xe0, 0x2c, 0x1b, 0xa3, 0xf3, 0x72, 0xa0, 0xa4, 0xf3, 0x28, 0xc8, 0xb1, 0x24, 0xaf, + 0x96, 0x3e, 0x7d, 0xb3, 0x4a, 0x63, 0xff, 0x20, 0xf1, 0xc3, 0x2f, 0x87, 0xa4, 0xfa, 0xff, 0x2c, + 0x45, 0x1d, 0x15, 0xee, 0x7f, 0xe5, 0x7e, 0x26, 0x35, 0xf2, 0x3a, 0x35, 0xec, 0x93, 0x1e, 0xa9, + 0x63, 0xc1, 0x85, 0xa5, 0xa9, 0x71, 0x26, 0x2d, 0xa1, 0x38, 0xb9, 0xcb, 0x8b, 0x45, 0xad, 0x58, + 0x64, 0xb8, 0xdc, 0x45, 0x64, 0x80, 0x81, 0x7c, 0xd6, 0x4f, 0xc6, 0x9f, 0x87, 0xfc, 0x6b, 0x1c, + 0x0a, 0x20, 0xca, 0x7c, 0x58, 0xe7, 0xba, 0x01, 0x5b, 0x41, 0x6c, 0x8f, 0xae, 0x47, 0x49, 0xfd, + 0x20, 0xca, 0xc6, 0xad, 0x1e, 0xf1, 0x64, 0xd3, 0xdc, 0x5f, 0xad, 0x77, 0x95, 0xc7, 0x58, 0x16, + 0x5b, 0x45, 0xad, 0x5d, 0xef, 0x76, 0x31, 0xf7, 0x25, 0xba, 0xbb, 0x1e, 0x1a, 0x6a, 0x35, 0x96, + 0x7d, 0x61, 0x0d, 0x8c, 0x57, 0xb9, 0x6d, 0xb9, 0x63, 0xf6, 0x0e, 0x95, 0x4f, 0xb0, 0x4c, 0xbb, + 0xdf, 0x70, 0xf8, 0x11, 0xe2, 0x5f, 0x0a, 0xe5, 0xaf, 0xf6, 0x1b, 0x3e, 0x3a, 0xcc, 0x8f, 0xcd, + 0xc6, 0xe1, 0x47, 0x8f, 0x98, 0x1f, 0xcb, 0xcf, 0xe7, 0x40, 0x03, 0xc1, 0x0a, 0x89, 0x6b, 0x1a, + 0xa8, 0x03, 0xe9, 0x20, 0x33, 0xc5, 0x8b, 0xa1, 0x74, 0xa8, 0xf0, 0x2d, 0x03, 0xfe, 0x43, 0xdc, + 0xa9, 0x22, 0x93, 0x87, 0xf6, 0xe3, 0x11, 0x2f, 0x71, 0xbf, 0x78, 0x49, 0x6b, 0x91, 0x6b, 0xd2, + 0xd4, 0xa7, 0x58, 0x2e, 0xb8, 0x07, 0x0f, 0x45, 0x01, 0xc5, 0xe0, 0xa1, 0x64, 0x8a, 0x67, 0x3c, + 0x5f, 0x69, 0xbd, 0xc7, 0x42, 0xbe, 0x60, 0xfe, 0xa1, 0xfd, 0x78, 0x9c, 0xa5, 0x02, 0xe2, 0x89, + 0x38, 0x8f, 0xb2, 0x31, 0xdf, 0x26, 0xbc, 0x84, 0xf4, 0x88, 0x05, 0xab, 0xef, 0x47, 0x59, 0xbc, + 0xda, 0xd1, 0x8d, 0x3d, 0xd0, 0x01, 0xbe, 0xb6, 0xfd, 0xf8, 0x09, 0x10, 0x0b, 0xfe, 0x96, 0xed, + 0x19, 0xb2, 0x1b, 0x36, 0x0c, 0x4d, 0x0e, 0xb5, 0x6b, 0xdf, 0xa0, 0xdd, 0xab, 0x61, 0x50, 0x09, + 0x36, 0x6a, 0xef, 0x98, 0xdd, 0xa4, 0xed, 0x49, 0x3c, 0x0d, 0xda, 0x36, 0xf3, 0xb6, 0x66, 0x7b, + 0xcc, 0xdb, 0x94, 0x6d, 0xaa, 0xa7, 0x09, 0x3b, 0x66, 0x9e, 0xee, 0xeb, 0x1d, 0xb3, 0x5b, 0x2f, + 0x8c, 0x5d, 0x09, 0xf4, 0xdd, 0x70, 0xdd, 0x05, 0xc6, 0x97, 0x71, 0x7f, 0xb6, 0xa4, 0xc8, 0x09, + 0xbe, 0x3a, 0x93, 0x6d, 0x72, 0xcf, 0x92, 0xd5, 0x32, 0x55, 0xad, 0xe7, 0xd4, 0x29, 0xf4, 0x85, + 0x4a, 0x8d, 0xaa, 0x17, 0x6c, 0xcf, 0x41, 0x7d, 0xd6, 0x56, 0xea, 0xbd, 0x06, 0x18, 0xd4, 0xe0, + 0xb9, 0xe1, 0x3c, 0x30, 0x30, 0xf8, 0x39, 0xfb, 0xf8, 0x76, 0x69, 0x40, 0x9a, 0x3a, 0x89, 0xbb, + 0xe5, 0x32, 0x8d, 0xca, 0x1d, 0xbb, 0x7a, 0x7c, 0x11, 0x24, 0xc3, 0xa0, 0x03, 0x82, 0x66, 0x31, + 0xcd, 0x92, 0xa6, 0xd1, 0x6b, 0xd7, 0x4d, 0x43, 0xfd, 0x2e, 0xbc, 0xe3, 0x40, 0xf0, 0xb4, 0x01, + 0xb8, 0x43, 0x97, 0x71, 0xa6, 0x5d, 0x3f, 0x80, 0xba, 0xd2, 0x6b, 0x3b, 0x3d, 0x3b, 0x9d, 0x64, + 0x5b, 0x38, 0xd1, 0x81, 0xe1, 0x84, 0xe3, 0x96, 0x52, 0x48, 0x58, 0xd1, 0x1d, 0xb7, 0xd4, 0x5b, + 0xd2, 0x0a, 0x2d, 0x30, 0x4c, 0xbd, 0xdd, 0xad, 0xed, 0xd0, 0x39, 0xe1, 0x99, 0x5c, 0x62, 0x51, + 0x68, 0xe0, 0x74, 0x44, 0x47, 0x44, 0x70, 0x9a, 0x45, 0xa1, 0x33, 0xd0, 0xc1, 0x65, 0x8a, 0x13, + 0x9e, 0x6b, 0x87, 0x37, 0xd1, 0xc7, 0x4f, 0x38, 0xfb, 0xb8, 0x9c, 0x63, 0xd1, 0x4a, 0xb5, 0x8a, + 0x77, 0x0a, 0xfc, 0x6f, 0x56, 0x96, 0xb4, 0x07, 0x59, 0xaa, 0xd1, 0xd3, 0x75, 0x2c, 0x97, 0xd1, + 0x22, 0xef, 0x19, 0xec, 0xc0, 0xda, 0x2d, 0x96, 0xdc, 0xe1, 0x22, 0x4f, 0x09, 0x51, 0xe6, 0xf9, + 0xef, 0xf1, 0xe7, 0xd3, 0x94, 0x0b, 0x07, 0x65, 0xa1, 0x56, 0x01, 0xc9, 0x5c, 0x3b, 0xca, 0xcf, + 0xf3, 0xbc, 0x33, 0x8a, 0xfc, 0x94, 0xd8, 0x44, 0xc7, 0xb0, 0xbf, 0x5f, 0xd5, 0x76, 0x29, 0x97, + 0x95, 0xb3, 0xc3, 0x97, 0xbb, 0xed, 0x52, 0x27, 0x05, 0x32, 0xc7, 0x64, 0x0f, 0x8b, 0x54, 0xba, + 0x88, 0xb4, 0x47, 0xf7, 0xba, 0x9f, 0x44, 0xa9, 0x2f, 0x22, 0x35, 0x48, 0x8f, 0x0d, 0x91, 0x40, + 0x8b, 0x08, 0x48, 0xfb, 0x74, 0x87, 0xfb, 0x37, 0x35, 0x38, 0x72, 0xaa, 0x26, 0xe9, 0xb3, 0x61, + 0x96, 0x78, 0xae, 0x67, 0x48, 0xbd, 0xf9, 0x59, 0xfd, 0x23, 0xe7, 0x3a, 0x20, 0xa9, 0x35, 0xcc, + 0x12, 0xcf, 0xd5, 0x22, 0x25, 0x36, 0xcf, 0x14, 0x6f, 0xd8, 0x79, 0x77, 0x13, 0xd1, 0xda, 0xa4, + 0x53, 0x47, 0xd0, 0xc4, 0xb3, 0x75, 0x48, 0xc6, 0x2e, 0xb0, 0x49, 0xef, 0x1a, 0x8f, 0x31, 0x9d, + 0x01, 0xbc, 0xdc, 0x48, 0x9e, 0x78, 0xbe, 0x2e, 0xf0, 0x64, 0xad, 0xc8, 0x72, 0x1e, 0x1e, 0x4a, + 0x22, 0x11, 0xe7, 0x0e, 0xa9, 0xf8, 0x40, 0x1c, 0xa9, 0x4a, 0x45, 0xac, 0x1e, 0x5d, 0x31, 0xfe, + 0xa4, 0xa2, 0x87, 0x83, 0x88, 0xd4, 0xa7, 0x8b, 0xec, 0x69, 0xdf, 0xf2, 0x74, 0x14, 0x86, 0x02, + 0x8e, 0x49, 0xbd, 0xe6, 0x62, 0xa8, 0x41, 0xc1, 0xfb, 0x26, 0xd3, 0x34, 0x36, 0x7e, 0xfc, 0x12, + 0x7c, 0x5e, 0xe2, 0xaf, 0x80, 0xb9, 0x02, 0x3e, 0x10, 0xb4, 0xab, 0x6c, 0xec, 0xd8, 0x85, 0xf8, + 0x82, 0xc4, 0x65, 0x37, 0x52, 0x21, 0x2d, 0xc6, 0x8e, 0x5d, 0x8c, 0x2f, 0x4a, 0xfc, 0x75, 0x54, + 0x2a, 0x06, 0x68, 0xe2, 0x83, 0x7d, 0x89, 0x6b, 0xea, 0x48, 0x69, 0x0e, 0xb2, 0x62, 0xfc, 0xf8, + 0x05, 0xf9, 0xb2, 0x44, 0x15, 0x19, 0x29, 0x95, 0x82, 0x3c, 0xf1, 0x7c, 0xaf, 0x48, 0x54, 0x93, + 0x91, 0xd2, 0xbc, 0x97, 0x77, 0x74, 0x51, 0xbe, 0x2a, 0x51, 0x55, 0x46, 0x4a, 0x0b, 0x41, 0x9e, + 0x78, 0xbe, 0xd7, 0x48, 0x3f, 0x01, 0xef, 0x2a, 0x1c, 0x43, 0xee, 0x63, 0x14, 0xe6, 0xeb, 0x12, + 0x55, 0x66, 0xa4, 0x74, 0x6d, 0x88, 0x28, 0x9e, 0xf1, 0x0d, 0x89, 0x6a, 0x33, 0x52, 0xba, 0xae, + 0x5d, 0x63, 0xf2, 0xc7, 0x29, 0xce, 0x37, 0x25, 0xaa, 0xce, 0xc8, 0xfc, 0xcc, 0x30, 0x53, 0x3c, + 0xe7, 0x5b, 0x12, 0xd5, 0x67, 0x64, 0x7e, 0x16, 0xa2, 0x93, 0x3d, 0x6e, 0x81, 0xbe, 0xed, 0x79, + 0x67, 0x6b, 0x37, 0x3c, 0x51, 0x3d, 0xb2, 0x48, 0xdf, 0x21, 0x5d, 0xa8, 0x8d, 0x3d, 0xce, 0x1f, + 0xb3, 0x9c, 0xa0, 0x3d, 0xe6, 0xe6, 0xdd, 0x91, 0x15, 0xfb, 0xae, 0x44, 0x25, 0x9b, 0xb5, 0x3c, + 0x90, 0xbd, 0xf6, 0x39, 0x77, 0xed, 0x47, 0x55, 0xef, 0x7b, 0xd2, 0xc7, 0x2a, 0x5f, 0xfc, 0x8c, + 0x02, 0xa1, 0x89, 0xdd, 0x2d, 0xce, 0xcc, 0x7a, 0x2f, 0x63, 0xef, 0x17, 0x14, 0x5e, 0xb6, 0x99, + 0x62, 0xce, 0xf3, 0xe9, 0x08, 0x3f, 0xa1, 0x58, 0xbc, 0x62, 0x28, 0xef, 0x05, 0x21, 0x6f, 0x2e, + 0x94, 0xf7, 0xa2, 0x90, 0x57, 0x0a, 0xe5, 0xbd, 0x24, 0xe4, 0xcd, 0x87, 0xf2, 0x5e, 0x16, 0xf2, + 0x16, 0x42, 0x79, 0xaf, 0x08, 0x79, 0x57, 0x43, 0x79, 0xaf, 0x0a, 0x79, 0xd7, 0x42, 0x79, 0xaf, + 0x09, 0x79, 0xd7, 0x43, 0x79, 0xaf, 0x8b, 0x78, 0xb3, 0x33, 0xa1, 0xbc, 0x37, 0x84, 0xbc, 0xf0, + 0x7c, 0x79, 0x53, 0xc8, 0x0b, 0xcf, 0x97, 0xb7, 0x84, 0xbc, 0xf0, 0x7c, 0x79, 0x5b, 0xc8, 0x0b, + 0xcf, 0x97, 0x77, 0x84, 0xbc, 0xf0, 0x7c, 0x79, 0x57, 0xc8, 0x0b, 0xcf, 0x97, 0xf7, 0x84, 0xbc, + 0xf0, 0x7c, 0xf9, 0xbe, 0x90, 0x17, 0x9e, 0x2f, 0x3f, 0x10, 0xf2, 0xc2, 0xf3, 0xe5, 0x87, 0x22, + 0x5e, 0x31, 0x3c, 0x5f, 0x7e, 0x24, 0xe4, 0x85, 0xe7, 0xcb, 0x8f, 0x85, 0xbc, 0xf0, 0x7c, 0xf9, + 0x89, 0x90, 0x17, 0x9e, 0x2f, 0x3f, 0x15, 0xf2, 0xc2, 0xf3, 0xe5, 0x67, 0x42, 0x5e, 0x78, 0xbe, + 0xfc, 0x5c, 0xc8, 0x0b, 0xcf, 0x97, 0x5f, 0x08, 0x79, 0xe1, 0xf9, 0xf2, 0x4b, 0x21, 0x2f, 0x3c, + 0x5f, 0xde, 0x17, 0xf2, 0xc2, 0xf3, 0xe5, 0x57, 0x22, 0xde, 0x5c, 0x78, 0xbe, 0xfc, 0x5a, 0xc8, + 0x0b, 0xcf, 0x97, 0xdf, 0x08, 0x79, 0xe1, 0xf9, 0xf2, 0x5b, 0x21, 0x2f, 0x3c, 0x5f, 0x7e, 0x27, + 0xe4, 0x85, 0xe7, 0xcb, 0xef, 0x85, 0xbc, 0xf0, 0x7c, 0xf9, 0x83, 0x90, 0x17, 0x9e, 0x2f, 0x7f, + 0x14, 0xf2, 0xc2, 0xf3, 0xe5, 0x4f, 0x42, 0x5e, 0x78, 0xbe, 0xfc, 0x59, 0xc8, 0x0b, 0xcf, 0x97, + 0xbf, 0x88, 0x78, 0xa5, 0xf0, 0x7c, 0xf9, 0xab, 0x90, 0x17, 0x9e, 0x2f, 0x7f, 0x13, 0xf2, 0xc2, + 0xf3, 0xe5, 0x03, 0x21, 0x2f, 0x3c, 0x5f, 0xfe, 0x2e, 0xe4, 0x85, 0xe7, 0xcb, 0x3f, 0x84, 0xbc, + 0xf0, 0x7c, 0xf9, 0xa7, 0x90, 0x17, 0x9e, 0x2f, 0x1f, 0x0a, 0x79, 0xe1, 0xf9, 0xf2, 0x91, 0x90, + 0x17, 0x9e, 0x2f, 0xff, 0x12, 0xf2, 0xc2, 0xf3, 0xe5, 0xdf, 0x22, 0xde, 0x7c, 0x78, 0xbe, 0xfc, + 0x67, 0x34, 0xef, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x8e, 0xa4, 0xcf, 0x8d, 0xf9, 0x2b, 0x00, + 0x00, +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/test.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/test.proto new file mode 100644 index 00000000..698c8ce2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/testdata/test.proto @@ -0,0 +1,535 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// A feature-rich test file for the protocol compiler and libraries. + +syntax = "proto2"; + +package testdata; + +enum FOO { FOO1 = 1; }; + +message GoEnum { + required FOO foo = 1; +} + +message GoTestField { + required string Label = 1; + required string Type = 2; +} + +message GoTest { + // An enum, for completeness. + enum KIND { + VOID = 0; + + // Basic types + BOOL = 1; + BYTES = 2; + FINGERPRINT = 3; + FLOAT = 4; + INT = 5; + STRING = 6; + TIME = 7; + + // Groupings + TUPLE = 8; + ARRAY = 9; + MAP = 10; + + // Table types + TABLE = 11; + + // Functions + FUNCTION = 12; // last tag + }; + + // Some typical parameters + required KIND Kind = 1; + optional string Table = 2; + optional int32 Param = 3; + + // Required, repeated and optional foreign fields. + required GoTestField RequiredField = 4; + repeated GoTestField RepeatedField = 5; + optional GoTestField OptionalField = 6; + + // Required fields of all basic types + required bool F_Bool_required = 10; + required int32 F_Int32_required = 11; + required int64 F_Int64_required = 12; + required fixed32 F_Fixed32_required = 13; + required fixed64 F_Fixed64_required = 14; + required uint32 F_Uint32_required = 15; + required uint64 F_Uint64_required = 16; + required float F_Float_required = 17; + required double F_Double_required = 18; + required string F_String_required = 19; + required bytes F_Bytes_required = 101; + required sint32 F_Sint32_required = 102; + required sint64 F_Sint64_required = 103; + + // Repeated fields of all basic types + repeated bool F_Bool_repeated = 20; + repeated int32 F_Int32_repeated = 21; + repeated int64 F_Int64_repeated = 22; + repeated fixed32 F_Fixed32_repeated = 23; + repeated fixed64 F_Fixed64_repeated = 24; + repeated uint32 F_Uint32_repeated = 25; + repeated uint64 F_Uint64_repeated = 26; + repeated float F_Float_repeated = 27; + repeated double F_Double_repeated = 28; + repeated string F_String_repeated = 29; + repeated bytes F_Bytes_repeated = 201; + repeated sint32 F_Sint32_repeated = 202; + repeated sint64 F_Sint64_repeated = 203; + + // Optional fields of all basic types + optional bool F_Bool_optional = 30; + optional int32 F_Int32_optional = 31; + optional int64 F_Int64_optional = 32; + optional fixed32 F_Fixed32_optional = 33; + optional fixed64 F_Fixed64_optional = 34; + optional uint32 F_Uint32_optional = 35; + optional uint64 F_Uint64_optional = 36; + optional float F_Float_optional = 37; + optional double F_Double_optional = 38; + optional string F_String_optional = 39; + optional bytes F_Bytes_optional = 301; + optional sint32 F_Sint32_optional = 302; + optional sint64 F_Sint64_optional = 303; + + // Default-valued fields of all basic types + optional bool F_Bool_defaulted = 40 [default=true]; + optional int32 F_Int32_defaulted = 41 [default=32]; + optional int64 F_Int64_defaulted = 42 [default=64]; + optional fixed32 F_Fixed32_defaulted = 43 [default=320]; + optional fixed64 F_Fixed64_defaulted = 44 [default=640]; + optional uint32 F_Uint32_defaulted = 45 [default=3200]; + optional uint64 F_Uint64_defaulted = 46 [default=6400]; + optional float F_Float_defaulted = 47 [default=314159.]; + optional double F_Double_defaulted = 48 [default=271828.]; + optional string F_String_defaulted = 49 [default="hello, \"world!\"\n"]; + optional bytes F_Bytes_defaulted = 401 [default="Bignose"]; + optional sint32 F_Sint32_defaulted = 402 [default = -32]; + optional sint64 F_Sint64_defaulted = 403 [default = -64]; + + // Packed repeated fields (no string or bytes). + repeated bool F_Bool_repeated_packed = 50 [packed=true]; + repeated int32 F_Int32_repeated_packed = 51 [packed=true]; + repeated int64 F_Int64_repeated_packed = 52 [packed=true]; + repeated fixed32 F_Fixed32_repeated_packed = 53 [packed=true]; + repeated fixed64 F_Fixed64_repeated_packed = 54 [packed=true]; + repeated uint32 F_Uint32_repeated_packed = 55 [packed=true]; + repeated uint64 F_Uint64_repeated_packed = 56 [packed=true]; + repeated float F_Float_repeated_packed = 57 [packed=true]; + repeated double F_Double_repeated_packed = 58 [packed=true]; + repeated sint32 F_Sint32_repeated_packed = 502 [packed=true]; + repeated sint64 F_Sint64_repeated_packed = 503 [packed=true]; + + // Required, repeated, and optional groups. + required group RequiredGroup = 70 { + required string RequiredField = 71; + }; + + repeated group RepeatedGroup = 80 { + required string RequiredField = 81; + }; + + optional group OptionalGroup = 90 { + required string RequiredField = 91; + }; +} + +// For testing skipping of unrecognized fields. +// Numbers are all big, larger than tag numbers in GoTestField, +// the message used in the corresponding test. +message GoSkipTest { + required int32 skip_int32 = 11; + required fixed32 skip_fixed32 = 12; + required fixed64 skip_fixed64 = 13; + required string skip_string = 14; + required group SkipGroup = 15 { + required int32 group_int32 = 16; + required string group_string = 17; + } +} + +// For testing packed/non-packed decoder switching. +// A serialized instance of one should be deserializable as the other. +message NonPackedTest { + repeated int32 a = 1; +} + +message PackedTest { + repeated int32 b = 1 [packed=true]; +} + +message MaxTag { + // Maximum possible tag number. + optional string last_field = 536870911; +} + +message OldMessage { + message Nested { + optional string name = 1; + } + optional Nested nested = 1; + + optional int32 num = 2; +} + +// NewMessage is wire compatible with OldMessage; +// imagine it as a future version. +message NewMessage { + message Nested { + optional string name = 1; + optional string food_group = 2; + } + optional Nested nested = 1; + + // This is an int32 in OldMessage. + optional int64 num = 2; +} + +// Smaller tests for ASCII formatting. + +message InnerMessage { + required string host = 1; + optional int32 port = 2 [default=4000]; + optional bool connected = 3; +} + +message OtherMessage { + optional int64 key = 1; + optional bytes value = 2; + optional float weight = 3; + optional InnerMessage inner = 4; + + extensions 100 to max; +} + +message MyMessage { + required int32 count = 1; + optional string name = 2; + optional string quote = 3; + repeated string pet = 4; + optional InnerMessage inner = 5; + repeated OtherMessage others = 6; + repeated InnerMessage rep_inner = 12; + + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + }; + optional Color bikeshed = 7; + + optional group SomeGroup = 8 { + optional int32 group_field = 9; + } + + // This field becomes [][]byte in the generated code. + repeated bytes rep_bytes = 10; + + optional double bigfloat = 11; + + extensions 100 to max; +} + +message Ext { + extend MyMessage { + optional Ext more = 103; + optional string text = 104; + optional int32 number = 105; + } + + optional string data = 1; +} + +extend MyMessage { + repeated string greeting = 106; +} + +message ComplexExtension { + optional int32 first = 1; + optional int32 second = 2; + repeated int32 third = 3; +} + +extend OtherMessage { + optional ComplexExtension complex = 200; + repeated ComplexExtension r_complex = 201; +} + +message DefaultsMessage { + enum DefaultsEnum { + ZERO = 0; + ONE = 1; + TWO = 2; + }; + extensions 100 to max; +} + +extend DefaultsMessage { + optional double no_default_double = 101; + optional float no_default_float = 102; + optional int32 no_default_int32 = 103; + optional int64 no_default_int64 = 104; + optional uint32 no_default_uint32 = 105; + optional uint64 no_default_uint64 = 106; + optional sint32 no_default_sint32 = 107; + optional sint64 no_default_sint64 = 108; + optional fixed32 no_default_fixed32 = 109; + optional fixed64 no_default_fixed64 = 110; + optional sfixed32 no_default_sfixed32 = 111; + optional sfixed64 no_default_sfixed64 = 112; + optional bool no_default_bool = 113; + optional string no_default_string = 114; + optional bytes no_default_bytes = 115; + optional DefaultsMessage.DefaultsEnum no_default_enum = 116; + + optional double default_double = 201 [default = 3.1415]; + optional float default_float = 202 [default = 3.14]; + optional int32 default_int32 = 203 [default = 42]; + optional int64 default_int64 = 204 [default = 43]; + optional uint32 default_uint32 = 205 [default = 44]; + optional uint64 default_uint64 = 206 [default = 45]; + optional sint32 default_sint32 = 207 [default = 46]; + optional sint64 default_sint64 = 208 [default = 47]; + optional fixed32 default_fixed32 = 209 [default = 48]; + optional fixed64 default_fixed64 = 210 [default = 49]; + optional sfixed32 default_sfixed32 = 211 [default = 50]; + optional sfixed64 default_sfixed64 = 212 [default = 51]; + optional bool default_bool = 213 [default = true]; + optional string default_string = 214 [default = "Hello, string"]; + optional bytes default_bytes = 215 [default = "Hello, bytes"]; + optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE]; +} + +message MyMessageSet { + option message_set_wire_format = true; + extensions 100 to max; +} + +message Empty { +} + +extend MyMessageSet { + optional Empty x201 = 201; + optional Empty x202 = 202; + optional Empty x203 = 203; + optional Empty x204 = 204; + optional Empty x205 = 205; + optional Empty x206 = 206; + optional Empty x207 = 207; + optional Empty x208 = 208; + optional Empty x209 = 209; + optional Empty x210 = 210; + optional Empty x211 = 211; + optional Empty x212 = 212; + optional Empty x213 = 213; + optional Empty x214 = 214; + optional Empty x215 = 215; + optional Empty x216 = 216; + optional Empty x217 = 217; + optional Empty x218 = 218; + optional Empty x219 = 219; + optional Empty x220 = 220; + optional Empty x221 = 221; + optional Empty x222 = 222; + optional Empty x223 = 223; + optional Empty x224 = 224; + optional Empty x225 = 225; + optional Empty x226 = 226; + optional Empty x227 = 227; + optional Empty x228 = 228; + optional Empty x229 = 229; + optional Empty x230 = 230; + optional Empty x231 = 231; + optional Empty x232 = 232; + optional Empty x233 = 233; + optional Empty x234 = 234; + optional Empty x235 = 235; + optional Empty x236 = 236; + optional Empty x237 = 237; + optional Empty x238 = 238; + optional Empty x239 = 239; + optional Empty x240 = 240; + optional Empty x241 = 241; + optional Empty x242 = 242; + optional Empty x243 = 243; + optional Empty x244 = 244; + optional Empty x245 = 245; + optional Empty x246 = 246; + optional Empty x247 = 247; + optional Empty x248 = 248; + optional Empty x249 = 249; + optional Empty x250 = 250; +} + +message MessageList { + repeated group Message = 1 { + required string name = 2; + required int32 count = 3; + } +} + +message Strings { + optional string string_field = 1; + optional bytes bytes_field = 2; +} + +message Defaults { + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + } + + // Default-valued fields of all basic types. + // Same as GoTest, but copied here to make testing easier. + optional bool F_Bool = 1 [default=true]; + optional int32 F_Int32 = 2 [default=32]; + optional int64 F_Int64 = 3 [default=64]; + optional fixed32 F_Fixed32 = 4 [default=320]; + optional fixed64 F_Fixed64 = 5 [default=640]; + optional uint32 F_Uint32 = 6 [default=3200]; + optional uint64 F_Uint64 = 7 [default=6400]; + optional float F_Float = 8 [default=314159.]; + optional double F_Double = 9 [default=271828.]; + optional string F_String = 10 [default="hello, \"world!\"\n"]; + optional bytes F_Bytes = 11 [default="Bignose"]; + optional sint32 F_Sint32 = 12 [default=-32]; + optional sint64 F_Sint64 = 13 [default=-64]; + optional Color F_Enum = 14 [default=GREEN]; + + // More fields with crazy defaults. + optional float F_Pinf = 15 [default=inf]; + optional float F_Ninf = 16 [default=-inf]; + optional float F_Nan = 17 [default=nan]; + + // Sub-message. + optional SubDefaults sub = 18; + + // Redundant but explicit defaults. + optional string str_zero = 19 [default=""]; +} + +message SubDefaults { + optional int64 n = 1 [default=7]; +} + +message RepeatedEnum { + enum Color { + RED = 1; + } + repeated Color color = 1; +} + +message MoreRepeated { + repeated bool bools = 1; + repeated bool bools_packed = 2 [packed=true]; + repeated int32 ints = 3; + repeated int32 ints_packed = 4 [packed=true]; + repeated int64 int64s_packed = 7 [packed=true]; + repeated string strings = 5; + repeated fixed32 fixeds = 6; +} + +// GroupOld and GroupNew have the same wire format. +// GroupNew has a new field inside a group. + +message GroupOld { + optional group G = 101 { + optional int32 x = 2; + } +} + +message GroupNew { + optional group G = 101 { + optional int32 x = 2; + optional int32 y = 3; + } +} + +message FloatingPoint { + required double f = 1; +} + +message MessageWithMap { + map name_mapping = 1; + map msg_mapping = 2; + map byte_mapping = 3; + map str_to_str = 4; +} + +message Oneof { + oneof union { + bool F_Bool = 1; + int32 F_Int32 = 2; + int64 F_Int64 = 3; + fixed32 F_Fixed32 = 4; + fixed64 F_Fixed64 = 5; + uint32 F_Uint32 = 6; + uint64 F_Uint64 = 7; + float F_Float = 8; + double F_Double = 9; + string F_String = 10; + bytes F_Bytes = 11; + sint32 F_Sint32 = 12; + sint64 F_Sint64 = 13; + MyMessage.Color F_Enum = 14; + GoTestField F_Message = 15; + group F_Group = 16 { + optional int32 x = 17; + } + int32 F_Largest_Tag = 536870911; + } + + oneof tormato { + int32 value = 100; + } +} + +message Communique { + optional bool make_me_cry = 1; + + // This is a oneof, called "union". + oneof union { + int32 number = 5; + string name = 6; + bytes data = 7; + double temp_c = 8; + MyMessage.Color col = 9; + Strings msg = 10; + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text.go new file mode 100644 index 00000000..2336b144 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text.go @@ -0,0 +1,751 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +// Functions for writing the text protocol buffer format. + +import ( + "bufio" + "bytes" + "encoding" + "errors" + "fmt" + "io" + "log" + "math" + "reflect" + "sort" + "strings" +) + +var ( + newline = []byte("\n") + spaces = []byte(" ") + gtNewline = []byte(">\n") + endBraceNewline = []byte("}\n") + backslashN = []byte{'\\', 'n'} + backslashR = []byte{'\\', 'r'} + backslashT = []byte{'\\', 't'} + backslashDQ = []byte{'\\', '"'} + backslashBS = []byte{'\\', '\\'} + posInf = []byte("inf") + negInf = []byte("-inf") + nan = []byte("nan") +) + +type writer interface { + io.Writer + WriteByte(byte) error +} + +// textWriter is an io.Writer that tracks its indentation level. +type textWriter struct { + ind int + complete bool // if the current position is a complete line + compact bool // whether to write out as a one-liner + w writer +} + +func (w *textWriter) WriteString(s string) (n int, err error) { + if !strings.Contains(s, "\n") { + if !w.compact && w.complete { + w.writeIndent() + } + w.complete = false + return io.WriteString(w.w, s) + } + // WriteString is typically called without newlines, so this + // codepath and its copy are rare. We copy to avoid + // duplicating all of Write's logic here. + return w.Write([]byte(s)) +} + +func (w *textWriter) Write(p []byte) (n int, err error) { + newlines := bytes.Count(p, newline) + if newlines == 0 { + if !w.compact && w.complete { + w.writeIndent() + } + n, err = w.w.Write(p) + w.complete = false + return n, err + } + + frags := bytes.SplitN(p, newline, newlines+1) + if w.compact { + for i, frag := range frags { + if i > 0 { + if err := w.w.WriteByte(' '); err != nil { + return n, err + } + n++ + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + } + return n, nil + } + + for i, frag := range frags { + if w.complete { + w.writeIndent() + } + nn, err := w.w.Write(frag) + n += nn + if err != nil { + return n, err + } + if i+1 < len(frags) { + if err := w.w.WriteByte('\n'); err != nil { + return n, err + } + n++ + } + } + w.complete = len(frags[len(frags)-1]) == 0 + return n, nil +} + +func (w *textWriter) WriteByte(c byte) error { + if w.compact && c == '\n' { + c = ' ' + } + if !w.compact && w.complete { + w.writeIndent() + } + err := w.w.WriteByte(c) + w.complete = c == '\n' + return err +} + +func (w *textWriter) indent() { w.ind++ } + +func (w *textWriter) unindent() { + if w.ind == 0 { + log.Printf("proto: textWriter unindented too far") + return + } + w.ind-- +} + +func writeName(w *textWriter, props *Properties) error { + if _, err := w.WriteString(props.OrigName); err != nil { + return err + } + if props.Wire != "group" { + return w.WriteByte(':') + } + return nil +} + +// raw is the interface satisfied by RawMessage. +type raw interface { + Bytes() []byte +} + +func writeStruct(w *textWriter, sv reflect.Value) error { + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < sv.NumField(); i++ { + fv := sv.Field(i) + props := sprops.Prop[i] + name := st.Field(i).Name + + if strings.HasPrefix(name, "XXX_") { + // There are two XXX_ fields: + // XXX_unrecognized []byte + // XXX_extensions map[int32]proto.Extension + // The first is handled here; + // the second is handled at the bottom of this function. + if name == "XXX_unrecognized" && !fv.IsNil() { + if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Field not filled in. This could be an optional field or + // a required field that wasn't filled in. Either way, there + // isn't anything we can show for it. + continue + } + if fv.Kind() == reflect.Slice && fv.IsNil() { + // Repeated field that is empty, or a bytes field that is unused. + continue + } + + if props.Repeated && fv.Kind() == reflect.Slice { + // Repeated field. + for j := 0; j < fv.Len(); j++ { + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + v := fv.Index(j) + if v.Kind() == reflect.Ptr && v.IsNil() { + // A nil message in a repeated field is not valid, + // but we can handle that more gracefully than panicking. + if _, err := w.Write([]byte("\n")); err != nil { + return err + } + continue + } + if err := writeAny(w, v, props); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if fv.Kind() == reflect.Map { + // Map fields are rendered as a repeated struct with key/value fields. + keys := fv.MapKeys() + sort.Sort(mapKeys(keys)) + for _, key := range keys { + val := fv.MapIndex(key) + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + // open struct + if err := w.WriteByte('<'); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + // key + if _, err := w.WriteString("key:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := writeAny(w, key, props.mkeyprop); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + // nil values aren't legal, but we can avoid panicking because of them. + if val.Kind() != reflect.Ptr || !val.IsNil() { + // value + if _, err := w.WriteString("value:"); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := writeAny(w, val, props.mvalprop); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + // close struct + w.unindent() + if err := w.WriteByte('>'); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + } + continue + } + if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { + // empty bytes field + continue + } + if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { + // proto3 non-repeated scalar field; skip if zero value + if isProto3Zero(fv) { + continue + } + } + + if fv.Kind() == reflect.Interface { + // Check if it is a oneof. + if st.Field(i).Tag.Get("protobuf_oneof") != "" { + // fv is nil, or holds a pointer to generated struct. + // That generated struct has exactly one field, + // which has a protobuf struct tag. + if fv.IsNil() { + continue + } + inner := fv.Elem().Elem() // interface -> *T -> T + tag := inner.Type().Field(0).Tag.Get("protobuf") + props = new(Properties) // Overwrite the outer props var, but not its pointee. + props.Parse(tag) + // Write the value in the oneof, not the oneof itself. + fv = inner.Field(0) + + // Special case to cope with malformed messages gracefully: + // If the value in the oneof is a nil pointer, don't panic + // in writeAny. + if fv.Kind() == reflect.Ptr && fv.IsNil() { + // Use errors.New so writeAny won't render quotes. + msg := errors.New("/* nil */") + fv = reflect.ValueOf(&msg).Elem() + } + } + } + + if err := writeName(w, props); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if b, ok := fv.Interface().(raw); ok { + if err := writeRaw(w, b.Bytes()); err != nil { + return err + } + continue + } + + // Enums have a String method, so writeAny will work fine. + if err := writeAny(w, fv, props); err != nil { + return err + } + + if err := w.WriteByte('\n'); err != nil { + return err + } + } + + // Extensions (the XXX_extensions field). + pv := sv.Addr() + if pv.Type().Implements(extendableProtoType) { + if err := writeExtensions(w, pv); err != nil { + return err + } + } + + return nil +} + +// writeRaw writes an uninterpreted raw message. +func writeRaw(w *textWriter, b []byte) error { + if err := w.WriteByte('<'); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + if err := writeUnknownStruct(w, b); err != nil { + return err + } + w.unindent() + if err := w.WriteByte('>'); err != nil { + return err + } + return nil +} + +// writeAny writes an arbitrary field. +func writeAny(w *textWriter, v reflect.Value, props *Properties) error { + v = reflect.Indirect(v) + + // Floats have special cases. + if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { + x := v.Float() + var b []byte + switch { + case math.IsInf(x, 1): + b = posInf + case math.IsInf(x, -1): + b = negInf + case math.IsNaN(x): + b = nan + } + if b != nil { + _, err := w.Write(b) + return err + } + // Other values are handled below. + } + + // We don't attempt to serialise every possible value type; only those + // that can occur in protocol buffers. + switch v.Kind() { + case reflect.Slice: + // Should only be a []byte; repeated fields are handled in writeStruct. + if err := writeString(w, string(v.Interface().([]byte))); err != nil { + return err + } + case reflect.String: + if err := writeString(w, v.String()); err != nil { + return err + } + case reflect.Struct: + // Required/optional group/message. + var bra, ket byte = '<', '>' + if props != nil && props.Wire == "group" { + bra, ket = '{', '}' + } + if err := w.WriteByte(bra); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte('\n'); err != nil { + return err + } + } + w.indent() + if tm, ok := v.Interface().(encoding.TextMarshaler); ok { + text, err := tm.MarshalText() + if err != nil { + return err + } + if _, err = w.Write(text); err != nil { + return err + } + } else if err := writeStruct(w, v); err != nil { + return err + } + w.unindent() + if err := w.WriteByte(ket); err != nil { + return err + } + default: + _, err := fmt.Fprint(w, v.Interface()) + return err + } + return nil +} + +// equivalent to C's isprint. +func isprint(c byte) bool { + return c >= 0x20 && c < 0x7f +} + +// writeString writes a string in the protocol buffer text format. +// It is similar to strconv.Quote except we don't use Go escape sequences, +// we treat the string as a byte sequence, and we use octal escapes. +// These differences are to maintain interoperability with the other +// languages' implementations of the text format. +func writeString(w *textWriter, s string) error { + // use WriteByte here to get any needed indent + if err := w.WriteByte('"'); err != nil { + return err + } + // Loop over the bytes, not the runes. + for i := 0; i < len(s); i++ { + var err error + // Divergence from C++: we don't escape apostrophes. + // There's no need to escape them, and the C++ parser + // copes with a naked apostrophe. + switch c := s[i]; c { + case '\n': + _, err = w.w.Write(backslashN) + case '\r': + _, err = w.w.Write(backslashR) + case '\t': + _, err = w.w.Write(backslashT) + case '"': + _, err = w.w.Write(backslashDQ) + case '\\': + _, err = w.w.Write(backslashBS) + default: + if isprint(c) { + err = w.w.WriteByte(c) + } else { + _, err = fmt.Fprintf(w.w, "\\%03o", c) + } + } + if err != nil { + return err + } + } + return w.WriteByte('"') +} + +func writeUnknownStruct(w *textWriter, data []byte) (err error) { + if !w.compact { + if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { + return err + } + } + b := NewBuffer(data) + for b.index < len(b.buf) { + x, err := b.DecodeVarint() + if err != nil { + _, err := fmt.Fprintf(w, "/* %v */\n", err) + return err + } + wire, tag := x&7, x>>3 + if wire == WireEndGroup { + w.unindent() + if _, err := w.Write(endBraceNewline); err != nil { + return err + } + continue + } + if _, err := fmt.Fprint(w, tag); err != nil { + return err + } + if wire != WireStartGroup { + if err := w.WriteByte(':'); err != nil { + return err + } + } + if !w.compact || wire == WireStartGroup { + if err := w.WriteByte(' '); err != nil { + return err + } + } + switch wire { + case WireBytes: + buf, e := b.DecodeRawBytes(false) + if e == nil { + _, err = fmt.Fprintf(w, "%q", buf) + } else { + _, err = fmt.Fprintf(w, "/* %v */", e) + } + case WireFixed32: + x, err = b.DecodeFixed32() + err = writeUnknownInt(w, x, err) + case WireFixed64: + x, err = b.DecodeFixed64() + err = writeUnknownInt(w, x, err) + case WireStartGroup: + err = w.WriteByte('{') + w.indent() + case WireVarint: + x, err = b.DecodeVarint() + err = writeUnknownInt(w, x, err) + default: + _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) + } + if err != nil { + return err + } + if err = w.WriteByte('\n'); err != nil { + return err + } + } + return nil +} + +func writeUnknownInt(w *textWriter, x uint64, err error) error { + if err == nil { + _, err = fmt.Fprint(w, x) + } else { + _, err = fmt.Fprintf(w, "/* %v */", err) + } + return err +} + +type int32Slice []int32 + +func (s int32Slice) Len() int { return len(s) } +func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } +func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +// writeExtensions writes all the extensions in pv. +// pv is assumed to be a pointer to a protocol message struct that is extendable. +func writeExtensions(w *textWriter, pv reflect.Value) error { + emap := extensionMaps[pv.Type().Elem()] + ep := pv.Interface().(extendableProto) + + // Order the extensions by ID. + // This isn't strictly necessary, but it will give us + // canonical output, which will also make testing easier. + m := ep.ExtensionMap() + ids := make([]int32, 0, len(m)) + for id := range m { + ids = append(ids, id) + } + sort.Sort(int32Slice(ids)) + + for _, extNum := range ids { + ext := m[extNum] + var desc *ExtensionDesc + if emap != nil { + desc = emap[extNum] + } + if desc == nil { + // Unknown extension. + if err := writeUnknownStruct(w, ext.enc); err != nil { + return err + } + continue + } + + pb, err := GetExtension(ep, desc) + if err != nil { + return fmt.Errorf("failed getting extension: %v", err) + } + + // Repeated extensions will appear as a slice. + if !desc.repeated() { + if err := writeExtension(w, desc.Name, pb); err != nil { + return err + } + } else { + v := reflect.ValueOf(pb) + for i := 0; i < v.Len(); i++ { + if err := writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { + return err + } + } + } + } + return nil +} + +func writeExtension(w *textWriter, name string, pb interface{}) error { + if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { + return err + } + if !w.compact { + if err := w.WriteByte(' '); err != nil { + return err + } + } + if err := writeAny(w, reflect.ValueOf(pb), nil); err != nil { + return err + } + if err := w.WriteByte('\n'); err != nil { + return err + } + return nil +} + +func (w *textWriter) writeIndent() { + if !w.complete { + return + } + remain := w.ind * 2 + for remain > 0 { + n := remain + if n > len(spaces) { + n = len(spaces) + } + w.w.Write(spaces[:n]) + remain -= n + } + w.complete = false +} + +func marshalText(w io.Writer, pb Message, compact bool) error { + val := reflect.ValueOf(pb) + if pb == nil || val.IsNil() { + w.Write([]byte("")) + return nil + } + var bw *bufio.Writer + ww, ok := w.(writer) + if !ok { + bw = bufio.NewWriter(w) + ww = bw + } + aw := &textWriter{ + w: ww, + complete: true, + compact: compact, + } + + if tm, ok := pb.(encoding.TextMarshaler); ok { + text, err := tm.MarshalText() + if err != nil { + return err + } + if _, err = aw.Write(text); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil + } + // Dereference the received pointer so we don't have outer < and >. + v := reflect.Indirect(val) + if err := writeStruct(aw, v); err != nil { + return err + } + if bw != nil { + return bw.Flush() + } + return nil +} + +// MarshalText writes a given protocol buffer in text format. +// The only errors returned are from w. +func MarshalText(w io.Writer, pb Message) error { + return marshalText(w, pb, false) +} + +// MarshalTextString is the same as MarshalText, but returns the string directly. +func MarshalTextString(pb Message) string { + var buf bytes.Buffer + marshalText(&buf, pb, false) + return buf.String() +} + +// CompactText writes a given protocol buffer in compact text format (one line). +func CompactText(w io.Writer, pb Message) error { return marshalText(w, pb, true) } + +// CompactTextString is the same as CompactText, but returns the string directly. +func CompactTextString(pb Message) string { + var buf bytes.Buffer + marshalText(&buf, pb, true) + return buf.String() +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_parser.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_parser.go new file mode 100644 index 00000000..45132326 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_parser.go @@ -0,0 +1,806 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto + +// Functions for parsing the Text protocol buffer format. +// TODO: message sets. + +import ( + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "unicode/utf8" +) + +type ParseError struct { + Message string + Line int // 1-based line number + Offset int // 0-based byte offset from start of input +} + +func (p *ParseError) Error() string { + if p.Line == 1 { + // show offset only for first line + return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) + } + return fmt.Sprintf("line %d: %v", p.Line, p.Message) +} + +type token struct { + value string + err *ParseError + line int // line number + offset int // byte number from start of input, not start of line + unquoted string // the unquoted version of value, if it was a quoted string +} + +func (t *token) String() string { + if t.err == nil { + return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) + } + return fmt.Sprintf("parse error: %v", t.err) +} + +type textParser struct { + s string // remaining input + done bool // whether the parsing is finished (success or error) + backed bool // whether back() was called + offset, line int + cur token +} + +func newTextParser(s string) *textParser { + p := new(textParser) + p.s = s + p.line = 1 + p.cur.line = 1 + return p +} + +func (p *textParser) errorf(format string, a ...interface{}) *ParseError { + pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} + p.cur.err = pe + p.done = true + return pe +} + +// Numbers and identifiers are matched by [-+._A-Za-z0-9] +func isIdentOrNumberChar(c byte) bool { + switch { + case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': + return true + case '0' <= c && c <= '9': + return true + } + switch c { + case '-', '+', '.', '_': + return true + } + return false +} + +func isWhitespace(c byte) bool { + switch c { + case ' ', '\t', '\n', '\r': + return true + } + return false +} + +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} + +func (p *textParser) skipWhitespace() { + i := 0 + for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { + if p.s[i] == '#' { + // comment; skip to end of line or input + for i < len(p.s) && p.s[i] != '\n' { + i++ + } + if i == len(p.s) { + break + } + } + if p.s[i] == '\n' { + p.line++ + } + i++ + } + p.offset += i + p.s = p.s[i:len(p.s)] + if len(p.s) == 0 { + p.done = true + } +} + +func (p *textParser) advance() { + // Skip whitespace + p.skipWhitespace() + if p.done { + return + } + + // Start of non-whitespace + p.cur.err = nil + p.cur.offset, p.cur.line = p.offset, p.line + p.cur.unquoted = "" + switch p.s[0] { + case '<', '>', '{', '}', ':', '[', ']', ';', ',': + // Single symbol + p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] + case '"', '\'': + // Quoted string + i := 1 + for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { + if p.s[i] == '\\' && i+1 < len(p.s) { + // skip escaped char + i++ + } + i++ + } + if i >= len(p.s) || p.s[i] != p.s[0] { + p.errorf("unmatched quote") + return + } + unq, err := unquoteC(p.s[1:i], rune(p.s[0])) + if err != nil { + p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) + return + } + p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] + p.cur.unquoted = unq + default: + i := 0 + for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { + i++ + } + if i == 0 { + p.errorf("unexpected byte %#x", p.s[0]) + return + } + p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] + } + p.offset += len(p.cur.value) +} + +var ( + errBadUTF8 = errors.New("proto: bad UTF-8") + errBadHex = errors.New("proto: bad hexadecimal") +) + +func unquoteC(s string, quote rune) (string, error) { + // This is based on C++'s tokenizer.cc. + // Despite its name, this is *not* parsing C syntax. + // For instance, "\0" is an invalid quoted string. + + // Avoid allocation in trivial cases. + simple := true + for _, r := range s { + if r == '\\' || r == quote { + simple = false + break + } + } + if simple { + return s, nil + } + + buf := make([]byte, 0, 3*len(s)/2) + for len(s) > 0 { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", errBadUTF8 + } + s = s[n:] + if r != '\\' { + if r < utf8.RuneSelf { + buf = append(buf, byte(r)) + } else { + buf = append(buf, string(r)...) + } + continue + } + + ch, tail, err := unescape(s) + if err != nil { + return "", err + } + buf = append(buf, ch...) + s = tail + } + return string(buf), nil +} + +func unescape(s string) (ch string, tail string, err error) { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", "", errBadUTF8 + } + s = s[n:] + switch r { + case 'a': + return "\a", s, nil + case 'b': + return "\b", s, nil + case 'f': + return "\f", s, nil + case 'n': + return "\n", s, nil + case 'r': + return "\r", s, nil + case 't': + return "\t", s, nil + case 'v': + return "\v", s, nil + case '?': + return "?", s, nil // trigraph workaround + case '\'', '"', '\\': + return string(r), s, nil + case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X': + if len(s) < 2 { + return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) + } + base := 8 + ss := s[:2] + s = s[2:] + if r == 'x' || r == 'X' { + base = 16 + } else { + ss = string(r) + ss + } + i, err := strconv.ParseUint(ss, base, 8) + if err != nil { + return "", "", err + } + return string([]byte{byte(i)}), s, nil + case 'u', 'U': + n := 4 + if r == 'U' { + n = 8 + } + if len(s) < n { + return "", "", fmt.Errorf(`\%c requires %d digits`, r, n) + } + + bs := make([]byte, n/2) + for i := 0; i < n; i += 2 { + a, ok1 := unhex(s[i]) + b, ok2 := unhex(s[i+1]) + if !ok1 || !ok2 { + return "", "", errBadHex + } + bs[i/2] = a<<4 | b + } + s = s[n:] + return string(bs), s, nil + } + return "", "", fmt.Errorf(`unknown escape \%c`, r) +} + +// Adapted from src/pkg/strconv/quote.go. +func unhex(b byte) (v byte, ok bool) { + switch { + case '0' <= b && b <= '9': + return b - '0', true + case 'a' <= b && b <= 'f': + return b - 'a' + 10, true + case 'A' <= b && b <= 'F': + return b - 'A' + 10, true + } + return 0, false +} + +// Back off the parser by one token. Can only be done between calls to next(). +// It makes the next advance() a no-op. +func (p *textParser) back() { p.backed = true } + +// Advances the parser and returns the new current token. +func (p *textParser) next() *token { + if p.backed || p.done { + p.backed = false + return &p.cur + } + p.advance() + if p.done { + p.cur.value = "" + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { + // Look for multiple quoted strings separated by whitespace, + // and concatenate them. + cat := p.cur + for { + p.skipWhitespace() + if p.done || !isQuote(p.s[0]) { + break + } + p.advance() + if p.cur.err != nil { + return &p.cur + } + cat.value += " " + p.cur.value + cat.unquoted += p.cur.unquoted + } + p.done = false // parser may have seen EOF, but we want to return cat + p.cur = cat + } + return &p.cur +} + +func (p *textParser) consumeToken(s string) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != s { + p.back() + return p.errorf("expected %q, found %q", s, tok.value) + } + return nil +} + +// Return a RequiredNotSetError indicating which required field was not set. +func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { + st := sv.Type() + sprops := GetProperties(st) + for i := 0; i < st.NumField(); i++ { + if !isNil(sv.Field(i)) { + continue + } + + props := sprops.Prop[i] + if props.Required { + return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} + } + } + return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen +} + +// Returns the index in the struct for the named field, as well as the parsed tag properties. +func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { + i, ok := sprops.decoderOrigNames[name] + if ok { + return i, sprops.Prop[i], true + } + return -1, nil, false +} + +// Consume a ':' from the input stream (if the next token is a colon), +// returning an error if a colon is needed but not present. +func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ":" { + // Colon is optional when the field is a group or message. + needColon := true + switch props.Wire { + case "group": + needColon = false + case "bytes": + // A "bytes" field is either a message, a string, or a repeated field; + // those three become *T, *string and []T respectively, so we can check for + // this field being a pointer to a non-string. + if typ.Kind() == reflect.Ptr { + // *T or *string + if typ.Elem().Kind() == reflect.String { + break + } + } else if typ.Kind() == reflect.Slice { + // []T or []*T + if typ.Elem().Kind() != reflect.Ptr { + break + } + } else if typ.Kind() == reflect.String { + // The proto3 exception is for a string field, + // which requires a colon. + break + } + needColon = false + } + if needColon { + return p.errorf("expected ':', found %q", tok.value) + } + p.back() + } + return nil +} + +func (p *textParser) readStruct(sv reflect.Value, terminator string) error { + st := sv.Type() + sprops := GetProperties(st) + reqCount := sprops.reqCount + var reqFieldErr error + fieldSet := make(map[string]bool) + // A struct is a sequence of "name: value", terminated by one of + // '>' or '}', or the end of the input. A name may also be + // "[extension]". + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + if tok.value == "[" { + // Looks like an extension. + // + // TODO: Check whether we need to handle + // namespace rooted names (e.g. ".something.Foo"). + tok = p.next() + if tok.err != nil { + return tok.err + } + var desc *ExtensionDesc + // This could be faster, but it's functional. + // TODO: Do something smarter than a linear scan. + for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { + if d.Name == tok.value { + desc = d + break + } + } + if desc == nil { + return p.errorf("unrecognized extension %q", tok.value) + } + // Check the extension terminator. + tok = p.next() + if tok.err != nil { + return tok.err + } + if tok.value != "]" { + return p.errorf("unrecognized extension terminator %q", tok.value) + } + + props := &Properties{} + props.Parse(desc.Tag) + + typ := reflect.TypeOf(desc.ExtensionType) + if err := p.checkForColon(props, typ); err != nil { + return err + } + + rep := desc.repeated() + + // Read the extension structure, and set it in + // the value we're constructing. + var ext reflect.Value + if !rep { + ext = reflect.New(typ).Elem() + } else { + ext = reflect.New(typ.Elem()).Elem() + } + if err := p.readAny(ext, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } + ep := sv.Addr().Interface().(extendableProto) + if !rep { + SetExtension(ep, desc, ext.Interface()) + } else { + old, err := GetExtension(ep, desc) + var sl reflect.Value + if err == nil { + sl = reflect.ValueOf(old) // existing slice + } else { + sl = reflect.MakeSlice(typ, 0, 1) + } + sl = reflect.Append(sl, ext) + SetExtension(ep, desc, sl.Interface()) + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + continue + } + + // This is a normal, non-extension field. + name := tok.value + var dst reflect.Value + fi, props, ok := structFieldByName(sprops, name) + if ok { + dst = sv.Field(fi) + } else if oop, ok := sprops.OneofTypes[name]; ok { + // It is a oneof. + props = oop.Prop + nv := reflect.New(oop.Type.Elem()) + dst = nv.Elem().Field(0) + sv.Field(oop.Field).Set(nv) + } + if !dst.IsValid() { + return p.errorf("unknown field name %q in %v", name, st) + } + + if dst.Kind() == reflect.Map { + // Consume any colon. + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Construct the map if it doesn't already exist. + if dst.IsNil() { + dst.Set(reflect.MakeMap(dst.Type())) + } + key := reflect.New(dst.Type().Key()).Elem() + val := reflect.New(dst.Type().Elem()).Elem() + + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // Technically the "key" and "value" could come in any order, + // but in practice they won't. + + tok := p.next() + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + if err := p.consumeToken("key"); err != nil { + return err + } + if err := p.consumeToken(":"); err != nil { + return err + } + if err := p.readAny(key, props.mkeyprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken("value"); err != nil { + return err + } + if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil { + return err + } + if err := p.readAny(val, props.mvalprop); err != nil { + return err + } + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + if err := p.consumeToken(terminator); err != nil { + return err + } + + dst.SetMapIndex(key, val) + continue + } + + // Check that it's not already set if it's not a repeated field. + if !props.Repeated && fieldSet[name] { + return p.errorf("non-repeated field %q was repeated", name) + } + + if err := p.checkForColon(props, dst.Type()); err != nil { + return err + } + + // Parse into the field. + fieldSet[name] = true + if err := p.readAny(dst, props); err != nil { + if _, ok := err.(*RequiredNotSetError); !ok { + return err + } + reqFieldErr = err + } else if props.Required { + reqCount-- + } + + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + + } + + if reqCount > 0 { + return p.missingRequiredFieldError(sv) + } + return reqFieldErr +} + +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in readStruct to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } + return nil +} + +func (p *textParser) readAny(v reflect.Value, props *Properties) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "" { + return p.errorf("unexpected EOF") + } + + switch fv := v; fv.Kind() { + case reflect.Slice: + at := v.Type() + if at.Elem().Kind() == reflect.Uint8 { + // Special case for []byte + if tok.value[0] != '"' && tok.value[0] != '\'' { + // Deliberately written out here, as the error after + // this switch statement would write "invalid []byte: ...", + // which is not as user-friendly. + return p.errorf("invalid string: %v", tok.value) + } + bytes := []byte(tok.unquoted) + fv.Set(reflect.ValueOf(bytes)) + return nil + } + // Repeated field. + if tok.value == "[" { + // Repeated field with list notation, like [1,2,3]. + for { + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + err := p.readAny(fv.Index(fv.Len()-1), props) + if err != nil { + return err + } + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == "]" { + break + } + if tok.value != "," { + return p.errorf("Expected ']' or ',' found %q", tok.value) + } + } + return nil + } + // One value of the repeated field. + p.back() + fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) + return p.readAny(fv.Index(fv.Len()-1), props) + case reflect.Bool: + // Either "true", "false", 1 or 0. + switch tok.value { + case "true", "1": + fv.SetBool(true) + return nil + case "false", "0": + fv.SetBool(false) + return nil + } + case reflect.Float32, reflect.Float64: + v := tok.value + // Ignore 'f' for compatibility with output generated by C++, but don't + // remove 'f' when the value is "-inf" or "inf". + if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { + v = v[:len(v)-1] + } + if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { + fv.SetFloat(f) + return nil + } + case reflect.Int32: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + fv.SetInt(x) + return nil + } + + if len(props.Enum) == 0 { + break + } + m, ok := enumValueMaps[props.Enum] + if !ok { + break + } + x, ok := m[tok.value] + if !ok { + break + } + fv.SetInt(int64(x)) + return nil + case reflect.Int64: + if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { + fv.SetInt(x) + return nil + } + + case reflect.Ptr: + // A basic field (indirected through pointer), or a repeated message/group + p.back() + fv.Set(reflect.New(fv.Type().Elem())) + return p.readAny(fv.Elem(), props) + case reflect.String: + if tok.value[0] == '"' || tok.value[0] == '\'' { + fv.SetString(tok.unquoted) + return nil + } + case reflect.Struct: + var terminator string + switch tok.value { + case "{": + terminator = "}" + case "<": + terminator = ">" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + // TODO: Handle nested messages which implement encoding.TextUnmarshaler. + return p.readStruct(fv, terminator) + case reflect.Uint32: + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + fv.SetUint(uint64(x)) + return nil + } + case reflect.Uint64: + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + fv.SetUint(x) + return nil + } + } + return p.errorf("invalid %v: %v", v.Type(), tok.value) +} + +// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb +// before starting to unmarshal, so any existing data in pb is always removed. +// If a required field is not set and no other error occurs, +// UnmarshalText returns *RequiredNotSetError. +func UnmarshalText(s string, pb Message) error { + if um, ok := pb.(encoding.TextUnmarshaler); ok { + err := um.UnmarshalText([]byte(s)) + return err + } + pb.Reset() + v := reflect.ValueOf(pb) + if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil { + return pe + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_parser_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_parser_test.go new file mode 100644 index 00000000..d2e4cca0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_parser_test.go @@ -0,0 +1,557 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "math" + "reflect" + "testing" + + . "github.com/golang/protobuf/proto" + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + . "github.com/golang/protobuf/proto/testdata" +) + +type UnmarshalTextTest struct { + in string + err string // if "", no error expected + out *MyMessage +} + +func buildExtStructTest(text string) UnmarshalTextTest { + msg := &MyMessage{ + Count: Int32(42), + } + SetExtension(msg, E_Ext_More, &Ext{ + Data: String("Hello, world!"), + }) + return UnmarshalTextTest{in: text, out: msg} +} + +func buildExtDataTest(text string) UnmarshalTextTest { + msg := &MyMessage{ + Count: Int32(42), + } + SetExtension(msg, E_Ext_Text, String("Hello, world!")) + SetExtension(msg, E_Ext_Number, Int32(1729)) + return UnmarshalTextTest{in: text, out: msg} +} + +func buildExtRepStringTest(text string) UnmarshalTextTest { + msg := &MyMessage{ + Count: Int32(42), + } + if err := SetExtension(msg, E_Greeting, []string{"bula", "hola"}); err != nil { + panic(err) + } + return UnmarshalTextTest{in: text, out: msg} +} + +var unMarshalTextTests = []UnmarshalTextTest{ + // Basic + { + in: " count:42\n name:\"Dave\" ", + out: &MyMessage{ + Count: Int32(42), + Name: String("Dave"), + }, + }, + + // Empty quoted string + { + in: `count:42 name:""`, + out: &MyMessage{ + Count: Int32(42), + Name: String(""), + }, + }, + + // Quoted string concatenation with double quotes + { + in: `count:42 name: "My name is "` + "\n" + `"elsewhere"`, + out: &MyMessage{ + Count: Int32(42), + Name: String("My name is elsewhere"), + }, + }, + + // Quoted string concatenation with single quotes + { + in: "count:42 name: 'My name is '\n'elsewhere'", + out: &MyMessage{ + Count: Int32(42), + Name: String("My name is elsewhere"), + }, + }, + + // Quoted string concatenations with mixed quotes + { + in: "count:42 name: 'My name is '\n\"elsewhere\"", + out: &MyMessage{ + Count: Int32(42), + Name: String("My name is elsewhere"), + }, + }, + { + in: "count:42 name: \"My name is \"\n'elsewhere'", + out: &MyMessage{ + Count: Int32(42), + Name: String("My name is elsewhere"), + }, + }, + + // Quoted string with escaped apostrophe + { + in: `count:42 name: "HOLIDAY - New Year\'s Day"`, + out: &MyMessage{ + Count: Int32(42), + Name: String("HOLIDAY - New Year's Day"), + }, + }, + + // Quoted string with single quote + { + in: `count:42 name: 'Roger "The Ramster" Ramjet'`, + out: &MyMessage{ + Count: Int32(42), + Name: String(`Roger "The Ramster" Ramjet`), + }, + }, + + // Quoted string with all the accepted special characters from the C++ test + { + in: `count:42 name: ` + "\"\\\"A string with \\' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"", + out: &MyMessage{ + Count: Int32(42), + Name: String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces"), + }, + }, + + // Quoted string with quoted backslash + { + in: `count:42 name: "\\'xyz"`, + out: &MyMessage{ + Count: Int32(42), + Name: String(`\'xyz`), + }, + }, + + // Quoted string with UTF-8 bytes. + { + in: "count:42 name: '\303\277\302\201\xAB'", + out: &MyMessage{ + Count: Int32(42), + Name: String("\303\277\302\201\xAB"), + }, + }, + + // Bad quoted string + { + in: `inner: < host: "\0" >` + "\n", + err: `line 1.15: invalid quoted string "\0": \0 requires 2 following digits`, + }, + + // Number too large for int64 + { + in: "count: 1 others { key: 123456789012345678901 }", + err: "line 1.23: invalid int64: 123456789012345678901", + }, + + // Number too large for int32 + { + in: "count: 1234567890123", + err: "line 1.7: invalid int32: 1234567890123", + }, + + // Number in hexadecimal + { + in: "count: 0x2beef", + out: &MyMessage{ + Count: Int32(0x2beef), + }, + }, + + // Number in octal + { + in: "count: 024601", + out: &MyMessage{ + Count: Int32(024601), + }, + }, + + // Floating point number with "f" suffix + { + in: "count: 4 others:< weight: 17.0f >", + out: &MyMessage{ + Count: Int32(4), + Others: []*OtherMessage{ + { + Weight: Float32(17), + }, + }, + }, + }, + + // Floating point positive infinity + { + in: "count: 4 bigfloat: inf", + out: &MyMessage{ + Count: Int32(4), + Bigfloat: Float64(math.Inf(1)), + }, + }, + + // Floating point negative infinity + { + in: "count: 4 bigfloat: -inf", + out: &MyMessage{ + Count: Int32(4), + Bigfloat: Float64(math.Inf(-1)), + }, + }, + + // Number too large for float32 + { + in: "others:< weight: 12345678901234567890123456789012345678901234567890 >", + err: "line 1.17: invalid float32: 12345678901234567890123456789012345678901234567890", + }, + + // Number posing as a quoted string + { + in: `inner: < host: 12 >` + "\n", + err: `line 1.15: invalid string: 12`, + }, + + // Quoted string posing as int32 + { + in: `count: "12"`, + err: `line 1.7: invalid int32: "12"`, + }, + + // Quoted string posing a float32 + { + in: `others:< weight: "17.4" >`, + err: `line 1.17: invalid float32: "17.4"`, + }, + + // Enum + { + in: `count:42 bikeshed: BLUE`, + out: &MyMessage{ + Count: Int32(42), + Bikeshed: MyMessage_BLUE.Enum(), + }, + }, + + // Repeated field + { + in: `count:42 pet: "horsey" pet:"bunny"`, + out: &MyMessage{ + Count: Int32(42), + Pet: []string{"horsey", "bunny"}, + }, + }, + + // Repeated field with list notation + { + in: `count:42 pet: ["horsey", "bunny"]`, + out: &MyMessage{ + Count: Int32(42), + Pet: []string{"horsey", "bunny"}, + }, + }, + + // Repeated message with/without colon and <>/{} + { + in: `count:42 others:{} others{} others:<> others:{}`, + out: &MyMessage{ + Count: Int32(42), + Others: []*OtherMessage{ + {}, + {}, + {}, + {}, + }, + }, + }, + + // Missing colon for inner message + { + in: `count:42 inner < host: "cauchy.syd" >`, + out: &MyMessage{ + Count: Int32(42), + Inner: &InnerMessage{ + Host: String("cauchy.syd"), + }, + }, + }, + + // Missing colon for string field + { + in: `name "Dave"`, + err: `line 1.5: expected ':', found "\"Dave\""`, + }, + + // Missing colon for int32 field + { + in: `count 42`, + err: `line 1.6: expected ':', found "42"`, + }, + + // Missing required field + { + in: `name: "Pawel"`, + err: `proto: required field "testdata.MyMessage.count" not set`, + out: &MyMessage{ + Name: String("Pawel"), + }, + }, + + // Repeated non-repeated field + { + in: `name: "Rob" name: "Russ"`, + err: `line 1.12: non-repeated field "name" was repeated`, + }, + + // Group + { + in: `count: 17 SomeGroup { group_field: 12 }`, + out: &MyMessage{ + Count: Int32(17), + Somegroup: &MyMessage_SomeGroup{ + GroupField: Int32(12), + }, + }, + }, + + // Semicolon between fields + { + in: `count:3;name:"Calvin"`, + out: &MyMessage{ + Count: Int32(3), + Name: String("Calvin"), + }, + }, + // Comma between fields + { + in: `count:4,name:"Ezekiel"`, + out: &MyMessage{ + Count: Int32(4), + Name: String("Ezekiel"), + }, + }, + + // Extension + buildExtStructTest(`count: 42 [testdata.Ext.more]:`), + buildExtStructTest(`count: 42 [testdata.Ext.more] {data:"Hello, world!"}`), + buildExtDataTest(`count: 42 [testdata.Ext.text]:"Hello, world!" [testdata.Ext.number]:1729`), + buildExtRepStringTest(`count: 42 [testdata.greeting]:"bula" [testdata.greeting]:"hola"`), + + // Big all-in-one + { + in: "count:42 # Meaning\n" + + `name:"Dave" ` + + `quote:"\"I didn't want to go.\"" ` + + `pet:"bunny" ` + + `pet:"kitty" ` + + `pet:"horsey" ` + + `inner:<` + + ` host:"footrest.syd" ` + + ` port:7001 ` + + ` connected:true ` + + `> ` + + `others:<` + + ` key:3735928559 ` + + ` value:"\x01A\a\f" ` + + `> ` + + `others:<` + + " weight:58.9 # Atomic weight of Co\n" + + ` inner:<` + + ` host:"lesha.mtv" ` + + ` port:8002 ` + + ` >` + + `>`, + out: &MyMessage{ + Count: Int32(42), + Name: String("Dave"), + Quote: String(`"I didn't want to go."`), + Pet: []string{"bunny", "kitty", "horsey"}, + Inner: &InnerMessage{ + Host: String("footrest.syd"), + Port: Int32(7001), + Connected: Bool(true), + }, + Others: []*OtherMessage{ + { + Key: Int64(3735928559), + Value: []byte{0x1, 'A', '\a', '\f'}, + }, + { + Weight: Float32(58.9), + Inner: &InnerMessage{ + Host: String("lesha.mtv"), + Port: Int32(8002), + }, + }, + }, + }, + }, +} + +func TestUnmarshalText(t *testing.T) { + for i, test := range unMarshalTextTests { + pb := new(MyMessage) + err := UnmarshalText(test.in, pb) + if test.err == "" { + // We don't expect failure. + if err != nil { + t.Errorf("Test %d: Unexpected error: %v", i, err) + } else if !reflect.DeepEqual(pb, test.out) { + t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v", + i, pb, test.out) + } + } else { + // We do expect failure. + if err == nil { + t.Errorf("Test %d: Didn't get expected error: %v", i, test.err) + } else if err.Error() != test.err { + t.Errorf("Test %d: Incorrect error.\nHave: %v\nWant: %v", + i, err.Error(), test.err) + } else if _, ok := err.(*RequiredNotSetError); ok && test.out != nil && !reflect.DeepEqual(pb, test.out) { + t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v", + i, pb, test.out) + } + } + } +} + +func TestUnmarshalTextCustomMessage(t *testing.T) { + msg := &textMessage{} + if err := UnmarshalText("custom", msg); err != nil { + t.Errorf("Unexpected error from custom unmarshal: %v", err) + } + if UnmarshalText("not custom", msg) == nil { + t.Errorf("Didn't get expected error from custom unmarshal") + } +} + +// Regression test; this caused a panic. +func TestRepeatedEnum(t *testing.T) { + pb := new(RepeatedEnum) + if err := UnmarshalText("color: RED", pb); err != nil { + t.Fatal(err) + } + exp := &RepeatedEnum{ + Color: []RepeatedEnum_Color{RepeatedEnum_RED}, + } + if !Equal(pb, exp) { + t.Errorf("Incorrect populated \nHave: %v\nWant: %v", pb, exp) + } +} + +func TestProto3TextParsing(t *testing.T) { + m := new(proto3pb.Message) + const in = `name: "Wallace" true_scotsman: true` + want := &proto3pb.Message{ + Name: "Wallace", + TrueScotsman: true, + } + if err := UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !Equal(m, want) { + t.Errorf("\n got %v\nwant %v", m, want) + } +} + +func TestMapParsing(t *testing.T) { + m := new(MessageWithMap) + const in = `name_mapping: name_mapping:` + + `msg_mapping:,>` + // separating commas are okay + `msg_mapping>` + // no colon after "value" + `byte_mapping:` + want := &MessageWithMap{ + NameMapping: map[int32]string{ + 1: "Beatles", + 1234: "Feist", + }, + MsgMapping: map[int64]*FloatingPoint{ + -4: {F: Float64(2.0)}, + -2: {F: Float64(4.0)}, + }, + ByteMapping: map[bool][]byte{ + true: []byte("so be it"), + }, + } + if err := UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !Equal(m, want) { + t.Errorf("\n got %v\nwant %v", m, want) + } +} + +func TestOneofParsing(t *testing.T) { + const in = `name:"Shrek"` + m := new(Communique) + want := &Communique{Union: &Communique_Name{"Shrek"}} + if err := UnmarshalText(in, m); err != nil { + t.Fatal(err) + } + if !Equal(m, want) { + t.Errorf("\n got %v\nwant %v", m, want) + } +} + +var benchInput string + +func init() { + benchInput = "count: 4\n" + for i := 0; i < 1000; i++ { + benchInput += "pet: \"fido\"\n" + } + + // Check it is valid input. + pb := new(MyMessage) + err := UnmarshalText(benchInput, pb) + if err != nil { + panic("Bad benchmark input: " + err.Error()) + } +} + +func BenchmarkUnmarshalText(b *testing.B) { + pb := new(MyMessage) + for i := 0; i < b.N; i++ { + UnmarshalText(benchInput, pb) + } + b.SetBytes(int64(len(benchInput))) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_test.go new file mode 100644 index 00000000..3eabacac --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/proto/text_test.go @@ -0,0 +1,474 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package proto_test + +import ( + "bytes" + "errors" + "io/ioutil" + "math" + "strings" + "testing" + + "github.com/golang/protobuf/proto" + + proto3pb "github.com/golang/protobuf/proto/proto3_proto" + pb "github.com/golang/protobuf/proto/testdata" +) + +// textMessage implements the methods that allow it to marshal and unmarshal +// itself as text. +type textMessage struct { +} + +func (*textMessage) MarshalText() ([]byte, error) { + return []byte("custom"), nil +} + +func (*textMessage) UnmarshalText(bytes []byte) error { + if string(bytes) != "custom" { + return errors.New("expected 'custom'") + } + return nil +} + +func (*textMessage) Reset() {} +func (*textMessage) String() string { return "" } +func (*textMessage) ProtoMessage() {} + +func newTestMessage() *pb.MyMessage { + msg := &pb.MyMessage{ + Count: proto.Int32(42), + Name: proto.String("Dave"), + Quote: proto.String(`"I didn't want to go."`), + Pet: []string{"bunny", "kitty", "horsey"}, + Inner: &pb.InnerMessage{ + Host: proto.String("footrest.syd"), + Port: proto.Int32(7001), + Connected: proto.Bool(true), + }, + Others: []*pb.OtherMessage{ + { + Key: proto.Int64(0xdeadbeef), + Value: []byte{1, 65, 7, 12}, + }, + { + Weight: proto.Float32(6.022), + Inner: &pb.InnerMessage{ + Host: proto.String("lesha.mtv"), + Port: proto.Int32(8002), + }, + }, + }, + Bikeshed: pb.MyMessage_BLUE.Enum(), + Somegroup: &pb.MyMessage_SomeGroup{ + GroupField: proto.Int32(8), + }, + // One normally wouldn't do this. + // This is an undeclared tag 13, as a varint (wire type 0) with value 4. + XXX_unrecognized: []byte{13<<3 | 0, 4}, + } + ext := &pb.Ext{ + Data: proto.String("Big gobs for big rats"), + } + if err := proto.SetExtension(msg, pb.E_Ext_More, ext); err != nil { + panic(err) + } + greetings := []string{"adg", "easy", "cow"} + if err := proto.SetExtension(msg, pb.E_Greeting, greetings); err != nil { + panic(err) + } + + // Add an unknown extension. We marshal a pb.Ext, and fake the ID. + b, err := proto.Marshal(&pb.Ext{Data: proto.String("3G skiing")}) + if err != nil { + panic(err) + } + b = append(proto.EncodeVarint(201<<3|proto.WireBytes), b...) + proto.SetRawExtension(msg, 201, b) + + // Extensions can be plain fields, too, so let's test that. + b = append(proto.EncodeVarint(202<<3|proto.WireVarint), 19) + proto.SetRawExtension(msg, 202, b) + + return msg +} + +const text = `count: 42 +name: "Dave" +quote: "\"I didn't want to go.\"" +pet: "bunny" +pet: "kitty" +pet: "horsey" +inner: < + host: "footrest.syd" + port: 7001 + connected: true +> +others: < + key: 3735928559 + value: "\001A\007\014" +> +others: < + weight: 6.022 + inner: < + host: "lesha.mtv" + port: 8002 + > +> +bikeshed: BLUE +SomeGroup { + group_field: 8 +} +/* 2 unknown bytes */ +13: 4 +[testdata.Ext.more]: < + data: "Big gobs for big rats" +> +[testdata.greeting]: "adg" +[testdata.greeting]: "easy" +[testdata.greeting]: "cow" +/* 13 unknown bytes */ +201: "\t3G skiing" +/* 3 unknown bytes */ +202: 19 +` + +func TestMarshalText(t *testing.T) { + buf := new(bytes.Buffer) + if err := proto.MarshalText(buf, newTestMessage()); err != nil { + t.Fatalf("proto.MarshalText: %v", err) + } + s := buf.String() + if s != text { + t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, text) + } +} + +func TestMarshalTextCustomMessage(t *testing.T) { + buf := new(bytes.Buffer) + if err := proto.MarshalText(buf, &textMessage{}); err != nil { + t.Fatalf("proto.MarshalText: %v", err) + } + s := buf.String() + if s != "custom" { + t.Errorf("Got %q, expected %q", s, "custom") + } +} +func TestMarshalTextNil(t *testing.T) { + want := "" + tests := []proto.Message{nil, (*pb.MyMessage)(nil)} + for i, test := range tests { + buf := new(bytes.Buffer) + if err := proto.MarshalText(buf, test); err != nil { + t.Fatal(err) + } + if got := buf.String(); got != want { + t.Errorf("%d: got %q want %q", i, got, want) + } + } +} + +func TestMarshalTextUnknownEnum(t *testing.T) { + // The Color enum only specifies values 0-2. + m := &pb.MyMessage{Bikeshed: pb.MyMessage_Color(3).Enum()} + got := m.String() + const want = `bikeshed:3 ` + if got != want { + t.Errorf("\n got %q\nwant %q", got, want) + } +} + +func TestTextOneof(t *testing.T) { + tests := []struct { + m proto.Message + want string + }{ + // zero message + {&pb.Communique{}, ``}, + // scalar field + {&pb.Communique{Union: &pb.Communique_Number{4}}, `number:4`}, + // message field + {&pb.Communique{Union: &pb.Communique_Msg{ + &pb.Strings{StringField: proto.String("why hello!")}, + }}, `msg:`}, + // bad oneof (should not panic) + {&pb.Communique{Union: &pb.Communique_Msg{nil}}, `msg:/* nil */`}, + } + for _, test := range tests { + got := strings.TrimSpace(test.m.String()) + if got != test.want { + t.Errorf("\n got %s\nwant %s", got, test.want) + } + } +} + +func BenchmarkMarshalTextBuffered(b *testing.B) { + buf := new(bytes.Buffer) + m := newTestMessage() + for i := 0; i < b.N; i++ { + buf.Reset() + proto.MarshalText(buf, m) + } +} + +func BenchmarkMarshalTextUnbuffered(b *testing.B) { + w := ioutil.Discard + m := newTestMessage() + for i := 0; i < b.N; i++ { + proto.MarshalText(w, m) + } +} + +func compact(src string) string { + // s/[ \n]+/ /g; s/ $//; + dst := make([]byte, len(src)) + space, comment := false, false + j := 0 + for i := 0; i < len(src); i++ { + if strings.HasPrefix(src[i:], "/*") { + comment = true + i++ + continue + } + if comment && strings.HasPrefix(src[i:], "*/") { + comment = false + i++ + continue + } + if comment { + continue + } + c := src[i] + if c == ' ' || c == '\n' { + space = true + continue + } + if j > 0 && (dst[j-1] == ':' || dst[j-1] == '<' || dst[j-1] == '{') { + space = false + } + if c == '{' { + space = false + } + if space { + dst[j] = ' ' + j++ + space = false + } + dst[j] = c + j++ + } + if space { + dst[j] = ' ' + j++ + } + return string(dst[0:j]) +} + +var compactText = compact(text) + +func TestCompactText(t *testing.T) { + s := proto.CompactTextString(newTestMessage()) + if s != compactText { + t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v\n===\n", s, compactText) + } +} + +func TestStringEscaping(t *testing.T) { + testCases := []struct { + in *pb.Strings + out string + }{ + { + // Test data from C++ test (TextFormatTest.StringEscape). + // Single divergence: we don't escape apostrophes. + &pb.Strings{StringField: proto.String("\"A string with ' characters \n and \r newlines and \t tabs and \001 slashes \\ and multiple spaces")}, + "string_field: \"\\\"A string with ' characters \\n and \\r newlines and \\t tabs and \\001 slashes \\\\ and multiple spaces\"\n", + }, + { + // Test data from the same C++ test. + &pb.Strings{StringField: proto.String("\350\260\267\346\255\214")}, + "string_field: \"\\350\\260\\267\\346\\255\\214\"\n", + }, + { + // Some UTF-8. + &pb.Strings{StringField: proto.String("\x00\x01\xff\x81")}, + `string_field: "\000\001\377\201"` + "\n", + }, + } + + for i, tc := range testCases { + var buf bytes.Buffer + if err := proto.MarshalText(&buf, tc.in); err != nil { + t.Errorf("proto.MarsalText: %v", err) + continue + } + s := buf.String() + if s != tc.out { + t.Errorf("#%d: Got:\n%s\nExpected:\n%s\n", i, s, tc.out) + continue + } + + // Check round-trip. + pb := new(pb.Strings) + if err := proto.UnmarshalText(s, pb); err != nil { + t.Errorf("#%d: UnmarshalText: %v", i, err) + continue + } + if !proto.Equal(pb, tc.in) { + t.Errorf("#%d: Round-trip failed:\nstart: %v\n end: %v", i, tc.in, pb) + } + } +} + +// A limitedWriter accepts some output before it fails. +// This is a proxy for something like a nearly-full or imminently-failing disk, +// or a network connection that is about to die. +type limitedWriter struct { + b bytes.Buffer + limit int +} + +var outOfSpace = errors.New("proto: insufficient space") + +func (w *limitedWriter) Write(p []byte) (n int, err error) { + var avail = w.limit - w.b.Len() + if avail <= 0 { + return 0, outOfSpace + } + if len(p) <= avail { + return w.b.Write(p) + } + n, _ = w.b.Write(p[:avail]) + return n, outOfSpace +} + +func TestMarshalTextFailing(t *testing.T) { + // Try lots of different sizes to exercise more error code-paths. + for lim := 0; lim < len(text); lim++ { + buf := new(limitedWriter) + buf.limit = lim + err := proto.MarshalText(buf, newTestMessage()) + // We expect a certain error, but also some partial results in the buffer. + if err != outOfSpace { + t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", err, outOfSpace) + } + s := buf.b.String() + x := text[:buf.limit] + if s != x { + t.Errorf("Got:\n===\n%v===\nExpected:\n===\n%v===\n", s, x) + } + } +} + +func TestFloats(t *testing.T) { + tests := []struct { + f float64 + want string + }{ + {0, "0"}, + {4.7, "4.7"}, + {math.Inf(1), "inf"}, + {math.Inf(-1), "-inf"}, + {math.NaN(), "nan"}, + } + for _, test := range tests { + msg := &pb.FloatingPoint{F: &test.f} + got := strings.TrimSpace(msg.String()) + want := `f:` + test.want + if got != want { + t.Errorf("f=%f: got %q, want %q", test.f, got, want) + } + } +} + +func TestRepeatedNilText(t *testing.T) { + m := &pb.MessageList{ + Message: []*pb.MessageList_Message{ + nil, + &pb.MessageList_Message{ + Name: proto.String("Horse"), + }, + nil, + }, + } + want := `Message +Message { + name: "Horse" +} +Message +` + if s := proto.MarshalTextString(m); s != want { + t.Errorf(" got: %s\nwant: %s", s, want) + } +} + +func TestProto3Text(t *testing.T) { + tests := []struct { + m proto.Message + want string + }{ + // zero message + {&proto3pb.Message{}, ``}, + // zero message except for an empty byte slice + {&proto3pb.Message{Data: []byte{}}, ``}, + // trivial case + {&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`}, + // empty map + {&pb.MessageWithMap{}, ``}, + // non-empty map; map format is the same as a repeated struct, + // and they are sorted by key (numerically for numeric keys). + { + &pb.MessageWithMap{NameMapping: map[int32]string{ + -1: "Negatory", + 7: "Lucky", + 1234: "Feist", + 6345789: "Otis", + }}, + `name_mapping: ` + + `name_mapping: ` + + `name_mapping: ` + + `name_mapping:`, + }, + // map with nil value; not well-defined, but we shouldn't crash + { + &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{7: nil}}, + `msg_mapping:`, + }, + } + for _, test := range tests { + got := strings.TrimSpace(test.m.String()) + if got != test.want { + t.Errorf("\n got %s\nwant %s", got, test.want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/Makefile new file mode 100644 index 00000000..a42cc371 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/Makefile @@ -0,0 +1,33 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +test: + cd testdata && make test diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/descriptor/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/descriptor/Makefile new file mode 100644 index 00000000..4942418e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/descriptor/Makefile @@ -0,0 +1,39 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +# Not stored here, but descriptor.proto is in https://github.com/google/protobuf/ +# at src/google/protobuf/descriptor.proto +regenerate: + echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION + protoc --go_out=. -I$(HOME)/src/protobuf/src $(HOME)/src/protobuf/src/google/protobuf/descriptor.proto && \ + sed 's,^package google_protobuf,package descriptor,' google/protobuf/descriptor.pb.go > \ + $(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go && \ + rm -f google/protobuf/descriptor.pb.go diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go new file mode 100644 index 00000000..6a3be28e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/descriptor/descriptor.pb.go @@ -0,0 +1,1812 @@ +// Code generated by protoc-gen-go. +// source: google/protobuf/descriptor.proto +// DO NOT EDIT! + +/* +Package google_protobuf is a generated protocol buffer package. + +It is generated from these files: + google/protobuf/descriptor.proto + +It has these top-level messages: + FileDescriptorSet + FileDescriptorProto + DescriptorProto + FieldDescriptorProto + OneofDescriptorProto + EnumDescriptorProto + EnumValueDescriptorProto + ServiceDescriptorProto + MethodDescriptorProto + FileOptions + MessageOptions + FieldOptions + EnumOptions + EnumValueOptions + ServiceOptions + MethodOptions + UninterpretedOption + SourceCodeInfo +*/ +package descriptor + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +const _ = proto.ProtoPackageIsVersion1 + +type FieldDescriptorProto_Type int32 + +const ( + // 0 is reserved for errors. + // Order is weird for historical reasons. + FieldDescriptorProto_TYPE_DOUBLE FieldDescriptorProto_Type = 1 + FieldDescriptorProto_TYPE_FLOAT FieldDescriptorProto_Type = 2 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT64 FieldDescriptorProto_Type = 3 + FieldDescriptorProto_TYPE_UINT64 FieldDescriptorProto_Type = 4 + // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if + // negative values are likely. + FieldDescriptorProto_TYPE_INT32 FieldDescriptorProto_Type = 5 + FieldDescriptorProto_TYPE_FIXED64 FieldDescriptorProto_Type = 6 + FieldDescriptorProto_TYPE_FIXED32 FieldDescriptorProto_Type = 7 + FieldDescriptorProto_TYPE_BOOL FieldDescriptorProto_Type = 8 + FieldDescriptorProto_TYPE_STRING FieldDescriptorProto_Type = 9 + FieldDescriptorProto_TYPE_GROUP FieldDescriptorProto_Type = 10 + FieldDescriptorProto_TYPE_MESSAGE FieldDescriptorProto_Type = 11 + // New in version 2. + FieldDescriptorProto_TYPE_BYTES FieldDescriptorProto_Type = 12 + FieldDescriptorProto_TYPE_UINT32 FieldDescriptorProto_Type = 13 + FieldDescriptorProto_TYPE_ENUM FieldDescriptorProto_Type = 14 + FieldDescriptorProto_TYPE_SFIXED32 FieldDescriptorProto_Type = 15 + FieldDescriptorProto_TYPE_SFIXED64 FieldDescriptorProto_Type = 16 + FieldDescriptorProto_TYPE_SINT32 FieldDescriptorProto_Type = 17 + FieldDescriptorProto_TYPE_SINT64 FieldDescriptorProto_Type = 18 +) + +var FieldDescriptorProto_Type_name = map[int32]string{ + 1: "TYPE_DOUBLE", + 2: "TYPE_FLOAT", + 3: "TYPE_INT64", + 4: "TYPE_UINT64", + 5: "TYPE_INT32", + 6: "TYPE_FIXED64", + 7: "TYPE_FIXED32", + 8: "TYPE_BOOL", + 9: "TYPE_STRING", + 10: "TYPE_GROUP", + 11: "TYPE_MESSAGE", + 12: "TYPE_BYTES", + 13: "TYPE_UINT32", + 14: "TYPE_ENUM", + 15: "TYPE_SFIXED32", + 16: "TYPE_SFIXED64", + 17: "TYPE_SINT32", + 18: "TYPE_SINT64", +} +var FieldDescriptorProto_Type_value = map[string]int32{ + "TYPE_DOUBLE": 1, + "TYPE_FLOAT": 2, + "TYPE_INT64": 3, + "TYPE_UINT64": 4, + "TYPE_INT32": 5, + "TYPE_FIXED64": 6, + "TYPE_FIXED32": 7, + "TYPE_BOOL": 8, + "TYPE_STRING": 9, + "TYPE_GROUP": 10, + "TYPE_MESSAGE": 11, + "TYPE_BYTES": 12, + "TYPE_UINT32": 13, + "TYPE_ENUM": 14, + "TYPE_SFIXED32": 15, + "TYPE_SFIXED64": 16, + "TYPE_SINT32": 17, + "TYPE_SINT64": 18, +} + +func (x FieldDescriptorProto_Type) Enum() *FieldDescriptorProto_Type { + p := new(FieldDescriptorProto_Type) + *p = x + return p +} +func (x FieldDescriptorProto_Type) String() string { + return proto.EnumName(FieldDescriptorProto_Type_name, int32(x)) +} +func (x *FieldDescriptorProto_Type) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Type_value, data, "FieldDescriptorProto_Type") + if err != nil { + return err + } + *x = FieldDescriptorProto_Type(value) + return nil +} +func (FieldDescriptorProto_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3, 0} } + +type FieldDescriptorProto_Label int32 + +const ( + // 0 is reserved for errors + FieldDescriptorProto_LABEL_OPTIONAL FieldDescriptorProto_Label = 1 + FieldDescriptorProto_LABEL_REQUIRED FieldDescriptorProto_Label = 2 + FieldDescriptorProto_LABEL_REPEATED FieldDescriptorProto_Label = 3 +) + +var FieldDescriptorProto_Label_name = map[int32]string{ + 1: "LABEL_OPTIONAL", + 2: "LABEL_REQUIRED", + 3: "LABEL_REPEATED", +} +var FieldDescriptorProto_Label_value = map[string]int32{ + "LABEL_OPTIONAL": 1, + "LABEL_REQUIRED": 2, + "LABEL_REPEATED": 3, +} + +func (x FieldDescriptorProto_Label) Enum() *FieldDescriptorProto_Label { + p := new(FieldDescriptorProto_Label) + *p = x + return p +} +func (x FieldDescriptorProto_Label) String() string { + return proto.EnumName(FieldDescriptorProto_Label_name, int32(x)) +} +func (x *FieldDescriptorProto_Label) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldDescriptorProto_Label_value, data, "FieldDescriptorProto_Label") + if err != nil { + return err + } + *x = FieldDescriptorProto_Label(value) + return nil +} +func (FieldDescriptorProto_Label) EnumDescriptor() ([]byte, []int) { + return fileDescriptor0, []int{3, 1} +} + +// Generated classes can be optimized for speed or code size. +type FileOptions_OptimizeMode int32 + +const ( + FileOptions_SPEED FileOptions_OptimizeMode = 1 + // etc. + FileOptions_CODE_SIZE FileOptions_OptimizeMode = 2 + FileOptions_LITE_RUNTIME FileOptions_OptimizeMode = 3 +) + +var FileOptions_OptimizeMode_name = map[int32]string{ + 1: "SPEED", + 2: "CODE_SIZE", + 3: "LITE_RUNTIME", +} +var FileOptions_OptimizeMode_value = map[string]int32{ + "SPEED": 1, + "CODE_SIZE": 2, + "LITE_RUNTIME": 3, +} + +func (x FileOptions_OptimizeMode) Enum() *FileOptions_OptimizeMode { + p := new(FileOptions_OptimizeMode) + *p = x + return p +} +func (x FileOptions_OptimizeMode) String() string { + return proto.EnumName(FileOptions_OptimizeMode_name, int32(x)) +} +func (x *FileOptions_OptimizeMode) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FileOptions_OptimizeMode_value, data, "FileOptions_OptimizeMode") + if err != nil { + return err + } + *x = FileOptions_OptimizeMode(value) + return nil +} +func (FileOptions_OptimizeMode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{9, 0} } + +type FieldOptions_CType int32 + +const ( + // Default mode. + FieldOptions_STRING FieldOptions_CType = 0 + FieldOptions_CORD FieldOptions_CType = 1 + FieldOptions_STRING_PIECE FieldOptions_CType = 2 +) + +var FieldOptions_CType_name = map[int32]string{ + 0: "STRING", + 1: "CORD", + 2: "STRING_PIECE", +} +var FieldOptions_CType_value = map[string]int32{ + "STRING": 0, + "CORD": 1, + "STRING_PIECE": 2, +} + +func (x FieldOptions_CType) Enum() *FieldOptions_CType { + p := new(FieldOptions_CType) + *p = x + return p +} +func (x FieldOptions_CType) String() string { + return proto.EnumName(FieldOptions_CType_name, int32(x)) +} +func (x *FieldOptions_CType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(FieldOptions_CType_value, data, "FieldOptions_CType") + if err != nil { + return err + } + *x = FieldOptions_CType(value) + return nil +} +func (FieldOptions_CType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{11, 0} } + +// The protocol compiler can output a FileDescriptorSet containing the .proto +// files it parses. +type FileDescriptorSet struct { + File []*FileDescriptorProto `protobuf:"bytes,1,rep,name=file" json:"file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FileDescriptorSet) Reset() { *m = FileDescriptorSet{} } +func (m *FileDescriptorSet) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorSet) ProtoMessage() {} +func (*FileDescriptorSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *FileDescriptorSet) GetFile() []*FileDescriptorProto { + if m != nil { + return m.File + } + return nil +} + +// Describes a complete .proto file. +type FileDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Package *string `protobuf:"bytes,2,opt,name=package" json:"package,omitempty"` + // Names of files imported by this file. + Dependency []string `protobuf:"bytes,3,rep,name=dependency" json:"dependency,omitempty"` + // Indexes of the public imported files in the dependency list above. + PublicDependency []int32 `protobuf:"varint,10,rep,name=public_dependency" json:"public_dependency,omitempty"` + // Indexes of the weak imported files in the dependency list. + // For Google-internal migration only. Do not use. + WeakDependency []int32 `protobuf:"varint,11,rep,name=weak_dependency" json:"weak_dependency,omitempty"` + // All top-level definitions in this file. + MessageType []*DescriptorProto `protobuf:"bytes,4,rep,name=message_type" json:"message_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,5,rep,name=enum_type" json:"enum_type,omitempty"` + Service []*ServiceDescriptorProto `protobuf:"bytes,6,rep,name=service" json:"service,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,7,rep,name=extension" json:"extension,omitempty"` + Options *FileOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + // This field contains optional information about the original source code. + // You may safely remove this entire field without harming runtime + // functionality of the descriptors -- the information is needed only by + // development tools. + SourceCodeInfo *SourceCodeInfo `protobuf:"bytes,9,opt,name=source_code_info" json:"source_code_info,omitempty"` + // The syntax of the proto file. + // The supported values are "proto2" and "proto3". + Syntax *string `protobuf:"bytes,12,opt,name=syntax" json:"syntax,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FileDescriptorProto) Reset() { *m = FileDescriptorProto{} } +func (m *FileDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FileDescriptorProto) ProtoMessage() {} +func (*FileDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *FileDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FileDescriptorProto) GetPackage() string { + if m != nil && m.Package != nil { + return *m.Package + } + return "" +} + +func (m *FileDescriptorProto) GetDependency() []string { + if m != nil { + return m.Dependency + } + return nil +} + +func (m *FileDescriptorProto) GetPublicDependency() []int32 { + if m != nil { + return m.PublicDependency + } + return nil +} + +func (m *FileDescriptorProto) GetWeakDependency() []int32 { + if m != nil { + return m.WeakDependency + } + return nil +} + +func (m *FileDescriptorProto) GetMessageType() []*DescriptorProto { + if m != nil { + return m.MessageType + } + return nil +} + +func (m *FileDescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *FileDescriptorProto) GetService() []*ServiceDescriptorProto { + if m != nil { + return m.Service + } + return nil +} + +func (m *FileDescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *FileDescriptorProto) GetOptions() *FileOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *FileDescriptorProto) GetSourceCodeInfo() *SourceCodeInfo { + if m != nil { + return m.SourceCodeInfo + } + return nil +} + +func (m *FileDescriptorProto) GetSyntax() string { + if m != nil && m.Syntax != nil { + return *m.Syntax + } + return "" +} + +// Describes a message type. +type DescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Field []*FieldDescriptorProto `protobuf:"bytes,2,rep,name=field" json:"field,omitempty"` + Extension []*FieldDescriptorProto `protobuf:"bytes,6,rep,name=extension" json:"extension,omitempty"` + NestedType []*DescriptorProto `protobuf:"bytes,3,rep,name=nested_type" json:"nested_type,omitempty"` + EnumType []*EnumDescriptorProto `protobuf:"bytes,4,rep,name=enum_type" json:"enum_type,omitempty"` + ExtensionRange []*DescriptorProto_ExtensionRange `protobuf:"bytes,5,rep,name=extension_range" json:"extension_range,omitempty"` + OneofDecl []*OneofDescriptorProto `protobuf:"bytes,8,rep,name=oneof_decl" json:"oneof_decl,omitempty"` + Options *MessageOptions `protobuf:"bytes,7,opt,name=options" json:"options,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DescriptorProto) Reset() { *m = DescriptorProto{} } +func (m *DescriptorProto) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto) ProtoMessage() {} +func (*DescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *DescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *DescriptorProto) GetField() []*FieldDescriptorProto { + if m != nil { + return m.Field + } + return nil +} + +func (m *DescriptorProto) GetExtension() []*FieldDescriptorProto { + if m != nil { + return m.Extension + } + return nil +} + +func (m *DescriptorProto) GetNestedType() []*DescriptorProto { + if m != nil { + return m.NestedType + } + return nil +} + +func (m *DescriptorProto) GetEnumType() []*EnumDescriptorProto { + if m != nil { + return m.EnumType + } + return nil +} + +func (m *DescriptorProto) GetExtensionRange() []*DescriptorProto_ExtensionRange { + if m != nil { + return m.ExtensionRange + } + return nil +} + +func (m *DescriptorProto) GetOneofDecl() []*OneofDescriptorProto { + if m != nil { + return m.OneofDecl + } + return nil +} + +func (m *DescriptorProto) GetOptions() *MessageOptions { + if m != nil { + return m.Options + } + return nil +} + +type DescriptorProto_ExtensionRange struct { + Start *int32 `protobuf:"varint,1,opt,name=start" json:"start,omitempty"` + End *int32 `protobuf:"varint,2,opt,name=end" json:"end,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *DescriptorProto_ExtensionRange) Reset() { *m = DescriptorProto_ExtensionRange{} } +func (m *DescriptorProto_ExtensionRange) String() string { return proto.CompactTextString(m) } +func (*DescriptorProto_ExtensionRange) ProtoMessage() {} +func (*DescriptorProto_ExtensionRange) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{2, 0} +} + +func (m *DescriptorProto_ExtensionRange) GetStart() int32 { + if m != nil && m.Start != nil { + return *m.Start + } + return 0 +} + +func (m *DescriptorProto_ExtensionRange) GetEnd() int32 { + if m != nil && m.End != nil { + return *m.End + } + return 0 +} + +// Describes a field within a message. +type FieldDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,3,opt,name=number" json:"number,omitempty"` + Label *FieldDescriptorProto_Label `protobuf:"varint,4,opt,name=label,enum=google.protobuf.FieldDescriptorProto_Label" json:"label,omitempty"` + // If type_name is set, this need not be set. If both this and type_name + // are set, this must be one of TYPE_ENUM, TYPE_MESSAGE or TYPE_GROUP. + Type *FieldDescriptorProto_Type `protobuf:"varint,5,opt,name=type,enum=google.protobuf.FieldDescriptorProto_Type" json:"type,omitempty"` + // For message and enum types, this is the name of the type. If the name + // starts with a '.', it is fully-qualified. Otherwise, C++-like scoping + // rules are used to find the type (i.e. first the nested types within this + // message are searched, then within the parent, on up to the root + // namespace). + TypeName *string `protobuf:"bytes,6,opt,name=type_name" json:"type_name,omitempty"` + // For extensions, this is the name of the type being extended. It is + // resolved in the same manner as type_name. + Extendee *string `protobuf:"bytes,2,opt,name=extendee" json:"extendee,omitempty"` + // For numeric types, contains the original text representation of the value. + // For booleans, "true" or "false". + // For strings, contains the default text contents (not escaped in any way). + // For bytes, contains the C escaped value. All bytes >= 128 are escaped. + // TODO(kenton): Base-64 encode? + DefaultValue *string `protobuf:"bytes,7,opt,name=default_value" json:"default_value,omitempty"` + // If set, gives the index of a oneof in the containing type's oneof_decl + // list. This field is a member of that oneof. Extensions of a oneof should + // not set this since the oneof to which they belong will be inferred based + // on the extension range containing the extension's field number. + OneofIndex *int32 `protobuf:"varint,9,opt,name=oneof_index" json:"oneof_index,omitempty"` + // JSON name of this field. The value is set by protocol compiler. If the + // user has set a "json_name" option on this field, that option's value + // will be used. Otherwise, it's deduced from the field's name by converting + // it to camelCase. + JsonName *string `protobuf:"bytes,10,opt,name=json_name" json:"json_name,omitempty"` + Options *FieldOptions `protobuf:"bytes,8,opt,name=options" json:"options,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FieldDescriptorProto) Reset() { *m = FieldDescriptorProto{} } +func (m *FieldDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*FieldDescriptorProto) ProtoMessage() {} +func (*FieldDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *FieldDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *FieldDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *FieldDescriptorProto) GetLabel() FieldDescriptorProto_Label { + if m != nil && m.Label != nil { + return *m.Label + } + return FieldDescriptorProto_LABEL_OPTIONAL +} + +func (m *FieldDescriptorProto) GetType() FieldDescriptorProto_Type { + if m != nil && m.Type != nil { + return *m.Type + } + return FieldDescriptorProto_TYPE_DOUBLE +} + +func (m *FieldDescriptorProto) GetTypeName() string { + if m != nil && m.TypeName != nil { + return *m.TypeName + } + return "" +} + +func (m *FieldDescriptorProto) GetExtendee() string { + if m != nil && m.Extendee != nil { + return *m.Extendee + } + return "" +} + +func (m *FieldDescriptorProto) GetDefaultValue() string { + if m != nil && m.DefaultValue != nil { + return *m.DefaultValue + } + return "" +} + +func (m *FieldDescriptorProto) GetOneofIndex() int32 { + if m != nil && m.OneofIndex != nil { + return *m.OneofIndex + } + return 0 +} + +func (m *FieldDescriptorProto) GetJsonName() string { + if m != nil && m.JsonName != nil { + return *m.JsonName + } + return "" +} + +func (m *FieldDescriptorProto) GetOptions() *FieldOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a oneof. +type OneofDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OneofDescriptorProto) Reset() { *m = OneofDescriptorProto{} } +func (m *OneofDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*OneofDescriptorProto) ProtoMessage() {} +func (*OneofDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *OneofDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +// Describes an enum type. +type EnumDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Value []*EnumValueDescriptorProto `protobuf:"bytes,2,rep,name=value" json:"value,omitempty"` + Options *EnumOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *EnumDescriptorProto) Reset() { *m = EnumDescriptorProto{} } +func (m *EnumDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumDescriptorProto) ProtoMessage() {} +func (*EnumDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *EnumDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumDescriptorProto) GetValue() []*EnumValueDescriptorProto { + if m != nil { + return m.Value + } + return nil +} + +func (m *EnumDescriptorProto) GetOptions() *EnumOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a value within an enum. +type EnumValueDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Number *int32 `protobuf:"varint,2,opt,name=number" json:"number,omitempty"` + Options *EnumValueOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *EnumValueDescriptorProto) Reset() { *m = EnumValueDescriptorProto{} } +func (m *EnumValueDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*EnumValueDescriptorProto) ProtoMessage() {} +func (*EnumValueDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *EnumValueDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *EnumValueDescriptorProto) GetNumber() int32 { + if m != nil && m.Number != nil { + return *m.Number + } + return 0 +} + +func (m *EnumValueDescriptorProto) GetOptions() *EnumValueOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a service. +type ServiceDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Method []*MethodDescriptorProto `protobuf:"bytes,2,rep,name=method" json:"method,omitempty"` + Options *ServiceOptions `protobuf:"bytes,3,opt,name=options" json:"options,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ServiceDescriptorProto) Reset() { *m = ServiceDescriptorProto{} } +func (m *ServiceDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*ServiceDescriptorProto) ProtoMessage() {} +func (*ServiceDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *ServiceDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *ServiceDescriptorProto) GetMethod() []*MethodDescriptorProto { + if m != nil { + return m.Method + } + return nil +} + +func (m *ServiceDescriptorProto) GetOptions() *ServiceOptions { + if m != nil { + return m.Options + } + return nil +} + +// Describes a method of a service. +type MethodDescriptorProto struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // Input and output type names. These are resolved in the same way as + // FieldDescriptorProto.type_name, but must refer to a message type. + InputType *string `protobuf:"bytes,2,opt,name=input_type" json:"input_type,omitempty"` + OutputType *string `protobuf:"bytes,3,opt,name=output_type" json:"output_type,omitempty"` + Options *MethodOptions `protobuf:"bytes,4,opt,name=options" json:"options,omitempty"` + // Identifies if client streams multiple client messages + ClientStreaming *bool `protobuf:"varint,5,opt,name=client_streaming,def=0" json:"client_streaming,omitempty"` + // Identifies if server streams multiple server messages + ServerStreaming *bool `protobuf:"varint,6,opt,name=server_streaming,def=0" json:"server_streaming,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MethodDescriptorProto) Reset() { *m = MethodDescriptorProto{} } +func (m *MethodDescriptorProto) String() string { return proto.CompactTextString(m) } +func (*MethodDescriptorProto) ProtoMessage() {} +func (*MethodDescriptorProto) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } + +const Default_MethodDescriptorProto_ClientStreaming bool = false +const Default_MethodDescriptorProto_ServerStreaming bool = false + +func (m *MethodDescriptorProto) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *MethodDescriptorProto) GetInputType() string { + if m != nil && m.InputType != nil { + return *m.InputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOutputType() string { + if m != nil && m.OutputType != nil { + return *m.OutputType + } + return "" +} + +func (m *MethodDescriptorProto) GetOptions() *MethodOptions { + if m != nil { + return m.Options + } + return nil +} + +func (m *MethodDescriptorProto) GetClientStreaming() bool { + if m != nil && m.ClientStreaming != nil { + return *m.ClientStreaming + } + return Default_MethodDescriptorProto_ClientStreaming +} + +func (m *MethodDescriptorProto) GetServerStreaming() bool { + if m != nil && m.ServerStreaming != nil { + return *m.ServerStreaming + } + return Default_MethodDescriptorProto_ServerStreaming +} + +type FileOptions struct { + // Sets the Java package where classes generated from this .proto will be + // placed. By default, the proto package is used, but this is often + // inappropriate because proto packages do not normally start with backwards + // domain names. + JavaPackage *string `protobuf:"bytes,1,opt,name=java_package" json:"java_package,omitempty"` + // If set, all the classes from the .proto file are wrapped in a single + // outer class with the given name. This applies to both Proto1 + // (equivalent to the old "--one_java_file" option) and Proto2 (where + // a .proto always translates to a single class, but you may want to + // explicitly choose the class name). + JavaOuterClassname *string `protobuf:"bytes,8,opt,name=java_outer_classname" json:"java_outer_classname,omitempty"` + // If set true, then the Java code generator will generate a separate .java + // file for each top-level message, enum, and service defined in the .proto + // file. Thus, these types will *not* be nested inside the outer class + // named by java_outer_classname. However, the outer class will still be + // generated to contain the file's getDescriptor() method as well as any + // top-level extensions defined in the file. + JavaMultipleFiles *bool `protobuf:"varint,10,opt,name=java_multiple_files,def=0" json:"java_multiple_files,omitempty"` + // If set true, then the Java code generator will generate equals() and + // hashCode() methods for all messages defined in the .proto file. + // - In the full runtime, this is purely a speed optimization, as the + // AbstractMessage base class includes reflection-based implementations of + // these methods. + // - In the lite runtime, setting this option changes the semantics of + // equals() and hashCode() to more closely match those of the full runtime; + // the generated methods compute their results based on field values rather + // than object identity. (Implementations should not assume that hashcodes + // will be consistent across runtimes or versions of the protocol compiler.) + JavaGenerateEqualsAndHash *bool `protobuf:"varint,20,opt,name=java_generate_equals_and_hash,def=0" json:"java_generate_equals_and_hash,omitempty"` + // If set true, then the Java2 code generator will generate code that + // throws an exception whenever an attempt is made to assign a non-UTF-8 + // byte sequence to a string field. + // Message reflection will do the same. + // However, an extension field still accepts non-UTF-8 byte sequences. + // This option has no effect on when used with the lite runtime. + JavaStringCheckUtf8 *bool `protobuf:"varint,27,opt,name=java_string_check_utf8,def=0" json:"java_string_check_utf8,omitempty"` + OptimizeFor *FileOptions_OptimizeMode `protobuf:"varint,9,opt,name=optimize_for,enum=google.protobuf.FileOptions_OptimizeMode,def=1" json:"optimize_for,omitempty"` + // Sets the Go package where structs generated from this .proto will be + // placed. If omitted, the Go package will be derived from the following: + // - The basename of the package import path, if provided. + // - Otherwise, the package statement in the .proto file, if present. + // - Otherwise, the basename of the .proto file, without extension. + GoPackage *string `protobuf:"bytes,11,opt,name=go_package" json:"go_package,omitempty"` + // Should generic services be generated in each language? "Generic" services + // are not specific to any particular RPC system. They are generated by the + // main code generators in each language (without additional plugins). + // Generic services were the only kind of service generation supported by + // early versions of google.protobuf. + // + // Generic services are now considered deprecated in favor of using plugins + // that generate code specific to your particular RPC system. Therefore, + // these default to false. Old code which depends on generic services should + // explicitly set them to true. + CcGenericServices *bool `protobuf:"varint,16,opt,name=cc_generic_services,def=0" json:"cc_generic_services,omitempty"` + JavaGenericServices *bool `protobuf:"varint,17,opt,name=java_generic_services,def=0" json:"java_generic_services,omitempty"` + PyGenericServices *bool `protobuf:"varint,18,opt,name=py_generic_services,def=0" json:"py_generic_services,omitempty"` + // Is this file deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for everything in the file, or it will be completely ignored; in the very + // least, this is a formalization for deprecating files. + Deprecated *bool `protobuf:"varint,23,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Enables the use of arenas for the proto messages in this file. This applies + // only to generated classes for C++. + CcEnableArenas *bool `protobuf:"varint,31,opt,name=cc_enable_arenas,def=0" json:"cc_enable_arenas,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FileOptions) Reset() { *m = FileOptions{} } +func (m *FileOptions) String() string { return proto.CompactTextString(m) } +func (*FileOptions) ProtoMessage() {} +func (*FileOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } + +var extRange_FileOptions = []proto.ExtensionRange{ + {1000, 536870911}, +} + +func (*FileOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FileOptions +} +func (m *FileOptions) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +const Default_FileOptions_JavaMultipleFiles bool = false +const Default_FileOptions_JavaGenerateEqualsAndHash bool = false +const Default_FileOptions_JavaStringCheckUtf8 bool = false +const Default_FileOptions_OptimizeFor FileOptions_OptimizeMode = FileOptions_SPEED +const Default_FileOptions_CcGenericServices bool = false +const Default_FileOptions_JavaGenericServices bool = false +const Default_FileOptions_PyGenericServices bool = false +const Default_FileOptions_Deprecated bool = false +const Default_FileOptions_CcEnableArenas bool = false + +func (m *FileOptions) GetJavaPackage() string { + if m != nil && m.JavaPackage != nil { + return *m.JavaPackage + } + return "" +} + +func (m *FileOptions) GetJavaOuterClassname() string { + if m != nil && m.JavaOuterClassname != nil { + return *m.JavaOuterClassname + } + return "" +} + +func (m *FileOptions) GetJavaMultipleFiles() bool { + if m != nil && m.JavaMultipleFiles != nil { + return *m.JavaMultipleFiles + } + return Default_FileOptions_JavaMultipleFiles +} + +func (m *FileOptions) GetJavaGenerateEqualsAndHash() bool { + if m != nil && m.JavaGenerateEqualsAndHash != nil { + return *m.JavaGenerateEqualsAndHash + } + return Default_FileOptions_JavaGenerateEqualsAndHash +} + +func (m *FileOptions) GetJavaStringCheckUtf8() bool { + if m != nil && m.JavaStringCheckUtf8 != nil { + return *m.JavaStringCheckUtf8 + } + return Default_FileOptions_JavaStringCheckUtf8 +} + +func (m *FileOptions) GetOptimizeFor() FileOptions_OptimizeMode { + if m != nil && m.OptimizeFor != nil { + return *m.OptimizeFor + } + return Default_FileOptions_OptimizeFor +} + +func (m *FileOptions) GetGoPackage() string { + if m != nil && m.GoPackage != nil { + return *m.GoPackage + } + return "" +} + +func (m *FileOptions) GetCcGenericServices() bool { + if m != nil && m.CcGenericServices != nil { + return *m.CcGenericServices + } + return Default_FileOptions_CcGenericServices +} + +func (m *FileOptions) GetJavaGenericServices() bool { + if m != nil && m.JavaGenericServices != nil { + return *m.JavaGenericServices + } + return Default_FileOptions_JavaGenericServices +} + +func (m *FileOptions) GetPyGenericServices() bool { + if m != nil && m.PyGenericServices != nil { + return *m.PyGenericServices + } + return Default_FileOptions_PyGenericServices +} + +func (m *FileOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FileOptions_Deprecated +} + +func (m *FileOptions) GetCcEnableArenas() bool { + if m != nil && m.CcEnableArenas != nil { + return *m.CcEnableArenas + } + return Default_FileOptions_CcEnableArenas +} + +func (m *FileOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MessageOptions struct { + // Set true to use the old proto1 MessageSet wire format for extensions. + // This is provided for backwards-compatibility with the MessageSet wire + // format. You should not use this for any other reason: It's less + // efficient, has fewer features, and is more complicated. + // + // The message must be defined exactly as follows: + // message Foo { + // option message_set_wire_format = true; + // extensions 4 to max; + // } + // Note that the message cannot have any defined fields; MessageSets only + // have extensions. + // + // All extensions of your type must be singular messages; e.g. they cannot + // be int32s, enums, or repeated messages. + // + // Because this is an option, the above two restrictions are not enforced by + // the protocol compiler. + MessageSetWireFormat *bool `protobuf:"varint,1,opt,name=message_set_wire_format,def=0" json:"message_set_wire_format,omitempty"` + // Disables the generation of the standard "descriptor()" accessor, which can + // conflict with a field of the same name. This is meant to make migration + // from proto1 easier; new code should avoid fields named "descriptor". + NoStandardDescriptorAccessor *bool `protobuf:"varint,2,opt,name=no_standard_descriptor_accessor,def=0" json:"no_standard_descriptor_accessor,omitempty"` + // Is this message deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the message, or it will be completely ignored; in the very least, + // this is a formalization for deprecating messages. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // Whether the message is an automatically generated map entry type for the + // maps field. + // + // For maps fields: + // map map_field = 1; + // The parsed descriptor looks like: + // message MapFieldEntry { + // option map_entry = true; + // optional KeyType key = 1; + // optional ValueType value = 2; + // } + // repeated MapFieldEntry map_field = 1; + // + // Implementations may choose not to generate the map_entry=true message, but + // use a native map in the target language to hold the keys and values. + // The reflection APIs in such implementions still need to work as + // if the field is a repeated message field. + // + // NOTE: Do not set the option in .proto files. Always use the maps syntax + // instead. The option should only be implicitly set by the proto compiler + // parser. + MapEntry *bool `protobuf:"varint,7,opt,name=map_entry" json:"map_entry,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MessageOptions) Reset() { *m = MessageOptions{} } +func (m *MessageOptions) String() string { return proto.CompactTextString(m) } +func (*MessageOptions) ProtoMessage() {} +func (*MessageOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } + +var extRange_MessageOptions = []proto.ExtensionRange{ + {1000, 536870911}, +} + +func (*MessageOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MessageOptions +} +func (m *MessageOptions) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +const Default_MessageOptions_MessageSetWireFormat bool = false +const Default_MessageOptions_NoStandardDescriptorAccessor bool = false +const Default_MessageOptions_Deprecated bool = false + +func (m *MessageOptions) GetMessageSetWireFormat() bool { + if m != nil && m.MessageSetWireFormat != nil { + return *m.MessageSetWireFormat + } + return Default_MessageOptions_MessageSetWireFormat +} + +func (m *MessageOptions) GetNoStandardDescriptorAccessor() bool { + if m != nil && m.NoStandardDescriptorAccessor != nil { + return *m.NoStandardDescriptorAccessor + } + return Default_MessageOptions_NoStandardDescriptorAccessor +} + +func (m *MessageOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MessageOptions_Deprecated +} + +func (m *MessageOptions) GetMapEntry() bool { + if m != nil && m.MapEntry != nil { + return *m.MapEntry + } + return false +} + +func (m *MessageOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type FieldOptions struct { + // The ctype option instructs the C++ code generator to use a different + // representation of the field than it normally would. See the specific + // options below. This option is not yet implemented in the open source + // release -- sorry, we'll try to include it in a future version! + Ctype *FieldOptions_CType `protobuf:"varint,1,opt,name=ctype,enum=google.protobuf.FieldOptions_CType,def=0" json:"ctype,omitempty"` + // The packed option can be enabled for repeated primitive fields to enable + // a more efficient representation on the wire. Rather than repeatedly + // writing the tag and type for each element, the entire array is encoded as + // a single length-delimited blob. + Packed *bool `protobuf:"varint,2,opt,name=packed" json:"packed,omitempty"` + // Should this field be parsed lazily? Lazy applies only to message-type + // fields. It means that when the outer message is initially parsed, the + // inner message's contents will not be parsed but instead stored in encoded + // form. The inner message will actually be parsed when it is first accessed. + // + // This is only a hint. Implementations are free to choose whether to use + // eager or lazy parsing regardless of the value of this option. However, + // setting this option true suggests that the protocol author believes that + // using lazy parsing on this field is worth the additional bookkeeping + // overhead typically needed to implement it. + // + // This option does not affect the public interface of any generated code; + // all method signatures remain the same. Furthermore, thread-safety of the + // interface is not affected by this option; const methods remain safe to + // call from multiple threads concurrently, while non-const methods continue + // to require exclusive access. + // + // + // Note that implementations may choose not to check required fields within + // a lazy sub-message. That is, calling IsInitialized() on the outher message + // may return true even if the inner message has missing required fields. + // This is necessary because otherwise the inner message would have to be + // parsed in order to perform the check, defeating the purpose of lazy + // parsing. An implementation which chooses not to check required fields + // must be consistent about it. That is, for any particular sub-message, the + // implementation must either *always* check its required fields, or *never* + // check its required fields, regardless of whether or not the message has + // been parsed. + Lazy *bool `protobuf:"varint,5,opt,name=lazy,def=0" json:"lazy,omitempty"` + // Is this field deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for accessors, or it will be completely ignored; in the very least, this + // is a formalization for deprecating fields. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // For Google-internal migration only. Do not use. + Weak *bool `protobuf:"varint,10,opt,name=weak,def=0" json:"weak,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *FieldOptions) Reset() { *m = FieldOptions{} } +func (m *FieldOptions) String() string { return proto.CompactTextString(m) } +func (*FieldOptions) ProtoMessage() {} +func (*FieldOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } + +var extRange_FieldOptions = []proto.ExtensionRange{ + {1000, 536870911}, +} + +func (*FieldOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_FieldOptions +} +func (m *FieldOptions) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +const Default_FieldOptions_Ctype FieldOptions_CType = FieldOptions_STRING +const Default_FieldOptions_Lazy bool = false +const Default_FieldOptions_Deprecated bool = false +const Default_FieldOptions_Weak bool = false + +func (m *FieldOptions) GetCtype() FieldOptions_CType { + if m != nil && m.Ctype != nil { + return *m.Ctype + } + return Default_FieldOptions_Ctype +} + +func (m *FieldOptions) GetPacked() bool { + if m != nil && m.Packed != nil { + return *m.Packed + } + return false +} + +func (m *FieldOptions) GetLazy() bool { + if m != nil && m.Lazy != nil { + return *m.Lazy + } + return Default_FieldOptions_Lazy +} + +func (m *FieldOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_FieldOptions_Deprecated +} + +func (m *FieldOptions) GetWeak() bool { + if m != nil && m.Weak != nil { + return *m.Weak + } + return Default_FieldOptions_Weak +} + +func (m *FieldOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumOptions struct { + // Set this option to true to allow mapping different tag names to the same + // value. + AllowAlias *bool `protobuf:"varint,2,opt,name=allow_alias" json:"allow_alias,omitempty"` + // Is this enum deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum, or it will be completely ignored; in the very least, this + // is a formalization for deprecating enums. + Deprecated *bool `protobuf:"varint,3,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *EnumOptions) Reset() { *m = EnumOptions{} } +func (m *EnumOptions) String() string { return proto.CompactTextString(m) } +func (*EnumOptions) ProtoMessage() {} +func (*EnumOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } + +var extRange_EnumOptions = []proto.ExtensionRange{ + {1000, 536870911}, +} + +func (*EnumOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumOptions +} +func (m *EnumOptions) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +const Default_EnumOptions_Deprecated bool = false + +func (m *EnumOptions) GetAllowAlias() bool { + if m != nil && m.AllowAlias != nil { + return *m.AllowAlias + } + return false +} + +func (m *EnumOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumOptions_Deprecated +} + +func (m *EnumOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type EnumValueOptions struct { + // Is this enum value deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the enum value, or it will be completely ignored; in the very least, + // this is a formalization for deprecating enum values. + Deprecated *bool `protobuf:"varint,1,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *EnumValueOptions) Reset() { *m = EnumValueOptions{} } +func (m *EnumValueOptions) String() string { return proto.CompactTextString(m) } +func (*EnumValueOptions) ProtoMessage() {} +func (*EnumValueOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } + +var extRange_EnumValueOptions = []proto.ExtensionRange{ + {1000, 536870911}, +} + +func (*EnumValueOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_EnumValueOptions +} +func (m *EnumValueOptions) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +const Default_EnumValueOptions_Deprecated bool = false + +func (m *EnumValueOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_EnumValueOptions_Deprecated +} + +func (m *EnumValueOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type ServiceOptions struct { + // Is this service deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the service, or it will be completely ignored; in the very least, + // this is a formalization for deprecating services. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *ServiceOptions) Reset() { *m = ServiceOptions{} } +func (m *ServiceOptions) String() string { return proto.CompactTextString(m) } +func (*ServiceOptions) ProtoMessage() {} +func (*ServiceOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } + +var extRange_ServiceOptions = []proto.ExtensionRange{ + {1000, 536870911}, +} + +func (*ServiceOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ServiceOptions +} +func (m *ServiceOptions) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +const Default_ServiceOptions_Deprecated bool = false + +func (m *ServiceOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_ServiceOptions_Deprecated +} + +func (m *ServiceOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +type MethodOptions struct { + // Is this method deprecated? + // Depending on the target platform, this can emit Deprecated annotations + // for the method, or it will be completely ignored; in the very least, + // this is a formalization for deprecating methods. + Deprecated *bool `protobuf:"varint,33,opt,name=deprecated,def=0" json:"deprecated,omitempty"` + // The parser stores options it doesn't recognize here. See above. + UninterpretedOption []*UninterpretedOption `protobuf:"bytes,999,rep,name=uninterpreted_option" json:"uninterpreted_option,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *MethodOptions) Reset() { *m = MethodOptions{} } +func (m *MethodOptions) String() string { return proto.CompactTextString(m) } +func (*MethodOptions) ProtoMessage() {} +func (*MethodOptions) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } + +var extRange_MethodOptions = []proto.ExtensionRange{ + {1000, 536870911}, +} + +func (*MethodOptions) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_MethodOptions +} +func (m *MethodOptions) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +const Default_MethodOptions_Deprecated bool = false + +func (m *MethodOptions) GetDeprecated() bool { + if m != nil && m.Deprecated != nil { + return *m.Deprecated + } + return Default_MethodOptions_Deprecated +} + +func (m *MethodOptions) GetUninterpretedOption() []*UninterpretedOption { + if m != nil { + return m.UninterpretedOption + } + return nil +} + +// A message representing a option the parser does not recognize. This only +// appears in options protos created by the compiler::Parser class. +// DescriptorPool resolves these when building Descriptor objects. Therefore, +// options protos in descriptor objects (e.g. returned by Descriptor::options(), +// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions +// in them. +type UninterpretedOption struct { + Name []*UninterpretedOption_NamePart `protobuf:"bytes,2,rep,name=name" json:"name,omitempty"` + // The value of the uninterpreted option, in whatever type the tokenizer + // identified it as during parsing. Exactly one of these should be set. + IdentifierValue *string `protobuf:"bytes,3,opt,name=identifier_value" json:"identifier_value,omitempty"` + PositiveIntValue *uint64 `protobuf:"varint,4,opt,name=positive_int_value" json:"positive_int_value,omitempty"` + NegativeIntValue *int64 `protobuf:"varint,5,opt,name=negative_int_value" json:"negative_int_value,omitempty"` + DoubleValue *float64 `protobuf:"fixed64,6,opt,name=double_value" json:"double_value,omitempty"` + StringValue []byte `protobuf:"bytes,7,opt,name=string_value" json:"string_value,omitempty"` + AggregateValue *string `protobuf:"bytes,8,opt,name=aggregate_value" json:"aggregate_value,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *UninterpretedOption) Reset() { *m = UninterpretedOption{} } +func (m *UninterpretedOption) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption) ProtoMessage() {} +func (*UninterpretedOption) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } + +func (m *UninterpretedOption) GetName() []*UninterpretedOption_NamePart { + if m != nil { + return m.Name + } + return nil +} + +func (m *UninterpretedOption) GetIdentifierValue() string { + if m != nil && m.IdentifierValue != nil { + return *m.IdentifierValue + } + return "" +} + +func (m *UninterpretedOption) GetPositiveIntValue() uint64 { + if m != nil && m.PositiveIntValue != nil { + return *m.PositiveIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetNegativeIntValue() int64 { + if m != nil && m.NegativeIntValue != nil { + return *m.NegativeIntValue + } + return 0 +} + +func (m *UninterpretedOption) GetDoubleValue() float64 { + if m != nil && m.DoubleValue != nil { + return *m.DoubleValue + } + return 0 +} + +func (m *UninterpretedOption) GetStringValue() []byte { + if m != nil { + return m.StringValue + } + return nil +} + +func (m *UninterpretedOption) GetAggregateValue() string { + if m != nil && m.AggregateValue != nil { + return *m.AggregateValue + } + return "" +} + +// The name of the uninterpreted option. Each string represents a segment in +// a dot-separated name. is_extension is true iff a segment represents an +// extension (denoted with parentheses in options specs in .proto files). +// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents +// "foo.(bar.baz).qux". +type UninterpretedOption_NamePart struct { + NamePart *string `protobuf:"bytes,1,req,name=name_part" json:"name_part,omitempty"` + IsExtension *bool `protobuf:"varint,2,req,name=is_extension" json:"is_extension,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *UninterpretedOption_NamePart) Reset() { *m = UninterpretedOption_NamePart{} } +func (m *UninterpretedOption_NamePart) String() string { return proto.CompactTextString(m) } +func (*UninterpretedOption_NamePart) ProtoMessage() {} +func (*UninterpretedOption_NamePart) Descriptor() ([]byte, []int) { + return fileDescriptor0, []int{16, 0} +} + +func (m *UninterpretedOption_NamePart) GetNamePart() string { + if m != nil && m.NamePart != nil { + return *m.NamePart + } + return "" +} + +func (m *UninterpretedOption_NamePart) GetIsExtension() bool { + if m != nil && m.IsExtension != nil { + return *m.IsExtension + } + return false +} + +// Encapsulates information about the original source file from which a +// FileDescriptorProto was generated. +type SourceCodeInfo struct { + // A Location identifies a piece of source code in a .proto file which + // corresponds to a particular definition. This information is intended + // to be useful to IDEs, code indexers, documentation generators, and similar + // tools. + // + // For example, say we have a file like: + // message Foo { + // optional string foo = 1; + // } + // Let's look at just the field definition: + // optional string foo = 1; + // ^ ^^ ^^ ^ ^^^ + // a bc de f ghi + // We have the following locations: + // span path represents + // [a,i) [ 4, 0, 2, 0 ] The whole field definition. + // [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). + // [c,d) [ 4, 0, 2, 0, 5 ] The type (string). + // [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). + // [g,h) [ 4, 0, 2, 0, 3 ] The number (1). + // + // Notes: + // - A location may refer to a repeated field itself (i.e. not to any + // particular index within it). This is used whenever a set of elements are + // logically enclosed in a single code segment. For example, an entire + // extend block (possibly containing multiple extension definitions) will + // have an outer location whose path refers to the "extensions" repeated + // field without an index. + // - Multiple locations may have the same path. This happens when a single + // logical declaration is spread out across multiple places. The most + // obvious example is the "extend" block again -- there may be multiple + // extend blocks in the same scope, each of which will have the same path. + // - A location's span is not always a subset of its parent's span. For + // example, the "extendee" of an extension declaration appears at the + // beginning of the "extend" block and is shared by all extensions within + // the block. + // - Just because a location's span is a subset of some other location's span + // does not mean that it is a descendent. For example, a "group" defines + // both a type and a field in a single declaration. Thus, the locations + // corresponding to the type and field and their components will overlap. + // - Code which tries to interpret locations should probably be designed to + // ignore those that it doesn't understand, as more types of locations could + // be recorded in the future. + Location []*SourceCodeInfo_Location `protobuf:"bytes,1,rep,name=location" json:"location,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *SourceCodeInfo) Reset() { *m = SourceCodeInfo{} } +func (m *SourceCodeInfo) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo) ProtoMessage() {} +func (*SourceCodeInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } + +func (m *SourceCodeInfo) GetLocation() []*SourceCodeInfo_Location { + if m != nil { + return m.Location + } + return nil +} + +type SourceCodeInfo_Location struct { + // Identifies which part of the FileDescriptorProto was defined at this + // location. + // + // Each element is a field number or an index. They form a path from + // the root FileDescriptorProto to the place where the definition. For + // example, this path: + // [ 4, 3, 2, 7, 1 ] + // refers to: + // file.message_type(3) // 4, 3 + // .field(7) // 2, 7 + // .name() // 1 + // This is because FileDescriptorProto.message_type has field number 4: + // repeated DescriptorProto message_type = 4; + // and DescriptorProto.field has field number 2: + // repeated FieldDescriptorProto field = 2; + // and FieldDescriptorProto.name has field number 1: + // optional string name = 1; + // + // Thus, the above path gives the location of a field name. If we removed + // the last element: + // [ 4, 3, 2, 7 ] + // this path refers to the whole field declaration (from the beginning + // of the label to the terminating semicolon). + Path []int32 `protobuf:"varint,1,rep,packed,name=path" json:"path,omitempty"` + // Always has exactly three or four elements: start line, start column, + // end line (optional, otherwise assumed same as start line), end column. + // These are packed into a single field for efficiency. Note that line + // and column numbers are zero-based -- typically you will want to add + // 1 to each before displaying to a user. + Span []int32 `protobuf:"varint,2,rep,packed,name=span" json:"span,omitempty"` + // If this SourceCodeInfo represents a complete declaration, these are any + // comments appearing before and after the declaration which appear to be + // attached to the declaration. + // + // A series of line comments appearing on consecutive lines, with no other + // tokens appearing on those lines, will be treated as a single comment. + // + // Only the comment content is provided; comment markers (e.g. //) are + // stripped out. For block comments, leading whitespace and an asterisk + // will be stripped from the beginning of each line other than the first. + // Newlines are included in the output. + // + // Examples: + // + // optional int32 foo = 1; // Comment attached to foo. + // // Comment attached to bar. + // optional int32 bar = 2; + // + // optional string baz = 3; + // // Comment attached to baz. + // // Another line attached to baz. + // + // // Comment attached to qux. + // // + // // Another line attached to qux. + // optional double qux = 4; + // + // optional string corge = 5; + // /* Block comment attached + // * to corge. Leading asterisks + // * will be removed. */ + // /* Block comment attached to + // * grault. */ + // optional int32 grault = 6; + LeadingComments *string `protobuf:"bytes,3,opt,name=leading_comments" json:"leading_comments,omitempty"` + TrailingComments *string `protobuf:"bytes,4,opt,name=trailing_comments" json:"trailing_comments,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *SourceCodeInfo_Location) Reset() { *m = SourceCodeInfo_Location{} } +func (m *SourceCodeInfo_Location) String() string { return proto.CompactTextString(m) } +func (*SourceCodeInfo_Location) ProtoMessage() {} +func (*SourceCodeInfo_Location) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17, 0} } + +func (m *SourceCodeInfo_Location) GetPath() []int32 { + if m != nil { + return m.Path + } + return nil +} + +func (m *SourceCodeInfo_Location) GetSpan() []int32 { + if m != nil { + return m.Span + } + return nil +} + +func (m *SourceCodeInfo_Location) GetLeadingComments() string { + if m != nil && m.LeadingComments != nil { + return *m.LeadingComments + } + return "" +} + +func (m *SourceCodeInfo_Location) GetTrailingComments() string { + if m != nil && m.TrailingComments != nil { + return *m.TrailingComments + } + return "" +} + +func init() { + proto.RegisterType((*FileDescriptorSet)(nil), "google.protobuf.FileDescriptorSet") + proto.RegisterType((*FileDescriptorProto)(nil), "google.protobuf.FileDescriptorProto") + proto.RegisterType((*DescriptorProto)(nil), "google.protobuf.DescriptorProto") + proto.RegisterType((*DescriptorProto_ExtensionRange)(nil), "google.protobuf.DescriptorProto.ExtensionRange") + proto.RegisterType((*FieldDescriptorProto)(nil), "google.protobuf.FieldDescriptorProto") + proto.RegisterType((*OneofDescriptorProto)(nil), "google.protobuf.OneofDescriptorProto") + proto.RegisterType((*EnumDescriptorProto)(nil), "google.protobuf.EnumDescriptorProto") + proto.RegisterType((*EnumValueDescriptorProto)(nil), "google.protobuf.EnumValueDescriptorProto") + proto.RegisterType((*ServiceDescriptorProto)(nil), "google.protobuf.ServiceDescriptorProto") + proto.RegisterType((*MethodDescriptorProto)(nil), "google.protobuf.MethodDescriptorProto") + proto.RegisterType((*FileOptions)(nil), "google.protobuf.FileOptions") + proto.RegisterType((*MessageOptions)(nil), "google.protobuf.MessageOptions") + proto.RegisterType((*FieldOptions)(nil), "google.protobuf.FieldOptions") + proto.RegisterType((*EnumOptions)(nil), "google.protobuf.EnumOptions") + proto.RegisterType((*EnumValueOptions)(nil), "google.protobuf.EnumValueOptions") + proto.RegisterType((*ServiceOptions)(nil), "google.protobuf.ServiceOptions") + proto.RegisterType((*MethodOptions)(nil), "google.protobuf.MethodOptions") + proto.RegisterType((*UninterpretedOption)(nil), "google.protobuf.UninterpretedOption") + proto.RegisterType((*UninterpretedOption_NamePart)(nil), "google.protobuf.UninterpretedOption.NamePart") + proto.RegisterType((*SourceCodeInfo)(nil), "google.protobuf.SourceCodeInfo") + proto.RegisterType((*SourceCodeInfo_Location)(nil), "google.protobuf.SourceCodeInfo.Location") + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Type", FieldDescriptorProto_Type_name, FieldDescriptorProto_Type_value) + proto.RegisterEnum("google.protobuf.FieldDescriptorProto_Label", FieldDescriptorProto_Label_name, FieldDescriptorProto_Label_value) + proto.RegisterEnum("google.protobuf.FileOptions_OptimizeMode", FileOptions_OptimizeMode_name, FileOptions_OptimizeMode_value) + proto.RegisterEnum("google.protobuf.FieldOptions_CType", FieldOptions_CType_name, FieldOptions_CType_value) +} + +var fileDescriptor0 = []byte{ + // 1635 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xbc, 0x58, 0xcd, 0x72, 0xdb, 0xd4, + 0x17, 0xff, 0xfb, 0x43, 0xfe, 0x38, 0x76, 0x1c, 0x45, 0x49, 0x5b, 0x35, 0xff, 0x96, 0xb4, 0xa6, + 0x2d, 0x69, 0x69, 0x1d, 0x26, 0x2d, 0xa5, 0x84, 0x55, 0x3e, 0xd4, 0xd4, 0x33, 0x4e, 0x6c, 0x12, + 0x87, 0xa1, 0x6c, 0x34, 0x37, 0xf2, 0xb5, 0xa3, 0x56, 0x96, 0x8c, 0x24, 0xa7, 0x4d, 0x19, 0x66, + 0x78, 0x00, 0x98, 0xe1, 0x09, 0x18, 0x5e, 0x81, 0x0d, 0x2b, 0x36, 0xec, 0x79, 0x03, 0xb6, 0x0c, + 0xf0, 0x18, 0x9c, 0x7b, 0xaf, 0x25, 0x4b, 0x8a, 0x9d, 0xb6, 0x4c, 0x4b, 0x57, 0xee, 0xb9, 0xbf, + 0x73, 0xce, 0xef, 0x9e, 0xcf, 0xab, 0xc0, 0x95, 0x9e, 0xe3, 0xf4, 0x2c, 0xba, 0x32, 0x70, 0x1d, + 0xdf, 0x39, 0x1c, 0x76, 0x57, 0x3a, 0xd4, 0x33, 0x5c, 0x73, 0xe0, 0x3b, 0x6e, 0x8d, 0xcb, 0x94, + 0x59, 0x81, 0xa8, 0x05, 0x88, 0xea, 0x36, 0xcc, 0x3d, 0x34, 0x2d, 0xba, 0x15, 0x02, 0xf7, 0xa9, + 0xaf, 0xac, 0x42, 0xb6, 0x8b, 0x42, 0x35, 0x75, 0x25, 0xb3, 0x5c, 0x5a, 0xbd, 0x56, 0x4b, 0x28, + 0xd5, 0xe2, 0x1a, 0x2d, 0x26, 0xae, 0xfe, 0x9e, 0x81, 0xf9, 0x09, 0x72, 0xa5, 0x0c, 0x59, 0x9b, + 0xf4, 0x99, 0xad, 0xd4, 0x72, 0x51, 0x99, 0x85, 0xfc, 0x80, 0x18, 0x4f, 0x49, 0x8f, 0xaa, 0x69, + 0x2e, 0x50, 0x00, 0x3a, 0x74, 0x40, 0xed, 0x0e, 0xb5, 0x8d, 0x13, 0x35, 0x83, 0x0e, 0x8b, 0xca, + 0x45, 0x98, 0x1b, 0x0c, 0x0f, 0x2d, 0xd3, 0xd0, 0x23, 0x47, 0x80, 0x47, 0x92, 0x72, 0x01, 0x66, + 0x9f, 0x51, 0xf2, 0x34, 0x7a, 0x50, 0xe2, 0x07, 0xf7, 0xa1, 0xdc, 0xa7, 0x9e, 0x87, 0x86, 0x75, + 0xff, 0x64, 0x40, 0xd5, 0x2c, 0xa7, 0x7e, 0xe5, 0x14, 0xf5, 0x24, 0xbd, 0x8f, 0xa0, 0x48, 0xed, + 0x61, 0x5f, 0x28, 0x49, 0x53, 0xee, 0xab, 0x21, 0x22, 0xa9, 0xf8, 0x00, 0xf2, 0x1e, 0x75, 0x8f, + 0x4d, 0x83, 0xaa, 0x39, 0xae, 0xf6, 0xde, 0x29, 0xb5, 0x7d, 0x71, 0x7e, 0x5a, 0xb3, 0x48, 0x9f, + 0xfb, 0xd4, 0xf6, 0x4c, 0xc7, 0x56, 0xf3, 0x5c, 0xf7, 0xfa, 0x84, 0x10, 0x53, 0xab, 0x93, 0xd4, + 0xbc, 0x03, 0x79, 0x67, 0xe0, 0xa3, 0x9a, 0xa7, 0x16, 0x30, 0x7a, 0xa5, 0xd5, 0x4b, 0x13, 0x53, + 0xd3, 0x14, 0x18, 0xe5, 0x63, 0x90, 0x3d, 0x67, 0xe8, 0x1a, 0x54, 0x37, 0x9c, 0x0e, 0xd5, 0x4d, + 0xbb, 0xeb, 0xa8, 0x45, 0xae, 0xb7, 0x74, 0x9a, 0x2b, 0x07, 0x6e, 0x22, 0xae, 0x8e, 0x30, 0xa5, + 0x02, 0x39, 0xef, 0xc4, 0xf6, 0xc9, 0x73, 0xb5, 0xcc, 0xd2, 0x54, 0xfd, 0x23, 0x03, 0xb3, 0x67, + 0x67, 0xf6, 0x1e, 0x48, 0x5d, 0xc6, 0x19, 0xf3, 0xfa, 0x1a, 0x37, 0x8a, 0xc5, 0x22, 0xf7, 0x3a, + 0x9a, 0x1f, 0x42, 0xc9, 0xa6, 0x9e, 0x4f, 0x3b, 0x22, 0x75, 0x99, 0x7f, 0x93, 0xef, 0xec, 0x6b, + 0xe4, 0xfb, 0x11, 0xcc, 0x86, 0x4c, 0x75, 0x97, 0xd8, 0xbd, 0xa0, 0x5c, 0x56, 0x5e, 0xe6, 0xb3, + 0xa6, 0x05, 0x7a, 0x7b, 0x4c, 0x0d, 0xd3, 0x02, 0x8e, 0x4d, 0x9d, 0x2e, 0x16, 0xb1, 0x61, 0x61, + 0x22, 0x27, 0x5f, 0xba, 0xc9, 0x20, 0x49, 0x12, 0x1f, 0x8c, 0x0b, 0x20, 0x3f, 0x25, 0x91, 0x3b, + 0xa2, 0x0b, 0x46, 0x35, 0xb0, 0x78, 0x1b, 0x2a, 0x09, 0xf7, 0x33, 0x20, 0x79, 0x3e, 0x71, 0x7d, + 0x9e, 0x37, 0x49, 0x29, 0x41, 0x06, 0x3b, 0x89, 0x77, 0xa3, 0x54, 0xfd, 0x45, 0x82, 0x85, 0x89, + 0xd1, 0x8e, 0xe7, 0x1a, 0xab, 0x03, 0x23, 0x74, 0x48, 0x5d, 0x0c, 0x3b, 0xb3, 0xb1, 0x06, 0x92, + 0x45, 0x0e, 0xa9, 0x85, 0x01, 0x4d, 0x2d, 0x57, 0x56, 0xdf, 0x7f, 0xa5, 0x0c, 0xd6, 0x1a, 0x4c, + 0x05, 0x2b, 0x20, 0x3b, 0xea, 0x3d, 0xa6, 0x7a, 0xeb, 0xd5, 0x54, 0xdb, 0xa8, 0xa1, 0xcc, 0x41, + 0x91, 0x69, 0xea, 0x9c, 0x58, 0x8e, 0x13, 0x93, 0xa1, 0xc0, 0x93, 0xd4, 0xa1, 0xc1, 0x7c, 0x39, + 0x07, 0x33, 0x1d, 0xda, 0x25, 0x43, 0xcb, 0xd7, 0x8f, 0x89, 0x35, 0xa4, 0x3c, 0x6e, 0x45, 0x65, + 0x1e, 0x4a, 0x22, 0x07, 0x26, 0x62, 0x9f, 0xf3, 0xae, 0x90, 0x98, 0xc1, 0x27, 0x1e, 0x66, 0x97, + 0x1b, 0x04, 0x8e, 0xab, 0x25, 0x3b, 0xee, 0xf2, 0x64, 0x82, 0xa3, 0x70, 0x57, 0x7f, 0x4e, 0x43, + 0x96, 0x93, 0x9b, 0x85, 0x52, 0xfb, 0x71, 0x4b, 0xd3, 0xb7, 0x9a, 0x07, 0x1b, 0x0d, 0x4d, 0x4e, + 0x61, 0xcc, 0x80, 0x0b, 0x1e, 0x36, 0x9a, 0xeb, 0x6d, 0x39, 0x1d, 0xfe, 0xbf, 0xbe, 0xdb, 0xbe, + 0x7f, 0x4f, 0xce, 0x84, 0x0a, 0x07, 0x42, 0x90, 0x8d, 0x02, 0xee, 0xae, 0xca, 0x12, 0xde, 0xad, + 0x2c, 0x0c, 0xd4, 0x3f, 0xd7, 0xb6, 0x10, 0x91, 0x8b, 0x4b, 0x10, 0x93, 0xc7, 0xdc, 0x16, 0xb9, + 0x64, 0xa3, 0xd9, 0x6c, 0xc8, 0x85, 0xd0, 0xe6, 0x7e, 0x7b, 0xaf, 0xbe, 0xbb, 0x2d, 0x17, 0x43, + 0x9b, 0xdb, 0x7b, 0xcd, 0x83, 0x96, 0x0c, 0xa1, 0x85, 0x1d, 0x6d, 0x7f, 0x7f, 0x7d, 0x5b, 0x93, + 0x4b, 0x21, 0x62, 0xe3, 0x71, 0x5b, 0xdb, 0x97, 0xcb, 0x31, 0x5a, 0xe8, 0x62, 0x26, 0x74, 0xa1, + 0xed, 0x1e, 0xec, 0xc8, 0x15, 0x8c, 0xd9, 0x8c, 0x70, 0x11, 0x90, 0x98, 0x4d, 0x88, 0x90, 0xa9, + 0x3c, 0x26, 0x22, 0xac, 0xcc, 0xc5, 0x04, 0x88, 0x50, 0xaa, 0x9b, 0x20, 0x89, 0x7a, 0x50, 0xa0, + 0xd2, 0x58, 0xdf, 0xd0, 0x1a, 0x7a, 0xb3, 0xd5, 0xae, 0x37, 0x77, 0xd7, 0x1b, 0x18, 0xbb, 0x50, + 0xb6, 0xa7, 0x7d, 0x7a, 0x50, 0xdf, 0xd3, 0xb6, 0x30, 0x7e, 0x11, 0x59, 0x4b, 0x5b, 0x6f, 0xa3, + 0x2c, 0x53, 0xbd, 0x06, 0x0b, 0x13, 0xdb, 0x26, 0x56, 0xbd, 0xd5, 0x6f, 0x53, 0x30, 0x3f, 0xa9, + 0xc3, 0xe3, 0x35, 0xfe, 0x00, 0x24, 0x51, 0x30, 0x62, 0x9e, 0xdd, 0x9c, 0x38, 0x24, 0x3e, 0x63, + 0x88, 0x33, 0xa6, 0x74, 0x66, 0xca, 0x94, 0x66, 0xba, 0x41, 0xc9, 0x58, 0xa0, 0x4e, 0x35, 0x35, + 0xad, 0xed, 0x78, 0xb7, 0xe2, 0x9a, 0x4e, 0x38, 0xba, 0x3a, 0x9d, 0x64, 0xe0, 0xed, 0xfb, 0x14, + 0x9c, 0x9f, 0xb2, 0x97, 0xe2, 0xce, 0xee, 0x43, 0xae, 0x4f, 0xfd, 0x23, 0x27, 0x18, 0xe8, 0x37, + 0x26, 0x4c, 0x1a, 0x76, 0x7c, 0xc6, 0x88, 0xca, 0x4c, 0xdb, 0x35, 0xc2, 0x7f, 0x40, 0xe9, 0xd7, + 0x14, 0x9c, 0x9b, 0x6c, 0x2b, 0xce, 0x08, 0x9f, 0x0a, 0xa6, 0x3d, 0x18, 0xfa, 0x62, 0x76, 0xa7, + 0xc3, 0x3e, 0x1e, 0xfa, 0xa1, 0x30, 0xc3, 0x85, 0x2b, 0x63, 0x0a, 0x59, 0x4e, 0xe1, 0x9d, 0x29, + 0xdc, 0x83, 0x45, 0xb9, 0x04, 0xb2, 0x61, 0x99, 0xd4, 0xf6, 0x75, 0xcf, 0x77, 0x29, 0xe9, 0x9b, + 0x76, 0x8f, 0xcf, 0xa3, 0xc2, 0x9a, 0xd4, 0x25, 0x96, 0x47, 0x19, 0x80, 0x2d, 0x7b, 0xea, 0x46, + 0x00, 0xb9, 0x08, 0xa0, 0xfa, 0x5b, 0x16, 0x4a, 0xd1, 0xd5, 0xbb, 0x00, 0xe5, 0x27, 0xe4, 0x98, + 0xe8, 0xc1, 0x63, 0x47, 0xdc, 0xe0, 0x12, 0x2c, 0x70, 0x29, 0x52, 0x46, 0x53, 0x86, 0x45, 0x3c, + 0x8f, 0xdf, 0xaf, 0xc0, 0x4f, 0xab, 0x30, 0xcf, 0x4f, 0xfb, 0x38, 0xac, 0xcc, 0x81, 0x45, 0x75, + 0xf6, 0x06, 0xf3, 0xf8, 0x20, 0x0a, 0x89, 0xdc, 0x86, 0xcb, 0x1c, 0xd3, 0xa3, 0x36, 0x75, 0x89, + 0x4f, 0x75, 0xfa, 0xe5, 0x10, 0x0f, 0x74, 0x62, 0x77, 0xf4, 0x23, 0xe2, 0x1d, 0xa9, 0x0b, 0x51, + 0xf4, 0x75, 0x38, 0xcf, 0xd1, 0x48, 0x1a, 0x19, 0xeb, 0xc6, 0x11, 0x35, 0x9e, 0xea, 0x43, 0xbf, + 0xfb, 0x40, 0xfd, 0x7f, 0x14, 0xf6, 0x10, 0xca, 0x2c, 0x5e, 0x7d, 0xf3, 0x05, 0xfa, 0x74, 0x5c, + 0x3e, 0x0d, 0x2b, 0x13, 0x2a, 0x3e, 0x72, 0xc1, 0x5a, 0x73, 0xa4, 0xb0, 0x83, 0x2f, 0x86, 0x35, + 0x69, 0xbf, 0xa5, 0x69, 0x5b, 0x2c, 0x41, 0x3d, 0x27, 0xbc, 0x72, 0x29, 0xb8, 0x94, 0x61, 0x08, + 0xba, 0xf8, 0x9e, 0x1b, 0xbd, 0x98, 0x3c, 0x55, 0x8e, 0xfa, 0xbf, 0x06, 0xe7, 0xc6, 0x97, 0x8a, + 0xa2, 0xe6, 0xa2, 0x28, 0xb4, 0x34, 0x38, 0x39, 0x8d, 0x51, 0xa2, 0x98, 0x8b, 0xfc, 0x35, 0xe9, + 0x52, 0x03, 0x43, 0xd3, 0x51, 0x2f, 0x24, 0x52, 0x88, 0x44, 0xa8, 0x4d, 0x0e, 0x31, 0xb2, 0xc4, + 0xc5, 0x1f, 0x9e, 0xba, 0x14, 0x05, 0x6c, 0xc2, 0xc2, 0xd0, 0x36, 0x6d, 0xcc, 0x0c, 0x1a, 0x60, + 0xef, 0x0a, 0x51, 0x43, 0xea, 0x5f, 0xf9, 0x29, 0xaf, 0x84, 0x83, 0x28, 0x5a, 0xc4, 0xa5, 0xba, + 0x06, 0xe5, 0x68, 0x64, 0x94, 0x22, 0x88, 0xd8, 0xe0, 0x10, 0xc3, 0xc1, 0xb9, 0xd9, 0xdc, 0x62, + 0x23, 0xef, 0x0b, 0x0d, 0xe7, 0x17, 0x8e, 0xde, 0x46, 0xbd, 0xad, 0xe9, 0x7b, 0x07, 0xbb, 0xed, + 0xfa, 0x8e, 0x26, 0x67, 0x6e, 0x15, 0x0b, 0x7f, 0xe7, 0xe5, 0x6f, 0xf0, 0x5f, 0xba, 0xfa, 0x67, + 0x0a, 0x2a, 0xf1, 0x45, 0xae, 0xdc, 0x80, 0x0b, 0xc1, 0x03, 0xd7, 0xa3, 0xbe, 0xfe, 0xcc, 0x74, + 0x79, 0xb2, 0xfa, 0x44, 0x2c, 0xf2, 0xf0, 0x1a, 0x35, 0x58, 0xb2, 0x1d, 0xcc, 0x38, 0x56, 0x04, + 0x71, 0x3b, 0xfa, 0xf8, 0x0b, 0x40, 0x27, 0x06, 0xc6, 0xcb, 0x73, 0xc4, 0xf4, 0x98, 0x12, 0xb2, + 0x4c, 0xf4, 0x08, 0xf7, 0x61, 0x9f, 0x0c, 0x30, 0x66, 0xbe, 0x7b, 0xc2, 0xf7, 0x66, 0xe1, 0x8d, + 0x04, 0x29, 0x7a, 0xd1, 0x1f, 0xd3, 0x50, 0x8e, 0x2e, 0x50, 0xf6, 0x94, 0x30, 0x78, 0x2b, 0xa7, + 0x78, 0x11, 0xbe, 0x7b, 0xe6, 0xba, 0xad, 0x6d, 0xb2, 0x5d, 0xbb, 0x96, 0x13, 0xfb, 0x8d, 0xcd, + 0x47, 0x56, 0x7c, 0x54, 0xbc, 0x66, 0x0a, 0x38, 0x1c, 0xb2, 0x16, 0x79, 0x71, 0x12, 0x6f, 0xe5, + 0x33, 0xee, 0x8b, 0x78, 0xf6, 0x71, 0x11, 0xef, 0xb8, 0x37, 0x52, 0x16, 0x2b, 0x20, 0x71, 0xaa, + 0xd8, 0x21, 0x23, 0xb2, 0xf2, 0xff, 0x94, 0x02, 0x64, 0x37, 0x9b, 0x7b, 0xac, 0x34, 0xb0, 0x16, + 0x84, 0x54, 0x6f, 0xd5, 0xb5, 0x4d, 0xac, 0x8e, 0x68, 0x88, 0xbe, 0x4b, 0x41, 0x29, 0xb2, 0x2f, + 0xd8, 0xc8, 0x23, 0x96, 0xe5, 0x3c, 0xd3, 0x89, 0x65, 0x62, 0x0d, 0x8b, 0xab, 0x9e, 0x71, 0xab, + 0x37, 0x9d, 0xb2, 0xaf, 0x41, 0x4e, 0x6e, 0x95, 0x84, 0xfb, 0xd4, 0xdb, 0x74, 0xff, 0x15, 0x54, + 0xe2, 0xfb, 0x23, 0xe1, 0xfc, 0xea, 0xdb, 0x74, 0xfe, 0x02, 0x66, 0xe2, 0x9b, 0xe3, 0x3f, 0xf4, + 0xfd, 0x43, 0x1a, 0xe6, 0x27, 0x40, 0x94, 0x4f, 0x46, 0x4b, 0x52, 0xac, 0xe9, 0x3b, 0xaf, 0x62, + 0xb6, 0xb6, 0x8b, 0x0a, 0x2d, 0xfc, 0x06, 0x50, 0x54, 0x90, 0x4d, 0xfc, 0x8c, 0xf6, 0x4d, 0xfc, + 0x76, 0x73, 0x47, 0x2f, 0x64, 0xb1, 0x44, 0x17, 0x41, 0x19, 0x38, 0x9e, 0xe9, 0x9b, 0xc7, 0xec, + 0xcb, 0x31, 0x78, 0x3d, 0xb3, 0x7d, 0x9a, 0x65, 0x67, 0x36, 0xed, 0x91, 0xc4, 0x19, 0x6b, 0xb3, + 0x0c, 0xdb, 0x7c, 0x1d, 0x67, 0xc8, 0x86, 0xac, 0x90, 0xb2, 0x35, 0x99, 0x62, 0xd2, 0xd1, 0x12, + 0x1a, 0xbf, 0xc2, 0xcb, 0xec, 0x6b, 0x9e, 0xf4, 0x7a, 0x2e, 0x33, 0x15, 0xc0, 0xf9, 0x2a, 0x5c, + 0xbc, 0x0b, 0x85, 0x90, 0x22, 0x4e, 0x21, 0x76, 0x3f, 0xdc, 0x2b, 0xfc, 0x9b, 0x25, 0x8d, 0xdc, + 0xd0, 0x9a, 0xe9, 0xe9, 0xe3, 0x0f, 0xc7, 0x34, 0x4a, 0x0b, 0xd5, 0x9f, 0x70, 0x68, 0x26, 0x3e, + 0x63, 0xd7, 0xa0, 0x60, 0x39, 0x98, 0x1b, 0x06, 0x12, 0x7f, 0xcc, 0x58, 0x7e, 0xc9, 0x97, 0x6f, + 0xad, 0x31, 0xc2, 0x2f, 0x1a, 0x50, 0x08, 0x7e, 0x63, 0x83, 0x66, 0x07, 0xc4, 0x3f, 0xe2, 0x36, + 0xa4, 0x8d, 0x34, 0x6f, 0xd9, 0xac, 0x37, 0x20, 0x36, 0x8f, 0xba, 0x90, 0x60, 0x28, 0x2d, 0x4a, + 0x3a, 0x7c, 0xd1, 0x3a, 0xfd, 0x3e, 0x06, 0xd5, 0x1b, 0x85, 0xf2, 0x22, 0xcc, 0xf9, 0x2e, 0x31, + 0xad, 0xd8, 0x11, 0x8b, 0x64, 0x71, 0xe3, 0x26, 0xae, 0x47, 0xa7, 0x9f, 0xe4, 0xb4, 0x21, 0x27, + 0x5e, 0x42, 0xde, 0xa3, 0xd4, 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x3d, 0xe5, 0x5c, 0x96, 0xdd, + 0x11, 0x00, 0x00, +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/doc.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/doc.go new file mode 100644 index 00000000..0d6055d6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/doc.go @@ -0,0 +1,51 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +/* + A plugin for the Google protocol buffer compiler to generate Go code. + Run it by building this program and putting it in your path with the name + protoc-gen-go + That word 'go' at the end becomes part of the option string set for the + protocol compiler, so once the protocol compiler (protoc) is installed + you can run + protoc --go_out=output_directory input_directory/file.proto + to generate Go bindings for the protocol defined by file.proto. + With that input, the output will be written to + output_directory/file.pb.go + + The generated code is documented in the package comment for + the library. + + See the README and documentation for protocol buffers to learn more: + https://developers.google.com/protocol-buffers/ + +*/ +package documentation diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/Makefile new file mode 100644 index 00000000..b5715c35 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/Makefile @@ -0,0 +1,40 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +include $(GOROOT)/src/Make.inc + +TARG=github.com/golang/protobuf/compiler/generator +GOFILES=\ + generator.go\ + +DEPS=../descriptor ../plugin ../../proto + +include $(GOROOT)/src/Make.pkg diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/generator.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/generator.go new file mode 100644 index 00000000..0f7a3373 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/generator.go @@ -0,0 +1,2717 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +/* + The code generator for the plugin for the Google protocol buffer compiler. + It generates Go code from the protocol buffer description files read by the + main routine. +*/ +package generator + +import ( + "bufio" + "bytes" + "compress/gzip" + "fmt" + "go/parser" + "go/printer" + "go/token" + "log" + "os" + "path" + "strconv" + "strings" + "unicode" + "unicode/utf8" + + "github.com/golang/protobuf/proto" + + "github.com/golang/protobuf/protoc-gen-go/descriptor" + plugin "github.com/golang/protobuf/protoc-gen-go/plugin" +) + +// generatedCodeVersion indicates a version of the generated code. +// It is incremented whenever an incompatibility between the generated code and +// proto package is introduced; the generated code references +// a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion). +const generatedCodeVersion = 1 + +// A Plugin provides functionality to add to the output during Go code generation, +// such as to produce RPC stubs. +type Plugin interface { + // Name identifies the plugin. + Name() string + // Init is called once after data structures are built but before + // code generation begins. + Init(g *Generator) + // Generate produces the code generated by the plugin for this file, + // except for the imports, by calling the generator's methods P, In, and Out. + Generate(file *FileDescriptor) + // GenerateImports produces the import declarations for this file. + // It is called after Generate. + GenerateImports(file *FileDescriptor) +} + +var plugins []Plugin + +// RegisterPlugin installs a (second-order) plugin to be run when the Go output is generated. +// It is typically called during initialization. +func RegisterPlugin(p Plugin) { + plugins = append(plugins, p) +} + +// Each type we import as a protocol buffer (other than FileDescriptorProto) needs +// a pointer to the FileDescriptorProto that represents it. These types achieve that +// wrapping by placing each Proto inside a struct with the pointer to its File. The +// structs have the same names as their contents, with "Proto" removed. +// FileDescriptor is used to store the things that it points to. + +// The file and package name method are common to messages and enums. +type common struct { + file *descriptor.FileDescriptorProto // File this object comes from. +} + +// PackageName is name in the package clause in the generated file. +func (c *common) PackageName() string { return uniquePackageOf(c.file) } + +func (c *common) File() *descriptor.FileDescriptorProto { return c.file } + +func fileIsProto3(file *descriptor.FileDescriptorProto) bool { + return file.GetSyntax() == "proto3" +} + +func (c *common) proto3() bool { return fileIsProto3(c.file) } + +// Descriptor represents a protocol buffer message. +type Descriptor struct { + common + *descriptor.DescriptorProto + parent *Descriptor // The containing message, if any. + nested []*Descriptor // Inner messages, if any. + enums []*EnumDescriptor // Inner enums, if any. + ext []*ExtensionDescriptor // Extensions, if any. + typename []string // Cached typename vector. + index int // The index into the container, whether the file or another message. + path string // The SourceCodeInfo path as comma-separated integers. + group bool +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (d *Descriptor) TypeName() []string { + if d.typename != nil { + return d.typename + } + n := 0 + for parent := d; parent != nil; parent = parent.parent { + n++ + } + s := make([]string, n, n) + for parent := d; parent != nil; parent = parent.parent { + n-- + s[n] = parent.GetName() + } + d.typename = s + return s +} + +// EnumDescriptor describes an enum. If it's at top level, its parent will be nil. +// Otherwise it will be the descriptor of the message in which it is defined. +type EnumDescriptor struct { + common + *descriptor.EnumDescriptorProto + parent *Descriptor // The containing message, if any. + typename []string // Cached typename vector. + index int // The index into the container, whether the file or a message. + path string // The SourceCodeInfo path as comma-separated integers. +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (e *EnumDescriptor) TypeName() (s []string) { + if e.typename != nil { + return e.typename + } + name := e.GetName() + if e.parent == nil { + s = make([]string, 1) + } else { + pname := e.parent.TypeName() + s = make([]string, len(pname)+1) + copy(s, pname) + } + s[len(s)-1] = name + e.typename = s + return s +} + +// Everything but the last element of the full type name, CamelCased. +// The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... . +func (e *EnumDescriptor) prefix() string { + if e.parent == nil { + // If the enum is not part of a message, the prefix is just the type name. + return CamelCase(*e.Name) + "_" + } + typeName := e.TypeName() + return CamelCaseSlice(typeName[0:len(typeName)-1]) + "_" +} + +// The integer value of the named constant in this enumerated type. +func (e *EnumDescriptor) integerValueAsString(name string) string { + for _, c := range e.Value { + if c.GetName() == name { + return fmt.Sprint(c.GetNumber()) + } + } + log.Fatal("cannot find value for enum constant") + return "" +} + +// ExtensionDescriptor describes an extension. If it's at top level, its parent will be nil. +// Otherwise it will be the descriptor of the message in which it is defined. +type ExtensionDescriptor struct { + common + *descriptor.FieldDescriptorProto + parent *Descriptor // The containing message, if any. +} + +// TypeName returns the elements of the dotted type name. +// The package name is not part of this name. +func (e *ExtensionDescriptor) TypeName() (s []string) { + name := e.GetName() + if e.parent == nil { + // top-level extension + s = make([]string, 1) + } else { + pname := e.parent.TypeName() + s = make([]string, len(pname)+1) + copy(s, pname) + } + s[len(s)-1] = name + return s +} + +// DescName returns the variable name used for the generated descriptor. +func (e *ExtensionDescriptor) DescName() string { + // The full type name. + typeName := e.TypeName() + // Each scope of the extension is individually CamelCased, and all are joined with "_" with an "E_" prefix. + for i, s := range typeName { + typeName[i] = CamelCase(s) + } + return "E_" + strings.Join(typeName, "_") +} + +// ImportedDescriptor describes a type that has been publicly imported from another file. +type ImportedDescriptor struct { + common + o Object +} + +func (id *ImportedDescriptor) TypeName() []string { return id.o.TypeName() } + +// FileDescriptor describes an protocol buffer descriptor file (.proto). +// It includes slices of all the messages and enums defined within it. +// Those slices are constructed by WrapTypes. +type FileDescriptor struct { + *descriptor.FileDescriptorProto + desc []*Descriptor // All the messages defined in this file. + enum []*EnumDescriptor // All the enums defined in this file. + ext []*ExtensionDescriptor // All the top-level extensions defined in this file. + imp []*ImportedDescriptor // All types defined in files publicly imported by this file. + + // Comments, stored as a map of path (comma-separated integers) to the comment. + comments map[string]*descriptor.SourceCodeInfo_Location + + // The full list of symbols that are exported, + // as a map from the exported object to its symbols. + // This is used for supporting public imports. + exported map[Object][]symbol + + index int // The index of this file in the list of files to generate code for + + proto3 bool // whether to generate proto3 code for this file +} + +// PackageName is the package name we'll use in the generated code to refer to this file. +func (d *FileDescriptor) PackageName() string { return uniquePackageOf(d.FileDescriptorProto) } + +// goPackageName returns the Go package name to use in the +// generated Go file. The result explicit reports whether the name +// came from an option go_package statement. If explicit is false, +// the name was derived from the protocol buffer's package statement +// or the input file name. +func (d *FileDescriptor) goPackageName() (name string, explicit bool) { + // Does the file have a "go_package" option? + if opts := d.Options; opts != nil { + if pkg := opts.GetGoPackage(); pkg != "" { + return pkg, true + } + } + + // Does the file have a package clause? + if pkg := d.GetPackage(); pkg != "" { + return pkg, false + } + // Use the file base name. + return baseName(d.GetName()), false +} + +func (d *FileDescriptor) addExport(obj Object, sym symbol) { + d.exported[obj] = append(d.exported[obj], sym) +} + +// symbol is an interface representing an exported Go symbol. +type symbol interface { + // GenerateAlias should generate an appropriate alias + // for the symbol from the named package. + GenerateAlias(g *Generator, pkg string) +} + +type messageSymbol struct { + sym string + hasExtensions, isMessageSet bool + hasOneof bool + getters []getterSymbol +} + +type getterSymbol struct { + name string + typ string + typeName string // canonical name in proto world; empty for proto.Message and similar + genType bool // whether typ contains a generated type (message/group/enum) +} + +func (ms *messageSymbol) GenerateAlias(g *Generator, pkg string) { + remoteSym := pkg + "." + ms.sym + + g.P("type ", ms.sym, " ", remoteSym) + g.P("func (m *", ms.sym, ") Reset() { (*", remoteSym, ")(m).Reset() }") + g.P("func (m *", ms.sym, ") String() string { return (*", remoteSym, ")(m).String() }") + g.P("func (*", ms.sym, ") ProtoMessage() {}") + if ms.hasExtensions { + g.P("func (*", ms.sym, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange ", + "{ return (*", remoteSym, ")(nil).ExtensionRangeArray() }") + g.P("func (m *", ms.sym, ") ExtensionMap() map[int32]", g.Pkg["proto"], ".Extension ", + "{ return (*", remoteSym, ")(m).ExtensionMap() }") + if ms.isMessageSet { + g.P("func (m *", ms.sym, ") Marshal() ([]byte, error) ", + "{ return (*", remoteSym, ")(m).Marshal() }") + g.P("func (m *", ms.sym, ") Unmarshal(buf []byte) error ", + "{ return (*", remoteSym, ")(m).Unmarshal(buf) }") + } + } + if ms.hasOneof { + // Oneofs and public imports do not mix well. + // We can make them work okay for the binary format, + // but they're going to break weirdly for text/JSON. + enc := "_" + ms.sym + "_OneofMarshaler" + dec := "_" + ms.sym + "_OneofUnmarshaler" + size := "_" + ms.sym + "_OneofSizer" + encSig := "(msg " + g.Pkg["proto"] + ".Message, b *" + g.Pkg["proto"] + ".Buffer) error" + decSig := "(msg " + g.Pkg["proto"] + ".Message, tag, wire int, b *" + g.Pkg["proto"] + ".Buffer) (bool, error)" + sizeSig := "(msg " + g.Pkg["proto"] + ".Message) int" + g.P("func (m *", ms.sym, ") XXX_OneofFuncs() (func", encSig, ", func", decSig, ", func", sizeSig, ", []interface{}) {") + g.P("return ", enc, ", ", dec, ", ", size, ", nil") + g.P("}") + + g.P("func ", enc, encSig, " {") + g.P("m := msg.(*", ms.sym, ")") + g.P("m0 := (*", remoteSym, ")(m)") + g.P("enc, _, _, _ := m0.XXX_OneofFuncs()") + g.P("return enc(m0, b)") + g.P("}") + + g.P("func ", dec, decSig, " {") + g.P("m := msg.(*", ms.sym, ")") + g.P("m0 := (*", remoteSym, ")(m)") + g.P("_, dec, _, _ := m0.XXX_OneofFuncs()") + g.P("return dec(m0, tag, wire, b)") + g.P("}") + + g.P("func ", size, sizeSig, " {") + g.P("m := msg.(*", ms.sym, ")") + g.P("m0 := (*", remoteSym, ")(m)") + g.P("_, _, size, _ := m0.XXX_OneofFuncs()") + g.P("return size(m0)") + g.P("}") + } + for _, get := range ms.getters { + + if get.typeName != "" { + g.RecordTypeUse(get.typeName) + } + typ := get.typ + val := "(*" + remoteSym + ")(m)." + get.name + "()" + if get.genType { + // typ will be "*pkg.T" (message/group) or "pkg.T" (enum) + // or "map[t]*pkg.T" (map to message/enum). + // The first two of those might have a "[]" prefix if it is repeated. + // Drop any package qualifier since we have hoisted the type into this package. + rep := strings.HasPrefix(typ, "[]") + if rep { + typ = typ[2:] + } + isMap := strings.HasPrefix(typ, "map[") + star := typ[0] == '*' + if !isMap { // map types handled lower down + typ = typ[strings.Index(typ, ".")+1:] + } + if star { + typ = "*" + typ + } + if rep { + // Go does not permit conversion between slice types where both + // element types are named. That means we need to generate a bit + // of code in this situation. + // typ is the element type. + // val is the expression to get the slice from the imported type. + + ctyp := typ // conversion type expression; "Foo" or "(*Foo)" + if star { + ctyp = "(" + typ + ")" + } + + g.P("func (m *", ms.sym, ") ", get.name, "() []", typ, " {") + g.In() + g.P("o := ", val) + g.P("if o == nil {") + g.In() + g.P("return nil") + g.Out() + g.P("}") + g.P("s := make([]", typ, ", len(o))") + g.P("for i, x := range o {") + g.In() + g.P("s[i] = ", ctyp, "(x)") + g.Out() + g.P("}") + g.P("return s") + g.Out() + g.P("}") + continue + } + if isMap { + // Split map[keyTyp]valTyp. + bra, ket := strings.Index(typ, "["), strings.Index(typ, "]") + keyTyp, valTyp := typ[bra+1:ket], typ[ket+1:] + // Drop any package qualifier. + // Only the value type may be foreign. + star := valTyp[0] == '*' + valTyp = valTyp[strings.Index(valTyp, ".")+1:] + if star { + valTyp = "*" + valTyp + } + + typ := "map[" + keyTyp + "]" + valTyp + g.P("func (m *", ms.sym, ") ", get.name, "() ", typ, " {") + g.P("o := ", val) + g.P("if o == nil { return nil }") + g.P("s := make(", typ, ", len(o))") + g.P("for k, v := range o {") + g.P("s[k] = (", valTyp, ")(v)") + g.P("}") + g.P("return s") + g.P("}") + continue + } + // Convert imported type into the forwarding type. + val = "(" + typ + ")(" + val + ")" + } + + g.P("func (m *", ms.sym, ") ", get.name, "() ", typ, " { return ", val, " }") + } + +} + +type enumSymbol struct { + name string + proto3 bool // Whether this came from a proto3 file. +} + +func (es enumSymbol) GenerateAlias(g *Generator, pkg string) { + s := es.name + g.P("type ", s, " ", pkg, ".", s) + g.P("var ", s, "_name = ", pkg, ".", s, "_name") + g.P("var ", s, "_value = ", pkg, ".", s, "_value") + g.P("func (x ", s, ") String() string { return (", pkg, ".", s, ")(x).String() }") + if !es.proto3 { + g.P("func (x ", s, ") Enum() *", s, "{ return (*", s, ")((", pkg, ".", s, ")(x).Enum()) }") + g.P("func (x *", s, ") UnmarshalJSON(data []byte) error { return (*", pkg, ".", s, ")(x).UnmarshalJSON(data) }") + } +} + +type constOrVarSymbol struct { + sym string + typ string // either "const" or "var" + cast string // if non-empty, a type cast is required (used for enums) +} + +func (cs constOrVarSymbol) GenerateAlias(g *Generator, pkg string) { + v := pkg + "." + cs.sym + if cs.cast != "" { + v = cs.cast + "(" + v + ")" + } + g.P(cs.typ, " ", cs.sym, " = ", v) +} + +// Object is an interface abstracting the abilities shared by enums, messages, extensions and imported objects. +type Object interface { + PackageName() string // The name we use in our output (a_b_c), possibly renamed for uniqueness. + TypeName() []string + File() *descriptor.FileDescriptorProto +} + +// Each package name we generate must be unique. The package we're generating +// gets its own name but every other package must have a unique name that does +// not conflict in the code we generate. These names are chosen globally (although +// they don't have to be, it simplifies things to do them globally). +func uniquePackageOf(fd *descriptor.FileDescriptorProto) string { + s, ok := uniquePackageName[fd] + if !ok { + log.Fatal("internal error: no package name defined for " + fd.GetName()) + } + return s +} + +// Generator is the type whose methods generate the output, stored in the associated response structure. +type Generator struct { + *bytes.Buffer + + Request *plugin.CodeGeneratorRequest // The input. + Response *plugin.CodeGeneratorResponse // The output. + + Param map[string]string // Command-line parameters. + PackageImportPath string // Go import path of the package we're generating code for + ImportPrefix string // String to prefix to imported package file names. + ImportMap map[string]string // Mapping from import name to generated name + + Pkg map[string]string // The names under which we import support packages + + packageName string // What we're calling ourselves. + allFiles []*FileDescriptor // All files in the tree + allFilesByName map[string]*FileDescriptor // All files by filename. + genFiles []*FileDescriptor // Those files we will generate output for. + file *FileDescriptor // The file we are compiling now. + usedPackages map[string]bool // Names of packages used in current file. + typeNameToObject map[string]Object // Key is a fully-qualified name in input syntax. + init []string // Lines to emit in the init function. + indent string + writeOutput bool +} + +// New creates a new generator and allocates the request and response protobufs. +func New() *Generator { + g := new(Generator) + g.Buffer = new(bytes.Buffer) + g.Request = new(plugin.CodeGeneratorRequest) + g.Response = new(plugin.CodeGeneratorResponse) + return g +} + +// Error reports a problem, including an error, and exits the program. +func (g *Generator) Error(err error, msgs ...string) { + s := strings.Join(msgs, " ") + ":" + err.Error() + log.Print("protoc-gen-go: error:", s) + os.Exit(1) +} + +// Fail reports a problem and exits the program. +func (g *Generator) Fail(msgs ...string) { + s := strings.Join(msgs, " ") + log.Print("protoc-gen-go: error:", s) + os.Exit(1) +} + +// CommandLineParameters breaks the comma-separated list of key=value pairs +// in the parameter (a member of the request protobuf) into a key/value map. +// It then sets file name mappings defined by those entries. +func (g *Generator) CommandLineParameters(parameter string) { + g.Param = make(map[string]string) + for _, p := range strings.Split(parameter, ",") { + if i := strings.Index(p, "="); i < 0 { + g.Param[p] = "" + } else { + g.Param[p[0:i]] = p[i+1:] + } + } + + g.ImportMap = make(map[string]string) + pluginList := "none" // Default list of plugin names to enable (empty means all). + for k, v := range g.Param { + switch k { + case "import_prefix": + g.ImportPrefix = v + case "import_path": + g.PackageImportPath = v + case "plugins": + pluginList = v + default: + if len(k) > 0 && k[0] == 'M' { + g.ImportMap[k[1:]] = v + } + } + } + + if pluginList != "" { + // Amend the set of plugins. + enabled := make(map[string]bool) + for _, name := range strings.Split(pluginList, "+") { + enabled[name] = true + } + var nplugins []Plugin + for _, p := range plugins { + if enabled[p.Name()] { + nplugins = append(nplugins, p) + } + } + plugins = nplugins + } +} + +// DefaultPackageName returns the package name printed for the object. +// If its file is in a different package, it returns the package name we're using for this file, plus ".". +// Otherwise it returns the empty string. +func (g *Generator) DefaultPackageName(obj Object) string { + pkg := obj.PackageName() + if pkg == g.packageName { + return "" + } + return pkg + "." +} + +// For each input file, the unique package name to use, underscored. +var uniquePackageName = make(map[*descriptor.FileDescriptorProto]string) + +// Package names already registered. Key is the name from the .proto file; +// value is the name that appears in the generated code. +var pkgNamesInUse = make(map[string]bool) + +// Create and remember a guaranteed unique package name for this file descriptor. +// Pkg is the candidate name. If f is nil, it's a builtin package like "proto" and +// has no file descriptor. +func RegisterUniquePackageName(pkg string, f *FileDescriptor) string { + // Convert dots to underscores before finding a unique alias. + pkg = strings.Map(badToUnderscore, pkg) + + for i, orig := 1, pkg; pkgNamesInUse[pkg]; i++ { + // It's a duplicate; must rename. + pkg = orig + strconv.Itoa(i) + } + // Install it. + pkgNamesInUse[pkg] = true + if f != nil { + uniquePackageName[f.FileDescriptorProto] = pkg + } + return pkg +} + +var isGoKeyword = map[string]bool{ + "break": true, + "case": true, + "chan": true, + "const": true, + "continue": true, + "default": true, + "else": true, + "defer": true, + "fallthrough": true, + "for": true, + "func": true, + "go": true, + "goto": true, + "if": true, + "import": true, + "interface": true, + "map": true, + "package": true, + "range": true, + "return": true, + "select": true, + "struct": true, + "switch": true, + "type": true, + "var": true, +} + +// defaultGoPackage returns the package name to use, +// derived from the import path of the package we're building code for. +func (g *Generator) defaultGoPackage() string { + p := g.PackageImportPath + if i := strings.LastIndex(p, "/"); i >= 0 { + p = p[i+1:] + } + if p == "" { + return "" + } + + p = strings.Map(badToUnderscore, p) + // Identifier must not be keyword: insert _. + if isGoKeyword[p] { + p = "_" + p + } + // Identifier must not begin with digit: insert _. + if r, _ := utf8.DecodeRuneInString(p); unicode.IsDigit(r) { + p = "_" + p + } + return p +} + +// SetPackageNames sets the package name for this run. +// The package name must agree across all files being generated. +// It also defines unique package names for all imported files. +func (g *Generator) SetPackageNames() { + // Register the name for this package. It will be the first name + // registered so is guaranteed to be unmodified. + pkg, explicit := g.genFiles[0].goPackageName() + + // Check all files for an explicit go_package option. + for _, f := range g.genFiles { + thisPkg, thisExplicit := f.goPackageName() + if thisExplicit { + if !explicit { + // Let this file's go_package option serve for all input files. + pkg, explicit = thisPkg, true + } else if thisPkg != pkg { + g.Fail("inconsistent package names:", thisPkg, pkg) + } + } + } + + // If we don't have an explicit go_package option but we have an + // import path, use that. + if !explicit { + p := g.defaultGoPackage() + if p != "" { + pkg, explicit = p, true + } + } + + // If there was no go_package and no import path to use, + // double-check that all the inputs have the same implicit + // Go package name. + if !explicit { + for _, f := range g.genFiles { + thisPkg, _ := f.goPackageName() + if thisPkg != pkg { + g.Fail("inconsistent package names:", thisPkg, pkg) + } + } + } + + g.packageName = RegisterUniquePackageName(pkg, g.genFiles[0]) + + // Register the support package names. They might collide with the + // name of a package we import. + g.Pkg = map[string]string{ + "fmt": RegisterUniquePackageName("fmt", nil), + "math": RegisterUniquePackageName("math", nil), + "proto": RegisterUniquePackageName("proto", nil), + } + +AllFiles: + for _, f := range g.allFiles { + for _, genf := range g.genFiles { + if f == genf { + // In this package already. + uniquePackageName[f.FileDescriptorProto] = g.packageName + continue AllFiles + } + } + // The file is a dependency, so we want to ignore its go_package option + // because that is only relevant for its specific generated output. + pkg := f.GetPackage() + if pkg == "" { + pkg = baseName(*f.Name) + } + RegisterUniquePackageName(pkg, f) + } +} + +// WrapTypes walks the incoming data, wrapping DescriptorProtos, EnumDescriptorProtos +// and FileDescriptorProtos into file-referenced objects within the Generator. +// It also creates the list of files to generate and so should be called before GenerateAllFiles. +func (g *Generator) WrapTypes() { + g.allFiles = make([]*FileDescriptor, len(g.Request.ProtoFile)) + g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles)) + for i, f := range g.Request.ProtoFile { + // We must wrap the descriptors before we wrap the enums + descs := wrapDescriptors(f) + g.buildNestedDescriptors(descs) + enums := wrapEnumDescriptors(f, descs) + g.buildNestedEnums(descs, enums) + exts := wrapExtensions(f) + fd := &FileDescriptor{ + FileDescriptorProto: f, + desc: descs, + enum: enums, + ext: exts, + exported: make(map[Object][]symbol), + proto3: fileIsProto3(f), + } + extractComments(fd) + g.allFiles[i] = fd + g.allFilesByName[f.GetName()] = fd + } + for _, fd := range g.allFiles { + fd.imp = wrapImported(fd.FileDescriptorProto, g) + } + + g.genFiles = make([]*FileDescriptor, len(g.Request.FileToGenerate)) + for i, fileName := range g.Request.FileToGenerate { + g.genFiles[i] = g.allFilesByName[fileName] + if g.genFiles[i] == nil { + g.Fail("could not find file named", fileName) + } + g.genFiles[i].index = i + } + g.Response.File = make([]*plugin.CodeGeneratorResponse_File, len(g.genFiles)) +} + +// Scan the descriptors in this file. For each one, build the slice of nested descriptors +func (g *Generator) buildNestedDescriptors(descs []*Descriptor) { + for _, desc := range descs { + if len(desc.NestedType) != 0 { + for _, nest := range descs { + if nest.parent == desc { + desc.nested = append(desc.nested, nest) + } + } + if len(desc.nested) != len(desc.NestedType) { + g.Fail("internal error: nesting failure for", desc.GetName()) + } + } + } +} + +func (g *Generator) buildNestedEnums(descs []*Descriptor, enums []*EnumDescriptor) { + for _, desc := range descs { + if len(desc.EnumType) != 0 { + for _, enum := range enums { + if enum.parent == desc { + desc.enums = append(desc.enums, enum) + } + } + if len(desc.enums) != len(desc.EnumType) { + g.Fail("internal error: enum nesting failure for", desc.GetName()) + } + } + } +} + +// Construct the Descriptor +func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) *Descriptor { + d := &Descriptor{ + common: common{file}, + DescriptorProto: desc, + parent: parent, + index: index, + } + if parent == nil { + d.path = fmt.Sprintf("%d,%d", messagePath, index) + } else { + d.path = fmt.Sprintf("%s,%d,%d", parent.path, messageMessagePath, index) + } + + // The only way to distinguish a group from a message is whether + // the containing message has a TYPE_GROUP field that matches. + if parent != nil { + parts := d.TypeName() + if file.Package != nil { + parts = append([]string{*file.Package}, parts...) + } + exp := "." + strings.Join(parts, ".") + for _, field := range parent.Field { + if field.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP && field.GetTypeName() == exp { + d.group = true + break + } + } + } + + d.ext = make([]*ExtensionDescriptor, len(desc.Extension)) + for i, field := range desc.Extension { + d.ext[i] = &ExtensionDescriptor{common{file}, field, d} + } + + return d +} + +// Return a slice of all the Descriptors defined within this file +func wrapDescriptors(file *descriptor.FileDescriptorProto) []*Descriptor { + sl := make([]*Descriptor, 0, len(file.MessageType)+10) + for i, desc := range file.MessageType { + sl = wrapThisDescriptor(sl, desc, nil, file, i) + } + return sl +} + +// Wrap this Descriptor, recursively +func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) []*Descriptor { + sl = append(sl, newDescriptor(desc, parent, file, index)) + me := sl[len(sl)-1] + for i, nested := range desc.NestedType { + sl = wrapThisDescriptor(sl, nested, me, file, i) + } + return sl +} + +// Construct the EnumDescriptor +func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *descriptor.FileDescriptorProto, index int) *EnumDescriptor { + ed := &EnumDescriptor{ + common: common{file}, + EnumDescriptorProto: desc, + parent: parent, + index: index, + } + if parent == nil { + ed.path = fmt.Sprintf("%d,%d", enumPath, index) + } else { + ed.path = fmt.Sprintf("%s,%d,%d", parent.path, messageEnumPath, index) + } + return ed +} + +// Return a slice of all the EnumDescriptors defined within this file +func wrapEnumDescriptors(file *descriptor.FileDescriptorProto, descs []*Descriptor) []*EnumDescriptor { + sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10) + // Top-level enums. + for i, enum := range file.EnumType { + sl = append(sl, newEnumDescriptor(enum, nil, file, i)) + } + // Enums within messages. Enums within embedded messages appear in the outer-most message. + for _, nested := range descs { + for i, enum := range nested.EnumType { + sl = append(sl, newEnumDescriptor(enum, nested, file, i)) + } + } + return sl +} + +// Return a slice of all the top-level ExtensionDescriptors defined within this file. +func wrapExtensions(file *descriptor.FileDescriptorProto) []*ExtensionDescriptor { + sl := make([]*ExtensionDescriptor, len(file.Extension)) + for i, field := range file.Extension { + sl[i] = &ExtensionDescriptor{common{file}, field, nil} + } + return sl +} + +// Return a slice of all the types that are publicly imported into this file. +func wrapImported(file *descriptor.FileDescriptorProto, g *Generator) (sl []*ImportedDescriptor) { + for _, index := range file.PublicDependency { + df := g.fileByName(file.Dependency[index]) + for _, d := range df.desc { + if d.GetOptions().GetMapEntry() { + continue + } + sl = append(sl, &ImportedDescriptor{common{file}, d}) + } + for _, e := range df.enum { + sl = append(sl, &ImportedDescriptor{common{file}, e}) + } + for _, ext := range df.ext { + sl = append(sl, &ImportedDescriptor{common{file}, ext}) + } + } + return +} + +func extractComments(file *FileDescriptor) { + file.comments = make(map[string]*descriptor.SourceCodeInfo_Location) + for _, loc := range file.GetSourceCodeInfo().GetLocation() { + if loc.LeadingComments == nil { + continue + } + var p []string + for _, n := range loc.Path { + p = append(p, strconv.Itoa(int(n))) + } + file.comments[strings.Join(p, ",")] = loc + } +} + +// BuildTypeNameMap builds the map from fully qualified type names to objects. +// The key names for the map come from the input data, which puts a period at the beginning. +// It should be called after SetPackageNames and before GenerateAllFiles. +func (g *Generator) BuildTypeNameMap() { + g.typeNameToObject = make(map[string]Object) + for _, f := range g.allFiles { + // The names in this loop are defined by the proto world, not us, so the + // package name may be empty. If so, the dotted package name of X will + // be ".X"; otherwise it will be ".pkg.X". + dottedPkg := "." + f.GetPackage() + if dottedPkg != "." { + dottedPkg += "." + } + for _, enum := range f.enum { + name := dottedPkg + dottedSlice(enum.TypeName()) + g.typeNameToObject[name] = enum + } + for _, desc := range f.desc { + name := dottedPkg + dottedSlice(desc.TypeName()) + g.typeNameToObject[name] = desc + } + } +} + +// ObjectNamed, given a fully-qualified input type name as it appears in the input data, +// returns the descriptor for the message or enum with that name. +func (g *Generator) ObjectNamed(typeName string) Object { + o, ok := g.typeNameToObject[typeName] + if !ok { + g.Fail("can't find object with type", typeName) + } + + // If the file of this object isn't a direct dependency of the current file, + // or in the current file, then this object has been publicly imported into + // a dependency of the current file. + // We should return the ImportedDescriptor object for it instead. + direct := *o.File().Name == *g.file.Name + if !direct { + for _, dep := range g.file.Dependency { + if *g.fileByName(dep).Name == *o.File().Name { + direct = true + break + } + } + } + if !direct { + found := false + Loop: + for _, dep := range g.file.Dependency { + df := g.fileByName(*g.fileByName(dep).Name) + for _, td := range df.imp { + if td.o == o { + // Found it! + o = td + found = true + break Loop + } + } + } + if !found { + log.Printf("protoc-gen-go: WARNING: failed finding publicly imported dependency for %v, used in %v", typeName, *g.file.Name) + } + } + + return o +} + +// P prints the arguments to the generated output. It handles strings and int32s, plus +// handling indirections because they may be *string, etc. +func (g *Generator) P(str ...interface{}) { + if !g.writeOutput { + return + } + g.WriteString(g.indent) + for _, v := range str { + switch s := v.(type) { + case string: + g.WriteString(s) + case *string: + g.WriteString(*s) + case bool: + fmt.Fprintf(g, "%t", s) + case *bool: + fmt.Fprintf(g, "%t", *s) + case int: + fmt.Fprintf(g, "%d", s) + case *int32: + fmt.Fprintf(g, "%d", *s) + case *int64: + fmt.Fprintf(g, "%d", *s) + case float64: + fmt.Fprintf(g, "%g", s) + case *float64: + fmt.Fprintf(g, "%g", *s) + default: + g.Fail(fmt.Sprintf("unknown type in printer: %T", v)) + } + } + g.WriteByte('\n') +} + +// addInitf stores the given statement to be printed inside the file's init function. +// The statement is given as a format specifier and arguments. +func (g *Generator) addInitf(stmt string, a ...interface{}) { + g.init = append(g.init, fmt.Sprintf(stmt, a...)) +} + +// In Indents the output one tab stop. +func (g *Generator) In() { g.indent += "\t" } + +// Out unindents the output one tab stop. +func (g *Generator) Out() { + if len(g.indent) > 0 { + g.indent = g.indent[1:] + } +} + +// GenerateAllFiles generates the output for all the files we're outputting. +func (g *Generator) GenerateAllFiles() { + // Initialize the plugins + for _, p := range plugins { + p.Init(g) + } + // Generate the output. The generator runs for every file, even the files + // that we don't generate output for, so that we can collate the full list + // of exported symbols to support public imports. + genFileMap := make(map[*FileDescriptor]bool, len(g.genFiles)) + for _, file := range g.genFiles { + genFileMap[file] = true + } + i := 0 + for _, file := range g.allFiles { + g.Reset() + g.writeOutput = genFileMap[file] + g.generate(file) + if !g.writeOutput { + continue + } + g.Response.File[i] = new(plugin.CodeGeneratorResponse_File) + g.Response.File[i].Name = proto.String(goFileName(*file.Name)) + g.Response.File[i].Content = proto.String(g.String()) + i++ + } +} + +// Run all the plugins associated with the file. +func (g *Generator) runPlugins(file *FileDescriptor) { + for _, p := range plugins { + p.Generate(file) + } +} + +// FileOf return the FileDescriptor for this FileDescriptorProto. +func (g *Generator) FileOf(fd *descriptor.FileDescriptorProto) *FileDescriptor { + for _, file := range g.allFiles { + if file.FileDescriptorProto == fd { + return file + } + } + g.Fail("could not find file in table:", fd.GetName()) + return nil +} + +// Fill the response protocol buffer with the generated output for all the files we're +// supposed to generate. +func (g *Generator) generate(file *FileDescriptor) { + g.file = g.FileOf(file.FileDescriptorProto) + g.usedPackages = make(map[string]bool) + + if g.file.index == 0 { + // For one file in the package, assert version compatibility. + g.P("// This is a compile-time assertion to ensure that this generated file") + g.P("// is compatible with the proto package it is being compiled against.") + g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion) + g.P() + } + + for _, td := range g.file.imp { + g.generateImported(td) + } + for _, enum := range g.file.enum { + g.generateEnum(enum) + } + for _, desc := range g.file.desc { + // Don't generate virtual messages for maps. + if desc.GetOptions().GetMapEntry() { + continue + } + g.generateMessage(desc) + } + for _, ext := range g.file.ext { + g.generateExtension(ext) + } + g.generateInitFunction() + + // Run the plugins before the imports so we know which imports are necessary. + g.runPlugins(file) + + g.generateFileDescriptor(file) + + // Generate header and imports last, though they appear first in the output. + rem := g.Buffer + g.Buffer = new(bytes.Buffer) + g.generateHeader() + g.generateImports() + if !g.writeOutput { + return + } + g.Write(rem.Bytes()) + + // Reformat generated code. + fset := token.NewFileSet() + raw := g.Bytes() + ast, err := parser.ParseFile(fset, "", g, parser.ParseComments) + if err != nil { + // Print out the bad code with line numbers. + // This should never happen in practice, but it can while changing generated code, + // so consider this a debugging aid. + var src bytes.Buffer + s := bufio.NewScanner(bytes.NewReader(raw)) + for line := 1; s.Scan(); line++ { + fmt.Fprintf(&src, "%5d\t%s\n", line, s.Bytes()) + } + g.Fail("bad Go source code was generated:", err.Error(), "\n"+src.String()) + } + g.Reset() + err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(g, fset, ast) + if err != nil { + g.Fail("generated Go source code could not be reformatted:", err.Error()) + } +} + +// Generate the header, including package definition +func (g *Generator) generateHeader() { + g.P("// Code generated by protoc-gen-go.") + g.P("// source: ", g.file.Name) + g.P("// DO NOT EDIT!") + g.P() + + name := g.file.PackageName() + + if g.file.index == 0 { + // Generate package docs for the first file in the package. + g.P("/*") + g.P("Package ", name, " is a generated protocol buffer package.") + g.P() + if loc, ok := g.file.comments[strconv.Itoa(packagePath)]; ok { + // not using g.PrintComments because this is a /* */ comment block. + text := strings.TrimSuffix(loc.GetLeadingComments(), "\n") + for _, line := range strings.Split(text, "\n") { + line = strings.TrimPrefix(line, " ") + // ensure we don't escape from the block comment + line = strings.Replace(line, "*/", "* /", -1) + g.P(line) + } + g.P() + } + var topMsgs []string + g.P("It is generated from these files:") + for _, f := range g.genFiles { + g.P("\t", f.Name) + for _, msg := range f.desc { + if msg.parent != nil { + continue + } + topMsgs = append(topMsgs, CamelCaseSlice(msg.TypeName())) + } + } + g.P() + g.P("It has these top-level messages:") + for _, msg := range topMsgs { + g.P("\t", msg) + } + g.P("*/") + } + + g.P("package ", name) + g.P() +} + +// PrintComments prints any comments from the source .proto file. +// The path is a comma-separated list of integers. +// It returns an indication of whether any comments were printed. +// See descriptor.proto for its format. +func (g *Generator) PrintComments(path string) bool { + if !g.writeOutput { + return false + } + if loc, ok := g.file.comments[path]; ok { + text := strings.TrimSuffix(loc.GetLeadingComments(), "\n") + for _, line := range strings.Split(text, "\n") { + g.P("// ", strings.TrimPrefix(line, " ")) + } + return true + } + return false +} + +func (g *Generator) fileByName(filename string) *FileDescriptor { + return g.allFilesByName[filename] +} + +// weak returns whether the ith import of the current file is a weak import. +func (g *Generator) weak(i int32) bool { + for _, j := range g.file.WeakDependency { + if j == i { + return true + } + } + return false +} + +// Generate the imports +func (g *Generator) generateImports() { + // We almost always need a proto import. Rather than computing when we + // do, which is tricky when there's a plugin, just import it and + // reference it later. The same argument applies to the fmt and math packages. + g.P("import " + g.Pkg["proto"] + " " + strconv.Quote(g.ImportPrefix+"github.com/golang/protobuf/proto")) + g.P("import " + g.Pkg["fmt"] + ` "fmt"`) + g.P("import " + g.Pkg["math"] + ` "math"`) + for i, s := range g.file.Dependency { + fd := g.fileByName(s) + // Do not import our own package. + if fd.PackageName() == g.packageName { + continue + } + filename := goFileName(s) + // By default, import path is the dirname of the Go filename. + importPath := path.Dir(filename) + if substitution, ok := g.ImportMap[s]; ok { + importPath = substitution + } + importPath = g.ImportPrefix + importPath + // Skip weak imports. + if g.weak(int32(i)) { + g.P("// skipping weak import ", fd.PackageName(), " ", strconv.Quote(importPath)) + continue + } + // We need to import all the dependencies, even if we don't reference them, + // because other code and tools depend on having the full transitive closure + // of protocol buffer types in the binary. + pname := fd.PackageName() + if _, ok := g.usedPackages[pname]; !ok { + pname = "_" + } + g.P("import ", pname, " ", strconv.Quote(importPath)) + } + g.P() + // TODO: may need to worry about uniqueness across plugins + for _, p := range plugins { + p.GenerateImports(g.file) + g.P() + } + g.P("// Reference imports to suppress errors if they are not otherwise used.") + g.P("var _ = ", g.Pkg["proto"], ".Marshal") + g.P("var _ = ", g.Pkg["fmt"], ".Errorf") + g.P("var _ = ", g.Pkg["math"], ".Inf") + g.P() +} + +func (g *Generator) generateImported(id *ImportedDescriptor) { + // Don't generate public import symbols for files that we are generating + // code for, since those symbols will already be in this package. + // We can't simply avoid creating the ImportedDescriptor objects, + // because g.genFiles isn't populated at that stage. + tn := id.TypeName() + sn := tn[len(tn)-1] + df := g.FileOf(id.o.File()) + filename := *df.Name + for _, fd := range g.genFiles { + if *fd.Name == filename { + g.P("// Ignoring public import of ", sn, " from ", filename) + g.P() + return + } + } + g.P("// ", sn, " from public import ", filename) + g.usedPackages[df.PackageName()] = true + + for _, sym := range df.exported[id.o] { + sym.GenerateAlias(g, df.PackageName()) + } + + g.P() +} + +// Generate the enum definitions for this EnumDescriptor. +func (g *Generator) generateEnum(enum *EnumDescriptor) { + // The full type name + typeName := enum.TypeName() + // The full type name, CamelCased. + ccTypeName := CamelCaseSlice(typeName) + ccPrefix := enum.prefix() + + g.PrintComments(enum.path) + g.P("type ", ccTypeName, " int32") + g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()}) + g.P("const (") + g.In() + for i, e := range enum.Value { + g.PrintComments(fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i)) + + name := ccPrefix + *e.Name + g.P(name, " ", ccTypeName, " = ", e.Number) + g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName}) + } + g.Out() + g.P(")") + g.P("var ", ccTypeName, "_name = map[int32]string{") + g.In() + generated := make(map[int32]bool) // avoid duplicate values + for _, e := range enum.Value { + duplicate := "" + if _, present := generated[*e.Number]; present { + duplicate = "// Duplicate value: " + } + g.P(duplicate, e.Number, ": ", strconv.Quote(*e.Name), ",") + generated[*e.Number] = true + } + g.Out() + g.P("}") + g.P("var ", ccTypeName, "_value = map[string]int32{") + g.In() + for _, e := range enum.Value { + g.P(strconv.Quote(*e.Name), ": ", e.Number, ",") + } + g.Out() + g.P("}") + + if !enum.proto3() { + g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {") + g.In() + g.P("p := new(", ccTypeName, ")") + g.P("*p = x") + g.P("return p") + g.Out() + g.P("}") + } + + g.P("func (x ", ccTypeName, ") String() string {") + g.In() + g.P("return ", g.Pkg["proto"], ".EnumName(", ccTypeName, "_name, int32(x))") + g.Out() + g.P("}") + + if !enum.proto3() { + g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {") + g.In() + g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`) + g.P("if err != nil {") + g.In() + g.P("return err") + g.Out() + g.P("}") + g.P("*x = ", ccTypeName, "(value)") + g.P("return nil") + g.Out() + g.P("}") + } + + var indexes []string + for m := enum.parent; m != nil; m = m.parent { + // XXX: skip groups? + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + indexes = append(indexes, strconv.Itoa(enum.index)) + g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) { return fileDescriptor", g.file.index, ", []int{", strings.Join(indexes, ", "), "} }") + + g.P() +} + +// The tag is a string like "varint,2,opt,name=fieldname,def=7" that +// identifies details of the field for the protocol buffer marshaling and unmarshaling +// code. The fields are: +// wire encoding +// protocol tag number +// opt,req,rep for optional, required, or repeated +// packed whether the encoding is "packed" (optional; repeated primitives only) +// name= the original declared name +// enum= the name of the enum type if it is an enum-typed field. +// proto3 if this field is in a proto3 message +// def= string representation of the default value, if any. +// The default value must be in a representation that can be used at run-time +// to generate the default value. Thus bools become 0 and 1, for instance. +func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string { + optrepreq := "" + switch { + case isOptional(field): + optrepreq = "opt" + case isRequired(field): + optrepreq = "req" + case isRepeated(field): + optrepreq = "rep" + } + var defaultValue string + if dv := field.DefaultValue; dv != nil { // set means an explicit default + defaultValue = *dv + // Some types need tweaking. + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BOOL: + if defaultValue == "true" { + defaultValue = "1" + } else { + defaultValue = "0" + } + case descriptor.FieldDescriptorProto_TYPE_STRING, + descriptor.FieldDescriptorProto_TYPE_BYTES: + // Nothing to do. Quoting is done for the whole tag. + case descriptor.FieldDescriptorProto_TYPE_ENUM: + // For enums we need to provide the integer constant. + obj := g.ObjectNamed(field.GetTypeName()) + if id, ok := obj.(*ImportedDescriptor); ok { + // It is an enum that was publicly imported. + // We need the underlying type. + obj = id.o + } + enum, ok := obj.(*EnumDescriptor) + if !ok { + log.Printf("obj is a %T", obj) + if id, ok := obj.(*ImportedDescriptor); ok { + log.Printf("id.o is a %T", id.o) + } + g.Fail("unknown enum type", CamelCaseSlice(obj.TypeName())) + } + defaultValue = enum.integerValueAsString(defaultValue) + } + defaultValue = ",def=" + defaultValue + } + enum := "" + if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM { + // We avoid using obj.PackageName(), because we want to use the + // original (proto-world) package name. + obj := g.ObjectNamed(field.GetTypeName()) + if id, ok := obj.(*ImportedDescriptor); ok { + obj = id.o + } + enum = ",enum=" + if pkg := obj.File().GetPackage(); pkg != "" { + enum += pkg + "." + } + enum += CamelCaseSlice(obj.TypeName()) + } + packed := "" + if field.Options != nil && field.Options.GetPacked() { + packed = ",packed" + } + fieldName := field.GetName() + name := fieldName + if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP { + // We must use the type name for groups instead of + // the field name to preserve capitalization. + // type_name in FieldDescriptorProto is fully-qualified, + // but we only want the local part. + name = *field.TypeName + if i := strings.LastIndex(name, "."); i >= 0 { + name = name[i+1:] + } + } + name = ",name=" + name + if message.proto3() { + // We only need the extra tag for []byte fields; + // no need to add noise for the others. + if *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES { + name += ",proto3" + } + + } + oneof := "" + if field.OneofIndex != nil { + oneof = ",oneof" + } + return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s", + wiretype, + field.GetNumber(), + optrepreq, + packed, + name, + enum, + oneof, + defaultValue)) +} + +func needsStar(typ descriptor.FieldDescriptorProto_Type) bool { + switch typ { + case descriptor.FieldDescriptorProto_TYPE_GROUP: + return false + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + return false + case descriptor.FieldDescriptorProto_TYPE_BYTES: + return false + } + return true +} + +// TypeName is the printed name appropriate for an item. If the object is in the current file, +// TypeName drops the package name and underscores the rest. +// Otherwise the object is from another package; and the result is the underscored +// package name followed by the item name. +// The result always has an initial capital. +func (g *Generator) TypeName(obj Object) string { + return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName()) +} + +// TypeNameWithPackage is like TypeName, but always includes the package +// name even if the object is in our own package. +func (g *Generator) TypeNameWithPackage(obj Object) string { + return obj.PackageName() + CamelCaseSlice(obj.TypeName()) +} + +// GoType returns a string representing the type name, and the wire type +func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) { + // TODO: Options. + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + typ, wire = "float64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + typ, wire = "float32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_INT64: + typ, wire = "int64", "varint" + case descriptor.FieldDescriptorProto_TYPE_UINT64: + typ, wire = "uint64", "varint" + case descriptor.FieldDescriptorProto_TYPE_INT32: + typ, wire = "int32", "varint" + case descriptor.FieldDescriptorProto_TYPE_UINT32: + typ, wire = "uint32", "varint" + case descriptor.FieldDescriptorProto_TYPE_FIXED64: + typ, wire = "uint64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_FIXED32: + typ, wire = "uint32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_BOOL: + typ, wire = "bool", "varint" + case descriptor.FieldDescriptorProto_TYPE_STRING: + typ, wire = "string", "bytes" + case descriptor.FieldDescriptorProto_TYPE_GROUP: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = "*"+g.TypeName(desc), "group" + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = "*"+g.TypeName(desc), "bytes" + case descriptor.FieldDescriptorProto_TYPE_BYTES: + typ, wire = "[]byte", "bytes" + case descriptor.FieldDescriptorProto_TYPE_ENUM: + desc := g.ObjectNamed(field.GetTypeName()) + typ, wire = g.TypeName(desc), "varint" + case descriptor.FieldDescriptorProto_TYPE_SFIXED32: + typ, wire = "int32", "fixed32" + case descriptor.FieldDescriptorProto_TYPE_SFIXED64: + typ, wire = "int64", "fixed64" + case descriptor.FieldDescriptorProto_TYPE_SINT32: + typ, wire = "int32", "zigzag32" + case descriptor.FieldDescriptorProto_TYPE_SINT64: + typ, wire = "int64", "zigzag64" + default: + g.Fail("unknown type for", field.GetName()) + } + if isRepeated(field) { + typ = "[]" + typ + } else if message != nil && message.proto3() { + return + } else if field.OneofIndex != nil && message != nil { + return + } else if needsStar(*field.Type) { + typ = "*" + typ + } + return +} + +func (g *Generator) RecordTypeUse(t string) { + if obj, ok := g.typeNameToObject[t]; ok { + // Call ObjectNamed to get the true object to record the use. + obj = g.ObjectNamed(t) + g.usedPackages[obj.PackageName()] = true + } +} + +// Method names that may be generated. Fields with these names get an +// underscore appended. +var methodNames = [...]string{ + "Reset", + "String", + "ProtoMessage", + "Marshal", + "Unmarshal", + "ExtensionRangeArray", + "ExtensionMap", + "Descriptor", +} + +// Generate the type and default constant definitions for this Descriptor. +func (g *Generator) generateMessage(message *Descriptor) { + // The full type name + typeName := message.TypeName() + // The full type name, CamelCased. + ccTypeName := CamelCaseSlice(typeName) + + usedNames := make(map[string]bool) + for _, n := range methodNames { + usedNames[n] = true + } + fieldNames := make(map[*descriptor.FieldDescriptorProto]string) + fieldGetterNames := make(map[*descriptor.FieldDescriptorProto]string) + fieldTypes := make(map[*descriptor.FieldDescriptorProto]string) + mapFieldTypes := make(map[*descriptor.FieldDescriptorProto]string) + + oneofFieldName := make(map[int32]string) // indexed by oneof_index field of FieldDescriptorProto + oneofDisc := make(map[int32]string) // name of discriminator method + oneofTypeName := make(map[*descriptor.FieldDescriptorProto]string) // without star + oneofInsertPoints := make(map[int32]int) // oneof_index => offset of g.Buffer + + g.PrintComments(message.path) + g.P("type ", ccTypeName, " struct {") + g.In() + + // allocNames finds a conflict-free variation of the given strings, + // consistently mutating their suffixes. + // It returns the same number of strings. + allocNames := func(ns ...string) []string { + Loop: + for { + for _, n := range ns { + if usedNames[n] { + for i := range ns { + ns[i] += "_" + } + continue Loop + } + } + for _, n := range ns { + usedNames[n] = true + } + return ns + } + } + + for i, field := range message.Field { + // Allocate the getter and the field at the same time so name + // collisions create field/method consistent names. + // TODO: This allocation occurs based on the order of the fields + // in the proto file, meaning that a change in the field + // ordering can change generated Method/Field names. + base := CamelCase(*field.Name) + ns := allocNames(base, "Get"+base) + fieldName, fieldGetterName := ns[0], ns[1] + typename, wiretype := g.GoType(message, field) + jsonName := *field.Name + tag := fmt.Sprintf("protobuf:%s json:%q", g.goTag(message, field, wiretype), jsonName+",omitempty") + + fieldNames[field] = fieldName + fieldGetterNames[field] = fieldGetterName + + oneof := field.OneofIndex != nil + if oneof && oneofFieldName[*field.OneofIndex] == "" { + odp := message.OneofDecl[int(*field.OneofIndex)] + fname := allocNames(CamelCase(odp.GetName()))[0] + + // This is the first field of a oneof we haven't seen before. + // Generate the union field. + com := g.PrintComments(fmt.Sprintf("%s,%d,%d", message.path, messageOneofPath, *field.OneofIndex)) + if com { + g.P("//") + } + g.P("// Types that are valid to be assigned to ", fname, ":") + // Generate the rest of this comment later, + // when we've computed any disambiguation. + oneofInsertPoints[*field.OneofIndex] = g.Buffer.Len() + + dname := "is" + ccTypeName + "_" + fname + oneofFieldName[*field.OneofIndex] = fname + oneofDisc[*field.OneofIndex] = dname + tag := `protobuf_oneof:"` + odp.GetName() + `"` + g.P(fname, " ", dname, " `", tag, "`") + } + + if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE { + desc := g.ObjectNamed(field.GetTypeName()) + if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() { + // Figure out the Go types and tags for the key and value types. + keyField, valField := d.Field[0], d.Field[1] + keyType, keyWire := g.GoType(d, keyField) + valType, valWire := g.GoType(d, valField) + keyTag, valTag := g.goTag(d, keyField, keyWire), g.goTag(d, valField, valWire) + + // We don't use stars, except for message-typed values. + // Message and enum types are the only two possibly foreign types used in maps, + // so record their use. They are not permitted as map keys. + keyType = strings.TrimPrefix(keyType, "*") + switch *valField.Type { + case descriptor.FieldDescriptorProto_TYPE_ENUM: + valType = strings.TrimPrefix(valType, "*") + g.RecordTypeUse(valField.GetTypeName()) + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + g.RecordTypeUse(valField.GetTypeName()) + default: + valType = strings.TrimPrefix(valType, "*") + } + + typename = fmt.Sprintf("map[%s]%s", keyType, valType) + mapFieldTypes[field] = typename // record for the getter generation + + tag += fmt.Sprintf(" protobuf_key:%s protobuf_val:%s", keyTag, valTag) + } + } + + fieldTypes[field] = typename + + if oneof { + tname := ccTypeName + "_" + fieldName + // It is possible for this to collide with a message or enum + // nested in this message. Check for collisions. + for { + ok := true + for _, desc := range message.nested { + if CamelCaseSlice(desc.TypeName()) == tname { + ok = false + break + } + } + for _, enum := range message.enums { + if CamelCaseSlice(enum.TypeName()) == tname { + ok = false + break + } + } + if !ok { + tname += "_" + continue + } + break + } + + oneofTypeName[field] = tname + continue + } + + g.PrintComments(fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i)) + g.P(fieldName, "\t", typename, "\t`", tag, "`") + g.RecordTypeUse(field.GetTypeName()) + } + if len(message.ExtensionRange) > 0 { + g.P("XXX_extensions\t\tmap[int32]", g.Pkg["proto"], ".Extension `json:\"-\"`") + } + if !message.proto3() { + g.P("XXX_unrecognized\t[]byte `json:\"-\"`") + } + g.Out() + g.P("}") + + // Update g.Buffer to list valid oneof types. + // We do this down here, after we've disambiguated the oneof type names. + // We go in reverse order of insertion point to avoid invalidating offsets. + for oi := int32(len(message.OneofDecl)); oi >= 0; oi-- { + ip := oneofInsertPoints[oi] + all := g.Buffer.Bytes() + rem := all[ip:] + g.Buffer = bytes.NewBuffer(all[:ip:ip]) // set cap so we don't scribble on rem + for _, field := range message.Field { + if field.OneofIndex == nil || *field.OneofIndex != oi { + continue + } + g.P("//\t*", oneofTypeName[field]) + } + g.Buffer.Write(rem) + } + + // Reset, String and ProtoMessage methods. + g.P("func (m *", ccTypeName, ") Reset() { *m = ", ccTypeName, "{} }") + g.P("func (m *", ccTypeName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }") + g.P("func (*", ccTypeName, ") ProtoMessage() {}") + if !message.group { + var indexes []string + for m := message; m != nil; m = m.parent { + // XXX: skip groups? + indexes = append([]string{strconv.Itoa(m.index)}, indexes...) + } + g.P("func (*", ccTypeName, ") Descriptor() ([]byte, []int) { return fileDescriptor", g.file.index, ", []int{", strings.Join(indexes, ", "), "} }") + } + + // Extension support methods + var hasExtensions, isMessageSet bool + if len(message.ExtensionRange) > 0 { + hasExtensions = true + // message_set_wire_format only makes sense when extensions are defined. + if opts := message.Options; opts != nil && opts.GetMessageSetWireFormat() { + isMessageSet = true + g.P() + g.P("func (m *", ccTypeName, ") Marshal() ([]byte, error) {") + g.In() + g.P("return ", g.Pkg["proto"], ".MarshalMessageSet(m.ExtensionMap())") + g.Out() + g.P("}") + g.P("func (m *", ccTypeName, ") Unmarshal(buf []byte) error {") + g.In() + g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSet(buf, m.ExtensionMap())") + g.Out() + g.P("}") + g.P("func (m *", ccTypeName, ") MarshalJSON() ([]byte, error) {") + g.In() + g.P("return ", g.Pkg["proto"], ".MarshalMessageSetJSON(m.XXX_extensions)") + g.Out() + g.P("}") + g.P("func (m *", ccTypeName, ") UnmarshalJSON(buf []byte) error {") + g.In() + g.P("return ", g.Pkg["proto"], ".UnmarshalMessageSetJSON(buf, m.XXX_extensions)") + g.Out() + g.P("}") + g.P("// ensure ", ccTypeName, " satisfies proto.Marshaler and proto.Unmarshaler") + g.P("var _ ", g.Pkg["proto"], ".Marshaler = (*", ccTypeName, ")(nil)") + g.P("var _ ", g.Pkg["proto"], ".Unmarshaler = (*", ccTypeName, ")(nil)") + } + + g.P() + g.P("var extRange_", ccTypeName, " = []", g.Pkg["proto"], ".ExtensionRange{") + g.In() + for _, r := range message.ExtensionRange { + end := fmt.Sprint(*r.End - 1) // make range inclusive on both ends + g.P("{", r.Start, ", ", end, "},") + } + g.Out() + g.P("}") + g.P("func (*", ccTypeName, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange {") + g.In() + g.P("return extRange_", ccTypeName) + g.Out() + g.P("}") + g.P("func (m *", ccTypeName, ") ExtensionMap() map[int32]", g.Pkg["proto"], ".Extension {") + g.In() + g.P("if m.XXX_extensions == nil {") + g.In() + g.P("m.XXX_extensions = make(map[int32]", g.Pkg["proto"], ".Extension)") + g.Out() + g.P("}") + g.P("return m.XXX_extensions") + g.Out() + g.P("}") + } + + // Default constants + defNames := make(map[*descriptor.FieldDescriptorProto]string) + for _, field := range message.Field { + def := field.GetDefaultValue() + if def == "" { + continue + } + fieldname := "Default_" + ccTypeName + "_" + CamelCase(*field.Name) + defNames[field] = fieldname + typename, _ := g.GoType(message, field) + if typename[0] == '*' { + typename = typename[1:] + } + kind := "const " + switch { + case typename == "bool": + case typename == "string": + def = strconv.Quote(def) + case typename == "[]byte": + def = "[]byte(" + strconv.Quote(def) + ")" + kind = "var " + case def == "inf", def == "-inf", def == "nan": + // These names are known to, and defined by, the protocol language. + switch def { + case "inf": + def = "math.Inf(1)" + case "-inf": + def = "math.Inf(-1)" + case "nan": + def = "math.NaN()" + } + if *field.Type == descriptor.FieldDescriptorProto_TYPE_FLOAT { + def = "float32(" + def + ")" + } + kind = "var " + case *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM: + // Must be an enum. Need to construct the prefixed name. + obj := g.ObjectNamed(field.GetTypeName()) + var enum *EnumDescriptor + if id, ok := obj.(*ImportedDescriptor); ok { + // The enum type has been publicly imported. + enum, _ = id.o.(*EnumDescriptor) + } else { + enum, _ = obj.(*EnumDescriptor) + } + if enum == nil { + log.Printf("don't know how to generate constant for %s", fieldname) + continue + } + def = g.DefaultPackageName(obj) + enum.prefix() + def + } + g.P(kind, fieldname, " ", typename, " = ", def) + g.file.addExport(message, constOrVarSymbol{fieldname, kind, ""}) + } + g.P() + + // Oneof per-field types, discriminants and getters. + // + // Generate unexported named types for the discriminant interfaces. + // We shouldn't have to do this, but there was (~19 Aug 2015) a compiler/linker bug + // that was triggered by using anonymous interfaces here. + // TODO: Revisit this and consider reverting back to anonymous interfaces. + for oi := range message.OneofDecl { + dname := oneofDisc[int32(oi)] + g.P("type ", dname, " interface { ", dname, "() }") + } + g.P() + for _, field := range message.Field { + if field.OneofIndex == nil { + continue + } + _, wiretype := g.GoType(message, field) + tag := "protobuf:" + g.goTag(message, field, wiretype) + g.P("type ", oneofTypeName[field], " struct{ ", fieldNames[field], " ", fieldTypes[field], " `", tag, "` }") + g.RecordTypeUse(field.GetTypeName()) + } + g.P() + for _, field := range message.Field { + if field.OneofIndex == nil { + continue + } + g.P("func (*", oneofTypeName[field], ") ", oneofDisc[*field.OneofIndex], "() {}") + } + g.P() + for oi := range message.OneofDecl { + fname := oneofFieldName[int32(oi)] + g.P("func (m *", ccTypeName, ") Get", fname, "() ", oneofDisc[int32(oi)], " {") + g.P("if m != nil { return m.", fname, " }") + g.P("return nil") + g.P("}") + } + g.P() + + // Field getters + var getters []getterSymbol + for _, field := range message.Field { + oneof := field.OneofIndex != nil + + fname := fieldNames[field] + typename, _ := g.GoType(message, field) + if t, ok := mapFieldTypes[field]; ok { + typename = t + } + mname := fieldGetterNames[field] + star := "" + if needsStar(*field.Type) && typename[0] == '*' { + typename = typename[1:] + star = "*" + } + + // In proto3, only generate getters for message fields and oneof fields. + if message.proto3() && *field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE && !oneof { + continue + } + + // Only export getter symbols for basic types, + // and for messages and enums in the same package. + // Groups are not exported. + // Foreign types can't be hoisted through a public import because + // the importer may not already be importing the defining .proto. + // As an example, imagine we have an import tree like this: + // A.proto -> B.proto -> C.proto + // If A publicly imports B, we need to generate the getters from B in A's output, + // but if one such getter returns something from C then we cannot do that + // because A is not importing C already. + var getter, genType bool + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_GROUP: + getter = false + case descriptor.FieldDescriptorProto_TYPE_MESSAGE, descriptor.FieldDescriptorProto_TYPE_ENUM: + // Only export getter if its return type is in this package. + getter = g.ObjectNamed(field.GetTypeName()).PackageName() == message.PackageName() + genType = true + default: + getter = true + } + if getter { + getters = append(getters, getterSymbol{ + name: mname, + typ: typename, + typeName: field.GetTypeName(), + genType: genType, + }) + } + + g.P("func (m *", ccTypeName, ") "+mname+"() "+typename+" {") + g.In() + def, hasDef := defNames[field] + typeDefaultIsNil := false // whether this field type's default value is a literal nil unless specified + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BYTES: + typeDefaultIsNil = !hasDef + case descriptor.FieldDescriptorProto_TYPE_GROUP, descriptor.FieldDescriptorProto_TYPE_MESSAGE: + typeDefaultIsNil = true + } + if isRepeated(field) { + typeDefaultIsNil = true + } + if typeDefaultIsNil && !oneof { + // A bytes field with no explicit default needs less generated code, + // as does a message or group field, or a repeated field. + g.P("if m != nil {") + g.In() + g.P("return m." + fname) + g.Out() + g.P("}") + g.P("return nil") + g.Out() + g.P("}") + g.P() + continue + } + if !oneof { + g.P("if m != nil && m." + fname + " != nil {") + g.In() + g.P("return " + star + "m." + fname) + g.Out() + g.P("}") + } else { + uname := oneofFieldName[*field.OneofIndex] + tname := oneofTypeName[field] + g.P("if x, ok := m.Get", uname, "().(*", tname, "); ok {") + g.P("return x.", fname) + g.P("}") + } + if hasDef { + if *field.Type != descriptor.FieldDescriptorProto_TYPE_BYTES { + g.P("return " + def) + } else { + // The default is a []byte var. + // Make a copy when returning it to be safe. + g.P("return append([]byte(nil), ", def, "...)") + } + } else { + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BOOL: + g.P("return false") + case descriptor.FieldDescriptorProto_TYPE_STRING: + g.P(`return ""`) + case descriptor.FieldDescriptorProto_TYPE_GROUP, + descriptor.FieldDescriptorProto_TYPE_MESSAGE, + descriptor.FieldDescriptorProto_TYPE_BYTES: + // This is only possible for oneof fields. + g.P("return nil") + case descriptor.FieldDescriptorProto_TYPE_ENUM: + // The default default for an enum is the first value in the enum, + // not zero. + obj := g.ObjectNamed(field.GetTypeName()) + var enum *EnumDescriptor + if id, ok := obj.(*ImportedDescriptor); ok { + // The enum type has been publicly imported. + enum, _ = id.o.(*EnumDescriptor) + } else { + enum, _ = obj.(*EnumDescriptor) + } + if enum == nil { + log.Printf("don't know how to generate getter for %s", field.GetName()) + continue + } + if len(enum.Value) == 0 { + g.P("return 0 // empty enum") + } else { + first := enum.Value[0].GetName() + g.P("return ", g.DefaultPackageName(obj)+enum.prefix()+first) + } + default: + g.P("return 0") + } + } + g.Out() + g.P("}") + g.P() + } + + if !message.group { + ms := &messageSymbol{ + sym: ccTypeName, + hasExtensions: hasExtensions, + isMessageSet: isMessageSet, + hasOneof: len(message.OneofDecl) > 0, + getters: getters, + } + g.file.addExport(message, ms) + } + + // Oneof functions + if len(message.OneofDecl) > 0 { + fieldWire := make(map[*descriptor.FieldDescriptorProto]string) + + // method + enc := "_" + ccTypeName + "_OneofMarshaler" + dec := "_" + ccTypeName + "_OneofUnmarshaler" + size := "_" + ccTypeName + "_OneofSizer" + encSig := "(msg " + g.Pkg["proto"] + ".Message, b *" + g.Pkg["proto"] + ".Buffer) error" + decSig := "(msg " + g.Pkg["proto"] + ".Message, tag, wire int, b *" + g.Pkg["proto"] + ".Buffer) (bool, error)" + sizeSig := "(msg " + g.Pkg["proto"] + ".Message) (n int)" + + g.P("// XXX_OneofFuncs is for the internal use of the proto package.") + g.P("func (*", ccTypeName, ") XXX_OneofFuncs() (func", encSig, ", func", decSig, ", func", sizeSig, ", []interface{}) {") + g.P("return ", enc, ", ", dec, ", ", size, ", []interface{}{") + for _, field := range message.Field { + if field.OneofIndex == nil { + continue + } + g.P("(*", oneofTypeName[field], ")(nil),") + } + g.P("}") + g.P("}") + g.P() + + // marshaler + g.P("func ", enc, encSig, " {") + g.P("m := msg.(*", ccTypeName, ")") + for oi, odp := range message.OneofDecl { + g.P("// ", odp.GetName()) + fname := oneofFieldName[int32(oi)] + g.P("switch x := m.", fname, ".(type) {") + for _, field := range message.Field { + if field.OneofIndex == nil || int(*field.OneofIndex) != oi { + continue + } + g.P("case *", oneofTypeName[field], ":") + var wire, pre, post string + val := "x." + fieldNames[field] // overridden for TYPE_BOOL + canFail := false // only TYPE_MESSAGE and TYPE_GROUP can fail + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + wire = "WireFixed64" + pre = "b.EncodeFixed64(" + g.Pkg["math"] + ".Float64bits(" + post = "))" + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + wire = "WireFixed32" + pre = "b.EncodeFixed32(uint64(" + g.Pkg["math"] + ".Float32bits(" + post = ")))" + case descriptor.FieldDescriptorProto_TYPE_INT64, + descriptor.FieldDescriptorProto_TYPE_UINT64: + wire = "WireVarint" + pre, post = "b.EncodeVarint(uint64(", "))" + case descriptor.FieldDescriptorProto_TYPE_INT32, + descriptor.FieldDescriptorProto_TYPE_UINT32, + descriptor.FieldDescriptorProto_TYPE_ENUM: + wire = "WireVarint" + pre, post = "b.EncodeVarint(uint64(", "))" + case descriptor.FieldDescriptorProto_TYPE_FIXED64, + descriptor.FieldDescriptorProto_TYPE_SFIXED64: + wire = "WireFixed64" + pre, post = "b.EncodeFixed64(uint64(", "))" + case descriptor.FieldDescriptorProto_TYPE_FIXED32, + descriptor.FieldDescriptorProto_TYPE_SFIXED32: + wire = "WireFixed32" + pre, post = "b.EncodeFixed32(uint64(", "))" + case descriptor.FieldDescriptorProto_TYPE_BOOL: + // bool needs special handling. + g.P("t := uint64(0)") + g.P("if ", val, " { t = 1 }") + val = "t" + wire = "WireVarint" + pre, post = "b.EncodeVarint(", ")" + case descriptor.FieldDescriptorProto_TYPE_STRING: + wire = "WireBytes" + pre, post = "b.EncodeStringBytes(", ")" + case descriptor.FieldDescriptorProto_TYPE_GROUP: + wire = "WireStartGroup" + pre, post = "b.Marshal(", ")" + canFail = true + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + wire = "WireBytes" + pre, post = "b.EncodeMessage(", ")" + canFail = true + case descriptor.FieldDescriptorProto_TYPE_BYTES: + wire = "WireBytes" + pre, post = "b.EncodeRawBytes(", ")" + case descriptor.FieldDescriptorProto_TYPE_SINT32: + wire = "WireVarint" + pre, post = "b.EncodeZigzag32(uint64(", "))" + case descriptor.FieldDescriptorProto_TYPE_SINT64: + wire = "WireVarint" + pre, post = "b.EncodeZigzag64(uint64(", "))" + default: + g.Fail("unhandled oneof field type ", field.Type.String()) + } + fieldWire[field] = wire + g.P("b.EncodeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".", wire, ")") + if !canFail { + g.P(pre, val, post) + } else { + g.P("if err := ", pre, val, post, "; err != nil {") + g.P("return err") + g.P("}") + } + if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP { + g.P("b.EncodeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".WireEndGroup)") + } + } + g.P("case nil:") + g.P("default: return ", g.Pkg["fmt"], `.Errorf("`, ccTypeName, ".", fname, ` has unexpected type %T", x)`) + g.P("}") + } + g.P("return nil") + g.P("}") + g.P() + + // unmarshaler + g.P("func ", dec, decSig, " {") + g.P("m := msg.(*", ccTypeName, ")") + g.P("switch tag {") + for _, field := range message.Field { + if field.OneofIndex == nil { + continue + } + odp := message.OneofDecl[int(*field.OneofIndex)] + g.P("case ", field.Number, ": // ", odp.GetName(), ".", *field.Name) + g.P("if wire != ", g.Pkg["proto"], ".", fieldWire[field], " {") + g.P("return true, ", g.Pkg["proto"], ".ErrInternalBadWireType") + g.P("}") + lhs := "x, err" // overridden for TYPE_MESSAGE and TYPE_GROUP + var dec, cast, cast2 string + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + dec, cast = "b.DecodeFixed64()", g.Pkg["math"]+".Float64frombits" + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + dec, cast, cast2 = "b.DecodeFixed32()", "uint32", g.Pkg["math"]+".Float32frombits" + case descriptor.FieldDescriptorProto_TYPE_INT64: + dec, cast = "b.DecodeVarint()", "int64" + case descriptor.FieldDescriptorProto_TYPE_UINT64: + dec = "b.DecodeVarint()" + case descriptor.FieldDescriptorProto_TYPE_INT32: + dec, cast = "b.DecodeVarint()", "int32" + case descriptor.FieldDescriptorProto_TYPE_FIXED64: + dec = "b.DecodeFixed64()" + case descriptor.FieldDescriptorProto_TYPE_FIXED32: + dec, cast = "b.DecodeFixed32()", "uint32" + case descriptor.FieldDescriptorProto_TYPE_BOOL: + dec = "b.DecodeVarint()" + // handled specially below + case descriptor.FieldDescriptorProto_TYPE_STRING: + dec = "b.DecodeStringBytes()" + case descriptor.FieldDescriptorProto_TYPE_GROUP: + g.P("msg := new(", fieldTypes[field][1:], ")") // drop star + lhs = "err" + dec = "b.DecodeGroup(msg)" + // handled specially below + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + g.P("msg := new(", fieldTypes[field][1:], ")") // drop star + lhs = "err" + dec = "b.DecodeMessage(msg)" + // handled specially below + case descriptor.FieldDescriptorProto_TYPE_BYTES: + dec = "b.DecodeRawBytes(true)" + case descriptor.FieldDescriptorProto_TYPE_UINT32: + dec, cast = "b.DecodeVarint()", "uint32" + case descriptor.FieldDescriptorProto_TYPE_ENUM: + dec, cast = "b.DecodeVarint()", fieldTypes[field] + case descriptor.FieldDescriptorProto_TYPE_SFIXED32: + dec, cast = "b.DecodeFixed32()", "int32" + case descriptor.FieldDescriptorProto_TYPE_SFIXED64: + dec, cast = "b.DecodeFixed64()", "int64" + case descriptor.FieldDescriptorProto_TYPE_SINT32: + dec, cast = "b.DecodeZigzag32()", "int32" + case descriptor.FieldDescriptorProto_TYPE_SINT64: + dec, cast = "b.DecodeZigzag64()", "int64" + default: + g.Fail("unhandled oneof field type ", field.Type.String()) + } + g.P(lhs, " := ", dec) + val := "x" + if cast != "" { + val = cast + "(" + val + ")" + } + if cast2 != "" { + val = cast2 + "(" + val + ")" + } + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_BOOL: + val += " != 0" + case descriptor.FieldDescriptorProto_TYPE_GROUP, + descriptor.FieldDescriptorProto_TYPE_MESSAGE: + val = "msg" + } + g.P("m.", oneofFieldName[*field.OneofIndex], " = &", oneofTypeName[field], "{", val, "}") + g.P("return true, err") + } + g.P("default: return false, nil") + g.P("}") + g.P("}") + g.P() + + // sizer + g.P("func ", size, sizeSig, " {") + g.P("m := msg.(*", ccTypeName, ")") + for oi, odp := range message.OneofDecl { + g.P("// ", odp.GetName()) + fname := oneofFieldName[int32(oi)] + g.P("switch x := m.", fname, ".(type) {") + for _, field := range message.Field { + if field.OneofIndex == nil || int(*field.OneofIndex) != oi { + continue + } + g.P("case *", oneofTypeName[field], ":") + val := "x." + fieldNames[field] + var wire, varint, fixed string + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE: + wire = "WireFixed64" + fixed = "8" + case descriptor.FieldDescriptorProto_TYPE_FLOAT: + wire = "WireFixed32" + fixed = "4" + case descriptor.FieldDescriptorProto_TYPE_INT64, + descriptor.FieldDescriptorProto_TYPE_UINT64, + descriptor.FieldDescriptorProto_TYPE_INT32, + descriptor.FieldDescriptorProto_TYPE_UINT32, + descriptor.FieldDescriptorProto_TYPE_ENUM: + wire = "WireVarint" + varint = val + case descriptor.FieldDescriptorProto_TYPE_FIXED64, + descriptor.FieldDescriptorProto_TYPE_SFIXED64: + wire = "WireFixed64" + fixed = "8" + case descriptor.FieldDescriptorProto_TYPE_FIXED32, + descriptor.FieldDescriptorProto_TYPE_SFIXED32: + wire = "WireFixed32" + fixed = "4" + case descriptor.FieldDescriptorProto_TYPE_BOOL: + wire = "WireVarint" + fixed = "1" + case descriptor.FieldDescriptorProto_TYPE_STRING: + wire = "WireBytes" + fixed = "len(" + val + ")" + varint = fixed + case descriptor.FieldDescriptorProto_TYPE_GROUP: + wire = "WireStartGroup" + fixed = g.Pkg["proto"] + ".Size(" + val + ")" + case descriptor.FieldDescriptorProto_TYPE_MESSAGE: + wire = "WireBytes" + g.P("s := ", g.Pkg["proto"], ".Size(", val, ")") + fixed = "s" + varint = fixed + case descriptor.FieldDescriptorProto_TYPE_BYTES: + wire = "WireBytes" + fixed = "len(" + val + ")" + varint = fixed + case descriptor.FieldDescriptorProto_TYPE_SINT32: + wire = "WireVarint" + varint = "(uint32(" + val + ") << 1) ^ uint32((int32(" + val + ") >> 31))" + case descriptor.FieldDescriptorProto_TYPE_SINT64: + wire = "WireVarint" + varint = "uint64(" + val + " << 1) ^ uint64((int64(" + val + ") >> 63))" + default: + g.Fail("unhandled oneof field type ", field.Type.String()) + } + g.P("n += ", g.Pkg["proto"], ".SizeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".", wire, ")") + if varint != "" { + g.P("n += ", g.Pkg["proto"], ".SizeVarint(uint64(", varint, "))") + } + if fixed != "" { + g.P("n += ", fixed) + } + if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP { + g.P("n += ", g.Pkg["proto"], ".SizeVarint(", field.Number, "<<3|", g.Pkg["proto"], ".WireEndGroup)") + } + } + g.P("case nil:") + g.P("default:") + g.P("panic(", g.Pkg["fmt"], ".Sprintf(\"proto: unexpected type %T in oneof\", x))") + g.P("}") + } + g.P("return n") + g.P("}") + g.P() + } + + for _, ext := range message.ext { + g.generateExtension(ext) + } + + fullName := strings.Join(message.TypeName(), ".") + if g.file.Package != nil { + fullName = *g.file.Package + "." + fullName + } + + g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["proto"], ccTypeName, fullName) +} + +func (g *Generator) generateExtension(ext *ExtensionDescriptor) { + ccTypeName := ext.DescName() + + extObj := g.ObjectNamed(*ext.Extendee) + var extDesc *Descriptor + if id, ok := extObj.(*ImportedDescriptor); ok { + // This is extending a publicly imported message. + // We need the underlying type for goTag. + extDesc = id.o.(*Descriptor) + } else { + extDesc = extObj.(*Descriptor) + } + extendedType := "*" + g.TypeName(extObj) // always use the original + field := ext.FieldDescriptorProto + fieldType, wireType := g.GoType(ext.parent, field) + tag := g.goTag(extDesc, field, wireType) + g.RecordTypeUse(*ext.Extendee) + if n := ext.FieldDescriptorProto.TypeName; n != nil { + // foreign extension type + g.RecordTypeUse(*n) + } + + typeName := ext.TypeName() + + // Special case for proto2 message sets: If this extension is extending + // proto2_bridge.MessageSet, and its final name component is "message_set_extension", + // then drop that last component. + mset := false + if extendedType == "*proto2_bridge.MessageSet" && typeName[len(typeName)-1] == "message_set_extension" { + typeName = typeName[:len(typeName)-1] + mset = true + } + + // For text formatting, the package must be exactly what the .proto file declares, + // ignoring overrides such as the go_package option, and with no dot/underscore mapping. + extName := strings.Join(typeName, ".") + if g.file.Package != nil { + extName = *g.file.Package + "." + extName + } + + g.P("var ", ccTypeName, " = &", g.Pkg["proto"], ".ExtensionDesc{") + g.In() + g.P("ExtendedType: (", extendedType, ")(nil),") + g.P("ExtensionType: (", fieldType, ")(nil),") + g.P("Field: ", field.Number, ",") + g.P(`Name: "`, extName, `",`) + g.P("Tag: ", tag, ",") + + g.Out() + g.P("}") + g.P() + + if mset { + // Generate a bit more code to register with message_set.go. + g.addInitf("%s.RegisterMessageSetType((%s)(nil), %d, %q)", g.Pkg["proto"], fieldType, *field.Number, extName) + } + + g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""}) +} + +func (g *Generator) generateInitFunction() { + for _, enum := range g.file.enum { + g.generateEnumRegistration(enum) + } + for _, d := range g.file.desc { + for _, ext := range d.ext { + g.generateExtensionRegistration(ext) + } + } + for _, ext := range g.file.ext { + g.generateExtensionRegistration(ext) + } + if len(g.init) == 0 { + return + } + g.P("func init() {") + g.In() + for _, l := range g.init { + g.P(l) + } + g.Out() + g.P("}") + g.init = nil +} + +func (g *Generator) generateFileDescriptor(file *FileDescriptor) { + // Make a copy and trim source_code_info data. + // TODO: Trim this more when we know exactly what we need. + pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto) + pb.SourceCodeInfo = nil + + b, err := proto.Marshal(pb) + if err != nil { + g.Fail(err.Error()) + } + + var buf bytes.Buffer + w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression) + w.Write(b) + w.Close() + b = buf.Bytes() + + v := fmt.Sprintf("fileDescriptor%d", file.index) + g.P() + g.P("var ", v, " = []byte{") + g.In() + g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto") + for len(b) > 0 { + n := 16 + if n > len(b) { + n = len(b) + } + + s := "" + for _, c := range b[:n] { + s += fmt.Sprintf("0x%02x,", c) + } + g.P(s) + + b = b[n:] + } + g.Out() + g.P("}") +} + +func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) { + // // We always print the full (proto-world) package name here. + pkg := enum.File().GetPackage() + if pkg != "" { + pkg += "." + } + // The full type name + typeName := enum.TypeName() + // The full type name, CamelCased. + ccTypeName := CamelCaseSlice(typeName) + g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["proto"], pkg+ccTypeName, ccTypeName) +} + +func (g *Generator) generateExtensionRegistration(ext *ExtensionDescriptor) { + g.addInitf("%s.RegisterExtension(%s)", g.Pkg["proto"], ext.DescName()) +} + +// And now lots of helper functions. + +// Is c an ASCII lower-case letter? +func isASCIILower(c byte) bool { + return 'a' <= c && c <= 'z' +} + +// Is c an ASCII digit? +func isASCIIDigit(c byte) bool { + return '0' <= c && c <= '9' +} + +// CamelCase returns the CamelCased name. +// If there is an interior underscore followed by a lower case letter, +// drop the underscore and convert the letter to upper case. +// There is a remote possibility of this rewrite causing a name collision, +// but it's so remote we're prepared to pretend it's nonexistent - since the +// C++ generator lowercases names, it's extremely unlikely to have two fields +// with different capitalizations. +// In short, _my_field_name_2 becomes XMyFieldName_2. +func CamelCase(s string) string { + if s == "" { + return "" + } + t := make([]byte, 0, 32) + i := 0 + if s[0] == '_' { + // Need a capital letter; drop the '_'. + t = append(t, 'X') + i++ + } + // Invariant: if the next letter is lower case, it must be converted + // to upper case. + // That is, we process a word at a time, where words are marked by _ or + // upper case letter. Digits are treated as words. + for ; i < len(s); i++ { + c := s[i] + if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) { + continue // Skip the underscore in s. + } + if isASCIIDigit(c) { + t = append(t, c) + continue + } + // Assume we have a letter now - if not, it's a bogus identifier. + // The next word is a sequence of characters that must start upper case. + if isASCIILower(c) { + c ^= ' ' // Make it a capital letter. + } + t = append(t, c) // Guaranteed not lower case. + // Accept lower case sequence that follows. + for i+1 < len(s) && isASCIILower(s[i+1]) { + i++ + t = append(t, s[i]) + } + } + return string(t) +} + +// CamelCaseSlice is like CamelCase, but the argument is a slice of strings to +// be joined with "_". +func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) } + +// dottedSlice turns a sliced name into a dotted name. +func dottedSlice(elem []string) string { return strings.Join(elem, ".") } + +// Given a .proto file name, return the output name for the generated Go program. +func goFileName(name string) string { + ext := path.Ext(name) + if ext == ".proto" || ext == ".protodevel" { + name = name[0 : len(name)-len(ext)] + } + return name + ".pb.go" +} + +// Is this field optional? +func isOptional(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL +} + +// Is this field required? +func isRequired(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED +} + +// Is this field repeated? +func isRepeated(field *descriptor.FieldDescriptorProto) bool { + return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED +} + +// badToUnderscore is the mapping function used to generate Go names from package names, +// which can be dotted in the input .proto file. It replaces non-identifier characters such as +// dot or dash with underscore. +func badToUnderscore(r rune) rune { + if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' { + return r + } + return '_' +} + +// baseName returns the last path element of the name, with the last dotted suffix removed. +func baseName(name string) string { + // First, find the last element + if i := strings.LastIndex(name, "/"); i >= 0 { + name = name[i+1:] + } + // Now drop the suffix + if i := strings.LastIndex(name, "."); i >= 0 { + name = name[0:i] + } + return name +} + +// The SourceCodeInfo message describes the location of elements of a parsed +// .proto file by way of a "path", which is a sequence of integers that +// describe the route from a FileDescriptorProto to the relevant submessage. +// The path alternates between a field number of a repeated field, and an index +// into that repeated field. The constants below define the field numbers that +// are used. +// +// See descriptor.proto for more information about this. +const ( + // tag numbers in FileDescriptorProto + packagePath = 2 // package + messagePath = 4 // message_type + enumPath = 5 // enum_type + // tag numbers in DescriptorProto + messageFieldPath = 2 // field + messageMessagePath = 3 // nested_type + messageEnumPath = 4 // enum_type + messageOneofPath = 8 // oneof_decl + // tag numbers in EnumDescriptorProto + enumValuePath = 2 // value +) diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/name_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/name_test.go new file mode 100644 index 00000000..f926918e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/generator/name_test.go @@ -0,0 +1,56 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2013 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package generator + +import ( + "testing" +) + +func TestCamelCase(t *testing.T) { + tests := []struct { + in, want string + }{ + {"one", "One"}, + {"one_two", "OneTwo"}, + {"_my_field_name_2", "XMyFieldName_2"}, + {"Something_Capped", "Something_Capped"}, + {"my_Name", "My_Name"}, + {"OneTwo", "OneTwo"}, + {"_", "X"}, + {"_a_", "XA_"}, + } + for _, tc := range tests { + if got := CamelCase(tc.in); got != tc.want { + t.Errorf("CamelCase(%q) = %q, want %q", tc.in, got, tc.want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/internal/grpc/grpc.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/internal/grpc/grpc.go new file mode 100644 index 00000000..f33f7011 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/internal/grpc/grpc.go @@ -0,0 +1,442 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// Package grpc outputs gRPC service descriptions in Go code. +// It runs as a plugin for the Go protocol buffer compiler plugin. +// It is linked in to protoc-gen-go. +package grpc + +import ( + "fmt" + "path" + "strconv" + "strings" + + pb "github.com/golang/protobuf/protoc-gen-go/descriptor" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +// Paths for packages used by code generated in this file, +// relative to the import_prefix of the generator.Generator. +const ( + contextPkgPath = "golang.org/x/net/context" + grpcPkgPath = "google.golang.org/grpc" +) + +func init() { + generator.RegisterPlugin(new(grpc)) +} + +// grpc is an implementation of the Go protocol buffer compiler's +// plugin architecture. It generates bindings for gRPC support. +type grpc struct { + gen *generator.Generator +} + +// Name returns the name of this plugin, "grpc". +func (g *grpc) Name() string { + return "grpc" +} + +// The names for packages imported in the generated code. +// They may vary from the final path component of the import path +// if the name is used by other packages. +var ( + contextPkg string + grpcPkg string +) + +// Init initializes the plugin. +func (g *grpc) Init(gen *generator.Generator) { + g.gen = gen + contextPkg = generator.RegisterUniquePackageName("context", nil) + grpcPkg = generator.RegisterUniquePackageName("grpc", nil) +} + +// Given a type name defined in a .proto, return its object. +// Also record that we're using it, to guarantee the associated import. +func (g *grpc) objectNamed(name string) generator.Object { + g.gen.RecordTypeUse(name) + return g.gen.ObjectNamed(name) +} + +// Given a type name defined in a .proto, return its name as we will print it. +func (g *grpc) typeName(str string) string { + return g.gen.TypeName(g.objectNamed(str)) +} + +// P forwards to g.gen.P. +func (g *grpc) P(args ...interface{}) { g.gen.P(args...) } + +// Generate generates code for the services in the given file. +func (g *grpc) Generate(file *generator.FileDescriptor) { + if len(file.FileDescriptorProto.Service) == 0 { + return + } + g.P("// Reference imports to suppress errors if they are not otherwise used.") + g.P("var _ ", contextPkg, ".Context") + g.P("var _ ", grpcPkg, ".ClientConn") + g.P() + for i, service := range file.FileDescriptorProto.Service { + g.generateService(file, service, i) + } +} + +// GenerateImports generates the import declaration for this file. +func (g *grpc) GenerateImports(file *generator.FileDescriptor) { + if len(file.FileDescriptorProto.Service) == 0 { + return + } + g.P("import (") + g.P(contextPkg, " ", strconv.Quote(path.Join(g.gen.ImportPrefix, contextPkgPath))) + g.P(grpcPkg, " ", strconv.Quote(path.Join(g.gen.ImportPrefix, grpcPkgPath))) + g.P(")") + g.P() +} + +// reservedClientName records whether a client name is reserved on the client side. +var reservedClientName = map[string]bool{ +// TODO: do we need any in gRPC? +} + +func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] } + +// generateService generates all the code for the named service. +func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) { + path := fmt.Sprintf("6,%d", index) // 6 means service. + + origServName := service.GetName() + fullServName := origServName + if pkg := file.GetPackage(); pkg != "" { + fullServName = pkg + "." + fullServName + } + servName := generator.CamelCase(origServName) + + g.P() + g.P("// Client API for ", servName, " service") + g.P() + + // Client interface. + g.P("type ", servName, "Client interface {") + for i, method := range service.Method { + g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. + g.P(g.generateClientSignature(servName, method)) + } + g.P("}") + g.P() + + // Client structure. + g.P("type ", unexport(servName), "Client struct {") + g.P("cc *", grpcPkg, ".ClientConn") + g.P("}") + g.P() + + // NewClient factory. + g.P("func New", servName, "Client (cc *", grpcPkg, ".ClientConn) ", servName, "Client {") + g.P("return &", unexport(servName), "Client{cc}") + g.P("}") + g.P() + + var methodIndex, streamIndex int + serviceDescVar := "_" + servName + "_serviceDesc" + // Client method implementations. + for _, method := range service.Method { + var descExpr string + if !method.GetServerStreaming() && !method.GetClientStreaming() { + // Unary RPC method + descExpr = fmt.Sprintf("&%s.Methods[%d]", serviceDescVar, methodIndex) + methodIndex++ + } else { + // Streaming RPC method + descExpr = fmt.Sprintf("&%s.Streams[%d]", serviceDescVar, streamIndex) + streamIndex++ + } + g.generateClientMethod(servName, fullServName, serviceDescVar, method, descExpr) + } + + g.P("// Server API for ", servName, " service") + g.P() + + // Server interface. + serverType := servName + "Server" + g.P("type ", serverType, " interface {") + for i, method := range service.Method { + g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service. + g.P(g.generateServerSignature(servName, method)) + } + g.P("}") + g.P() + + // Server registration. + g.P("func Register", servName, "Server(s *", grpcPkg, ".Server, srv ", serverType, ") {") + g.P("s.RegisterService(&", serviceDescVar, `, srv)`) + g.P("}") + g.P() + + // Server handler implementations. + var handlerNames []string + for _, method := range service.Method { + hname := g.generateServerMethod(servName, method) + handlerNames = append(handlerNames, hname) + } + + // Service descriptor. + g.P("var ", serviceDescVar, " = ", grpcPkg, ".ServiceDesc {") + g.P("ServiceName: ", strconv.Quote(fullServName), ",") + g.P("HandlerType: (*", serverType, ")(nil),") + g.P("Methods: []", grpcPkg, ".MethodDesc{") + for i, method := range service.Method { + if method.GetServerStreaming() || method.GetClientStreaming() { + continue + } + g.P("{") + g.P("MethodName: ", strconv.Quote(method.GetName()), ",") + g.P("Handler: ", handlerNames[i], ",") + g.P("},") + } + g.P("},") + g.P("Streams: []", grpcPkg, ".StreamDesc{") + for i, method := range service.Method { + if !method.GetServerStreaming() && !method.GetClientStreaming() { + continue + } + g.P("{") + g.P("StreamName: ", strconv.Quote(method.GetName()), ",") + g.P("Handler: ", handlerNames[i], ",") + if method.GetServerStreaming() { + g.P("ServerStreams: true,") + } + if method.GetClientStreaming() { + g.P("ClientStreams: true,") + } + g.P("},") + } + g.P("},") + g.P("}") + g.P() +} + +// generateClientSignature returns the client-side signature for a method. +func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string { + origMethName := method.GetName() + methName := generator.CamelCase(origMethName) + if reservedClientName[methName] { + methName += "_" + } + reqArg := ", in *" + g.typeName(method.GetInputType()) + if method.GetClientStreaming() { + reqArg = "" + } + respName := "*" + g.typeName(method.GetOutputType()) + if method.GetServerStreaming() || method.GetClientStreaming() { + respName = servName + "_" + generator.CamelCase(origMethName) + "Client" + } + return fmt.Sprintf("%s(ctx %s.Context%s, opts ...%s.CallOption) (%s, error)", methName, contextPkg, reqArg, grpcPkg, respName) +} + +func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) { + sname := fmt.Sprintf("/%s/%s", fullServName, method.GetName()) + methName := generator.CamelCase(method.GetName()) + inType := g.typeName(method.GetInputType()) + outType := g.typeName(method.GetOutputType()) + + g.P("func (c *", unexport(servName), "Client) ", g.generateClientSignature(servName, method), "{") + if !method.GetServerStreaming() && !method.GetClientStreaming() { + g.P("out := new(", outType, ")") + // TODO: Pass descExpr to Invoke. + g.P("err := ", grpcPkg, `.Invoke(ctx, "`, sname, `", in, out, c.cc, opts...)`) + g.P("if err != nil { return nil, err }") + g.P("return out, nil") + g.P("}") + g.P() + return + } + streamType := unexport(servName) + methName + "Client" + g.P("stream, err := ", grpcPkg, ".NewClientStream(ctx, ", descExpr, `, c.cc, "`, sname, `", opts...)`) + g.P("if err != nil { return nil, err }") + g.P("x := &", streamType, "{stream}") + if !method.GetClientStreaming() { + g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + } + g.P("return x, nil") + g.P("}") + g.P() + + genSend := method.GetClientStreaming() + genRecv := method.GetServerStreaming() + genCloseAndRecv := !method.GetServerStreaming() + + // Stream auxiliary types and methods. + g.P("type ", servName, "_", methName, "Client interface {") + if genSend { + g.P("Send(*", inType, ") error") + } + if genRecv { + g.P("Recv() (*", outType, ", error)") + } + if genCloseAndRecv { + g.P("CloseAndRecv() (*", outType, ", error)") + } + g.P(grpcPkg, ".ClientStream") + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPkg, ".ClientStream") + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", inType, ") error {") + g.P("return x.ClientStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", outType, ", error) {") + g.P("m := new(", outType, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + if genCloseAndRecv { + g.P("func (x *", streamType, ") CloseAndRecv() (*", outType, ", error) {") + g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }") + g.P("m := new(", outType, ")") + g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } +} + +// generateServerSignature returns the server-side signature for a method. +func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string { + origMethName := method.GetName() + methName := generator.CamelCase(origMethName) + if reservedClientName[methName] { + methName += "_" + } + + var reqArgs []string + ret := "error" + if !method.GetServerStreaming() && !method.GetClientStreaming() { + reqArgs = append(reqArgs, contextPkg+".Context") + ret = "(*" + g.typeName(method.GetOutputType()) + ", error)" + } + if !method.GetClientStreaming() { + reqArgs = append(reqArgs, "*"+g.typeName(method.GetInputType())) + } + if method.GetServerStreaming() || method.GetClientStreaming() { + reqArgs = append(reqArgs, servName+"_"+generator.CamelCase(origMethName)+"Server") + } + + return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret +} + +func (g *grpc) generateServerMethod(servName string, method *pb.MethodDescriptorProto) string { + methName := generator.CamelCase(method.GetName()) + hname := fmt.Sprintf("_%s_%s_Handler", servName, methName) + inType := g.typeName(method.GetInputType()) + outType := g.typeName(method.GetOutputType()) + + if !method.GetServerStreaming() && !method.GetClientStreaming() { + g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, dec func(interface{}) error) (interface{}, error) {") + g.P("in := new(", inType, ")") + g.P("if err := dec(in); err != nil { return nil, err }") + g.P("out, err := srv.(", servName, "Server).", methName, "(ctx, in)") + g.P("if err != nil { return nil, err }") + g.P("return out, nil") + g.P("}") + g.P() + return hname + } + streamType := unexport(servName) + methName + "Server" + g.P("func ", hname, "(srv interface{}, stream ", grpcPkg, ".ServerStream) error {") + if !method.GetClientStreaming() { + g.P("m := new(", inType, ")") + g.P("if err := stream.RecvMsg(m); err != nil { return err }") + g.P("return srv.(", servName, "Server).", methName, "(m, &", streamType, "{stream})") + } else { + g.P("return srv.(", servName, "Server).", methName, "(&", streamType, "{stream})") + } + g.P("}") + g.P() + + genSend := method.GetServerStreaming() + genSendAndClose := !method.GetServerStreaming() + genRecv := method.GetClientStreaming() + + // Stream auxiliary types and methods. + g.P("type ", servName, "_", methName, "Server interface {") + if genSend { + g.P("Send(*", outType, ") error") + } + if genSendAndClose { + g.P("SendAndClose(*", outType, ") error") + } + if genRecv { + g.P("Recv() (*", inType, ", error)") + } + g.P(grpcPkg, ".ServerStream") + g.P("}") + g.P() + + g.P("type ", streamType, " struct {") + g.P(grpcPkg, ".ServerStream") + g.P("}") + g.P() + + if genSend { + g.P("func (x *", streamType, ") Send(m *", outType, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genSendAndClose { + g.P("func (x *", streamType, ") SendAndClose(m *", outType, ") error {") + g.P("return x.ServerStream.SendMsg(m)") + g.P("}") + g.P() + } + if genRecv { + g.P("func (x *", streamType, ") Recv() (*", inType, ", error) {") + g.P("m := new(", inType, ")") + g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }") + g.P("return m, nil") + g.P("}") + g.P() + } + + return hname +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/link_grpc.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/link_grpc.go new file mode 100644 index 00000000..24e490ec --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/link_grpc.go @@ -0,0 +1,34 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +package main + +import _ "github.com/golang/protobuf/protoc-gen-go/internal/grpc" diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/main.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/main.go new file mode 100644 index 00000000..8e2486de --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/main.go @@ -0,0 +1,98 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate +// Go code. Run it by building this program and putting it in your path with +// the name +// protoc-gen-go +// That word 'go' at the end becomes part of the option string set for the +// protocol compiler, so once the protocol compiler (protoc) is installed +// you can run +// protoc --go_out=output_directory input_directory/file.proto +// to generate Go bindings for the protocol defined by file.proto. +// With that input, the output will be written to +// output_directory/file.pb.go +// +// The generated code is documented in the package comment for +// the library. +// +// See the README and documentation for protocol buffers to learn more: +// https://developers.google.com/protocol-buffers/ +package main + +import ( + "io/ioutil" + "os" + + "github.com/golang/protobuf/proto" + "github.com/golang/protobuf/protoc-gen-go/generator" +) + +func main() { + // Begin by allocating a generator. The request and response structures are stored there + // so we can do error handling easily - the response structure contains the field to + // report failure. + g := generator.New() + + data, err := ioutil.ReadAll(os.Stdin) + if err != nil { + g.Error(err, "reading input") + } + + if err := proto.Unmarshal(data, g.Request); err != nil { + g.Error(err, "parsing input proto") + } + + if len(g.Request.FileToGenerate) == 0 { + g.Fail("no files to generate") + } + + g.CommandLineParameters(g.Request.GetParameter()) + + // Create a wrapped version of the Descriptors and EnumDescriptors that + // point to the file that defines them. + g.WrapTypes() + + g.SetPackageNames() + g.BuildTypeNameMap() + + g.GenerateAllFiles() + + // Send back the results. + data, err = proto.Marshal(g.Response) + if err != nil { + g.Error(err, "failed to marshal output proto") + } + _, err = os.Stdout.Write(data) + if err != nil { + g.Error(err, "failed to write output proto") + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/Makefile new file mode 100644 index 00000000..eb41f20d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/Makefile @@ -0,0 +1,45 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +# Not stored here, but plugin.proto is in https://github.com/google/protobuf/ +# at src/google/protobuf/compiler/plugin.proto +# Also we need to fix an import. +regenerate: + echo WARNING! THIS RULE IS PROBABLY NOT RIGHT FOR YOUR INSTALLATION + protoc --go_out=Mgoogle/protobuf/descriptor.proto=github.com/golang/protobuf/protoc-gen-go/descriptor:. \ + -I$(HOME)/src/protobuf/src $(HOME)/src/protobuf/src/google/protobuf/compiler/plugin.proto && \ + mv google/protobuf/compiler/plugin.pb.go $(GOPATH)/src/github.com/golang/protobuf/protoc-gen-go/plugin + +restore: + cp plugin.pb.golden plugin.pb.go + +preserve: + cp plugin.pb.go plugin.pb.golden diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go new file mode 100644 index 00000000..af31f733 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.go @@ -0,0 +1,222 @@ +// Code generated by protoc-gen-go. +// source: google/protobuf/compiler/plugin.proto +// DO NOT EDIT! + +/* +Package google_protobuf_compiler is a generated protocol buffer package. + +It is generated from these files: + google/protobuf/compiler/plugin.proto + +It has these top-level messages: + CodeGeneratorRequest + CodeGeneratorResponse +*/ +package google_protobuf_compiler + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +const _ = proto.ProtoPackageIsVersion1 + +// An encoded CodeGeneratorRequest is written to the plugin's stdin. +type CodeGeneratorRequest struct { + // The .proto files that were explicitly listed on the command-line. The + // code generator should generate code only for these files. Each file's + // descriptor will be included in proto_file, below. + FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate" json:"file_to_generate,omitempty"` + // The generator parameter passed on the command-line. + Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"` + // FileDescriptorProtos for all files in files_to_generate and everything + // they import. The files will appear in topological order, so each file + // appears before any file that imports it. + // + // protoc guarantees that all proto_files will be written after + // the fields above, even though this is not technically guaranteed by the + // protobuf wire format. This theoretically could allow a plugin to stream + // in the FileDescriptorProtos and handle them one by one rather than read + // the entire set into memory at once. However, as of this writing, this + // is not similarly optimized on protoc's end -- it will store all fields in + // memory at once before sending them to the plugin. + ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file" json:"proto_file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CodeGeneratorRequest) Reset() { *m = CodeGeneratorRequest{} } +func (m *CodeGeneratorRequest) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorRequest) ProtoMessage() {} +func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *CodeGeneratorRequest) GetFileToGenerate() []string { + if m != nil { + return m.FileToGenerate + } + return nil +} + +func (m *CodeGeneratorRequest) GetParameter() string { + if m != nil && m.Parameter != nil { + return *m.Parameter + } + return "" +} + +func (m *CodeGeneratorRequest) GetProtoFile() []*google_protobuf.FileDescriptorProto { + if m != nil { + return m.ProtoFile + } + return nil +} + +// The plugin writes an encoded CodeGeneratorResponse to stdout. +type CodeGeneratorResponse struct { + // Error message. If non-empty, code generation failed. The plugin process + // should exit with status code zero even if it reports an error in this way. + // + // This should be used to indicate errors in .proto files which prevent the + // code generator from generating correct code. Errors which indicate a + // problem in protoc itself -- such as the input CodeGeneratorRequest being + // unparseable -- should be reported by writing a message to stderr and + // exiting with a non-zero status code. + Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + File []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CodeGeneratorResponse) Reset() { *m = CodeGeneratorResponse{} } +func (m *CodeGeneratorResponse) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorResponse) ProtoMessage() {} +func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *CodeGeneratorResponse) GetError() string { + if m != nil && m.Error != nil { + return *m.Error + } + return "" +} + +func (m *CodeGeneratorResponse) GetFile() []*CodeGeneratorResponse_File { + if m != nil { + return m.File + } + return nil +} + +// Represents a single generated file. +type CodeGeneratorResponse_File struct { + // The file name, relative to the output directory. The name must not + // contain "." or ".." components and must be relative, not be absolute (so, + // the file cannot lie outside the output directory). "/" must be used as + // the path separator, not "\". + // + // If the name is omitted, the content will be appended to the previous + // file. This allows the generator to break large files into small chunks, + // and allows the generated text to be streamed back to protoc so that large + // files need not reside completely in memory at one time. Note that as of + // this writing protoc does not optimize for this -- it will read the entire + // CodeGeneratorResponse before writing files to disk. + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + // If non-empty, indicates that the named file should already exist, and the + // content here is to be inserted into that file at a defined insertion + // point. This feature allows a code generator to extend the output + // produced by another code generator. The original generator may provide + // insertion points by placing special annotations in the file that look + // like: + // @@protoc_insertion_point(NAME) + // The annotation can have arbitrary text before and after it on the line, + // which allows it to be placed in a comment. NAME should be replaced with + // an identifier naming the point -- this is what other generators will use + // as the insertion_point. Code inserted at this point will be placed + // immediately above the line containing the insertion point (thus multiple + // insertions to the same point will come out in the order they were added). + // The double-@ is intended to make it unlikely that the generated code + // could contain things that look like insertion points by accident. + // + // For example, the C++ code generator places the following line in the + // .pb.h files that it generates: + // // @@protoc_insertion_point(namespace_scope) + // This line appears within the scope of the file's package namespace, but + // outside of any particular class. Another plugin can then specify the + // insertion_point "namespace_scope" to generate additional classes or + // other declarations that should be placed in this scope. + // + // Note that if the line containing the insertion point begins with + // whitespace, the same whitespace will be added to every line of the + // inserted text. This is useful for languages like Python, where + // indentation matters. In these languages, the insertion point comment + // should be indented the same amount as any inserted code will need to be + // in order to work correctly in that context. + // + // The code generator that generates the initial file and the one which + // inserts into it must both run as part of a single invocation of protoc. + // Code generators are executed in the order in which they appear on the + // command line. + // + // If |insertion_point| is present, |name| must also be present. + InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point" json:"insertion_point,omitempty"` + // The file contents. + Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *CodeGeneratorResponse_File) Reset() { *m = CodeGeneratorResponse_File{} } +func (m *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(m) } +func (*CodeGeneratorResponse_File) ProtoMessage() {} +func (*CodeGeneratorResponse_File) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1, 0} } + +func (m *CodeGeneratorResponse_File) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +func (m *CodeGeneratorResponse_File) GetInsertionPoint() string { + if m != nil && m.InsertionPoint != nil { + return *m.InsertionPoint + } + return "" +} + +func (m *CodeGeneratorResponse_File) GetContent() string { + if m != nil && m.Content != nil { + return *m.Content + } + return "" +} + +func init() { + proto.RegisterType((*CodeGeneratorRequest)(nil), "google.protobuf.compiler.CodeGeneratorRequest") + proto.RegisterType((*CodeGeneratorResponse)(nil), "google.protobuf.compiler.CodeGeneratorResponse") + proto.RegisterType((*CodeGeneratorResponse_File)(nil), "google.protobuf.compiler.CodeGeneratorResponse.File") +} + +var fileDescriptor0 = []byte{ + // 269 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x91, 0xc1, 0x4a, 0xc3, 0x40, + 0x10, 0x86, 0xa9, 0x46, 0xa4, 0x63, 0x25, 0x1a, 0x14, 0x43, 0xf1, 0x10, 0x44, 0xc1, 0x83, 0x6c, + 0x40, 0x3c, 0x78, 0xf2, 0x10, 0x45, 0xaf, 0xc5, 0x17, 0x08, 0x31, 0x9d, 0x86, 0x85, 0x74, 0x67, + 0x9d, 0xdd, 0x1c, 0x7d, 0x21, 0x9f, 0xd2, 0xc9, 0xa6, 0x15, 0x09, 0xf6, 0x14, 0xf8, 0xe7, 0xcf, + 0xf7, 0xcd, 0xb0, 0x70, 0xd3, 0x10, 0x35, 0x2d, 0xe6, 0x96, 0xc9, 0xd3, 0x47, 0xb7, 0xca, 0x6b, + 0x5a, 0x5b, 0xdd, 0x22, 0xe7, 0xb6, 0xed, 0x1a, 0x6d, 0x54, 0x18, 0x24, 0xe9, 0x50, 0x53, 0xdb, + 0x9a, 0xda, 0xd6, 0xe6, 0xd9, 0x18, 0xb0, 0x44, 0x57, 0xb3, 0xb6, 0x9e, 0x78, 0x68, 0x5f, 0x7d, + 0xc1, 0xd9, 0x33, 0x2d, 0xf1, 0x0d, 0x0d, 0x72, 0x25, 0xf1, 0x3b, 0x7e, 0x76, 0xe8, 0x7c, 0x92, + 0xc2, 0xc9, 0x4a, 0x10, 0xa5, 0xa7, 0xb2, 0x19, 0x66, 0x98, 0x4e, 0xb2, 0xfd, 0xdb, 0x69, 0x72, + 0x0a, 0x53, 0x5b, 0x71, 0xb5, 0x46, 0x8f, 0x9c, 0xee, 0x65, 0x13, 0x89, 0x1e, 0x01, 0x02, 0xad, + 0xec, 0x7f, 0x49, 0x63, 0xa9, 0x1d, 0xdd, 0x5f, 0xab, 0xf1, 0x56, 0xaf, 0x32, 0x7c, 0xf9, 0xf5, + 0x2f, 0x82, 0xfe, 0x7b, 0x02, 0xe7, 0x23, 0xbf, 0xb3, 0x64, 0x1c, 0x26, 0xc7, 0x70, 0x80, 0xcc, + 0xc4, 0x62, 0xed, 0x15, 0x05, 0x44, 0x7f, 0xe0, 0x0f, 0x6a, 0xd7, 0xc9, 0xea, 0x5f, 0x5a, 0x70, + 0xcf, 0x9f, 0x20, 0xea, 0xbf, 0xc9, 0x0c, 0x22, 0x23, 0xfb, 0x6f, 0xc8, 0x17, 0x10, 0x6b, 0xa9, + 0xb0, 0xd7, 0x64, 0x4a, 0x4b, 0xda, 0xf8, 0xcd, 0x55, 0x31, 0x1c, 0xd6, 0x64, 0x3c, 0x4a, 0x10, + 0xf7, 0x41, 0x71, 0x07, 0x97, 0xa2, 0xd9, 0xa9, 0x2e, 0x66, 0x8b, 0xf0, 0x2a, 0xe1, 0x32, 0xf7, + 0x13, 0x00, 0x00, 0xff, 0xff, 0xdb, 0x18, 0x2a, 0x2a, 0xbd, 0x01, 0x00, 0x00, +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden new file mode 100644 index 00000000..8953d0ff --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/plugin/plugin.pb.golden @@ -0,0 +1,83 @@ +// Code generated by protoc-gen-go. +// source: google/protobuf/compiler/plugin.proto +// DO NOT EDIT! + +package google_protobuf_compiler + +import proto "github.com/golang/protobuf/proto" +import "math" +import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor" + +// Reference proto and math imports to suppress error if they are not otherwise used. +var _ = proto.GetString +var _ = math.Inf + +type CodeGeneratorRequest struct { + FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate" json:"file_to_generate,omitempty"` + Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"` + ProtoFile []*google_protobuf.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file" json:"proto_file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (this *CodeGeneratorRequest) Reset() { *this = CodeGeneratorRequest{} } +func (this *CodeGeneratorRequest) String() string { return proto.CompactTextString(this) } +func (*CodeGeneratorRequest) ProtoMessage() {} + +func (this *CodeGeneratorRequest) GetParameter() string { + if this != nil && this.Parameter != nil { + return *this.Parameter + } + return "" +} + +type CodeGeneratorResponse struct { + Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + File []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (this *CodeGeneratorResponse) Reset() { *this = CodeGeneratorResponse{} } +func (this *CodeGeneratorResponse) String() string { return proto.CompactTextString(this) } +func (*CodeGeneratorResponse) ProtoMessage() {} + +func (this *CodeGeneratorResponse) GetError() string { + if this != nil && this.Error != nil { + return *this.Error + } + return "" +} + +type CodeGeneratorResponse_File struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point" json:"insertion_point,omitempty"` + Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (this *CodeGeneratorResponse_File) Reset() { *this = CodeGeneratorResponse_File{} } +func (this *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(this) } +func (*CodeGeneratorResponse_File) ProtoMessage() {} + +func (this *CodeGeneratorResponse_File) GetName() string { + if this != nil && this.Name != nil { + return *this.Name + } + return "" +} + +func (this *CodeGeneratorResponse_File) GetInsertionPoint() string { + if this != nil && this.InsertionPoint != nil { + return *this.InsertionPoint + } + return "" +} + +func (this *CodeGeneratorResponse_File) GetContent() string { + if this != nil && this.Content != nil { + return *this.Content + } + return "" +} + +func init() { +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/Makefile new file mode 100644 index 00000000..a85cc565 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/Makefile @@ -0,0 +1,72 @@ +# Go support for Protocol Buffers - Google's data interchange format +# +# Copyright 2010 The Go Authors. All rights reserved. +# https://github.com/golang/protobuf +# +# 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. + +all: + @echo run make test + +include ../../Make.protobuf + +test: golden testbuild + +#test: golden testbuild extension_test +# ./extension_test +# @echo PASS + +my_test/test.pb.go: my_test/test.proto + protoc --go_out=Mmulti/multi1.proto=github.com/golang/protobuf/protoc-gen-go/testdata/multi:. $< + +golden: + make -B my_test/test.pb.go + sed -i '/return.*fileDescriptor/d' my_test/test.pb.go + sed -i '/^var fileDescriptor/,/^}/d' my_test/test.pb.go + gofmt -w my_test/test.pb.go + diff -w my_test/test.pb.go my_test/test.pb.go.golden + +nuke: clean + +testbuild: regenerate + go test + +regenerate: + # Invoke protoc once to generate three independent .pb.go files in the same package. + protoc --go_out=. multi/multi{1,2,3}.proto + +#extension_test: extension_test.$O +# $(LD) -L. -o $@ $< + +#multi.a: multi3.pb.$O multi2.pb.$O multi1.pb.$O +# rm -f multi.a +# $(QUOTED_GOBIN)/gopack grc $@ $< + +#test.pb.go: imp.pb.go +#multi1.pb.go: multi2.pb.go multi3.pb.go +#main.$O: imp.pb.$O test.pb.$O multi.a +#extension_test.$O: extension_base.pb.$O extension_extra.pb.$O extension_user.pb.$O diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_base.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_base.proto new file mode 100644 index 00000000..94acfc1b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_base.proto @@ -0,0 +1,46 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package extension_base; + +message BaseMessage { + optional int32 height = 1; + extensions 4 to 9; + extensions 16 to max; +} + +// Another message that may be extended, using message_set_wire_format. +message OldStyleMessage { + option message_set_wire_format = true; + extensions 100 to max; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_extra.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_extra.proto new file mode 100644 index 00000000..fca7f600 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_extra.proto @@ -0,0 +1,38 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package extension_extra; + +message ExtraMessage { + optional int32 width = 1; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_test.go new file mode 100644 index 00000000..86e9c118 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_test.go @@ -0,0 +1,210 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// Test that we can use protocol buffers that use extensions. + +package testdata + +/* + +import ( + "bytes" + "regexp" + "testing" + + "github.com/golang/protobuf/proto" + base "extension_base.pb" + user "extension_user.pb" +) + +func TestSingleFieldExtension(t *testing.T) { + bm := &base.BaseMessage{ + Height: proto.Int32(178), + } + + // Use extension within scope of another type. + vol := proto.Uint32(11) + err := proto.SetExtension(bm, user.E_LoudMessage_Volume, vol) + if err != nil { + t.Fatal("Failed setting extension:", err) + } + buf, err := proto.Marshal(bm) + if err != nil { + t.Fatal("Failed encoding message with extension:", err) + } + bm_new := new(base.BaseMessage) + if err := proto.Unmarshal(buf, bm_new); err != nil { + t.Fatal("Failed decoding message with extension:", err) + } + if !proto.HasExtension(bm_new, user.E_LoudMessage_Volume) { + t.Fatal("Decoded message didn't contain extension.") + } + vol_out, err := proto.GetExtension(bm_new, user.E_LoudMessage_Volume) + if err != nil { + t.Fatal("Failed getting extension:", err) + } + if v := vol_out.(*uint32); *v != *vol { + t.Errorf("vol_out = %v, expected %v", *v, *vol) + } + proto.ClearExtension(bm_new, user.E_LoudMessage_Volume) + if proto.HasExtension(bm_new, user.E_LoudMessage_Volume) { + t.Fatal("Failed clearing extension.") + } +} + +func TestMessageExtension(t *testing.T) { + bm := &base.BaseMessage{ + Height: proto.Int32(179), + } + + // Use extension that is itself a message. + um := &user.UserMessage{ + Name: proto.String("Dave"), + Rank: proto.String("Major"), + } + err := proto.SetExtension(bm, user.E_LoginMessage_UserMessage, um) + if err != nil { + t.Fatal("Failed setting extension:", err) + } + buf, err := proto.Marshal(bm) + if err != nil { + t.Fatal("Failed encoding message with extension:", err) + } + bm_new := new(base.BaseMessage) + if err := proto.Unmarshal(buf, bm_new); err != nil { + t.Fatal("Failed decoding message with extension:", err) + } + if !proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) { + t.Fatal("Decoded message didn't contain extension.") + } + um_out, err := proto.GetExtension(bm_new, user.E_LoginMessage_UserMessage) + if err != nil { + t.Fatal("Failed getting extension:", err) + } + if n := um_out.(*user.UserMessage).Name; *n != *um.Name { + t.Errorf("um_out.Name = %q, expected %q", *n, *um.Name) + } + if r := um_out.(*user.UserMessage).Rank; *r != *um.Rank { + t.Errorf("um_out.Rank = %q, expected %q", *r, *um.Rank) + } + proto.ClearExtension(bm_new, user.E_LoginMessage_UserMessage) + if proto.HasExtension(bm_new, user.E_LoginMessage_UserMessage) { + t.Fatal("Failed clearing extension.") + } +} + +func TestTopLevelExtension(t *testing.T) { + bm := &base.BaseMessage{ + Height: proto.Int32(179), + } + + width := proto.Int32(17) + err := proto.SetExtension(bm, user.E_Width, width) + if err != nil { + t.Fatal("Failed setting extension:", err) + } + buf, err := proto.Marshal(bm) + if err != nil { + t.Fatal("Failed encoding message with extension:", err) + } + bm_new := new(base.BaseMessage) + if err := proto.Unmarshal(buf, bm_new); err != nil { + t.Fatal("Failed decoding message with extension:", err) + } + if !proto.HasExtension(bm_new, user.E_Width) { + t.Fatal("Decoded message didn't contain extension.") + } + width_out, err := proto.GetExtension(bm_new, user.E_Width) + if err != nil { + t.Fatal("Failed getting extension:", err) + } + if w := width_out.(*int32); *w != *width { + t.Errorf("width_out = %v, expected %v", *w, *width) + } + proto.ClearExtension(bm_new, user.E_Width) + if proto.HasExtension(bm_new, user.E_Width) { + t.Fatal("Failed clearing extension.") + } +} + +func TestMessageSetWireFormat(t *testing.T) { + osm := new(base.OldStyleMessage) + osp := &user.OldStyleParcel{ + Name: proto.String("Dave"), + Height: proto.Int32(178), + } + + err := proto.SetExtension(osm, user.E_OldStyleParcel_MessageSetExtension, osp) + if err != nil { + t.Fatal("Failed setting extension:", err) + } + + buf, err := proto.Marshal(osm) + if err != nil { + t.Fatal("Failed encoding message:", err) + } + + // Data generated from Python implementation. + expected := []byte{ + 11, 16, 209, 15, 26, 9, 10, 4, 68, 97, 118, 101, 16, 178, 1, 12, + } + + if !bytes.Equal(expected, buf) { + t.Errorf("Encoding mismatch.\nwant %+v\n got %+v", expected, buf) + } + + // Check that it is restored correctly. + osm = new(base.OldStyleMessage) + if err := proto.Unmarshal(buf, osm); err != nil { + t.Fatal("Failed decoding message:", err) + } + osp_out, err := proto.GetExtension(osm, user.E_OldStyleParcel_MessageSetExtension) + if err != nil { + t.Fatal("Failed getting extension:", err) + } + osp = osp_out.(*user.OldStyleParcel) + if *osp.Name != "Dave" || *osp.Height != 178 { + t.Errorf("Retrieved extension from decoded message is not correct: %+v", osp) + } +} + +func main() { + // simpler than rigging up gotest + testing.Main(regexp.MatchString, []testing.InternalTest{ + {"TestSingleFieldExtension", TestSingleFieldExtension}, + {"TestMessageExtension", TestMessageExtension}, + {"TestTopLevelExtension", TestTopLevelExtension}, + }, + []testing.InternalBenchmark{}, + []testing.InternalExample{}) +} + +*/ diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_user.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_user.proto new file mode 100644 index 00000000..ff65873d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/extension_user.proto @@ -0,0 +1,100 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +import "extension_base.proto"; +import "extension_extra.proto"; + +package extension_user; + +message UserMessage { + optional string name = 1; + optional string rank = 2; +} + +// Extend with a message +extend extension_base.BaseMessage { + optional UserMessage user_message = 5; +} + +// Extend with a foreign message +extend extension_base.BaseMessage { + optional extension_extra.ExtraMessage extra_message = 9; +} + +// Extend with some primitive types +extend extension_base.BaseMessage { + optional int32 width = 6; + optional int64 area = 7; +} + +// Extend inside the scope of another type +message LoudMessage { + extend extension_base.BaseMessage { + optional uint32 volume = 8; + } + extensions 100 to max; +} + +// Extend inside the scope of another type, using a message. +message LoginMessage { + extend extension_base.BaseMessage { + optional UserMessage user_message = 16; + } +} + +// Extend with a repeated field +extend extension_base.BaseMessage { + repeated Detail detail = 17; +} + +message Detail { + optional string color = 1; +} + +// An extension of an extension +message Announcement { + optional string words = 1; + extend LoudMessage { + optional Announcement loud_ext = 100; + } +} + +// Something that can be put in a message set. +message OldStyleParcel { + extend extension_base.OldStyleMessage { + optional OldStyleParcel message_set_extension = 2001; + } + + required string name = 1; + optional int32 height = 2; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/grpc.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/grpc.proto new file mode 100644 index 00000000..b8bc41ac --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/grpc.proto @@ -0,0 +1,59 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2015 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto3"; + +package grpc.testing; + +message SimpleRequest { +} + +message SimpleResponse { +} + +message StreamMsg { +} + +message StreamMsg2 { +} + +service Test { + rpc UnaryCall(SimpleRequest) returns (SimpleResponse); + + // This RPC streams from the server only. + rpc Downstream(SimpleRequest) returns (stream StreamMsg); + + // This RPC streams from the client. + rpc Upstream(stream StreamMsg) returns (SimpleResponse); + + // This one streams in both directions. + rpc Bidi(stream StreamMsg) returns (stream StreamMsg2); +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp.pb.go.golden b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp.pb.go.golden new file mode 100644 index 00000000..784a4f86 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp.pb.go.golden @@ -0,0 +1,113 @@ +// Code generated by protoc-gen-go. +// source: imp.proto +// DO NOT EDIT! + +package imp + +import proto "github.com/golang/protobuf/proto" +import "math" +import "os" +import imp1 "imp2.pb" + +// Reference proto & math imports to suppress error if they are not otherwise used. +var _ = proto.GetString +var _ = math.Inf + +// Types from public import imp2.proto +type PubliclyImportedMessage imp1.PubliclyImportedMessage + +func (this *PubliclyImportedMessage) Reset() { (*imp1.PubliclyImportedMessage)(this).Reset() } +func (this *PubliclyImportedMessage) String() string { + return (*imp1.PubliclyImportedMessage)(this).String() +} + +// PubliclyImportedMessage from public import imp.proto + +type ImportedMessage_Owner int32 + +const ( + ImportedMessage_DAVE ImportedMessage_Owner = 1 + ImportedMessage_MIKE ImportedMessage_Owner = 2 +) + +var ImportedMessage_Owner_name = map[int32]string{ + 1: "DAVE", + 2: "MIKE", +} +var ImportedMessage_Owner_value = map[string]int32{ + "DAVE": 1, + "MIKE": 2, +} + +// NewImportedMessage_Owner is deprecated. Use x.Enum() instead. +func NewImportedMessage_Owner(x ImportedMessage_Owner) *ImportedMessage_Owner { + e := ImportedMessage_Owner(x) + return &e +} +func (x ImportedMessage_Owner) Enum() *ImportedMessage_Owner { + p := new(ImportedMessage_Owner) + *p = x + return p +} +func (x ImportedMessage_Owner) String() string { + return proto.EnumName(ImportedMessage_Owner_name, int32(x)) +} + +type ImportedMessage struct { + Field *int64 `protobuf:"varint,1,req,name=field" json:"field,omitempty"` + XXX_extensions map[int32][]byte `json:",omitempty"` + XXX_unrecognized []byte `json:",omitempty"` +} + +func (this *ImportedMessage) Reset() { *this = ImportedMessage{} } +func (this *ImportedMessage) String() string { return proto.CompactTextString(this) } + +var extRange_ImportedMessage = []proto.ExtensionRange{ + proto.ExtensionRange{90, 100}, +} + +func (*ImportedMessage) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ImportedMessage +} +func (this *ImportedMessage) ExtensionMap() map[int32][]byte { + if this.XXX_extensions == nil { + this.XXX_extensions = make(map[int32][]byte) + } + return this.XXX_extensions +} + +type ImportedExtendable struct { + XXX_extensions map[int32][]byte `json:",omitempty"` + XXX_unrecognized []byte `json:",omitempty"` +} + +func (this *ImportedExtendable) Reset() { *this = ImportedExtendable{} } +func (this *ImportedExtendable) String() string { return proto.CompactTextString(this) } + +func (this *ImportedExtendable) Marshal() ([]byte, error) { + return proto.MarshalMessageSet(this.ExtensionMap()) +} +func (this *ImportedExtendable) Unmarshal(buf []byte) error { + return proto.UnmarshalMessageSet(buf, this.ExtensionMap()) +} +// ensure ImportedExtendable satisfies proto.Marshaler and proto.Unmarshaler +var _ proto.Marshaler = (*ImportedExtendable)(nil) +var _ proto.Unmarshaler = (*ImportedExtendable)(nil) + +var extRange_ImportedExtendable = []proto.ExtensionRange{ + proto.ExtensionRange{100, 536870911}, +} + +func (*ImportedExtendable) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_ImportedExtendable +} +func (this *ImportedExtendable) ExtensionMap() map[int32][]byte { + if this.XXX_extensions == nil { + this.XXX_extensions = make(map[int32][]byte) + } + return this.XXX_extensions +} + +func init() { + proto.RegisterEnum("imp.ImportedMessage_Owner", ImportedMessage_Owner_name, ImportedMessage_Owner_value) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp.proto new file mode 100644 index 00000000..156e078d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp.proto @@ -0,0 +1,70 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package imp; + +import "imp2.proto"; +import "imp3.proto"; + +message ImportedMessage { + required int64 field = 1; + + // The forwarded getters for these fields are fiddly to get right. + optional ImportedMessage2 local_msg = 2; + optional ForeignImportedMessage foreign_msg = 3; // in imp3.proto + optional Owner enum_field = 4; + oneof union { + int32 state = 9; + } + + repeated string name = 5; + repeated Owner boss = 6; + repeated ImportedMessage2 memo = 7; + + map msg_map = 8; + + enum Owner { + DAVE = 1; + MIKE = 2; + } + + extensions 90 to 100; +} + +message ImportedMessage2 { +} + +message ImportedExtendable { + option message_set_wire_format = true; + extensions 100 to max; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp2.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp2.proto new file mode 100644 index 00000000..3bb0632b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp2.proto @@ -0,0 +1,43 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2011 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package imp; + +message PubliclyImportedMessage { + optional int64 field = 1; +} + +enum PubliclyImportedEnum { + GLASSES = 1; + HAIR = 2; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp3.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp3.proto new file mode 100644 index 00000000..58fc7598 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/imp3.proto @@ -0,0 +1,38 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2012 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package imp; + +message ForeignImportedMessage { + optional string tuber = 1; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/main_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/main_test.go new file mode 100644 index 00000000..f9b5ccf2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/main_test.go @@ -0,0 +1,46 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +// A simple binary to link together the protocol buffers in this test. + +package testdata + +import ( + "testing" + + mytestpb "./my_test" + multipb "github.com/golang/protobuf/protoc-gen-go/testdata/multi" +) + +func TestLink(t *testing.T) { + _ = &multipb.Multi1{} + _ = &mytestpb.Request{} +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi1.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi1.proto new file mode 100644 index 00000000..0da6e0af --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi1.proto @@ -0,0 +1,44 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +import "multi/multi2.proto"; +import "multi/multi3.proto"; + +package multitest; + +message Multi1 { + required Multi2 multi2 = 1; + optional Multi2.Color color = 2; + optional Multi3.HatType hat_type = 3; +} + diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi2.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi2.proto new file mode 100644 index 00000000..e6bfc71b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi2.proto @@ -0,0 +1,46 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package multitest; + +message Multi2 { + required int32 required_value = 1; + + enum Color { + BLUE = 1; + GREEN = 2; + RED = 3; + }; + optional Color color = 2; +} + diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi3.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi3.proto new file mode 100644 index 00000000..146c255b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/multi/multi3.proto @@ -0,0 +1,43 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +package multitest; + +message Multi3 { + enum HatType { + FEDORA = 1; + FEZ = 2; + }; + optional HatType hat_type = 1; +} + diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.pb.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.pb.go new file mode 100644 index 00000000..b0375f02 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.pb.go @@ -0,0 +1,882 @@ +// Code generated by protoc-gen-go. +// source: my_test/test.proto +// DO NOT EDIT! + +/* +Package my_test is a generated protocol buffer package. + +This package holds interesting messages. + +It is generated from these files: + my_test/test.proto + +It has these top-level messages: + Request + Reply + OtherBase + ReplyExtensions + OtherReplyExtensions + OldReply + Communique +*/ +package my_test + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/golang/protobuf/protoc-gen-go/testdata/multi" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +const _ = proto.ProtoPackageIsVersion1 + +type HatType int32 + +const ( + // deliberately skipping 0 + HatType_FEDORA HatType = 1 + HatType_FEZ HatType = 2 +) + +var HatType_name = map[int32]string{ + 1: "FEDORA", + 2: "FEZ", +} +var HatType_value = map[string]int32{ + "FEDORA": 1, + "FEZ": 2, +} + +func (x HatType) Enum() *HatType { + p := new(HatType) + *p = x + return p +} +func (x HatType) String() string { + return proto.EnumName(HatType_name, int32(x)) +} +func (x *HatType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(HatType_value, data, "HatType") + if err != nil { + return err + } + *x = HatType(value) + return nil +} + +// This enum represents days of the week. +type Days int32 + +const ( + Days_MONDAY Days = 1 + Days_TUESDAY Days = 2 + Days_LUNDI Days = 1 +) + +var Days_name = map[int32]string{ + 1: "MONDAY", + 2: "TUESDAY", + // Duplicate value: 1: "LUNDI", +} +var Days_value = map[string]int32{ + "MONDAY": 1, + "TUESDAY": 2, + "LUNDI": 1, +} + +func (x Days) Enum() *Days { + p := new(Days) + *p = x + return p +} +func (x Days) String() string { + return proto.EnumName(Days_name, int32(x)) +} +func (x *Days) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Days_value, data, "Days") + if err != nil { + return err + } + *x = Days(value) + return nil +} + +type Request_Color int32 + +const ( + Request_RED Request_Color = 0 + Request_GREEN Request_Color = 1 + Request_BLUE Request_Color = 2 +) + +var Request_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var Request_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Request_Color) Enum() *Request_Color { + p := new(Request_Color) + *p = x + return p +} +func (x Request_Color) String() string { + return proto.EnumName(Request_Color_name, int32(x)) +} +func (x *Request_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Request_Color_value, data, "Request_Color") + if err != nil { + return err + } + *x = Request_Color(value) + return nil +} + +type Reply_Entry_Game int32 + +const ( + Reply_Entry_FOOTBALL Reply_Entry_Game = 1 + Reply_Entry_TENNIS Reply_Entry_Game = 2 +) + +var Reply_Entry_Game_name = map[int32]string{ + 1: "FOOTBALL", + 2: "TENNIS", +} +var Reply_Entry_Game_value = map[string]int32{ + "FOOTBALL": 1, + "TENNIS": 2, +} + +func (x Reply_Entry_Game) Enum() *Reply_Entry_Game { + p := new(Reply_Entry_Game) + *p = x + return p +} +func (x Reply_Entry_Game) String() string { + return proto.EnumName(Reply_Entry_Game_name, int32(x)) +} +func (x *Reply_Entry_Game) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Reply_Entry_Game_value, data, "Reply_Entry_Game") + if err != nil { + return err + } + *x = Reply_Entry_Game(value) + return nil +} + +// This is a message that might be sent somewhere. +type Request struct { + Key []int64 `protobuf:"varint,1,rep,name=key" json:"key,omitempty"` + // optional imp.ImportedMessage imported_message = 2; + Hue *Request_Color `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"` + Hat *HatType `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"` + // optional imp.ImportedMessage.Owner owner = 6; + Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"` + Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` + // This is a map field. It will generate map[int32]string. + NameMapping map[int32]string `protobuf:"bytes,14,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // This is a map field whose value type is a message. + MsgMapping map[int64]*Reply `protobuf:"bytes,15,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"` + // This field should not conflict with any getters. + GetKey_ *string `protobuf:"bytes,16,opt,name=get_key" json:"get_key,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Request) Reset() { *m = Request{} } +func (m *Request) String() string { return proto.CompactTextString(m) } +func (*Request) ProtoMessage() {} + +const Default_Request_Hat HatType = HatType_FEDORA + +var Default_Request_Deadline float32 = float32(math.Inf(1)) + +func (m *Request) GetKey() []int64 { + if m != nil { + return m.Key + } + return nil +} + +func (m *Request) GetHue() Request_Color { + if m != nil && m.Hue != nil { + return *m.Hue + } + return Request_RED +} + +func (m *Request) GetHat() HatType { + if m != nil && m.Hat != nil { + return *m.Hat + } + return Default_Request_Hat +} + +func (m *Request) GetDeadline() float32 { + if m != nil && m.Deadline != nil { + return *m.Deadline + } + return Default_Request_Deadline +} + +func (m *Request) GetSomegroup() *Request_SomeGroup { + if m != nil { + return m.Somegroup + } + return nil +} + +func (m *Request) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *Request) GetMsgMapping() map[int64]*Reply { + if m != nil { + return m.MsgMapping + } + return nil +} + +func (m *Request) GetReset_() int32 { + if m != nil && m.Reset_ != nil { + return *m.Reset_ + } + return 0 +} + +func (m *Request) GetGetKey_() string { + if m != nil && m.GetKey_ != nil { + return *m.GetKey_ + } + return "" +} + +type Request_SomeGroup struct { + GroupField *int32 `protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Request_SomeGroup) Reset() { *m = Request_SomeGroup{} } +func (m *Request_SomeGroup) String() string { return proto.CompactTextString(m) } +func (*Request_SomeGroup) ProtoMessage() {} + +func (m *Request_SomeGroup) GetGroupField() int32 { + if m != nil && m.GroupField != nil { + return *m.GroupField + } + return 0 +} + +type Reply struct { + Found []*Reply_Entry `protobuf:"bytes,1,rep,name=found" json:"found,omitempty"` + CompactKeys []int32 `protobuf:"varint,2,rep,packed,name=compact_keys" json:"compact_keys,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Reply) Reset() { *m = Reply{} } +func (m *Reply) String() string { return proto.CompactTextString(m) } +func (*Reply) ProtoMessage() {} + +var extRange_Reply = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*Reply) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_Reply +} +func (m *Reply) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *Reply) GetFound() []*Reply_Entry { + if m != nil { + return m.Found + } + return nil +} + +func (m *Reply) GetCompactKeys() []int32 { + if m != nil { + return m.CompactKeys + } + return nil +} + +type Reply_Entry struct { + KeyThatNeeds_1234Camel_CasIng *int64 `protobuf:"varint,1,req,name=key_that_needs_1234camel_CasIng" json:"key_that_needs_1234camel_CasIng,omitempty"` + Value *int64 `protobuf:"varint,2,opt,name=value,def=7" json:"value,omitempty"` + XMyFieldName_2 *int64 `protobuf:"varint,3,opt,name=_my_field_name_2" json:"_my_field_name_2,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Reply_Entry) Reset() { *m = Reply_Entry{} } +func (m *Reply_Entry) String() string { return proto.CompactTextString(m) } +func (*Reply_Entry) ProtoMessage() {} + +const Default_Reply_Entry_Value int64 = 7 + +func (m *Reply_Entry) GetKeyThatNeeds_1234Camel_CasIng() int64 { + if m != nil && m.KeyThatNeeds_1234Camel_CasIng != nil { + return *m.KeyThatNeeds_1234Camel_CasIng + } + return 0 +} + +func (m *Reply_Entry) GetValue() int64 { + if m != nil && m.Value != nil { + return *m.Value + } + return Default_Reply_Entry_Value +} + +func (m *Reply_Entry) GetXMyFieldName_2() int64 { + if m != nil && m.XMyFieldName_2 != nil { + return *m.XMyFieldName_2 + } + return 0 +} + +type OtherBase struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherBase) Reset() { *m = OtherBase{} } +func (m *OtherBase) String() string { return proto.CompactTextString(m) } +func (*OtherBase) ProtoMessage() {} + +var extRange_OtherBase = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*OtherBase) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OtherBase +} +func (m *OtherBase) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *OtherBase) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +type ReplyExtensions struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *ReplyExtensions) Reset() { *m = ReplyExtensions{} } +func (m *ReplyExtensions) String() string { return proto.CompactTextString(m) } +func (*ReplyExtensions) ProtoMessage() {} + +var E_ReplyExtensions_Time = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*float64)(nil), + Field: 101, + Name: "my.test.ReplyExtensions.time", + Tag: "fixed64,101,opt,name=time", +} + +var E_ReplyExtensions_Carrot = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 105, + Name: "my.test.ReplyExtensions.carrot", + Tag: "bytes,105,opt,name=carrot", +} + +var E_ReplyExtensions_Donut = &proto.ExtensionDesc{ + ExtendedType: (*OtherBase)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 101, + Name: "my.test.ReplyExtensions.donut", + Tag: "bytes,101,opt,name=donut", +} + +type OtherReplyExtensions struct { + Key *int32 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherReplyExtensions) Reset() { *m = OtherReplyExtensions{} } +func (m *OtherReplyExtensions) String() string { return proto.CompactTextString(m) } +func (*OtherReplyExtensions) ProtoMessage() {} + +func (m *OtherReplyExtensions) GetKey() int32 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + +type OldReply struct { + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldReply) Reset() { *m = OldReply{} } +func (m *OldReply) String() string { return proto.CompactTextString(m) } +func (*OldReply) ProtoMessage() {} + +func (m *OldReply) Marshal() ([]byte, error) { + return proto.MarshalMessageSet(m.ExtensionMap()) +} +func (m *OldReply) Unmarshal(buf []byte) error { + return proto.UnmarshalMessageSet(buf, m.ExtensionMap()) +} +func (m *OldReply) MarshalJSON() ([]byte, error) { + return proto.MarshalMessageSetJSON(m.XXX_extensions) +} +func (m *OldReply) UnmarshalJSON(buf []byte) error { + return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions) +} + +// ensure OldReply satisfies proto.Marshaler and proto.Unmarshaler +var _ proto.Marshaler = (*OldReply)(nil) +var _ proto.Unmarshaler = (*OldReply)(nil) + +var extRange_OldReply = []proto.ExtensionRange{ + {100, 2147483646}, +} + +func (*OldReply) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OldReply +} +func (m *OldReply) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +type Communique struct { + MakeMeCry *bool `protobuf:"varint,1,opt,name=make_me_cry" json:"make_me_cry,omitempty"` + // This is a oneof, called "union". + // + // Types that are valid to be assigned to Union: + // *Communique_Number + // *Communique_Name + // *Communique_Data + // *Communique_TempC + // *Communique_Height + // *Communique_Today + // *Communique_Maybe + // *Communique_Delta_ + // *Communique_Msg + // *Communique_Somegroup + Union isCommunique_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique) Reset() { *m = Communique{} } +func (m *Communique) String() string { return proto.CompactTextString(m) } +func (*Communique) ProtoMessage() {} + +type isCommunique_Union interface { + isCommunique_Union() +} + +type Communique_Number struct { + Number int32 `protobuf:"varint,5,opt,name=number,oneof"` +} +type Communique_Name struct { + Name string `protobuf:"bytes,6,opt,name=name,oneof"` +} +type Communique_Data struct { + Data []byte `protobuf:"bytes,7,opt,name=data,oneof"` +} +type Communique_TempC struct { + TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"` +} +type Communique_Height struct { + Height float32 `protobuf:"fixed32,9,opt,name=height,oneof"` +} +type Communique_Today struct { + Today Days `protobuf:"varint,10,opt,name=today,enum=my.test.Days,oneof"` +} +type Communique_Maybe struct { + Maybe bool `protobuf:"varint,11,opt,name=maybe,oneof"` +} +type Communique_Delta_ struct { + Delta int32 `protobuf:"zigzag32,12,opt,name=delta,oneof"` +} +type Communique_Msg struct { + Msg *Reply `protobuf:"bytes,13,opt,name=msg,oneof"` +} +type Communique_Somegroup struct { + Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup,oneof"` +} + +func (*Communique_Number) isCommunique_Union() {} +func (*Communique_Name) isCommunique_Union() {} +func (*Communique_Data) isCommunique_Union() {} +func (*Communique_TempC) isCommunique_Union() {} +func (*Communique_Height) isCommunique_Union() {} +func (*Communique_Today) isCommunique_Union() {} +func (*Communique_Maybe) isCommunique_Union() {} +func (*Communique_Delta_) isCommunique_Union() {} +func (*Communique_Msg) isCommunique_Union() {} +func (*Communique_Somegroup) isCommunique_Union() {} + +func (m *Communique) GetUnion() isCommunique_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *Communique) GetMakeMeCry() bool { + if m != nil && m.MakeMeCry != nil { + return *m.MakeMeCry + } + return false +} + +func (m *Communique) GetNumber() int32 { + if x, ok := m.GetUnion().(*Communique_Number); ok { + return x.Number + } + return 0 +} + +func (m *Communique) GetName() string { + if x, ok := m.GetUnion().(*Communique_Name); ok { + return x.Name + } + return "" +} + +func (m *Communique) GetData() []byte { + if x, ok := m.GetUnion().(*Communique_Data); ok { + return x.Data + } + return nil +} + +func (m *Communique) GetTempC() float64 { + if x, ok := m.GetUnion().(*Communique_TempC); ok { + return x.TempC + } + return 0 +} + +func (m *Communique) GetHeight() float32 { + if x, ok := m.GetUnion().(*Communique_Height); ok { + return x.Height + } + return 0 +} + +func (m *Communique) GetToday() Days { + if x, ok := m.GetUnion().(*Communique_Today); ok { + return x.Today + } + return Days_MONDAY +} + +func (m *Communique) GetMaybe() bool { + if x, ok := m.GetUnion().(*Communique_Maybe); ok { + return x.Maybe + } + return false +} + +func (m *Communique) GetDelta() int32 { + if x, ok := m.GetUnion().(*Communique_Delta_); ok { + return x.Delta + } + return 0 +} + +func (m *Communique) GetMsg() *Reply { + if x, ok := m.GetUnion().(*Communique_Msg); ok { + return x.Msg + } + return nil +} + +func (m *Communique) GetSomegroup() *Communique_SomeGroup { + if x, ok := m.GetUnion().(*Communique_Somegroup); ok { + return x.Somegroup + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Communique) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Communique_OneofMarshaler, _Communique_OneofUnmarshaler, _Communique_OneofSizer, []interface{}{ + (*Communique_Number)(nil), + (*Communique_Name)(nil), + (*Communique_Data)(nil), + (*Communique_TempC)(nil), + (*Communique_Height)(nil), + (*Communique_Today)(nil), + (*Communique_Maybe)(nil), + (*Communique_Delta_)(nil), + (*Communique_Msg)(nil), + (*Communique_Somegroup)(nil), + } +} + +func _Communique_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Communique) + // union + switch x := m.Union.(type) { + case *Communique_Number: + b.EncodeVarint(5<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Number)) + case *Communique_Name: + b.EncodeVarint(6<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Name) + case *Communique_Data: + b.EncodeVarint(7<<3 | proto.WireBytes) + b.EncodeRawBytes(x.Data) + case *Communique_TempC: + b.EncodeVarint(8<<3 | proto.WireFixed64) + b.EncodeFixed64(math.Float64bits(x.TempC)) + case *Communique_Height: + b.EncodeVarint(9<<3 | proto.WireFixed32) + b.EncodeFixed32(uint64(math.Float32bits(x.Height))) + case *Communique_Today: + b.EncodeVarint(10<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Today)) + case *Communique_Maybe: + t := uint64(0) + if x.Maybe { + t = 1 + } + b.EncodeVarint(11<<3 | proto.WireVarint) + b.EncodeVarint(t) + case *Communique_Delta_: + b.EncodeVarint(12<<3 | proto.WireVarint) + b.EncodeZigzag32(uint64(x.Delta)) + case *Communique_Msg: + b.EncodeVarint(13<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Msg); err != nil { + return err + } + case *Communique_Somegroup: + b.EncodeVarint(14<<3 | proto.WireStartGroup) + if err := b.Marshal(x.Somegroup); err != nil { + return err + } + b.EncodeVarint(14<<3 | proto.WireEndGroup) + case nil: + default: + return fmt.Errorf("Communique.Union has unexpected type %T", x) + } + return nil +} + +func _Communique_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Communique) + switch tag { + case 5: // union.number + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Number{int32(x)} + return true, err + case 6: // union.name + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Union = &Communique_Name{x} + return true, err + case 7: // union.data + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.Union = &Communique_Data{x} + return true, err + case 8: // union.temp_c + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Union = &Communique_TempC{math.Float64frombits(x)} + return true, err + case 9: // union.height + if wire != proto.WireFixed32 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed32() + m.Union = &Communique_Height{math.Float32frombits(uint32(x))} + return true, err + case 10: // union.today + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Today{Days(x)} + return true, err + case 11: // union.maybe + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Maybe{x != 0} + return true, err + case 12: // union.delta + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeZigzag32() + m.Union = &Communique_Delta_{int32(x)} + return true, err + case 13: // union.msg + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Reply) + err := b.DecodeMessage(msg) + m.Union = &Communique_Msg{msg} + return true, err + case 14: // union.somegroup + if wire != proto.WireStartGroup { + return true, proto.ErrInternalBadWireType + } + msg := new(Communique_SomeGroup) + err := b.DecodeGroup(msg) + m.Union = &Communique_Somegroup{msg} + return true, err + default: + return false, nil + } +} + +func _Communique_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Communique) + // union + switch x := m.Union.(type) { + case *Communique_Number: + n += proto.SizeVarint(5<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Number)) + case *Communique_Name: + n += proto.SizeVarint(6<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Name))) + n += len(x.Name) + case *Communique_Data: + n += proto.SizeVarint(7<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Data))) + n += len(x.Data) + case *Communique_TempC: + n += proto.SizeVarint(8<<3 | proto.WireFixed64) + n += 8 + case *Communique_Height: + n += proto.SizeVarint(9<<3 | proto.WireFixed32) + n += 4 + case *Communique_Today: + n += proto.SizeVarint(10<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Today)) + case *Communique_Maybe: + n += proto.SizeVarint(11<<3 | proto.WireVarint) + n += 1 + case *Communique_Delta_: + n += proto.SizeVarint(12<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64((uint32(x.Delta) << 1) ^ uint32((int32(x.Delta) >> 31)))) + case *Communique_Msg: + s := proto.Size(x.Msg) + n += proto.SizeVarint(13<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *Communique_Somegroup: + n += proto.SizeVarint(14<<3 | proto.WireStartGroup) + n += proto.Size(x.Somegroup) + n += proto.SizeVarint(14<<3 | proto.WireEndGroup) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +type Communique_SomeGroup struct { + Member *string `protobuf:"bytes,15,opt,name=member" json:"member,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique_SomeGroup) Reset() { *m = Communique_SomeGroup{} } +func (m *Communique_SomeGroup) String() string { return proto.CompactTextString(m) } +func (*Communique_SomeGroup) ProtoMessage() {} + +func (m *Communique_SomeGroup) GetMember() string { + if m != nil && m.Member != nil { + return *m.Member + } + return "" +} + +type Communique_Delta struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique_Delta) Reset() { *m = Communique_Delta{} } +func (m *Communique_Delta) String() string { return proto.CompactTextString(m) } +func (*Communique_Delta) ProtoMessage() {} + +var E_Tag = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*string)(nil), + Field: 103, + Name: "my.test.tag", + Tag: "bytes,103,opt,name=tag", +} + +var E_Donut = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*OtherReplyExtensions)(nil), + Field: 106, + Name: "my.test.donut", + Tag: "bytes,106,opt,name=donut", +} + +func init() { + proto.RegisterType((*Request)(nil), "my.test.Request") + proto.RegisterType((*Request_SomeGroup)(nil), "my.test.Request.SomeGroup") + proto.RegisterType((*Reply)(nil), "my.test.Reply") + proto.RegisterType((*Reply_Entry)(nil), "my.test.Reply.Entry") + proto.RegisterType((*OtherBase)(nil), "my.test.OtherBase") + proto.RegisterType((*ReplyExtensions)(nil), "my.test.ReplyExtensions") + proto.RegisterType((*OtherReplyExtensions)(nil), "my.test.OtherReplyExtensions") + proto.RegisterType((*OldReply)(nil), "my.test.OldReply") + proto.RegisterType((*Communique)(nil), "my.test.Communique") + proto.RegisterType((*Communique_SomeGroup)(nil), "my.test.Communique.SomeGroup") + proto.RegisterType((*Communique_Delta)(nil), "my.test.Communique.Delta") + proto.RegisterEnum("my.test.HatType", HatType_name, HatType_value) + proto.RegisterEnum("my.test.Days", Days_name, Days_value) + proto.RegisterEnum("my.test.Request_Color", Request_Color_name, Request_Color_value) + proto.RegisterEnum("my.test.Reply_Entry_Game", Reply_Entry_Game_name, Reply_Entry_Game_value) + proto.RegisterExtension(E_ReplyExtensions_Time) + proto.RegisterExtension(E_ReplyExtensions_Carrot) + proto.RegisterExtension(E_ReplyExtensions_Donut) + proto.RegisterExtension(E_Tag) + proto.RegisterExtension(E_Donut) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.pb.go.golden b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.pb.go.golden new file mode 100644 index 00000000..b0375f02 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.pb.go.golden @@ -0,0 +1,882 @@ +// Code generated by protoc-gen-go. +// source: my_test/test.proto +// DO NOT EDIT! + +/* +Package my_test is a generated protocol buffer package. + +This package holds interesting messages. + +It is generated from these files: + my_test/test.proto + +It has these top-level messages: + Request + Reply + OtherBase + ReplyExtensions + OtherReplyExtensions + OldReply + Communique +*/ +package my_test + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/golang/protobuf/protoc-gen-go/testdata/multi" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +const _ = proto.ProtoPackageIsVersion1 + +type HatType int32 + +const ( + // deliberately skipping 0 + HatType_FEDORA HatType = 1 + HatType_FEZ HatType = 2 +) + +var HatType_name = map[int32]string{ + 1: "FEDORA", + 2: "FEZ", +} +var HatType_value = map[string]int32{ + "FEDORA": 1, + "FEZ": 2, +} + +func (x HatType) Enum() *HatType { + p := new(HatType) + *p = x + return p +} +func (x HatType) String() string { + return proto.EnumName(HatType_name, int32(x)) +} +func (x *HatType) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(HatType_value, data, "HatType") + if err != nil { + return err + } + *x = HatType(value) + return nil +} + +// This enum represents days of the week. +type Days int32 + +const ( + Days_MONDAY Days = 1 + Days_TUESDAY Days = 2 + Days_LUNDI Days = 1 +) + +var Days_name = map[int32]string{ + 1: "MONDAY", + 2: "TUESDAY", + // Duplicate value: 1: "LUNDI", +} +var Days_value = map[string]int32{ + "MONDAY": 1, + "TUESDAY": 2, + "LUNDI": 1, +} + +func (x Days) Enum() *Days { + p := new(Days) + *p = x + return p +} +func (x Days) String() string { + return proto.EnumName(Days_name, int32(x)) +} +func (x *Days) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Days_value, data, "Days") + if err != nil { + return err + } + *x = Days(value) + return nil +} + +type Request_Color int32 + +const ( + Request_RED Request_Color = 0 + Request_GREEN Request_Color = 1 + Request_BLUE Request_Color = 2 +) + +var Request_Color_name = map[int32]string{ + 0: "RED", + 1: "GREEN", + 2: "BLUE", +} +var Request_Color_value = map[string]int32{ + "RED": 0, + "GREEN": 1, + "BLUE": 2, +} + +func (x Request_Color) Enum() *Request_Color { + p := new(Request_Color) + *p = x + return p +} +func (x Request_Color) String() string { + return proto.EnumName(Request_Color_name, int32(x)) +} +func (x *Request_Color) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Request_Color_value, data, "Request_Color") + if err != nil { + return err + } + *x = Request_Color(value) + return nil +} + +type Reply_Entry_Game int32 + +const ( + Reply_Entry_FOOTBALL Reply_Entry_Game = 1 + Reply_Entry_TENNIS Reply_Entry_Game = 2 +) + +var Reply_Entry_Game_name = map[int32]string{ + 1: "FOOTBALL", + 2: "TENNIS", +} +var Reply_Entry_Game_value = map[string]int32{ + "FOOTBALL": 1, + "TENNIS": 2, +} + +func (x Reply_Entry_Game) Enum() *Reply_Entry_Game { + p := new(Reply_Entry_Game) + *p = x + return p +} +func (x Reply_Entry_Game) String() string { + return proto.EnumName(Reply_Entry_Game_name, int32(x)) +} +func (x *Reply_Entry_Game) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(Reply_Entry_Game_value, data, "Reply_Entry_Game") + if err != nil { + return err + } + *x = Reply_Entry_Game(value) + return nil +} + +// This is a message that might be sent somewhere. +type Request struct { + Key []int64 `protobuf:"varint,1,rep,name=key" json:"key,omitempty"` + // optional imp.ImportedMessage imported_message = 2; + Hue *Request_Color `protobuf:"varint,3,opt,name=hue,enum=my.test.Request_Color" json:"hue,omitempty"` + Hat *HatType `protobuf:"varint,4,opt,name=hat,enum=my.test.HatType,def=1" json:"hat,omitempty"` + // optional imp.ImportedMessage.Owner owner = 6; + Deadline *float32 `protobuf:"fixed32,7,opt,name=deadline,def=inf" json:"deadline,omitempty"` + Somegroup *Request_SomeGroup `protobuf:"group,8,opt,name=SomeGroup" json:"somegroup,omitempty"` + // This is a map field. It will generate map[int32]string. + NameMapping map[int32]string `protobuf:"bytes,14,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // This is a map field whose value type is a message. + MsgMapping map[int64]*Reply `protobuf:"bytes,15,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Reset_ *int32 `protobuf:"varint,12,opt,name=reset" json:"reset,omitempty"` + // This field should not conflict with any getters. + GetKey_ *string `protobuf:"bytes,16,opt,name=get_key" json:"get_key,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Request) Reset() { *m = Request{} } +func (m *Request) String() string { return proto.CompactTextString(m) } +func (*Request) ProtoMessage() {} + +const Default_Request_Hat HatType = HatType_FEDORA + +var Default_Request_Deadline float32 = float32(math.Inf(1)) + +func (m *Request) GetKey() []int64 { + if m != nil { + return m.Key + } + return nil +} + +func (m *Request) GetHue() Request_Color { + if m != nil && m.Hue != nil { + return *m.Hue + } + return Request_RED +} + +func (m *Request) GetHat() HatType { + if m != nil && m.Hat != nil { + return *m.Hat + } + return Default_Request_Hat +} + +func (m *Request) GetDeadline() float32 { + if m != nil && m.Deadline != nil { + return *m.Deadline + } + return Default_Request_Deadline +} + +func (m *Request) GetSomegroup() *Request_SomeGroup { + if m != nil { + return m.Somegroup + } + return nil +} + +func (m *Request) GetNameMapping() map[int32]string { + if m != nil { + return m.NameMapping + } + return nil +} + +func (m *Request) GetMsgMapping() map[int64]*Reply { + if m != nil { + return m.MsgMapping + } + return nil +} + +func (m *Request) GetReset_() int32 { + if m != nil && m.Reset_ != nil { + return *m.Reset_ + } + return 0 +} + +func (m *Request) GetGetKey_() string { + if m != nil && m.GetKey_ != nil { + return *m.GetKey_ + } + return "" +} + +type Request_SomeGroup struct { + GroupField *int32 `protobuf:"varint,9,opt,name=group_field" json:"group_field,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Request_SomeGroup) Reset() { *m = Request_SomeGroup{} } +func (m *Request_SomeGroup) String() string { return proto.CompactTextString(m) } +func (*Request_SomeGroup) ProtoMessage() {} + +func (m *Request_SomeGroup) GetGroupField() int32 { + if m != nil && m.GroupField != nil { + return *m.GroupField + } + return 0 +} + +type Reply struct { + Found []*Reply_Entry `protobuf:"bytes,1,rep,name=found" json:"found,omitempty"` + CompactKeys []int32 `protobuf:"varint,2,rep,packed,name=compact_keys" json:"compact_keys,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Reply) Reset() { *m = Reply{} } +func (m *Reply) String() string { return proto.CompactTextString(m) } +func (*Reply) ProtoMessage() {} + +var extRange_Reply = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*Reply) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_Reply +} +func (m *Reply) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *Reply) GetFound() []*Reply_Entry { + if m != nil { + return m.Found + } + return nil +} + +func (m *Reply) GetCompactKeys() []int32 { + if m != nil { + return m.CompactKeys + } + return nil +} + +type Reply_Entry struct { + KeyThatNeeds_1234Camel_CasIng *int64 `protobuf:"varint,1,req,name=key_that_needs_1234camel_CasIng" json:"key_that_needs_1234camel_CasIng,omitempty"` + Value *int64 `protobuf:"varint,2,opt,name=value,def=7" json:"value,omitempty"` + XMyFieldName_2 *int64 `protobuf:"varint,3,opt,name=_my_field_name_2" json:"_my_field_name_2,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Reply_Entry) Reset() { *m = Reply_Entry{} } +func (m *Reply_Entry) String() string { return proto.CompactTextString(m) } +func (*Reply_Entry) ProtoMessage() {} + +const Default_Reply_Entry_Value int64 = 7 + +func (m *Reply_Entry) GetKeyThatNeeds_1234Camel_CasIng() int64 { + if m != nil && m.KeyThatNeeds_1234Camel_CasIng != nil { + return *m.KeyThatNeeds_1234Camel_CasIng + } + return 0 +} + +func (m *Reply_Entry) GetValue() int64 { + if m != nil && m.Value != nil { + return *m.Value + } + return Default_Reply_Entry_Value +} + +func (m *Reply_Entry) GetXMyFieldName_2() int64 { + if m != nil && m.XMyFieldName_2 != nil { + return *m.XMyFieldName_2 + } + return 0 +} + +type OtherBase struct { + Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherBase) Reset() { *m = OtherBase{} } +func (m *OtherBase) String() string { return proto.CompactTextString(m) } +func (*OtherBase) ProtoMessage() {} + +var extRange_OtherBase = []proto.ExtensionRange{ + {100, 536870911}, +} + +func (*OtherBase) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OtherBase +} +func (m *OtherBase) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +func (m *OtherBase) GetName() string { + if m != nil && m.Name != nil { + return *m.Name + } + return "" +} + +type ReplyExtensions struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *ReplyExtensions) Reset() { *m = ReplyExtensions{} } +func (m *ReplyExtensions) String() string { return proto.CompactTextString(m) } +func (*ReplyExtensions) ProtoMessage() {} + +var E_ReplyExtensions_Time = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*float64)(nil), + Field: 101, + Name: "my.test.ReplyExtensions.time", + Tag: "fixed64,101,opt,name=time", +} + +var E_ReplyExtensions_Carrot = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 105, + Name: "my.test.ReplyExtensions.carrot", + Tag: "bytes,105,opt,name=carrot", +} + +var E_ReplyExtensions_Donut = &proto.ExtensionDesc{ + ExtendedType: (*OtherBase)(nil), + ExtensionType: (*ReplyExtensions)(nil), + Field: 101, + Name: "my.test.ReplyExtensions.donut", + Tag: "bytes,101,opt,name=donut", +} + +type OtherReplyExtensions struct { + Key *int32 `protobuf:"varint,1,opt,name=key" json:"key,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OtherReplyExtensions) Reset() { *m = OtherReplyExtensions{} } +func (m *OtherReplyExtensions) String() string { return proto.CompactTextString(m) } +func (*OtherReplyExtensions) ProtoMessage() {} + +func (m *OtherReplyExtensions) GetKey() int32 { + if m != nil && m.Key != nil { + return *m.Key + } + return 0 +} + +type OldReply struct { + XXX_extensions map[int32]proto.Extension `json:"-"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *OldReply) Reset() { *m = OldReply{} } +func (m *OldReply) String() string { return proto.CompactTextString(m) } +func (*OldReply) ProtoMessage() {} + +func (m *OldReply) Marshal() ([]byte, error) { + return proto.MarshalMessageSet(m.ExtensionMap()) +} +func (m *OldReply) Unmarshal(buf []byte) error { + return proto.UnmarshalMessageSet(buf, m.ExtensionMap()) +} +func (m *OldReply) MarshalJSON() ([]byte, error) { + return proto.MarshalMessageSetJSON(m.XXX_extensions) +} +func (m *OldReply) UnmarshalJSON(buf []byte) error { + return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions) +} + +// ensure OldReply satisfies proto.Marshaler and proto.Unmarshaler +var _ proto.Marshaler = (*OldReply)(nil) +var _ proto.Unmarshaler = (*OldReply)(nil) + +var extRange_OldReply = []proto.ExtensionRange{ + {100, 2147483646}, +} + +func (*OldReply) ExtensionRangeArray() []proto.ExtensionRange { + return extRange_OldReply +} +func (m *OldReply) ExtensionMap() map[int32]proto.Extension { + if m.XXX_extensions == nil { + m.XXX_extensions = make(map[int32]proto.Extension) + } + return m.XXX_extensions +} + +type Communique struct { + MakeMeCry *bool `protobuf:"varint,1,opt,name=make_me_cry" json:"make_me_cry,omitempty"` + // This is a oneof, called "union". + // + // Types that are valid to be assigned to Union: + // *Communique_Number + // *Communique_Name + // *Communique_Data + // *Communique_TempC + // *Communique_Height + // *Communique_Today + // *Communique_Maybe + // *Communique_Delta_ + // *Communique_Msg + // *Communique_Somegroup + Union isCommunique_Union `protobuf_oneof:"union"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique) Reset() { *m = Communique{} } +func (m *Communique) String() string { return proto.CompactTextString(m) } +func (*Communique) ProtoMessage() {} + +type isCommunique_Union interface { + isCommunique_Union() +} + +type Communique_Number struct { + Number int32 `protobuf:"varint,5,opt,name=number,oneof"` +} +type Communique_Name struct { + Name string `protobuf:"bytes,6,opt,name=name,oneof"` +} +type Communique_Data struct { + Data []byte `protobuf:"bytes,7,opt,name=data,oneof"` +} +type Communique_TempC struct { + TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"` +} +type Communique_Height struct { + Height float32 `protobuf:"fixed32,9,opt,name=height,oneof"` +} +type Communique_Today struct { + Today Days `protobuf:"varint,10,opt,name=today,enum=my.test.Days,oneof"` +} +type Communique_Maybe struct { + Maybe bool `protobuf:"varint,11,opt,name=maybe,oneof"` +} +type Communique_Delta_ struct { + Delta int32 `protobuf:"zigzag32,12,opt,name=delta,oneof"` +} +type Communique_Msg struct { + Msg *Reply `protobuf:"bytes,13,opt,name=msg,oneof"` +} +type Communique_Somegroup struct { + Somegroup *Communique_SomeGroup `protobuf:"group,14,opt,name=SomeGroup,oneof"` +} + +func (*Communique_Number) isCommunique_Union() {} +func (*Communique_Name) isCommunique_Union() {} +func (*Communique_Data) isCommunique_Union() {} +func (*Communique_TempC) isCommunique_Union() {} +func (*Communique_Height) isCommunique_Union() {} +func (*Communique_Today) isCommunique_Union() {} +func (*Communique_Maybe) isCommunique_Union() {} +func (*Communique_Delta_) isCommunique_Union() {} +func (*Communique_Msg) isCommunique_Union() {} +func (*Communique_Somegroup) isCommunique_Union() {} + +func (m *Communique) GetUnion() isCommunique_Union { + if m != nil { + return m.Union + } + return nil +} + +func (m *Communique) GetMakeMeCry() bool { + if m != nil && m.MakeMeCry != nil { + return *m.MakeMeCry + } + return false +} + +func (m *Communique) GetNumber() int32 { + if x, ok := m.GetUnion().(*Communique_Number); ok { + return x.Number + } + return 0 +} + +func (m *Communique) GetName() string { + if x, ok := m.GetUnion().(*Communique_Name); ok { + return x.Name + } + return "" +} + +func (m *Communique) GetData() []byte { + if x, ok := m.GetUnion().(*Communique_Data); ok { + return x.Data + } + return nil +} + +func (m *Communique) GetTempC() float64 { + if x, ok := m.GetUnion().(*Communique_TempC); ok { + return x.TempC + } + return 0 +} + +func (m *Communique) GetHeight() float32 { + if x, ok := m.GetUnion().(*Communique_Height); ok { + return x.Height + } + return 0 +} + +func (m *Communique) GetToday() Days { + if x, ok := m.GetUnion().(*Communique_Today); ok { + return x.Today + } + return Days_MONDAY +} + +func (m *Communique) GetMaybe() bool { + if x, ok := m.GetUnion().(*Communique_Maybe); ok { + return x.Maybe + } + return false +} + +func (m *Communique) GetDelta() int32 { + if x, ok := m.GetUnion().(*Communique_Delta_); ok { + return x.Delta + } + return 0 +} + +func (m *Communique) GetMsg() *Reply { + if x, ok := m.GetUnion().(*Communique_Msg); ok { + return x.Msg + } + return nil +} + +func (m *Communique) GetSomegroup() *Communique_SomeGroup { + if x, ok := m.GetUnion().(*Communique_Somegroup); ok { + return x.Somegroup + } + return nil +} + +// XXX_OneofFuncs is for the internal use of the proto package. +func (*Communique) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { + return _Communique_OneofMarshaler, _Communique_OneofUnmarshaler, _Communique_OneofSizer, []interface{}{ + (*Communique_Number)(nil), + (*Communique_Name)(nil), + (*Communique_Data)(nil), + (*Communique_TempC)(nil), + (*Communique_Height)(nil), + (*Communique_Today)(nil), + (*Communique_Maybe)(nil), + (*Communique_Delta_)(nil), + (*Communique_Msg)(nil), + (*Communique_Somegroup)(nil), + } +} + +func _Communique_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { + m := msg.(*Communique) + // union + switch x := m.Union.(type) { + case *Communique_Number: + b.EncodeVarint(5<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Number)) + case *Communique_Name: + b.EncodeVarint(6<<3 | proto.WireBytes) + b.EncodeStringBytes(x.Name) + case *Communique_Data: + b.EncodeVarint(7<<3 | proto.WireBytes) + b.EncodeRawBytes(x.Data) + case *Communique_TempC: + b.EncodeVarint(8<<3 | proto.WireFixed64) + b.EncodeFixed64(math.Float64bits(x.TempC)) + case *Communique_Height: + b.EncodeVarint(9<<3 | proto.WireFixed32) + b.EncodeFixed32(uint64(math.Float32bits(x.Height))) + case *Communique_Today: + b.EncodeVarint(10<<3 | proto.WireVarint) + b.EncodeVarint(uint64(x.Today)) + case *Communique_Maybe: + t := uint64(0) + if x.Maybe { + t = 1 + } + b.EncodeVarint(11<<3 | proto.WireVarint) + b.EncodeVarint(t) + case *Communique_Delta_: + b.EncodeVarint(12<<3 | proto.WireVarint) + b.EncodeZigzag32(uint64(x.Delta)) + case *Communique_Msg: + b.EncodeVarint(13<<3 | proto.WireBytes) + if err := b.EncodeMessage(x.Msg); err != nil { + return err + } + case *Communique_Somegroup: + b.EncodeVarint(14<<3 | proto.WireStartGroup) + if err := b.Marshal(x.Somegroup); err != nil { + return err + } + b.EncodeVarint(14<<3 | proto.WireEndGroup) + case nil: + default: + return fmt.Errorf("Communique.Union has unexpected type %T", x) + } + return nil +} + +func _Communique_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { + m := msg.(*Communique) + switch tag { + case 5: // union.number + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Number{int32(x)} + return true, err + case 6: // union.name + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeStringBytes() + m.Union = &Communique_Name{x} + return true, err + case 7: // union.data + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeRawBytes(true) + m.Union = &Communique_Data{x} + return true, err + case 8: // union.temp_c + if wire != proto.WireFixed64 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed64() + m.Union = &Communique_TempC{math.Float64frombits(x)} + return true, err + case 9: // union.height + if wire != proto.WireFixed32 { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeFixed32() + m.Union = &Communique_Height{math.Float32frombits(uint32(x))} + return true, err + case 10: // union.today + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Today{Days(x)} + return true, err + case 11: // union.maybe + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeVarint() + m.Union = &Communique_Maybe{x != 0} + return true, err + case 12: // union.delta + if wire != proto.WireVarint { + return true, proto.ErrInternalBadWireType + } + x, err := b.DecodeZigzag32() + m.Union = &Communique_Delta_{int32(x)} + return true, err + case 13: // union.msg + if wire != proto.WireBytes { + return true, proto.ErrInternalBadWireType + } + msg := new(Reply) + err := b.DecodeMessage(msg) + m.Union = &Communique_Msg{msg} + return true, err + case 14: // union.somegroup + if wire != proto.WireStartGroup { + return true, proto.ErrInternalBadWireType + } + msg := new(Communique_SomeGroup) + err := b.DecodeGroup(msg) + m.Union = &Communique_Somegroup{msg} + return true, err + default: + return false, nil + } +} + +func _Communique_OneofSizer(msg proto.Message) (n int) { + m := msg.(*Communique) + // union + switch x := m.Union.(type) { + case *Communique_Number: + n += proto.SizeVarint(5<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Number)) + case *Communique_Name: + n += proto.SizeVarint(6<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Name))) + n += len(x.Name) + case *Communique_Data: + n += proto.SizeVarint(7<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(len(x.Data))) + n += len(x.Data) + case *Communique_TempC: + n += proto.SizeVarint(8<<3 | proto.WireFixed64) + n += 8 + case *Communique_Height: + n += proto.SizeVarint(9<<3 | proto.WireFixed32) + n += 4 + case *Communique_Today: + n += proto.SizeVarint(10<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64(x.Today)) + case *Communique_Maybe: + n += proto.SizeVarint(11<<3 | proto.WireVarint) + n += 1 + case *Communique_Delta_: + n += proto.SizeVarint(12<<3 | proto.WireVarint) + n += proto.SizeVarint(uint64((uint32(x.Delta) << 1) ^ uint32((int32(x.Delta) >> 31)))) + case *Communique_Msg: + s := proto.Size(x.Msg) + n += proto.SizeVarint(13<<3 | proto.WireBytes) + n += proto.SizeVarint(uint64(s)) + n += s + case *Communique_Somegroup: + n += proto.SizeVarint(14<<3 | proto.WireStartGroup) + n += proto.Size(x.Somegroup) + n += proto.SizeVarint(14<<3 | proto.WireEndGroup) + case nil: + default: + panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) + } + return n +} + +type Communique_SomeGroup struct { + Member *string `protobuf:"bytes,15,opt,name=member" json:"member,omitempty"` + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique_SomeGroup) Reset() { *m = Communique_SomeGroup{} } +func (m *Communique_SomeGroup) String() string { return proto.CompactTextString(m) } +func (*Communique_SomeGroup) ProtoMessage() {} + +func (m *Communique_SomeGroup) GetMember() string { + if m != nil && m.Member != nil { + return *m.Member + } + return "" +} + +type Communique_Delta struct { + XXX_unrecognized []byte `json:"-"` +} + +func (m *Communique_Delta) Reset() { *m = Communique_Delta{} } +func (m *Communique_Delta) String() string { return proto.CompactTextString(m) } +func (*Communique_Delta) ProtoMessage() {} + +var E_Tag = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*string)(nil), + Field: 103, + Name: "my.test.tag", + Tag: "bytes,103,opt,name=tag", +} + +var E_Donut = &proto.ExtensionDesc{ + ExtendedType: (*Reply)(nil), + ExtensionType: (*OtherReplyExtensions)(nil), + Field: 106, + Name: "my.test.donut", + Tag: "bytes,106,opt,name=donut", +} + +func init() { + proto.RegisterType((*Request)(nil), "my.test.Request") + proto.RegisterType((*Request_SomeGroup)(nil), "my.test.Request.SomeGroup") + proto.RegisterType((*Reply)(nil), "my.test.Reply") + proto.RegisterType((*Reply_Entry)(nil), "my.test.Reply.Entry") + proto.RegisterType((*OtherBase)(nil), "my.test.OtherBase") + proto.RegisterType((*ReplyExtensions)(nil), "my.test.ReplyExtensions") + proto.RegisterType((*OtherReplyExtensions)(nil), "my.test.OtherReplyExtensions") + proto.RegisterType((*OldReply)(nil), "my.test.OldReply") + proto.RegisterType((*Communique)(nil), "my.test.Communique") + proto.RegisterType((*Communique_SomeGroup)(nil), "my.test.Communique.SomeGroup") + proto.RegisterType((*Communique_Delta)(nil), "my.test.Communique.Delta") + proto.RegisterEnum("my.test.HatType", HatType_name, HatType_value) + proto.RegisterEnum("my.test.Days", Days_name, Days_value) + proto.RegisterEnum("my.test.Request_Color", Request_Color_name, Request_Color_value) + proto.RegisterEnum("my.test.Reply_Entry_Game", Reply_Entry_Game_name, Reply_Entry_Game_value) + proto.RegisterExtension(E_ReplyExtensions_Time) + proto.RegisterExtension(E_ReplyExtensions_Carrot) + proto.RegisterExtension(E_ReplyExtensions_Donut) + proto.RegisterExtension(E_Tag) + proto.RegisterExtension(E_Donut) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.proto new file mode 100644 index 00000000..8e709463 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/my_test/test.proto @@ -0,0 +1,156 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2010 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto2"; + +// This package holds interesting messages. +package my.test; // dotted package name + +//import "imp.proto"; +import "multi/multi1.proto"; // unused import + +enum HatType { + // deliberately skipping 0 + FEDORA = 1; + FEZ = 2; +} + +// This enum represents days of the week. +enum Days { + option allow_alias = true; + + MONDAY = 1; + TUESDAY = 2; + LUNDI = 1; // same value as MONDAY +} + +// This is a message that might be sent somewhere. +message Request { + enum Color { + RED = 0; + GREEN = 1; + BLUE = 2; + } + repeated int64 key = 1; +// optional imp.ImportedMessage imported_message = 2; + optional Color hue = 3; // no default + optional HatType hat = 4 [default=FEDORA]; +// optional imp.ImportedMessage.Owner owner = 6; + optional float deadline = 7 [default=inf]; + optional group SomeGroup = 8 { + optional int32 group_field = 9; + } + + // These foreign types are in imp2.proto, + // which is publicly imported by imp.proto. +// optional imp.PubliclyImportedMessage pub = 10; +// optional imp.PubliclyImportedEnum pub_enum = 13 [default=HAIR]; + + + // This is a map field. It will generate map[int32]string. + map name_mapping = 14; + // This is a map field whose value type is a message. + map msg_mapping = 15; + + optional int32 reset = 12; + // This field should not conflict with any getters. + optional string get_key = 16; +} + +message Reply { + message Entry { + required int64 key_that_needs_1234camel_CasIng = 1; + optional int64 value = 2 [default=7]; + optional int64 _my_field_name_2 = 3; + enum Game { + FOOTBALL = 1; + TENNIS = 2; + } + } + repeated Entry found = 1; + repeated int32 compact_keys = 2 [packed=true]; + extensions 100 to max; +} + +message OtherBase { + optional string name = 1; + extensions 100 to max; +} + +message ReplyExtensions { + extend Reply { + optional double time = 101; + optional ReplyExtensions carrot = 105; + } + extend OtherBase { + optional ReplyExtensions donut = 101; + } +} + +message OtherReplyExtensions { + optional int32 key = 1; +} + +// top-level extension +extend Reply { + optional string tag = 103; + optional OtherReplyExtensions donut = 106; +// optional imp.ImportedMessage elephant = 107; // extend with message from another file. +} + +message OldReply { + // Extensions will be encoded in MessageSet wire format. + option message_set_wire_format = true; + extensions 100 to max; +} + +message Communique { + optional bool make_me_cry = 1; + + // This is a oneof, called "union". + oneof union { + int32 number = 5; + string name = 6; + bytes data = 7; + double temp_c = 8; + float height = 9; + Days today = 10; + bool maybe = 11; + sint32 delta = 12; // name will conflict with Delta below + Reply msg = 13; + group SomeGroup = 14 { + optional string member = 15; + } + } + + message Delta {} +} + diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/proto3.proto b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/proto3.proto new file mode 100644 index 00000000..c994914e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/protobuf/protoc-gen-go/testdata/proto3.proto @@ -0,0 +1,52 @@ +// Go support for Protocol Buffers - Google's data interchange format +// +// Copyright 2014 The Go Authors. All rights reserved. +// https://github.com/golang/protobuf +// +// 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. + +syntax = "proto3"; + +package proto3; + +message Request { + enum Flavour { + SWEET = 0; + SOUR = 1; + UMAMI = 2; + GOPHERLICIOUS = 3; + } + string name = 1; + repeated int64 key = 2; + Flavour taste = 3; + Book book = 4; +} + +message Book { + string title = 1; + bytes raw_data = 2; +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/AUTHORS b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/AUTHORS similarity index 83% rename from src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/AUTHORS rename to src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/AUTHORS index 8ddb5b7a..824bf2e1 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/AUTHORS +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/AUTHORS @@ -8,5 +8,7 @@ # Please keep the list sorted. +Damian Gryski Google Inc. Jan Mercl <0xjnml@gmail.com> +Sebastien Binet diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/CONTRIBUTORS b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/CONTRIBUTORS similarity index 94% rename from src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/CONTRIBUTORS rename to src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/CONTRIBUTORS index 50b69c80..9f54f21f 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/CONTRIBUTORS +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/CONTRIBUTORS @@ -26,9 +26,11 @@ # Please keep the list sorted. +Damian Gryski Jan Mercl <0xjnml@gmail.com> Kai Backman Marc-Antoine Ruel Nigel Tao Rob Pike Russ Cox +Sebastien Binet diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/LICENSE similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/snappy-go/LICENSE rename to src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/LICENSE diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/README b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/README new file mode 100644 index 00000000..5074bbab --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/README @@ -0,0 +1,7 @@ +The Snappy compression format in the Go programming language. + +To download and install from source: +$ go get github.com/golang/snappy + +Unless otherwise noted, the Snappy-Go source files are distributed +under the BSD-style license found in the LICENSE file. diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/decode.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/decode.go new file mode 100644 index 00000000..e7f1259a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/decode.go @@ -0,0 +1,294 @@ +// Copyright 2011 The Snappy-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 snappy + +import ( + "encoding/binary" + "errors" + "io" +) + +var ( + // ErrCorrupt reports that the input is invalid. + ErrCorrupt = errors.New("snappy: corrupt input") + // ErrTooLarge reports that the uncompressed length is too large. + ErrTooLarge = errors.New("snappy: decoded block is too large") + // ErrUnsupported reports that the input isn't supported. + ErrUnsupported = errors.New("snappy: unsupported input") +) + +// DecodedLen returns the length of the decoded block. +func DecodedLen(src []byte) (int, error) { + v, _, err := decodedLen(src) + return v, err +} + +// decodedLen returns the length of the decoded block and the number of bytes +// that the length header occupied. +func decodedLen(src []byte) (blockLen, headerLen int, err error) { + v, n := binary.Uvarint(src) + if n <= 0 || v > 0xffffffff { + return 0, 0, ErrCorrupt + } + + const wordSize = 32 << (^uint(0) >> 32 & 1) + if wordSize == 32 && v > 0x7fffffff { + return 0, 0, ErrTooLarge + } + return int(v), n, nil +} + +// Decode returns the decoded form of src. The returned slice may be a sub- +// slice of dst if dst was large enough to hold the entire decoded block. +// Otherwise, a newly allocated slice will be returned. +// It is valid to pass a nil dst. +func Decode(dst, src []byte) ([]byte, error) { + dLen, s, err := decodedLen(src) + if err != nil { + return nil, err + } + if len(dst) < dLen { + dst = make([]byte, dLen) + } + + var d, offset, length int + for s < len(src) { + switch src[s] & 0x03 { + case tagLiteral: + x := uint(src[s] >> 2) + switch { + case x < 60: + s++ + case x == 60: + s += 2 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-1]) + case x == 61: + s += 3 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-2]) | uint(src[s-1])<<8 + case x == 62: + s += 4 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16 + case x == 63: + s += 5 + if s > len(src) { + return nil, ErrCorrupt + } + x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24 + } + length = int(x + 1) + if length <= 0 { + return nil, errors.New("snappy: unsupported literal length") + } + if length > len(dst)-d || length > len(src)-s { + return nil, ErrCorrupt + } + copy(dst[d:], src[s:s+length]) + d += length + s += length + continue + + case tagCopy1: + s += 2 + if s > len(src) { + return nil, ErrCorrupt + } + length = 4 + int(src[s-2])>>2&0x7 + offset = int(src[s-2])&0xe0<<3 | int(src[s-1]) + + case tagCopy2: + s += 3 + if s > len(src) { + return nil, ErrCorrupt + } + length = 1 + int(src[s-3])>>2 + offset = int(src[s-2]) | int(src[s-1])<<8 + + case tagCopy4: + return nil, errors.New("snappy: unsupported COPY_4 tag") + } + + end := d + length + if offset > d || end > len(dst) { + return nil, ErrCorrupt + } + for ; d < end; d++ { + dst[d] = dst[d-offset] + } + } + if d != dLen { + return nil, ErrCorrupt + } + return dst[:d], nil +} + +// NewReader returns a new Reader that decompresses from r, using the framing +// format described at +// https://github.com/google/snappy/blob/master/framing_format.txt +func NewReader(r io.Reader) *Reader { + return &Reader{ + r: r, + decoded: make([]byte, maxUncompressedChunkLen), + buf: make([]byte, MaxEncodedLen(maxUncompressedChunkLen)+checksumSize), + } +} + +// Reader is an io.Reader than can read Snappy-compressed bytes. +type Reader struct { + r io.Reader + err error + decoded []byte + buf []byte + // decoded[i:j] contains decoded bytes that have not yet been passed on. + i, j int + readHeader bool +} + +// Reset discards any buffered data, resets all state, and switches the Snappy +// reader to read from r. This permits reusing a Reader rather than allocating +// a new one. +func (r *Reader) Reset(reader io.Reader) { + r.r = reader + r.err = nil + r.i = 0 + r.j = 0 + r.readHeader = false +} + +func (r *Reader) readFull(p []byte) (ok bool) { + if _, r.err = io.ReadFull(r.r, p); r.err != nil { + if r.err == io.ErrUnexpectedEOF { + r.err = ErrCorrupt + } + return false + } + return true +} + +// Read satisfies the io.Reader interface. +func (r *Reader) Read(p []byte) (int, error) { + if r.err != nil { + return 0, r.err + } + for { + if r.i < r.j { + n := copy(p, r.decoded[r.i:r.j]) + r.i += n + return n, nil + } + if !r.readFull(r.buf[:4]) { + return 0, r.err + } + chunkType := r.buf[0] + if !r.readHeader { + if chunkType != chunkTypeStreamIdentifier { + r.err = ErrCorrupt + return 0, r.err + } + r.readHeader = true + } + chunkLen := int(r.buf[1]) | int(r.buf[2])<<8 | int(r.buf[3])<<16 + if chunkLen > len(r.buf) { + r.err = ErrUnsupported + return 0, r.err + } + + // The chunk types are specified at + // https://github.com/google/snappy/blob/master/framing_format.txt + switch chunkType { + case chunkTypeCompressedData: + // Section 4.2. Compressed data (chunk type 0x00). + if chunkLen < checksumSize { + r.err = ErrCorrupt + return 0, r.err + } + buf := r.buf[:chunkLen] + if !r.readFull(buf) { + return 0, r.err + } + checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24 + buf = buf[checksumSize:] + + n, err := DecodedLen(buf) + if err != nil { + r.err = err + return 0, r.err + } + if n > len(r.decoded) { + r.err = ErrCorrupt + return 0, r.err + } + if _, err := Decode(r.decoded, buf); err != nil { + r.err = err + return 0, r.err + } + if crc(r.decoded[:n]) != checksum { + r.err = ErrCorrupt + return 0, r.err + } + r.i, r.j = 0, n + continue + + case chunkTypeUncompressedData: + // Section 4.3. Uncompressed data (chunk type 0x01). + if chunkLen < checksumSize { + r.err = ErrCorrupt + return 0, r.err + } + buf := r.buf[:checksumSize] + if !r.readFull(buf) { + return 0, r.err + } + checksum := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2])<<16 | uint32(buf[3])<<24 + // Read directly into r.decoded instead of via r.buf. + n := chunkLen - checksumSize + if !r.readFull(r.decoded[:n]) { + return 0, r.err + } + if crc(r.decoded[:n]) != checksum { + r.err = ErrCorrupt + return 0, r.err + } + r.i, r.j = 0, n + continue + + case chunkTypeStreamIdentifier: + // Section 4.1. Stream identifier (chunk type 0xff). + if chunkLen != len(magicBody) { + r.err = ErrCorrupt + return 0, r.err + } + if !r.readFull(r.buf[:len(magicBody)]) { + return 0, r.err + } + for i := 0; i < len(magicBody); i++ { + if r.buf[i] != magicBody[i] { + r.err = ErrCorrupt + return 0, r.err + } + } + continue + } + + if chunkType <= 0x7f { + // Section 4.5. Reserved unskippable chunks (chunk types 0x02-0x7f). + r.err = ErrUnsupported + return 0, r.err + } + // Section 4.4 Padding (chunk type 0xfe). + // Section 4.6. Reserved skippable chunks (chunk types 0x80-0xfd). + if !r.readFull(r.buf[:chunkLen]) { + return 0, r.err + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/encode.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/encode.go similarity index 69% rename from src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/encode.go rename to src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/encode.go index b2371db1..f3b5484b 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/encode.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/encode.go @@ -6,6 +6,7 @@ package snappy import ( "encoding/binary" + "io" ) // We limit how far copy back-references can go, the same as the C++ code. @@ -78,7 +79,7 @@ func emitCopy(dst []byte, offset, length int) int { // slice of dst if dst was large enough to hold the entire encoded block. // Otherwise, a newly allocated slice will be returned. // It is valid to pass a nil dst. -func Encode(dst, src []byte) ([]byte, error) { +func Encode(dst, src []byte) []byte { if n := MaxEncodedLen(len(src)); len(dst) < n { dst = make([]byte, n) } @@ -91,7 +92,7 @@ func Encode(dst, src []byte) ([]byte, error) { if len(src) != 0 { d += emitLiteral(dst[d:], src) } - return dst[:d], nil + return dst[:d] } // Initialize the hash table. Its size ranges from 1<<8 to 1<<14 inclusive. @@ -144,7 +145,7 @@ func Encode(dst, src []byte) ([]byte, error) { if lit != len(src) { d += emitLiteral(dst[d:], src[lit:]) } - return dst[:d], nil + return dst[:d] } // MaxEncodedLen returns the maximum length of a snappy block, given its @@ -172,3 +173,82 @@ func MaxEncodedLen(srcLen int) int { // This last factor dominates the blowup, so the final estimate is: return 32 + srcLen + srcLen/6 } + +// NewWriter returns a new Writer that compresses to w, using the framing +// format described at +// https://github.com/google/snappy/blob/master/framing_format.txt +func NewWriter(w io.Writer) *Writer { + return &Writer{ + w: w, + enc: make([]byte, MaxEncodedLen(maxUncompressedChunkLen)), + } +} + +// Writer is an io.Writer than can write Snappy-compressed bytes. +type Writer struct { + w io.Writer + err error + enc []byte + buf [checksumSize + chunkHeaderSize]byte + wroteHeader bool +} + +// Reset discards the writer's state and switches the Snappy writer to write to +// w. This permits reusing a Writer rather than allocating a new one. +func (w *Writer) Reset(writer io.Writer) { + w.w = writer + w.err = nil + w.wroteHeader = false +} + +// Write satisfies the io.Writer interface. +func (w *Writer) Write(p []byte) (n int, errRet error) { + if w.err != nil { + return 0, w.err + } + if !w.wroteHeader { + copy(w.enc, magicChunk) + if _, err := w.w.Write(w.enc[:len(magicChunk)]); err != nil { + w.err = err + return n, err + } + w.wroteHeader = true + } + for len(p) > 0 { + var uncompressed []byte + if len(p) > maxUncompressedChunkLen { + uncompressed, p = p[:maxUncompressedChunkLen], p[maxUncompressedChunkLen:] + } else { + uncompressed, p = p, nil + } + checksum := crc(uncompressed) + + // Compress the buffer, discarding the result if the improvement + // isn't at least 12.5%. + chunkType := uint8(chunkTypeCompressedData) + chunkBody := Encode(w.enc, uncompressed) + if len(chunkBody) >= len(uncompressed)-len(uncompressed)/8 { + chunkType, chunkBody = chunkTypeUncompressedData, uncompressed + } + + chunkLen := 4 + len(chunkBody) + w.buf[0] = chunkType + w.buf[1] = uint8(chunkLen >> 0) + w.buf[2] = uint8(chunkLen >> 8) + w.buf[3] = uint8(chunkLen >> 16) + w.buf[4] = uint8(checksum >> 0) + w.buf[5] = uint8(checksum >> 8) + w.buf[6] = uint8(checksum >> 16) + w.buf[7] = uint8(checksum >> 24) + if _, err := w.w.Write(w.buf[:]); err != nil { + w.err = err + return n, err + } + if _, err := w.w.Write(chunkBody); err != nil { + w.err = err + return n, err + } + n += len(uncompressed) + } + return n, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/snappy.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/snappy.go similarity index 64% rename from src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/snappy.go rename to src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/snappy.go index 2f1b790d..15af18d0 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/snappy.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/snappy.go @@ -5,8 +5,12 @@ // Package snappy implements the snappy block-based compression format. // It aims for very high speeds and reasonable compression. // -// The C++ snappy implementation is at http://code.google.com/p/snappy/ -package snappy +// The C++ snappy implementation is at https://github.com/google/snappy +package snappy // import "github.com/golang/snappy" + +import ( + "hash/crc32" +) /* Each encoded block begins with the varint-encoded length of the decoded data, @@ -36,3 +40,29 @@ const ( tagCopy2 = 0x02 tagCopy4 = 0x03 ) + +const ( + checksumSize = 4 + chunkHeaderSize = 4 + magicChunk = "\xff\x06\x00\x00" + magicBody + magicBody = "sNaPpY" + // https://github.com/google/snappy/blob/master/framing_format.txt says + // that "the uncompressed data in a chunk must be no longer than 65536 bytes". + maxUncompressedChunkLen = 65536 +) + +const ( + chunkTypeCompressedData = 0x00 + chunkTypeUncompressedData = 0x01 + chunkTypePadding = 0xfe + chunkTypeStreamIdentifier = 0xff +) + +var crcTable = crc32.MakeTable(crc32.Castagnoli) + +// crc implements the checksum specified in section 3 of +// https://github.com/google/snappy/blob/master/framing_format.txt +func crc(b []byte) uint32 { + c := crc32.Update(0, crcTable, b) + return uint32(c>>15|c<<17) + 0xa282ead8 +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/snappy_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/snappy_test.go similarity index 52% rename from src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/snappy_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/snappy_test.go index 7ba83924..f8188f11 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/snappy_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/golang/snappy/snappy_test.go @@ -18,14 +18,13 @@ import ( "testing" ) -var download = flag.Bool("download", false, "If true, download any missing files before running benchmarks") +var ( + download = flag.Bool("download", false, "If true, download any missing files before running benchmarks") + testdata = flag.String("testdata", "testdata", "Directory containing the test data") +) func roundtrip(b, ebuf, dbuf []byte) error { - e, err := Encode(ebuf, b) - if err != nil { - return fmt.Errorf("encoding error: %v", err) - } - d, err := Decode(dbuf, e) + d, err := Decode(dbuf, Encode(ebuf, b)) if err != nil { return fmt.Errorf("decoding error: %v", err) } @@ -55,11 +54,11 @@ func TestSmallCopy(t *testing.T) { } func TestSmallRand(t *testing.T) { - rand.Seed(27354294) + rng := rand.New(rand.NewSource(27354294)) for n := 1; n < 20000; n += 23 { b := make([]byte, n) - for i, _ := range b { - b[i] = uint8(rand.Uint32()) + for i := range b { + b[i] = uint8(rng.Uint32()) } if err := roundtrip(b, nil, nil); err != nil { t.Fatal(err) @@ -70,7 +69,7 @@ func TestSmallRand(t *testing.T) { func TestSmallRegular(t *testing.T) { for n := 1; n < 20000; n += 23 { b := make([]byte, n) - for i, _ := range b { + for i := range b { b[i] = uint8(i%10 + 'a') } if err := roundtrip(b, nil, nil); err != nil { @@ -79,11 +78,142 @@ func TestSmallRegular(t *testing.T) { } } -func benchDecode(b *testing.B, src []byte) { - encoded, err := Encode(nil, src) - if err != nil { - b.Fatal(err) +func TestInvalidVarint(t *testing.T) { + data := []byte("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00") + if _, err := DecodedLen(data); err != ErrCorrupt { + t.Errorf("DecodedLen: got %v, want ErrCorrupt", err) } + if _, err := Decode(nil, data); err != ErrCorrupt { + t.Errorf("Decode: got %v, want ErrCorrupt", err) + } + + // The encoded varint overflows 32 bits + data = []byte("\xff\xff\xff\xff\xff\x00") + + if _, err := DecodedLen(data); err != ErrCorrupt { + t.Errorf("DecodedLen: got %v, want ErrCorrupt", err) + } + if _, err := Decode(nil, data); err != ErrCorrupt { + t.Errorf("Decode: got %v, want ErrCorrupt", err) + } +} + +func cmp(a, b []byte) error { + if len(a) != len(b) { + return fmt.Errorf("got %d bytes, want %d", len(a), len(b)) + } + for i := range a { + if a[i] != b[i] { + return fmt.Errorf("byte #%d: got 0x%02x, want 0x%02x", i, a[i], b[i]) + } + } + return nil +} + +func TestFramingFormat(t *testing.T) { + // src is comprised of alternating 1e5-sized sequences of random + // (incompressible) bytes and repeated (compressible) bytes. 1e5 was chosen + // because it is larger than maxUncompressedChunkLen (64k). + src := make([]byte, 1e6) + rng := rand.New(rand.NewSource(1)) + for i := 0; i < 10; i++ { + if i%2 == 0 { + for j := 0; j < 1e5; j++ { + src[1e5*i+j] = uint8(rng.Intn(256)) + } + } else { + for j := 0; j < 1e5; j++ { + src[1e5*i+j] = uint8(i) + } + } + } + + buf := new(bytes.Buffer) + if _, err := NewWriter(buf).Write(src); err != nil { + t.Fatalf("Write: encoding: %v", err) + } + dst, err := ioutil.ReadAll(NewReader(buf)) + if err != nil { + t.Fatalf("ReadAll: decoding: %v", err) + } + if err := cmp(dst, src); err != nil { + t.Fatal(err) + } +} + +func TestReaderReset(t *testing.T) { + gold := bytes.Repeat([]byte("All that is gold does not glitter,\n"), 10000) + buf := new(bytes.Buffer) + if _, err := NewWriter(buf).Write(gold); err != nil { + t.Fatalf("Write: %v", err) + } + encoded, invalid, partial := buf.String(), "invalid", "partial" + r := NewReader(nil) + for i, s := range []string{encoded, invalid, partial, encoded, partial, invalid, encoded, encoded} { + if s == partial { + r.Reset(strings.NewReader(encoded)) + if _, err := r.Read(make([]byte, 101)); err != nil { + t.Errorf("#%d: %v", i, err) + continue + } + continue + } + r.Reset(strings.NewReader(s)) + got, err := ioutil.ReadAll(r) + switch s { + case encoded: + if err != nil { + t.Errorf("#%d: %v", i, err) + continue + } + if err := cmp(got, gold); err != nil { + t.Errorf("#%d: %v", i, err) + continue + } + case invalid: + if err == nil { + t.Errorf("#%d: got nil error, want non-nil", i) + continue + } + } + } +} + +func TestWriterReset(t *testing.T) { + gold := bytes.Repeat([]byte("Not all those who wander are lost;\n"), 10000) + var gots, wants [][]byte + const n = 20 + w, failed := NewWriter(nil), false + for i := 0; i <= n; i++ { + buf := new(bytes.Buffer) + w.Reset(buf) + want := gold[:len(gold)*i/n] + if _, err := w.Write(want); err != nil { + t.Errorf("#%d: Write: %v", i, err) + failed = true + continue + } + got, err := ioutil.ReadAll(NewReader(buf)) + if err != nil { + t.Errorf("#%d: ReadAll: %v", i, err) + failed = true + continue + } + gots = append(gots, got) + wants = append(wants, want) + } + if failed { + return + } + for i := range gots { + if err := cmp(gots[i], wants[i]); err != nil { + t.Errorf("#%d: %v", i, err) + } + } +} + +func benchDecode(b *testing.B, src []byte) { + encoded := Encode(nil, src) // Bandwidth is in amount of uncompressed data. b.SetBytes(int64(len(src))) b.ResetTimer() @@ -102,10 +232,10 @@ func benchEncode(b *testing.B, src []byte) { } } -func readFile(b *testing.B, filename string) []byte { +func readFile(b testing.TB, filename string) []byte { src, err := ioutil.ReadFile(filename) if err != nil { - b.Fatalf("failed reading %s: %s", filename, err) + b.Skipf("skipping benchmark: %v", err) } if len(src) == 0 { b.Fatalf("%s has zero length", filename) @@ -144,7 +274,7 @@ func BenchmarkWordsEncode1e5(b *testing.B) { benchWords(b, 1e5, false) } func BenchmarkWordsEncode1e6(b *testing.B) { benchWords(b, 1e6, false) } // testFiles' values are copied directly from -// https://code.google.com/p/snappy/source/browse/trunk/snappy_unittest.cc. +// https://raw.githubusercontent.com/google/snappy/master/snappy_unittest.cc // The label field is unused in snappy-go. var testFiles = []struct { label string @@ -152,29 +282,36 @@ var testFiles = []struct { }{ {"html", "html"}, {"urls", "urls.10K"}, - {"jpg", "house.jpg"}, - {"pdf", "mapreduce-osdi-1.pdf"}, + {"jpg", "fireworks.jpeg"}, + {"jpg_200", "fireworks.jpeg"}, + {"pdf", "paper-100k.pdf"}, {"html4", "html_x_4"}, - {"cp", "cp.html"}, - {"c", "fields.c"}, - {"lsp", "grammar.lsp"}, - {"xls", "kennedy.xls"}, {"txt1", "alice29.txt"}, {"txt2", "asyoulik.txt"}, {"txt3", "lcet10.txt"}, {"txt4", "plrabn12.txt"}, - {"bin", "ptt5"}, - {"sum", "sum"}, - {"man", "xargs.1"}, {"pb", "geo.protodata"}, {"gaviota", "kppkn.gtb"}, } // The test data files are present at this canonical URL. -const baseURL = "https://snappy.googlecode.com/svn/trunk/testdata/" +const baseURL = "https://raw.githubusercontent.com/google/snappy/master/testdata/" + +func downloadTestdata(b *testing.B, basename string) (errRet error) { + filename := filepath.Join(*testdata, basename) + if stat, err := os.Stat(filename); err == nil && stat.Size() != 0 { + return nil + } + + if !*download { + b.Skipf("test data not found; skipping benchmark without the -download flag") + } + // Download the official snappy C++ implementation reference test data + // files for benchmarking. + if err := os.Mkdir(*testdata, 0777); err != nil && !os.IsExist(err) { + return fmt.Errorf("failed to create testdata: %s", err) + } -func downloadTestdata(basename string) (errRet error) { - filename := filepath.Join("testdata", basename) f, err := os.Create(filename) if err != nil { return fmt.Errorf("failed to create %s: %s", filename, err) @@ -185,36 +322,27 @@ func downloadTestdata(basename string) (errRet error) { os.Remove(filename) } }() - resp, err := http.Get(baseURL + basename) + url := baseURL + basename + resp, err := http.Get(url) if err != nil { - return fmt.Errorf("failed to download %s: %s", baseURL+basename, err) + return fmt.Errorf("failed to download %s: %s", url, err) } defer resp.Body.Close() + if s := resp.StatusCode; s != http.StatusOK { + return fmt.Errorf("downloading %s: HTTP status code %d (%s)", url, s, http.StatusText(s)) + } _, err = io.Copy(f, resp.Body) if err != nil { - return fmt.Errorf("failed to write %s: %s", filename, err) + return fmt.Errorf("failed to download %s to %s: %s", url, filename, err) } return nil } func benchFile(b *testing.B, n int, decode bool) { - filename := filepath.Join("testdata", testFiles[n].filename) - if stat, err := os.Stat(filename); err != nil || stat.Size() == 0 { - if !*download { - b.Fatal("test data not found; skipping benchmark without the -download flag") - } - // Download the official snappy C++ implementation reference test data - // files for benchmarking. - if err := os.Mkdir("testdata", 0777); err != nil && !os.IsExist(err) { - b.Fatalf("failed to create testdata: %s", err) - } - for _, tf := range testFiles { - if err := downloadTestdata(tf.filename); err != nil { - b.Fatalf("failed to download testdata: %s", err) - } - } + if err := downloadTestdata(b, testFiles[n].filename); err != nil { + b.Fatalf("failed to download testdata: %s", err) } - data := readFile(b, filename) + data := readFile(b, filepath.Join(*testdata, testFiles[n].filename)) if decode { benchDecode(b, data) } else { @@ -235,12 +363,6 @@ func Benchmark_UFlat8(b *testing.B) { benchFile(b, 8, true) } func Benchmark_UFlat9(b *testing.B) { benchFile(b, 9, true) } func Benchmark_UFlat10(b *testing.B) { benchFile(b, 10, true) } func Benchmark_UFlat11(b *testing.B) { benchFile(b, 11, true) } -func Benchmark_UFlat12(b *testing.B) { benchFile(b, 12, true) } -func Benchmark_UFlat13(b *testing.B) { benchFile(b, 13, true) } -func Benchmark_UFlat14(b *testing.B) { benchFile(b, 14, true) } -func Benchmark_UFlat15(b *testing.B) { benchFile(b, 15, true) } -func Benchmark_UFlat16(b *testing.B) { benchFile(b, 16, true) } -func Benchmark_UFlat17(b *testing.B) { benchFile(b, 17, true) } func Benchmark_ZFlat0(b *testing.B) { benchFile(b, 0, false) } func Benchmark_ZFlat1(b *testing.B) { benchFile(b, 1, false) } func Benchmark_ZFlat2(b *testing.B) { benchFile(b, 2, false) } @@ -253,9 +375,3 @@ func Benchmark_ZFlat8(b *testing.B) { benchFile(b, 8, false) } func Benchmark_ZFlat9(b *testing.B) { benchFile(b, 9, false) } func Benchmark_ZFlat10(b *testing.B) { benchFile(b, 10, false) } func Benchmark_ZFlat11(b *testing.B) { benchFile(b, 11, false) } -func Benchmark_ZFlat12(b *testing.B) { benchFile(b, 12, false) } -func Benchmark_ZFlat13(b *testing.B) { benchFile(b, 13, false) } -func Benchmark_ZFlat14(b *testing.B) { benchFile(b, 14, false) } -func Benchmark_ZFlat15(b *testing.B) { benchFile(b, 15, false) } -func Benchmark_ZFlat16(b *testing.B) { benchFile(b, 16, false) } -func Benchmark_ZFlat17(b *testing.B) { benchFile(b, 17, false) } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/.travis.yml b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/.travis.yml new file mode 100644 index 00000000..3d338331 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/.travis.yml @@ -0,0 +1,6 @@ +language: go +sudo: false +go: + - 1.3 + - 1.4 + - tip diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/LICENSE new file mode 100644 index 00000000..1ff7f370 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Manuel Martínez-Almeida + +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/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/README.md b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/README.md new file mode 100644 index 00000000..4e1cf0ec --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/README.md @@ -0,0 +1,54 @@ +#Server-Sent Events [![GoDoc](https://godoc.org/github.com/manucorporat/sse?status.svg)](https://godoc.org/github.com/manucorporat/sse) [![Build Status](https://travis-ci.org/manucorporat/sse.svg)](https://travis-ci.org/manucorporat/sse) + +Server-sent events (SSE) is a technology where a browser receives automatic updates from a server via HTTP connection. The Server-Sent Events EventSource API is [standardized as part of HTML5[1] by the W3C](http://www.w3.org/TR/2009/WD-eventsource-20091029/). + +- [Real world demostration using Gin](http://sse.getgin.io/) +- [Read this great SSE introduction by the HTML5Rocks guys](http://www.html5rocks.com/en/tutorials/eventsource/basics/) +- [Browser support](http://caniuse.com/#feat=eventsource) + +##Sample code + +```go +import "github.com/manucorporat/sse" + +func httpHandler(w http.ResponseWriter, req *http.Request) { + // data can be a primitive like a string, an integer or a float + sse.Encode(w, sse.Event{ + Event: "message", + Data: "some data\nmore data", + }) + + // also a complex type, like a map, a struct or a slice + sse.Encode(w, sse.Event{ + Id: "124", + Event: "message", + Data: map[string]interface{}{ + "user": "manu", + "date": time.Now().Unix(), + "content": "hi!", + }, + }) +} +``` +``` +event: message +data: some data\\nmore data + +id: 124 +event: message +data: {"content":"hi!","date":1431540810,"user":"manu"} + +``` + +##Content-Type + +```go +fmt.Println(sse.ContentType) +``` +``` +text/event-stream +``` + +##Decoding support + +There is a client-side implementation of SSE coming soon. \ No newline at end of file diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-decoder.go b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-decoder.go new file mode 100644 index 00000000..fd49b9c3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-decoder.go @@ -0,0 +1,116 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package sse + +import ( + "bytes" + "io" + "io/ioutil" +) + +type decoder struct { + events []Event +} + +func Decode(r io.Reader) ([]Event, error) { + var dec decoder + return dec.decode(r) +} + +func (d *decoder) dispatchEvent(event Event, data string) { + dataLength := len(data) + if dataLength > 0 { + //If the data buffer's last character is a U+000A LINE FEED (LF) character, then remove the last character from the data buffer. + data = data[:dataLength-1] + dataLength-- + } + if dataLength == 0 && event.Event == "" { + return + } + if event.Event == "" { + event.Event = "message" + } + event.Data = data + d.events = append(d.events, event) +} + +func (d *decoder) decode(r io.Reader) ([]Event, error) { + buf, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + + var currentEvent Event + var dataBuffer *bytes.Buffer = new(bytes.Buffer) + // TODO (and unit tests) + // Lines must be separated by either a U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pair, + // a single U+000A LINE FEED (LF) character, + // or a single U+000D CARRIAGE RETURN (CR) character. + lines := bytes.Split(buf, []byte{'\n'}) + for _, line := range lines { + if len(line) == 0 { + // If the line is empty (a blank line). Dispatch the event. + d.dispatchEvent(currentEvent, dataBuffer.String()) + + // reset current event and data buffer + currentEvent = Event{} + dataBuffer.Reset() + continue + } + if line[0] == byte(':') { + // If the line starts with a U+003A COLON character (:), ignore the line. + continue + } + + var field, value []byte + colonIndex := bytes.IndexRune(line, ':') + if colonIndex != -1 { + // If the line contains a U+003A COLON character character (:) + // Collect the characters on the line before the first U+003A COLON character (:), + // and let field be that string. + field = line[:colonIndex] + // Collect the characters on the line after the first U+003A COLON character (:), + // and let value be that string. + value = line[colonIndex+1:] + // If value starts with a single U+0020 SPACE character, remove it from value. + if len(value) > 0 && value[0] == ' ' { + value = value[1:] + } + } else { + // Otherwise, the string is not empty but does not contain a U+003A COLON character character (:) + // Use the whole line as the field name, and the empty string as the field value. + field = line + value = []byte{} + } + // The steps to process the field given a field name and a field value depend on the field name, + // as given in the following list. Field names must be compared literally, + // with no case folding performed. + switch string(field) { + case "event": + // Set the event name buffer to field value. + currentEvent.Event = string(value) + case "id": + // Set the event stream's last event ID to the field value. + currentEvent.Id = string(value) + case "retry": + // If the field value consists of only characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), + // then interpret the field value as an integer in base ten, and set the event stream's reconnection time to that integer. + // Otherwise, ignore the field. + currentEvent.Id = string(value) + case "data": + // Append the field value to the data buffer, + dataBuffer.Write(value) + // then append a single U+000A LINE FEED (LF) character to the data buffer. + dataBuffer.WriteString("\n") + default: + //Otherwise. The field is ignored. + continue + } + } + // Once the end of the file is reached, the user agent must dispatch the event one final time. + d.dispatchEvent(currentEvent, dataBuffer.String()) + + return d.events, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-decoder_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-decoder_test.go new file mode 100644 index 00000000..068107b6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-decoder_test.go @@ -0,0 +1,116 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package sse + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDecodeSingle1(t *testing.T) { + events, err := Decode(bytes.NewBufferString( + `data: this is a text +event: message +fake: +id: 123456789010 +: we can append data +: and multiple comments should not break it +data: a very nice one`)) + + assert.NoError(t, err) + assert.Len(t, events, 1) + assert.Equal(t, events[0].Event, "message") + assert.Equal(t, events[0].Id, "123456789010") +} + +func TestDecodeSingle2(t *testing.T) { + events, err := Decode(bytes.NewBufferString( + `: starting with a comment +fake: + +data:this is a \ntext +event:a message\n\n +fake +:and multiple comments\n should not break it\n\n +id:1234567890\n10 +:we can append data +data:a very nice one\n! + + +`)) + assert.NoError(t, err) + assert.Len(t, events, 1) + assert.Equal(t, events[0].Event, "a message\\n\\n") + assert.Equal(t, events[0].Id, "1234567890\\n10") +} + +func TestDecodeSingle3(t *testing.T) { + events, err := Decode(bytes.NewBufferString( + ` +id:123456ABCabc789010 +event: message123 +: we can append data +data:this is a text +data: a very nice one +data: +data +: ending with a comment`)) + + assert.NoError(t, err) + assert.Len(t, events, 1) + assert.Equal(t, events[0].Event, "message123") + assert.Equal(t, events[0].Id, "123456ABCabc789010") +} + +func TestDecodeMulti1(t *testing.T) { + events, err := Decode(bytes.NewBufferString( + ` +id: +event: weird event +data:this is a text +:data: this should NOT APER +data: second line + +: a comment +event: message +id:123 +data:this is a text +:data: this should NOT APER +data: second line + + +: a comment +event: message +id:123 +data:this is a text +data: second line + +:hola + +data + +event: + +id`)) + assert.NoError(t, err) + assert.Len(t, events, 3) + assert.Equal(t, events[0].Event, "weird event") + assert.Equal(t, events[0].Id, "") +} + +func TestDecodeW3C(t *testing.T) { + events, err := Decode(bytes.NewBufferString( + `data + +data +data + +data: +`)) + assert.NoError(t, err) + assert.Len(t, events, 1) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-encoder.go b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-encoder.go new file mode 100644 index 00000000..19a385ea --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse-encoder.go @@ -0,0 +1,106 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package sse + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "reflect" + "strconv" + "strings" +) + +// Server-Sent Events +// W3C Working Draft 29 October 2009 +// http://www.w3.org/TR/2009/WD-eventsource-20091029/ + +const ContentType = "text/event-stream" + +var contentType = []string{ContentType} +var noCache = []string{"no-cache"} + +var fieldReplacer = strings.NewReplacer( + "\n", "\\n", + "\r", "\\r") + +var dataReplacer = strings.NewReplacer( + "\n", "\ndata:", + "\r", "\\r") + +type Event struct { + Event string + Id string + Retry uint + Data interface{} +} + +func Encode(writer io.Writer, event Event) error { + w := checkWriter(writer) + writeId(w, event.Id) + writeEvent(w, event.Event) + writeRetry(w, event.Retry) + return writeData(w, event.Data) +} + +func writeId(w stringWriter, id string) { + if len(id) > 0 { + w.WriteString("id:") + fieldReplacer.WriteString(w, id) + w.WriteString("\n") + } +} + +func writeEvent(w stringWriter, event string) { + if len(event) > 0 { + w.WriteString("event:") + fieldReplacer.WriteString(w, event) + w.WriteString("\n") + } +} + +func writeRetry(w stringWriter, retry uint) { + if retry > 0 { + w.WriteString("retry:") + w.WriteString(strconv.FormatUint(uint64(retry), 10)) + w.WriteString("\n") + } +} + +func writeData(w stringWriter, data interface{}) error { + w.WriteString("data:") + switch kindOfData(data) { + case reflect.Struct, reflect.Slice, reflect.Map: + err := json.NewEncoder(w).Encode(data) + if err != nil { + return err + } + w.WriteString("\n") + default: + dataReplacer.WriteString(w, fmt.Sprint(data)) + w.WriteString("\n\n") + } + return nil +} + +func (r Event) Render(w http.ResponseWriter) error { + header := w.Header() + header["Content-Type"] = contentType + + if _, exist := header["Cache-Control"]; !exist { + header["Cache-Control"] = noCache + } + return Encode(w, r) +} + +func kindOfData(data interface{}) reflect.Kind { + value := reflect.ValueOf(data) + valueType := value.Kind() + if valueType == reflect.Ptr { + valueType = value.Elem().Kind() + } + return valueType +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse_test.go new file mode 100644 index 00000000..61b685b0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/sse_test.go @@ -0,0 +1,255 @@ +// Copyright 2014 Manu Martinez-Almeida. All rights reserved. +// Use of this source code is governed by a MIT style +// license that can be found in the LICENSE file. + +package sse + +import ( + "bytes" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestEncodeOnlyData(t *testing.T) { + w := new(bytes.Buffer) + event := Event{ + Data: "junk\n\njk\nid:fake", + } + err := Encode(w, event) + assert.NoError(t, err) + assert.Equal(t, w.String(), + `data:junk +data: +data:jk +data:id:fake + +`) + + decoded, _ := Decode(w) + assert.Equal(t, decoded, []Event{event}) +} + +func TestEncodeWithEvent(t *testing.T) { + w := new(bytes.Buffer) + event := Event{ + Event: "t\n:<>\r\test", + Data: "junk\n\njk\nid:fake", + } + err := Encode(w, event) + assert.NoError(t, err) + assert.Equal(t, w.String(), + `event:t\n:<>\r est +data:junk +data: +data:jk +data:id:fake + +`) + + decoded, _ := Decode(w) + assert.Equal(t, decoded, []Event{event}) +} + +func TestEncodeWithId(t *testing.T) { + w := new(bytes.Buffer) + err := Encode(w, Event{ + Id: "t\n:<>\r\test", + Data: "junk\n\njk\nid:fa\rke", + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), + `id:t\n:<>\r est +data:junk +data: +data:jk +data:id:fa\rke + +`) +} + +func TestEncodeWithRetry(t *testing.T) { + w := new(bytes.Buffer) + err := Encode(w, Event{ + Retry: 11, + Data: "junk\n\njk\nid:fake\n", + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), + `retry:11 +data:junk +data: +data:jk +data:id:fake +data: + +`) +} + +func TestEncodeWithEverything(t *testing.T) { + w := new(bytes.Buffer) + err := Encode(w, Event{ + Event: "abc", + Id: "12345", + Retry: 10, + Data: "some data", + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), "id:12345\nevent:abc\nretry:10\ndata:some data\n\n") +} + +func TestEncodeMap(t *testing.T) { + w := new(bytes.Buffer) + err := Encode(w, Event{ + Event: "a map", + Data: map[string]interface{}{ + "foo": "b\n\rar", + "bar": "id: 2", + }, + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), "event:a map\ndata:{\"bar\":\"id: 2\",\"foo\":\"b\\n\\rar\"}\n\n") +} + +func TestEncodeSlice(t *testing.T) { + w := new(bytes.Buffer) + err := Encode(w, Event{ + Event: "a slice", + Data: []interface{}{1, "text", map[string]interface{}{"foo": "bar"}}, + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), "event:a slice\ndata:[1,\"text\",{\"foo\":\"bar\"}]\n\n") +} + +func TestEncodeStruct(t *testing.T) { + myStruct := struct { + A int + B string `json:"value"` + }{1, "number"} + + w := new(bytes.Buffer) + err := Encode(w, Event{ + Event: "a struct", + Data: myStruct, + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), "event:a struct\ndata:{\"A\":1,\"value\":\"number\"}\n\n") + + w.Reset() + err = Encode(w, Event{ + Event: "a struct", + Data: &myStruct, + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), "event:a struct\ndata:{\"A\":1,\"value\":\"number\"}\n\n") +} + +func TestEncodeInteger(t *testing.T) { + w := new(bytes.Buffer) + err := Encode(w, Event{ + Event: "an integer", + Data: 1, + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), "event:an integer\ndata:1\n\n") +} + +func TestEncodeFloat(t *testing.T) { + w := new(bytes.Buffer) + err := Encode(w, Event{ + Event: "Float", + Data: 1.5, + }) + assert.NoError(t, err) + assert.Equal(t, w.String(), "event:Float\ndata:1.5\n\n") +} + +func TestEncodeStream(t *testing.T) { + w := new(bytes.Buffer) + + Encode(w, Event{ + Event: "float", + Data: 1.5, + }) + + Encode(w, Event{ + Id: "123", + Data: map[string]interface{}{"foo": "bar", "bar": "foo"}, + }) + + Encode(w, Event{ + Id: "124", + Event: "chat", + Data: "hi! dude", + }) + assert.Equal(t, w.String(), "event:float\ndata:1.5\n\nid:123\ndata:{\"bar\":\"foo\",\"foo\":\"bar\"}\n\nid:124\nevent:chat\ndata:hi! dude\n\n") +} + +func TestRenderSSE(t *testing.T) { + w := httptest.NewRecorder() + + err := (Event{ + Event: "msg", + Data: "hi! how are you?", + }).Render(w) + + assert.NoError(t, err) + assert.Equal(t, w.Body.String(), "event:msg\ndata:hi! how are you?\n\n") + assert.Equal(t, w.Header().Get("Content-Type"), "text/event-stream") + assert.Equal(t, w.Header().Get("Cache-Control"), "no-cache") +} + +func BenchmarkResponseWriter(b *testing.B) { + w := httptest.NewRecorder() + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + (Event{ + Event: "new_message", + Data: "hi! how are you? I am fine. this is a long stupid message!!!", + }).Render(w) + } +} + +func BenchmarkFullSSE(b *testing.B) { + buf := new(bytes.Buffer) + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + Encode(buf, Event{ + Event: "new_message", + Id: "13435", + Retry: 10, + Data: "hi! how are you? I am fine. this is a long stupid message!!!", + }) + buf.Reset() + } +} + +func BenchmarkNoRetrySSE(b *testing.B) { + buf := new(bytes.Buffer) + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + Encode(buf, Event{ + Event: "new_message", + Id: "13435", + Data: "hi! how are you? I am fine. this is a long stupid message!!!", + }) + buf.Reset() + } +} + +func BenchmarkSimpleSSE(b *testing.B) { + buf := new(bytes.Buffer) + b.ResetTimer() + b.ReportAllocs() + for i := 0; i < b.N; i++ { + Encode(buf, Event{ + Event: "new_message", + Data: "hi! how are you? I am fine. this is a long stupid message!!!", + }) + buf.Reset() + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/writer.go b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/writer.go new file mode 100644 index 00000000..6f9806c5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/manucorporat/sse/writer.go @@ -0,0 +1,24 @@ +package sse + +import "io" + +type stringWriter interface { + io.Writer + WriteString(string) (int, error) +} + +type stringWrapper struct { + io.Writer +} + +func (w stringWrapper) WriteString(str string) (int, error) { + return w.Writer.Write([]byte(str)) +} + +func checkWriter(writer io.Writer) stringWriter { + if w, ok := writer.(stringWriter); ok { + return w + } else { + return stringWrapper{writer} + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/README.md b/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/README.md deleted file mode 100644 index c69da4a7..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# go-colorable - -Colorable writer for windows. - -For example, most of logger packages doesn't show colors on windows. (I know we can do it with ansicon. But I don't want.) -This package is possible to handle escape sequence for ansi color on windows. - -## Too Bad! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/bad.png) - - -## So Good! - -![](https://raw.githubusercontent.com/mattn/go-colorable/gh-pages/good.png) - -## Usage - -```go -logrus.SetOutput(colorable.NewColorableStdout()) - -logrus.Info("succeeded") -logrus.Warn("not correct") -logrus.Error("something error") -logrus.Fatal("panic") -``` - -You can compile above code on non-windows OSs. - -## Installation - -``` -$ go get github.com/mattn/go-colorable -``` - -# License - -MIT - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/_example/main.go b/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/_example/main.go deleted file mode 100644 index f4115046..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/_example/main.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "github.com/mattn/go-colorable" - "github.com/Sirupsen/logrus" -) - -func main() { - logrus.SetOutput(colorable.NewColorableStdout()) - - logrus.Info("succeeded") - logrus.Warn("not correct") - logrus.Error("something error") - logrus.Fatal("panic") -} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/colorable_others.go b/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/colorable_others.go deleted file mode 100644 index 219f02f6..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/colorable_others.go +++ /dev/null @@ -1,16 +0,0 @@ -// +build !windows - -package colorable - -import ( - "io" - "os" -) - -func NewColorableStdout() io.Writer { - return os.Stdout -} - -func NewColorableStderr() io.Writer { - return os.Stderr -} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/colorable_windows.go b/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/colorable_windows.go deleted file mode 100644 index 6a278780..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mattn/go-colorable/colorable_windows.go +++ /dev/null @@ -1,594 +0,0 @@ -package colorable - -import ( - "bytes" - "fmt" - "io" - "os" - "strconv" - "strings" - "syscall" - "unsafe" - - "github.com/mattn/go-isatty" -) - -const ( - foregroundBlue = 0x1 - foregroundGreen = 0x2 - foregroundRed = 0x4 - foregroundIntensity = 0x8 - foregroundMask = (foregroundRed | foregroundBlue | foregroundGreen | foregroundIntensity) - backgroundBlue = 0x10 - backgroundGreen = 0x20 - backgroundRed = 0x40 - backgroundIntensity = 0x80 - backgroundMask = (backgroundRed | backgroundBlue | backgroundGreen | backgroundIntensity) -) - -type wchar uint16 -type short int16 -type dword uint32 -type word uint16 - -type coord struct { - x short - y short -} - -type smallRect struct { - left short - top short - right short - bottom short -} - -type consoleScreenBufferInfo struct { - size coord - cursorPosition coord - attributes word - window smallRect - maximumWindowSize coord -} - -var ( - kernel32 = syscall.NewLazyDLL("kernel32.dll") - procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo") - procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute") -) - -type Writer struct { - out io.Writer - handle syscall.Handle - lastbuf bytes.Buffer - oldattr word -} - -func NewColorableStdout() io.Writer { - var csbi consoleScreenBufferInfo - out := os.Stdout - if !isatty.IsTerminal(out.Fd()) { - return out - } - handle := syscall.Handle(out.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &Writer{out: out, handle: handle, oldattr: csbi.attributes} -} - -func NewColorableStderr() io.Writer { - var csbi consoleScreenBufferInfo - out := os.Stderr - if !isatty.IsTerminal(out.Fd()) { - return out - } - handle := syscall.Handle(out.Fd()) - procGetConsoleScreenBufferInfo.Call(uintptr(handle), uintptr(unsafe.Pointer(&csbi))) - return &Writer{out: out, handle: handle, oldattr: csbi.attributes} -} - -var color256 = map[int]int{ - 0: 0x000000, - 1: 0x800000, - 2: 0x008000, - 3: 0x808000, - 4: 0x000080, - 5: 0x800080, - 6: 0x008080, - 7: 0xc0c0c0, - 8: 0x808080, - 9: 0xff0000, - 10: 0x00ff00, - 11: 0xffff00, - 12: 0x0000ff, - 13: 0xff00ff, - 14: 0x00ffff, - 15: 0xffffff, - 16: 0x000000, - 17: 0x00005f, - 18: 0x000087, - 19: 0x0000af, - 20: 0x0000d7, - 21: 0x0000ff, - 22: 0x005f00, - 23: 0x005f5f, - 24: 0x005f87, - 25: 0x005faf, - 26: 0x005fd7, - 27: 0x005fff, - 28: 0x008700, - 29: 0x00875f, - 30: 0x008787, - 31: 0x0087af, - 32: 0x0087d7, - 33: 0x0087ff, - 34: 0x00af00, - 35: 0x00af5f, - 36: 0x00af87, - 37: 0x00afaf, - 38: 0x00afd7, - 39: 0x00afff, - 40: 0x00d700, - 41: 0x00d75f, - 42: 0x00d787, - 43: 0x00d7af, - 44: 0x00d7d7, - 45: 0x00d7ff, - 46: 0x00ff00, - 47: 0x00ff5f, - 48: 0x00ff87, - 49: 0x00ffaf, - 50: 0x00ffd7, - 51: 0x00ffff, - 52: 0x5f0000, - 53: 0x5f005f, - 54: 0x5f0087, - 55: 0x5f00af, - 56: 0x5f00d7, - 57: 0x5f00ff, - 58: 0x5f5f00, - 59: 0x5f5f5f, - 60: 0x5f5f87, - 61: 0x5f5faf, - 62: 0x5f5fd7, - 63: 0x5f5fff, - 64: 0x5f8700, - 65: 0x5f875f, - 66: 0x5f8787, - 67: 0x5f87af, - 68: 0x5f87d7, - 69: 0x5f87ff, - 70: 0x5faf00, - 71: 0x5faf5f, - 72: 0x5faf87, - 73: 0x5fafaf, - 74: 0x5fafd7, - 75: 0x5fafff, - 76: 0x5fd700, - 77: 0x5fd75f, - 78: 0x5fd787, - 79: 0x5fd7af, - 80: 0x5fd7d7, - 81: 0x5fd7ff, - 82: 0x5fff00, - 83: 0x5fff5f, - 84: 0x5fff87, - 85: 0x5fffaf, - 86: 0x5fffd7, - 87: 0x5fffff, - 88: 0x870000, - 89: 0x87005f, - 90: 0x870087, - 91: 0x8700af, - 92: 0x8700d7, - 93: 0x8700ff, - 94: 0x875f00, - 95: 0x875f5f, - 96: 0x875f87, - 97: 0x875faf, - 98: 0x875fd7, - 99: 0x875fff, - 100: 0x878700, - 101: 0x87875f, - 102: 0x878787, - 103: 0x8787af, - 104: 0x8787d7, - 105: 0x8787ff, - 106: 0x87af00, - 107: 0x87af5f, - 108: 0x87af87, - 109: 0x87afaf, - 110: 0x87afd7, - 111: 0x87afff, - 112: 0x87d700, - 113: 0x87d75f, - 114: 0x87d787, - 115: 0x87d7af, - 116: 0x87d7d7, - 117: 0x87d7ff, - 118: 0x87ff00, - 119: 0x87ff5f, - 120: 0x87ff87, - 121: 0x87ffaf, - 122: 0x87ffd7, - 123: 0x87ffff, - 124: 0xaf0000, - 125: 0xaf005f, - 126: 0xaf0087, - 127: 0xaf00af, - 128: 0xaf00d7, - 129: 0xaf00ff, - 130: 0xaf5f00, - 131: 0xaf5f5f, - 132: 0xaf5f87, - 133: 0xaf5faf, - 134: 0xaf5fd7, - 135: 0xaf5fff, - 136: 0xaf8700, - 137: 0xaf875f, - 138: 0xaf8787, - 139: 0xaf87af, - 140: 0xaf87d7, - 141: 0xaf87ff, - 142: 0xafaf00, - 143: 0xafaf5f, - 144: 0xafaf87, - 145: 0xafafaf, - 146: 0xafafd7, - 147: 0xafafff, - 148: 0xafd700, - 149: 0xafd75f, - 150: 0xafd787, - 151: 0xafd7af, - 152: 0xafd7d7, - 153: 0xafd7ff, - 154: 0xafff00, - 155: 0xafff5f, - 156: 0xafff87, - 157: 0xafffaf, - 158: 0xafffd7, - 159: 0xafffff, - 160: 0xd70000, - 161: 0xd7005f, - 162: 0xd70087, - 163: 0xd700af, - 164: 0xd700d7, - 165: 0xd700ff, - 166: 0xd75f00, - 167: 0xd75f5f, - 168: 0xd75f87, - 169: 0xd75faf, - 170: 0xd75fd7, - 171: 0xd75fff, - 172: 0xd78700, - 173: 0xd7875f, - 174: 0xd78787, - 175: 0xd787af, - 176: 0xd787d7, - 177: 0xd787ff, - 178: 0xd7af00, - 179: 0xd7af5f, - 180: 0xd7af87, - 181: 0xd7afaf, - 182: 0xd7afd7, - 183: 0xd7afff, - 184: 0xd7d700, - 185: 0xd7d75f, - 186: 0xd7d787, - 187: 0xd7d7af, - 188: 0xd7d7d7, - 189: 0xd7d7ff, - 190: 0xd7ff00, - 191: 0xd7ff5f, - 192: 0xd7ff87, - 193: 0xd7ffaf, - 194: 0xd7ffd7, - 195: 0xd7ffff, - 196: 0xff0000, - 197: 0xff005f, - 198: 0xff0087, - 199: 0xff00af, - 200: 0xff00d7, - 201: 0xff00ff, - 202: 0xff5f00, - 203: 0xff5f5f, - 204: 0xff5f87, - 205: 0xff5faf, - 206: 0xff5fd7, - 207: 0xff5fff, - 208: 0xff8700, - 209: 0xff875f, - 210: 0xff8787, - 211: 0xff87af, - 212: 0xff87d7, - 213: 0xff87ff, - 214: 0xffaf00, - 215: 0xffaf5f, - 216: 0xffaf87, - 217: 0xffafaf, - 218: 0xffafd7, - 219: 0xffafff, - 220: 0xffd700, - 221: 0xffd75f, - 222: 0xffd787, - 223: 0xffd7af, - 224: 0xffd7d7, - 225: 0xffd7ff, - 226: 0xffff00, - 227: 0xffff5f, - 228: 0xffff87, - 229: 0xffffaf, - 230: 0xffffd7, - 231: 0xffffff, - 232: 0x080808, - 233: 0x121212, - 234: 0x1c1c1c, - 235: 0x262626, - 236: 0x303030, - 237: 0x3a3a3a, - 238: 0x444444, - 239: 0x4e4e4e, - 240: 0x585858, - 241: 0x626262, - 242: 0x6c6c6c, - 243: 0x767676, - 244: 0x808080, - 245: 0x8a8a8a, - 246: 0x949494, - 247: 0x9e9e9e, - 248: 0xa8a8a8, - 249: 0xb2b2b2, - 250: 0xbcbcbc, - 251: 0xc6c6c6, - 252: 0xd0d0d0, - 253: 0xdadada, - 254: 0xe4e4e4, - 255: 0xeeeeee, -} - -func (w *Writer) Write(data []byte) (n int, err error) { - var csbi consoleScreenBufferInfo - procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - - er := bytes.NewBuffer(data) -loop: - for { - r1, _, err := procGetConsoleScreenBufferInfo.Call(uintptr(w.handle), uintptr(unsafe.Pointer(&csbi))) - if r1 == 0 { - break loop - } - - c1, _, err := er.ReadRune() - if err != nil { - break loop - } - if c1 != 0x1b { - fmt.Fprint(w.out, string(c1)) - continue - } - c2, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - break loop - } - if c2 != 0x5b { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - continue - } - - var buf bytes.Buffer - var m rune - for { - c, _, err := er.ReadRune() - if err != nil { - w.lastbuf.WriteRune(c1) - w.lastbuf.WriteRune(c2) - w.lastbuf.Write(buf.Bytes()) - break loop - } - if ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || c == '@' { - m = c - break - } - buf.Write([]byte(string(c))) - } - - switch m { - case 'm': - attr := csbi.attributes - cs := buf.String() - if cs == "" { - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(w.oldattr)) - continue - } - token := strings.Split(cs, ";") - for i, ns := range token { - if n, err = strconv.Atoi(ns); err == nil { - switch { - case n == 0 || n == 100: - attr = w.oldattr - case 1 <= n && n <= 5: - attr |= foregroundIntensity - case n == 7: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 22 == n || n == 25 || n == 25: - attr |= foregroundIntensity - case n == 27: - attr = ((attr & foregroundMask) << 4) | ((attr & backgroundMask) >> 4) - case 30 <= n && n <= 37: - attr = (attr & backgroundMask) - if (n-30)&1 != 0 { - attr |= foregroundRed - } - if (n-30)&2 != 0 { - attr |= foregroundGreen - } - if (n-30)&4 != 0 { - attr |= foregroundBlue - } - case n == 38: // set foreground color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256foreAttr == nil { - n256setup() - } - attr &= backgroundMask - attr |= n256foreAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & backgroundMask) - } - case n == 39: // reset foreground color. - attr &= backgroundMask - attr |= w.oldattr & foregroundMask - case 40 <= n && n <= 47: - attr = (attr & foregroundMask) - if (n-40)&1 != 0 { - attr |= backgroundRed - } - if (n-40)&2 != 0 { - attr |= backgroundGreen - } - if (n-40)&4 != 0 { - attr |= backgroundBlue - } - case n == 48: // set background color. - if i < len(token)-2 && token[i+1] == "5" { - if n256, err := strconv.Atoi(token[i+2]); err == nil { - if n256backAttr == nil { - n256setup() - } - attr &= foregroundMask - attr |= n256backAttr[n256] - i += 2 - } - } else { - attr = attr & (w.oldattr & foregroundMask) - } - case n == 49: // reset foreground color. - attr &= foregroundMask - attr |= w.oldattr & backgroundMask - } - procSetConsoleTextAttribute.Call(uintptr(w.handle), uintptr(attr)) - } - } - } - } - return len(data) - w.lastbuf.Len(), nil -} - -type consoleColor struct { - red bool - green bool - blue bool - intensity bool -} - -func minmax3(a, b, c int) (min, max int) { - if a < b { - if b < c { - return a, c - } else if a < c { - return a, b - } else { - return c, b - } - } else { - if a < c { - return b, c - } else if b < c { - return b, a - } else { - return c, a - } - } -} - -func toConsoleColor(rgb int) (c consoleColor) { - r, g, b := (rgb&0xFF0000)>>16, (rgb&0x00FF00)>>8, rgb&0x0000FF - min, max := minmax3(r, g, b) - a := (min + max) / 2 - if r < 128 && g < 128 && b < 128 { - if r >= a { - c.red = true - } - if g >= a { - c.green = true - } - if b >= a { - c.blue = true - } - // non-intensed white is lighter than intensed black, so swap those. - if c.red && c.green && c.blue { - c.red, c.green, c.blue = false, false, false - c.intensity = true - } - } else { - if min < 128 { - min = 128 - a = (min + max) / 2 - } - if r >= a { - c.red = true - } - if g >= a { - c.green = true - } - if b >= a { - c.blue = true - } - c.intensity = true - // intensed black is darker than non-intensed white, so swap those. - if !c.red && !c.green && !c.blue { - c.red, c.green, c.blue = true, true, true - c.intensity = false - } - } - return c -} - -func (c consoleColor) foregroundAttr() (attr word) { - if c.red { - attr |= foregroundRed - } - if c.green { - attr |= foregroundGreen - } - if c.blue { - attr |= foregroundBlue - } - if c.intensity { - attr |= foregroundIntensity - } - return -} - -func (c consoleColor) backgroundAttr() (attr word) { - if c.red { - attr |= backgroundRed - } - if c.green { - attr |= backgroundGreen - } - if c.blue { - attr |= backgroundBlue - } - if c.intensity { - attr |= backgroundIntensity - } - return -} - -var n256foreAttr []word -var n256backAttr []word - -func n256setup() { - n256foreAttr = make([]word, 256) - n256backAttr = make([]word, 256) - for i, rgb := range color256 { - c := toConsoleColor(rgb) - n256foreAttr[i] = c.foregroundAttr() - n256backAttr[i] = c.backgroundAttr() - } -} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling.go index e2cef98e..6f64bff3 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling.go @@ -88,50 +88,110 @@ func makeParams(action string) map[string]string { return params } +func addBlockDeviceParams(prename string, params map[string]string, blockdevices []BlockDeviceMapping) { + for i, k := range blockdevices { + // Fixup index since Amazon counts these from 1 + prefix := prename + "BlockDeviceMappings.member." + strconv.Itoa(i+1) + "." + + if k.DeviceName != "" { + params[prefix+"DeviceName"] = k.DeviceName + } + + if k.VirtualName != "" { + params[prefix+"VirtualName"] = k.VirtualName + } else if k.NoDevice { + params[prefix+"NoDevice"] = "" + } else { + if k.SnapshotId != "" { + params[prefix+"Ebs.SnapshotId"] = k.SnapshotId + } + if k.VolumeType != "" { + params[prefix+"Ebs.VolumeType"] = k.VolumeType + } + if k.IOPS != 0 { + params[prefix+"Ebs.Iops"] = strconv.FormatInt(k.IOPS, 10) + } + if k.VolumeSize != 0 { + params[prefix+"Ebs.VolumeSize"] = strconv.FormatInt(k.VolumeSize, 10) + } + if k.DeleteOnTermination { + params[prefix+"Ebs.DeleteOnTermination"] = "true" + } else { + params[prefix+"Ebs.DeleteOnTermination"] = "false" + } + if k.Encrypted { + params[prefix+"Ebs.Encrypted"] = "true" + } + } + } +} + // ---------------------------------------------------------------------------- // AutoScaling objects type Tag struct { Key string `xml:"Key"` Value string `xml:"Value"` - PropogateAtLaunch string `xml:"PropogateAtLaunch"` -} - -type SecurityGroup struct { - SecurityGroup string `xml:"member"` -} - -type AvailabilityZone struct { - AvailabilityZone string `xml:"member"` -} - -type LoadBalancerName struct { - LoadBalancerName string `xml:"member"` + PropagateAtLaunch bool `xml:"PropagateAtLaunch"` } type LaunchConfiguration struct { - IamInstanceProfile string `xml:"member>IamInstanceProfile"` - ImageId string `xml:"member>ImageId"` - InstanceType string `xml:"member>InstanceType"` - KeyName string `xml:"member>KeyName"` - Name string `xml:"member>LaunchConfigurationName"` - SecurityGroups []SecurityGroup `xml:"member>SecurityGroups"` - UserData []byte `xml:"member>UserData"` + AssociatePublicIpAddress bool `xml:"AssociatePublicIpAddress"` + IamInstanceProfile string `xml:"IamInstanceProfile"` + ImageId string `xml:"ImageId"` + InstanceType string `xml:"InstanceType"` + KernelId string `xml:"KernelId"` + KeyName string `xml:"KeyName"` + SpotPrice string `xml:"SpotPrice"` + Name string `xml:"LaunchConfigurationName"` + SecurityGroups []string `xml:"SecurityGroups>member"` + UserData []byte `xml:"UserData"` + BlockDevices []BlockDeviceMapping `xml:"BlockDeviceMappings>member"` +} + +type Instance struct { + AvailabilityZone string `xml:"AvailabilityZone"` + HealthStatus string `xml:"HealthStatus"` + InstanceId string `xml:"InstanceId"` + LaunchConfigurationName string `xml:"LaunchConfigurationName"` + LifecycleState string `xml:"LifecycleState"` } type AutoScalingGroup struct { - AvailabilityZones []AvailabilityZone `xml:"member>AvailabilityZones"` - DefaultCooldown int `xml:"member>DefaultCooldown"` - DesiredCapacity int `xml:"member>DesiredCapacity"` - HealthCheckGracePeriod int `xml:"member>HealthCheckGracePeriod"` - HealthCheckType string `xml:"member>HealthCheckType"` - InstanceId string `xml:"member>InstanceId"` - LaunchConfigurationName string `xml:"member>LaunchConfigurationName"` - LoadBalancerNames []LoadBalancerName `xml:"member>LoadBalancerNames"` - MaxSize int `xml:"member>MaxSize"` - MinSize int `xml:"member>MinSize"` - Name string `xml:"member>AutoScalingGroupName"` - VPCZoneIdentifier string `xml:"member>VPCZoneIdentifier"` + AvailabilityZones []string `xml:"AvailabilityZones>member"` + CreatedTime time.Time `xml:"CreatedTime"` + DefaultCooldown int `xml:"DefaultCooldown"` + DesiredCapacity int `xml:"DesiredCapacity"` + HealthCheckGracePeriod int `xml:"HealthCheckGracePeriod"` + HealthCheckType string `xml:"HealthCheckType"` + InstanceId string `xml:"InstanceId"` + Instances []Instance `xml:"Instances>member"` + LaunchConfigurationName string `xml:"LaunchConfigurationName"` + LoadBalancerNames []string `xml:"LoadBalancerNames>member"` + MaxSize int `xml:"MaxSize"` + MinSize int `xml:"MinSize"` + Name string `xml:"AutoScalingGroupName"` + Status string `xml:"Status"` + Tags []Tag `xml:"Tags>member"` + VPCZoneIdentifier string `xml:"VPCZoneIdentifier"` + TerminationPolicies []string `xml:"TerminationPolicies>member"` +} + +// BlockDeviceMapping represents the association of a block device with an image. +// +// See http://goo.gl/wnDBf for more details. +type BlockDeviceMapping struct { + DeviceName string `xml:"DeviceName"` + VirtualName string `xml:"VirtualName"` + SnapshotId string `xml:"Ebs>SnapshotId"` + VolumeType string `xml:"Ebs>VolumeType"` + VolumeSize int64 `xml:"Ebs>VolumeSize"` + DeleteOnTermination bool `xml:"Ebs>DeleteOnTermination"` + Encrypted bool `xml:"Ebs>Encrypted"` + NoDevice bool `xml:"NoDevice"` + + // The number of I/O operations per second (IOPS) that the volume supports. + IOPS int64 `xml:"ebs>iops"` } // ---------------------------------------------------------------------------- @@ -212,8 +272,9 @@ func (autoscaling *AutoScaling) CreateAutoScalingGroup(options *CreateAutoScalin } for j, tag := range options.Tags { - params["Tag.member."+strconv.Itoa(j+1)+".Key"] = tag.Key - params["Tag.member."+strconv.Itoa(j+1)+".Value"] = tag.Value + params["Tags.member."+strconv.Itoa(j+1)+".Key"] = tag.Key + params["Tags.member."+strconv.Itoa(j+1)+".Value"] = tag.Value + params["Tags.member."+strconv.Itoa(j+1)+".PropagateAtLaunch"] = strconv.FormatBool(tag.PropagateAtLaunch) } for i, v := range options.TerminationPolicies { @@ -237,13 +298,18 @@ func (autoscaling *AutoScaling) CreateAutoScalingGroup(options *CreateAutoScalin // The CreateLaunchConfiguration request parameters type CreateLaunchConfiguration struct { - ImageId string - InstanceId string - InstanceType string - KeyName string - Name string - SecurityGroups []string - UserData string + AssociatePublicIpAddress bool + IamInstanceProfile string + ImageId string + InstanceId string + InstanceType string + KernelId string + KeyName string + SpotPrice string + Name string + SecurityGroups []string + UserData string + BlockDevices []BlockDeviceMapping } func (autoscaling *AutoScaling) CreateLaunchConfiguration(options *CreateLaunchConfiguration) (resp *SimpleResp, err error) { @@ -251,6 +317,14 @@ func (autoscaling *AutoScaling) CreateLaunchConfiguration(options *CreateLaunchC params["LaunchConfigurationName"] = options.Name + if options.AssociatePublicIpAddress { + params["AssociatePublicIpAddress"] = "true" + } + + if options.IamInstanceProfile != "" { + params["IamInstanceProfile"] = options.IamInstanceProfile + } + if options.ImageId != "" { params["ImageId"] = options.ImageId } @@ -260,11 +334,18 @@ func (autoscaling *AutoScaling) CreateLaunchConfiguration(options *CreateLaunchC if options.InstanceId != "" { params["InstanceId"] = options.InstanceId } + if options.KernelId != "" { + params["KernelId"] = options.KernelId + } if options.KeyName != "" { params["KeyName"] = options.KeyName } + if options.SpotPrice != "" { + params["SpotPrice"] = options.SpotPrice + } + for i, v := range options.SecurityGroups { params["SecurityGroups.member."+strconv.Itoa(i+1)] = v } @@ -274,6 +355,7 @@ func (autoscaling *AutoScaling) CreateLaunchConfiguration(options *CreateLaunchC b64.Encode(userData, []byte(options.UserData)) params["UserData"] = string(userData) } + addBlockDeviceParams("", params, options.BlockDevices) resp = &SimpleResp{} @@ -295,7 +377,7 @@ type DescribeAutoScalingGroups struct { type DescribeAutoScalingGroupsResp struct { RequestId string `xml:"ResponseMetadata>RequestId"` - AutoScalingGroups []AutoScalingGroup `xml:"DescribeAutoScalingGroupsResult>AutoScalingGroups"` + AutoScalingGroups []AutoScalingGroup `xml:"DescribeAutoScalingGroupsResult>AutoScalingGroups>member"` } func (autoscaling *AutoScaling) DescribeAutoScalingGroups(options *DescribeAutoScalingGroups) (resp *DescribeAutoScalingGroupsResp, err error) { @@ -323,7 +405,7 @@ type DescribeLaunchConfigurations struct { type DescribeLaunchConfigurationsResp struct { RequestId string `xml:"ResponseMetadata>RequestId"` - LaunchConfigurations []LaunchConfiguration `xml:"DescribeLaunchConfigurationsResult>LaunchConfigurations"` + LaunchConfigurations []LaunchConfiguration `xml:"DescribeLaunchConfigurationsResult>LaunchConfigurations>member"` } func (autoscaling *AutoScaling) DescribeLaunchConfigurations(options *DescribeLaunchConfigurations) (resp *DescribeLaunchConfigurationsResp, err error) { diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling_test.go index 8cccdc2b..c7f20cfc 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/autoscaling/autoscaling_test.go @@ -79,6 +79,10 @@ func (s *S) Test_CreateLaunchConfiguration(c *C) { KeyName: "foobar", Name: "i-141421", UserData: "#!/bin/bash\necho Hello\n", + BlockDevices: []autoscaling.BlockDeviceMapping{ + {DeviceName: "/dev/sdb", VirtualName: "ephemeral0"}, + {DeviceName: "/dev/sdc", SnapshotId: "snap-a08912c9", DeleteOnTermination: true}, + }, } resp, err := s.autoscaling.CreateLaunchConfiguration(&options) @@ -88,6 +92,10 @@ func (s *S) Test_CreateLaunchConfiguration(c *C) { c.Assert(req.Form["InstanceType"], DeepEquals, []string{"m1.small"}) c.Assert(req.Form["SecurityGroups.member.1"], DeepEquals, []string{"sg-1111"}) c.Assert(req.Form["UserData"], DeepEquals, []string{"IyEvYmluL2Jhc2gKZWNobyBIZWxsbwo="}) + c.Assert(req.Form["BlockDeviceMappings.member.1.DeviceName"], DeepEquals, []string{"/dev/sdb"}) + c.Assert(req.Form["BlockDeviceMappings.member.1.VirtualName"], DeepEquals, []string{"ephemeral0"}) + c.Assert(req.Form["BlockDeviceMappings.member.2.Ebs.SnapshotId"], DeepEquals, []string{"snap-a08912c9"}) + c.Assert(req.Form["BlockDeviceMappings.member.2.Ebs.DeleteOnTermination"], DeepEquals, []string{"true"}) c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "7c6e177f-f082-11e1-ac58-3714bEXAMPLE") } @@ -108,6 +116,7 @@ func (s *S) Test_DescribeAutoScalingGroups(c *C) { c.Assert(resp.RequestId, Equals, "0f02a07d-b677-11e2-9eb0-dd50EXAMPLE") c.Assert(resp.AutoScalingGroups[0].Name, Equals, "my-test-asg-lbs") c.Assert(resp.AutoScalingGroups[0].LaunchConfigurationName, Equals, "my-test-lc") + c.Assert(resp.AutoScalingGroups[0].TerminationPolicies[0], Equals, "Default") } func (s *S) Test_DescribeLaunchConfigurations(c *C) { diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/aws/aws.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/aws/aws.go index 85e395e6..cfc42c03 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/aws/aws.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/aws/aws.go @@ -124,6 +124,23 @@ var EUWest = Region{ "https://route53.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://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://autoscaling.eu-central-1.amazonaws.com", + "https://rds.eu-central-1.amazonaws.com", + "https://route53.amazonaws.com", +} + var APSoutheast = Region{ "ap-southeast-1", "https://ec2.ap-southeast-1.amazonaws.com", @@ -214,6 +231,7 @@ var Regions = map[string]Region{ APSoutheast.Name: APSoutheast, APSoutheast2.Name: APSoutheast2, EUWest.Name: EUWest, + EUCentral.Name: EUCentral, USEast.Name: USEast, USWest.Name: USWest, USWest2.Name: USWest2, diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2.go index 0d9b09be..8fc381ec 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2.go @@ -127,7 +127,7 @@ type xmlErrors struct { var timeNow = time.Now func (ec2 *EC2) query(params map[string]string, resp interface{}) error { - params["Version"] = "2014-05-01" + params["Version"] = "2014-06-15" params["Timestamp"] = timeNow().In(time.UTC).Format(time.RFC3339) endpoint, err := url.Parse(ec2.Region.EC2Endpoint) if err != nil { @@ -203,31 +203,32 @@ func addBlockDeviceParams(prename string, params map[string]string, blockdevices if k.DeviceName != "" { params[prefix+"DeviceName"] = k.DeviceName } + if k.VirtualName != "" { params[prefix+"VirtualName"] = k.VirtualName - } - if k.SnapshotId != "" { - params[prefix+"Ebs.SnapshotId"] = k.SnapshotId - } - if k.VolumeType != "" { - params[prefix+"Ebs.VolumeType"] = k.VolumeType - } - if k.IOPS != 0 { - params[prefix+"Ebs.Iops"] = strconv.FormatInt(k.IOPS, 10) - } - if k.VolumeSize != 0 { - params[prefix+"Ebs.VolumeSize"] = strconv.FormatInt(k.VolumeSize, 10) - } - if k.DeleteOnTermination { - params[prefix+"Ebs.DeleteOnTermination"] = "true" - } else { - params[prefix+"Ebs.DeleteOnTermination"] = "false" - } - if k.Encrypted { - params[prefix+"Ebs.Encrypted"] = "true" - } - if k.NoDevice { + } else if k.NoDevice { params[prefix+"NoDevice"] = "" + } else { + if k.SnapshotId != "" { + params[prefix+"Ebs.SnapshotId"] = k.SnapshotId + } + if k.VolumeType != "" { + params[prefix+"Ebs.VolumeType"] = k.VolumeType + } + if k.IOPS != 0 { + params[prefix+"Ebs.Iops"] = strconv.FormatInt(k.IOPS, 10) + } + if k.VolumeSize != 0 { + params[prefix+"Ebs.VolumeSize"] = strconv.FormatInt(k.VolumeSize, 10) + } + if k.DeleteOnTermination { + params[prefix+"Ebs.DeleteOnTermination"] = "true" + } else { + params[prefix+"Ebs.DeleteOnTermination"] = "false" + } + if k.Encrypted { + params[prefix+"Ebs.Encrypted"] = "true" + } } } } @@ -259,6 +260,7 @@ type RunInstances struct { ShutdownBehavior string PrivateIPAddress string BlockDevices []BlockDeviceMapping + Tenancy string } // Response to a RunInstances request. @@ -296,6 +298,7 @@ type Instance struct { VirtType string `xml:"virtualizationType"` Monitoring string `xml:"monitoring>state"` AvailZone string `xml:"placement>availabilityZone"` + Tenancy string `xml:"placement>tenancy"` PlacementGroupName string `xml:"placement>groupName"` State InstanceState `xml:"instanceState"` Tags []Tag `xml:"tagSet>item"` @@ -310,6 +313,7 @@ type Instance struct { SecurityGroups []SecurityGroup `xml:"groupSet>item"` EbsOptimized string `xml:"ebsOptimized"` BlockDevices []BlockDevice `xml:"blockDeviceMapping>item"` + RootDeviceName string `xml:"rootDeviceName"` } // RunInstances starts new instances in EC2. @@ -364,6 +368,9 @@ func (ec2 *EC2) RunInstances(options *RunInstances) (resp *RunInstancesResp, err if options.Monitoring { params["Monitoring.Enabled"] = "true" } + if options.Tenancy != "" { + params["Placement.Tenancy"] = options.Tenancy + } if options.SubnetId != "" && options.AssociatePublicIpAddress { // If we have a non-default VPC / Subnet specified, we can flag // AssociatePublicIpAddress to get a Public IP assigned. By default these are not provided. @@ -376,6 +383,10 @@ func (ec2 *EC2) RunInstances(options *RunInstances) (resp *RunInstancesResp, err params["NetworkInterface.0.AssociatePublicIpAddress"] = "true" params["NetworkInterface.0.SubnetId"] = options.SubnetId + if options.PrivateIPAddress != "" { + params["NetworkInterface.0.PrivateIpAddress"] = options.PrivateIPAddress + } + i := 1 for _, g := range options.SecurityGroups { // We only have SecurityGroupId's on NetworkInterface's, no SecurityGroup params. @@ -389,6 +400,10 @@ func (ec2 *EC2) RunInstances(options *RunInstances) (resp *RunInstancesResp, err params["SubnetId"] = options.SubnetId } + if options.PrivateIPAddress != "" { + params["PrivateIpAddress"] = options.PrivateIPAddress + } + i, j := 1, 1 for _, g := range options.SecurityGroups { if g.Id != "" { @@ -412,9 +427,6 @@ func (ec2 *EC2) RunInstances(options *RunInstances) (resp *RunInstancesResp, err if options.ShutdownBehavior != "" { params["InstanceInitiatedShutdownBehavior"] = options.ShutdownBehavior } - if options.PrivateIPAddress != "" { - params["PrivateIpAddress"] = options.PrivateIPAddress - } addBlockDeviceParams("", params, options.BlockDevices) resp = &RunInstancesResp{} @@ -436,6 +448,39 @@ func clientToken() (string, error) { return hex.EncodeToString(buf), nil } +// The GetConsoleOutput type encapsulates options for the respective request in EC2. +// +// See http://goo.gl/EY70zb for more details. +type GetConsoleOutput struct { + InstanceId string +} + +// Response to a GetConsoleOutput request. Note that Output is base64-encoded, +// as in the underlying AWS API. +// +// See http://goo.gl/EY70zb for more details. +type GetConsoleOutputResp struct { + RequestId string `xml:"requestId"` + InstanceId string `xml:"instanceId"` + Timestamp time.Time `xml:"timestamp"` + Output string `xml:"output"` +} + +// GetConsoleOutput returns the console output for the sepcified instance. Note +// that console output is base64-encoded, as in the underlying AWS API. +// +// See http://goo.gl/EY70zb for more details. +func (ec2 *EC2) GetConsoleOutput(options *GetConsoleOutput) (resp *GetConsoleOutputResp, err error) { + params := makeParams("GetConsoleOutput") + params["InstanceId"] = options.InstanceId + resp = &GetConsoleOutputResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + // ---------------------------------------------------------------------------- // Instance events and status functions and types. @@ -487,7 +532,7 @@ func (ec2 *EC2) DescribeInstanceStatus(options *DescribeInstanceStatus, filter * params["IncludeAllInstances"] = "true" } if len(options.InstanceIds) > 0 { - addParamsList(params, "InstanceIds", options.InstanceIds) + addParamsList(params, "InstanceId", options.InstanceIds) } if options.MaxResults > 0 { params["MaxResults"] = strconv.FormatInt(options.MaxResults, 10) @@ -1015,6 +1060,47 @@ func (ec2 *EC2) Volumes(volIds []string, filter *Filter) (resp *VolumesResp, err return } +// ---------------------------------------------------------------------------- +// Availability zone management functions and types. +// See http://goo.gl/ylxT4R for more details. + +// DescribeAvailabilityZonesResp represents a response to a DescribeAvailabilityZones +// request in EC2. +type DescribeAvailabilityZonesResp struct { + RequestId string `xml:"requestId"` + Zones []AvailabilityZoneInfo `xml:"availabilityZoneInfo>item"` +} + +// AvailabilityZoneInfo encapsulates details for an availability zone in EC2. +type AvailabilityZoneInfo struct { + AvailabilityZone + State string `xml:"zoneState"` + MessageSet []string `xml:"messageSet>item"` +} + +// AvailabilityZone represents an EC2 availability zone. +type AvailabilityZone struct { + Name string `xml:"zoneName"` + Region string `xml:"regionName"` +} + +// DescribeAvailabilityZones returns details about availability zones in EC2. +// The filter parameter is optional, and if provided will limit the +// availability zones returned to those matching the given filtering +// rules. +// +// See http://goo.gl/ylxT4R for more details. +func (ec2 *EC2) DescribeAvailabilityZones(filter *Filter) (resp *DescribeAvailabilityZonesResp, err error) { + params := makeParams("DescribeAvailabilityZones") + filter.addParams(params) + resp = &DescribeAvailabilityZonesResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + // ---------------------------------------------------------------------------- // ElasticIp management (for VPC) @@ -1147,6 +1233,20 @@ func (ec2 *EC2) DisassociateAddress(id string) (resp *SimpleResp, err error) { return } +// Disassociate an address from a VPC instance. +func (ec2 *EC2) DisassociateAddressClassic(ip string) (resp *SimpleResp, err error) { + params := makeParams("DisassociateAddress") + params["PublicIp"] = ip + + resp = &SimpleResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return +} + // DescribeAddresses returns details about one or more // Elastic IP Addresses. Returned addresses can be // filtered by Public IP, Allocation ID or multiple filters @@ -1795,9 +1895,10 @@ type SecurityGroupsResp struct { // See http://goo.gl/CIdyP for more details. type SecurityGroupInfo struct { SecurityGroup - OwnerId string `xml:"ownerId"` - Description string `xml:"groupDescription"` - IPPerms []IPPerm `xml:"ipPermissions>item"` + OwnerId string `xml:"ownerId"` + Description string `xml:"groupDescription"` + IPPerms []IPPerm `xml:"ipPermissions>item"` + IPPermsEgress []IPPerm `xml:"ipPermissionsEgress>item"` } // IPPerm represents an allowance within an EC2 security group. @@ -1827,6 +1928,7 @@ type SecurityGroup struct { Name string `xml:"groupName"` Description string `xml:"groupDescription"` VpcId string `xml:"vpcId"` + Tags []Tag `xml:"tagSet>item"` } // SecurityGroupNames is a convenience function that @@ -1918,6 +2020,13 @@ func (ec2 *EC2) RevokeSecurityGroup(group SecurityGroup, perms []IPPerm) (resp * return ec2.authOrRevoke("RevokeSecurityGroupIngress", group, perms) } +// RevokeSecurityGroupEgress revokes egress permissions from a group +// +// see http://goo.gl/Zv4wh8 +func (ec2 *EC2) RevokeSecurityGroupEgress(group SecurityGroup, perms []IPPerm) (resp *SimpleResp, err error) { + return ec2.authOrRevoke("RevokeSecurityGroupEgress", group, perms) +} + func (ec2 *EC2) authOrRevoke(op string, group SecurityGroup, perms []IPPerm) (resp *SimpleResp, err error) { params := makeParams(op) if group.Id != "" { @@ -1985,6 +2094,28 @@ func (ec2 *EC2) CreateTags(resourceIds []string, tags []Tag) (resp *SimpleResp, return resp, nil } +// DeleteTags deletes tags. +func (ec2 *EC2) DeleteTags(resourceIds []string, tags []Tag) (resp *SimpleResp, err error) { + params := makeParams("DeleteTags") + addParamsList(params, "ResourceId", resourceIds) + + for j, tag := range tags { + params["Tag."+strconv.Itoa(j+1)+".Key"] = tag.Key + + if tag.Value != "" { + params["Tag."+strconv.Itoa(j+1)+".Value"] = tag.Value + } + } + + resp = &SimpleResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return resp, nil +} + type TagsResp struct { RequestId string `xml:"requestId"` Tags []ResourceTag `xml:"tagSet>item"` @@ -2212,6 +2343,64 @@ type CreateInternetGatewayResp struct { InternetGateway InternetGateway `xml:"internetGateway"` } +// The CreateVpcPeeringConnection request parameters +// +// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateVpcPeeringConnection.html +type CreateVpcPeeringConnection struct { + PeerOwnerId string + PeerVpcId string + VpcId string +} + +// Response to a CreateVpcPeeringConnection +type CreateVpcPeeringConnectionResp struct { + RequestId string `xml:"requestId"` + VpcPeeringConnection VpcPeeringConnection `xml:"vpcPeeringConnection"` +} + +// The AcceptVpcPeeringConnection request parameters +// +// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AcceptVpcPeeringConnection.html +type AcceptVpcPeeringConnection struct { + VpcPeeringConnectionId string `xml:"vpcPeeringConnectionId"` +} + +// Response to a AcceptVpcPeeringConnection request. +type AcceptVpcPeeringConnectionResp struct { + RequestId string `xml:"requestId"` + VpcPeeringConnection VpcPeeringConnection `xml:"vpcPeeringConnection"` +} + +// The DeleteVpcPeeringConnection request +// +// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteVpcPeeringConnection.html +type DeleteVpcPeeringConnection struct { + VpcPeeringConnectionId string `xml:"vpcPeeringConnectionId"` +} + +// Response to a DeleteVpcPeeringConnection request. +type DeleteVpcPeeringConnectionResp struct { + RequestId string `xml:"requestId"` +} + +// Response to a DescribeVpcPeeringConnection request. +type DescribeVpcPeeringConnectionResp struct { + RequestId string `xml:"requestId"` + VpcPeeringConnections []VpcPeeringConnection `xml:"vpcPeeringConnectionSet>item"` +} + +// The RejectVpcPeeringConnection request +// +// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RejectVpcPeeringConnection.html +type RejectVpcPeeringConnection struct { + VpcPeeringConnectionId string `xml:"vpcPeeringConnectionId"` +} + +// Response to a RejectVpcPeeringConnection request. +type RejectVpcPeeringConnectionResp struct { + RequestId string `xml:"requestId"` +} + // The CreateRouteTable request parameters. // // http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-CreateRouteTable.html @@ -2254,6 +2443,23 @@ type ReassociateRouteTableResp struct { AssociationId string `xml:"newAssociationId"` } +// The CreateDhcpOptions request parameters +// +// http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateDhcpOptions.html +type CreateDhcpOptions struct { + DomainNameServers string + DomainName string + NtpServers string + NetbiosNameServers string + NetbiosNodeType string +} + +// Response to a CreateDhcpOptions request +type CreateDhcpOptionsResp struct { + RequestId string `xml:"requestId"` + DhcpOptions DhcpOptions `xml:"dhcpOptions"` +} + // The CreateSubnet request parameters // // http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-CreateSubnet.html @@ -2282,6 +2488,25 @@ type ModifySubnetAttributeResp struct { Return bool `xml:"return"` } +// The CreateNetworkAcl request parameters +// +// http://goo.gl/BZmCRF +type CreateNetworkAcl struct { + VpcId string +} + +// Response to a CreateNetworkAcl request +type CreateNetworkAclResp struct { + RequestId string `xml:"requestId"` + NetworkAcl NetworkAcl `xml:"networkAcl"` +} + +// Response to CreateNetworkAclEntry request +type CreateNetworkAclEntryResp struct { + RequestId string `xml:"requestId"` + Return bool `xml:"return"` +} + // Response to a DescribeInternetGateways request. type InternetGatewaysResp struct { RequestId string `xml:"requestId"` @@ -2312,6 +2537,27 @@ type InternetGatewayAttachment struct { State string `xml:"state"` } +// vpc peering +type VpcPeeringConnection struct { + AccepterVpcInfo VpcPeeringConnectionVpcInfo `xml:"accepterVpcInfo"` + ExpirationTime string `xml:"expirationTime"` + RequesterVpcInfo VpcPeeringConnectionVpcInfo `xml:"requesterVpcInfo"` + Status VpcPeeringConnectionStateReason `xml:"status"` + Tags []Tag `xml:"tagSet>item"` + VpcPeeringConnectionId string `xml:"vpcPeeringConnectionId"` +} + +type VpcPeeringConnectionVpcInfo struct { + CidrBlock string `xml:"cidrBlock"` + OwnerId string `xml:"ownerId"` + VpcId string `xml:"vpcId"` +} + +type VpcPeeringConnectionStateReason struct { + Code string `xml:"code"` + Message string `xml:"message"` +} + // Routing Table type RouteTable struct { RouteTableId string `xml:"routeTableId"` @@ -2352,6 +2598,62 @@ type Subnet struct { Tags []Tag `xml:"tagSet>item"` } +// DhcpOptions +type DhcpOptions struct { + DhcpOptionsId string `xml:"dhcpOptionsId"` + DhcpConfigurationSets DhcpConfigurationSet `xml:"dhcpConfigurationSet"` +} + +type DhcpConfigurationSet struct { + Tags []Tag `xml:"dhcpConfigurationSet>item"` +} + +// NetworkAcl represent network acl +type NetworkAcl struct { + NetworkAclId string `xml:"networkAclId"` + VpcId string `xml:"vpcId"` + Default string `xml:"default"` + EntrySet []NetworkAclEntry `xml:"entrySet>item"` + AssociationSet []NetworkAclAssociation `xml:"associationSet>item"` + Tags []Tag `xml:"tagSet>item"` +} + +// NetworkAclAssociation +type NetworkAclAssociation struct { + NetworkAclAssociationId string `xml:"networkAclAssociationId"` + NetworkAclId string `xml:"networkAclId"` + SubnetId string `xml:"subnetId"` +} + +// NetworkAclEntry represent a rule within NetworkAcl +type NetworkAclEntry struct { + RuleNumber int `xml:"ruleNumber"` + Protocol int `xml:"protocol"` + RuleAction string `xml:"ruleAction"` + Egress bool `xml:"egress"` + CidrBlock string `xml:"cidrBlock"` + IcmpCode IcmpCode `xml:"icmpTypeCode"` + PortRange PortRange `xml:"portRange"` +} + +// IcmpCode +type IcmpCode struct { + Code int `xml:"code"` + Type int `xml:"type"` +} + +// PortRange +type PortRange struct { + From int `xml:"from"` + To int `xml:"to"` +} + +// Response to describe NetworkAcls +type NetworkAclsResp struct { + RequestId string `xml:"requestId"` + NetworkAcls []NetworkAcl `xml:"networkAclSet>item"` +} + // VPC represents a single VPC. type VPC struct { VpcId string `xml:"vpcId"` @@ -2525,6 +2827,175 @@ func (ec2 *EC2) DescribeSubnets(ids []string, filter *Filter) (resp *SubnetsResp return } +// Create DhcpOptions. +func (ec2 *EC2) CreateDhcpOptions(options *CreateDhcpOptions) (resp *CreateDhcpOptionsResp, err error) { + params := makeParams("CreateDhcpOptions") + params["DomainNameServers"] = options.DomainNameServers + params["DomainName"] = options.DomainName + params["NtpServers"] = options.NtpServers + params["NetbiosNameServers"] = options.NetbiosNameServers + params["NetbiosNodeType"] = options.NetbiosNodeType + + resp = &CreateDhcpOptionsResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return +} + +// Delete DhcpOptions. +func (ec2 *EC2) DeleteDhcpOptions(id string) (resp *SimpleResp, err error) { + params := makeParams("DeleteDhcpOptions") + params["DhcpOptionsId"] = id + + resp = &SimpleResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + +// Associate DhcpOptions to a VPC. +func (ec2 *EC2) AssociateDhcpOptions(dhcpOptionsId string, vpcId string) (resp *SimpleResp, err error) { + params := makeParams("AssociateDhcpOptions") + params["DhcpOptionsId"] = dhcpOptionsId + params["VpcId"] = vpcId + + resp = &SimpleResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + +// CreateNetworkAcl creates a network ACL in a VPC. +// +// http://goo.gl/51X7db +func (ec2 *EC2) CreateNetworkAcl(options *CreateNetworkAcl) (resp *CreateNetworkAclResp, err error) { + params := makeParams("CreateNetworkAcl") + params["VpcId"] = options.VpcId + + resp = &CreateNetworkAclResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return +} + +// CreateNetworkAclEntry creates an entry (a rule) in a network ACL with the specified rule number. +// +// http://goo.gl/BtXhtj +func (ec2 *EC2) CreateNetworkAclEntry(networkAclId string, options *NetworkAclEntry) (resp *CreateNetworkAclEntryResp, err error) { + + params := makeParams("CreateNetworkAclEntry") + params["NetworkAclId"] = networkAclId + params["RuleNumber"] = strconv.Itoa(options.RuleNumber) + params["Protocol"] = strconv.Itoa(options.Protocol) + params["RuleAction"] = options.RuleAction + params["Egress"] = strconv.FormatBool(options.Egress) + params["CidrBlock"] = options.CidrBlock + if params["Protocol"] == "-1" { + params["Icmp.Type"] = strconv.Itoa(options.IcmpCode.Type) + params["Icmp.Code"] = strconv.Itoa(options.IcmpCode.Code) + } + params["PortRange.From"] = strconv.Itoa(options.PortRange.From) + params["PortRange.To"] = strconv.Itoa(options.PortRange.To) + + resp = &CreateNetworkAclEntryResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return resp, nil +} + +// NetworkAcls describes one or more of your network ACLs for given filter. +// +// http://goo.gl/mk9RsV +func (ec2 *EC2) NetworkAcls(networkAclIds []string, filter *Filter) (resp *NetworkAclsResp, err error) { + params := makeParams("DescribeNetworkAcls") + addParamsList(params, "NetworkAclId", networkAclIds) + filter.addParams(params) + resp = &NetworkAclsResp{} + if err = ec2.query(params, resp); err != nil { + return nil, err + } + + return resp, nil +} + +// Response to a DeleteNetworkAcl request. +type DeleteNetworkAclResp struct { + RequestId string `xml:"requestId"` + Return bool `xml:"return"` +} + +// DeleteNetworkAcl deletes the network ACL with specified id. +// +// http://goo.gl/nC78Wx +func (ec2 *EC2) DeleteNetworkAcl(id string) (resp *DeleteNetworkAclResp, err error) { + params := makeParams("DeleteNetworkAcl") + params["NetworkAclId"] = id + + resp = &DeleteNetworkAclResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return resp, nil +} + +// Response to a DeleteNetworkAclEntry request. +type DeleteNetworkAclEntryResp struct { + RequestId string `xml:"requestId"` + Return bool `xml:"return"` +} + +// DeleteNetworkAclEntry deletes the specified ingress or egress entry (rule) from the specified network ACL. +// +// http://goo.gl/moQbE2 +func (ec2 *EC2) DeleteNetworkAclEntry(id string, ruleNumber int, egress bool) (resp *DeleteNetworkAclEntryResp, err error) { + params := makeParams("DeleteNetworkAclEntry") + params["NetworkAclId"] = id + params["RuleNumber"] = strconv.Itoa(ruleNumber) + params["Egress"] = strconv.FormatBool(egress) + + resp = &DeleteNetworkAclEntryResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return resp, nil +} + +type ReplaceNetworkAclAssociationResponse struct { + RequestId string `xml:"requestId"` + NewAssociationId string `xml:"newAssociationId"` +} + +// ReplaceNetworkAclAssociation changes which network ACL a subnet is associated with. +// +// http://goo.gl/ar0MH5 +func (ec2 *EC2) ReplaceNetworkAclAssociation(associationId string, networkAclId string) (resp *ReplaceNetworkAclAssociationResponse, err error) { + params := makeParams("ReplaceNetworkAclAssociation") + params["NetworkAclId"] = networkAclId + params["AssociationId"] = associationId + + resp = &ReplaceNetworkAclAssociationResponse{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return resp, nil +} + // Create a new internet gateway. func (ec2 *EC2) CreateInternetGateway( options *CreateInternetGateway) (resp *CreateInternetGatewayResp, err error) { @@ -2751,6 +3222,74 @@ func (ec2 *EC2) ReplaceRoute(options *ReplaceRoute) (resp *SimpleResp, err error return } +// Create a vpc peering connection +func (ec2 *EC2) CreateVpcPeeringConnection( + options *CreateVpcPeeringConnection) (resp *CreateVpcPeeringConnectionResp, err error) { + params := makeParams("CreateVpcPeeringConnection") + params["PeerOwnerId"] = options.PeerOwnerId + params["PeerVpcId"] = options.PeerVpcId + params["VpcId"] = options.VpcId + + resp = &CreateVpcPeeringConnectionResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + +// AcceptVpcPeeringConnection +func (ec2 *EC2) AcceptVpcPeeringConnection(id string) (resp *AcceptVpcPeeringConnectionResp, err error) { + params := makeParams("AcceptVpcPeeringConnection") + params["VpcPeeringConnectionId"] = id + + resp = &AcceptVpcPeeringConnectionResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + +func (ec2 *EC2) DeleteVpcPeeringConnection(id string) (resp *DeleteVpcPeeringConnectionResp, err error) { + params := makeParams("DeleteVpcPeeringConnection") + params["VpcPeeringConnectionId"] = id + + resp = &DeleteVpcPeeringConnectionResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + +// DescribeVpcPeeringConnection +func (ec2 *EC2) DescribeVpcPeeringConnection(ids []string, filter *Filter) (resp *DescribeVpcPeeringConnectionResp, err error) { + params := makeParams("DescribeVpcPeeringConnections") + addParamsList(params, "VpcPeeringConnectionId", ids) + filter.addParams(params) + resp = &DescribeVpcPeeringConnectionResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return +} + +// RejectVpcPeeringConnection +func (ec2 *EC2) RejectVpcPeeringConnection(id string) (resp *RejectVpcPeeringConnectionResp, err error) { + params := makeParams("RejectVpcPeeringConnection") + params["VpcPeeringConnectionId"] = id + + resp = &RejectVpcPeeringConnectionResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + // The ResetImageAttribute request parameters. type ResetImageAttribute struct { Attribute string @@ -2774,3 +3313,78 @@ func (ec2 *EC2) ResetImageAttribute(imageId string, options *ResetImageAttribute } return } + +type CreateCustomerGateway struct { + Type string + IpAddress string + BgpAsn int +} + +// Response to a CreateCustomerGateway request +type CreateCustomerGatewayResp struct { + RequestId string `xml:"requestId"` + CustomerGateway CustomerGateway `xml:"customerGateway"` +} + +type CustomerGateway struct { + CustomerGatewayId string `xml:"customerGatewayId"` + State string `xml:"state"` + Type string `xml:"type"` + IpAddress string `xml:"ipAddress"` + BgpAsn int `xml:"bgpAsn"` + Tags []Tag `xml:"tagSet>item"` +} + +type DescribeCustomerGatewaysResp struct { + RequestId string `xml:"requestId"` + CustomerGateways []CustomerGateway `xml:"customerGatewaySet>item"` +} + +//Create a customer gateway +func (ec2 *EC2) CreateCustomerGateway(options *CreateCustomerGateway) (resp *CreateCustomerGatewayResp, err error) { + params := makeParams("CreateCustomerGateway") + params["Type"] = options.Type + params["IpAddress"] = options.IpAddress + if options.BgpAsn != 0 { + params["BgpAsn"] = strconv.Itoa(options.BgpAsn) + } + + resp = &CreateCustomerGatewayResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + return +} + +func (ec2 *EC2) DescribeCustomerGateways(ids []string, filter *Filter) (resp *DescribeCustomerGatewaysResp, err error) { + params := makeParams("DescribeCustomerGateways") + addParamsList(params, "CustomerGatewayId", ids) + filter.addParams(params) + + resp = &DescribeCustomerGatewaysResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return +} + +type DeleteCustomerGatewayResp struct { + RequestId string `xml:"requestId"` + Return bool `xml:"return"` +} + +func (ec2 *EC2) DeleteCustomerGateway(customerGatewayId string) (resp *DeleteCustomerGatewayResp, err error) { + params := makeParams("DeleteCustomerGateway") + params["CustomerGatewayId"] = customerGatewayId + + resp = &DeleteCustomerGatewayResp{} + err = ec2.query(params, resp) + if err != nil { + return nil, err + } + + return +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2_test.go index 93f2eaf3..aac13ae4 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2_test.go @@ -136,6 +136,7 @@ func (s *S) TestRunInstancesExample(c *C) { KernelId: "kernel-id", RamdiskId: "ramdisk-id", AvailZone: "zone", + Tenancy: "dedicated", PlacementGroupName: "group", Monitoring: true, SubnetId: "subnet-id", @@ -375,6 +376,7 @@ func (s *S) TestDescribeInstancesExample1(c *C) { c.Assert(r0i.PrivateDNSName, Equals, "domU-12-31-39-10-56-34.compute-1.internal") c.Assert(r0i.DNSName, Equals, "ec2-174-129-165-232.compute-1.amazonaws.com") c.Assert(r0i.AvailZone, Equals, "us-east-1b") + c.Assert(r0i.RootDeviceName, Equals, "/dev/sda1") b0 := r0i.BlockDevices[0] c.Assert(b0.DeviceName, Equals, "/dev/sda1") @@ -758,6 +760,7 @@ func (s *S) TestDescribeSecurityGroupsExample(c *C) { c.Assert(g0.Id, Equals, "sg-67ad940e") c.Assert(g0.Description, Equals, "Web Servers") c.Assert(g0.IPPerms, HasLen, 1) + c.Assert(g0.IPPermsEgress, HasLen, 1) g0ipp := g0.IPPerms[0] c.Assert(g0ipp.Protocol, Equals, "tcp") @@ -765,6 +768,12 @@ func (s *S) TestDescribeSecurityGroupsExample(c *C) { c.Assert(g0ipp.ToPort, Equals, 80) c.Assert(g0ipp.SourceIPs, DeepEquals, []string{"0.0.0.0/0"}) + g0ippe := g0.IPPermsEgress[0] + c.Assert(g0ippe.Protocol, Equals, "tcp") + c.Assert(g0ippe.FromPort, Equals, 80) + c.Assert(g0ippe.ToPort, Equals, 80) + c.Assert(g0ippe.SourceIPs, DeepEquals, []string{"0.0.0.0/0"}) + g1 := resp.Groups[1] c.Assert(g1.OwnerId, Equals, "999988887777") c.Assert(g1.Name, Equals, "RangedPortsBySource") @@ -1054,7 +1063,7 @@ func (s *S) TestSignatureWithEndpointPath(c *C) { c.Assert(err, IsNil) req := testServer.WaitRequest() - c.Assert(req.Form["Signature"], DeepEquals, []string{"QmvgkYGn19WirCuCz/jRp3RmRgFwWR5WRkKZ5AZnyXQ="}) + c.Assert(req.Form["Signature"], DeepEquals, []string{"tyOTQ0c0T5ujskCPTWa5ATMtv7UyErgT339cU8O2+Q8="}) } func (s *S) TestDescribeInstanceStatusExample(c *C) { @@ -1294,3 +1303,199 @@ func (s *S) TestResetImageAttribute(c *C) { c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") } + +func (s *S) TestDescribeAvailabilityZonesExample1(c *C) { + testServer.Response(200, nil, DescribeAvailabilityZonesExample1) + + resp, err := s.ec2.DescribeAvailabilityZones(nil) + + req := testServer.WaitRequest() + c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeAvailabilityZones"}) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") + c.Assert(resp.Zones, HasLen, 4) + + z0 := resp.Zones[0] + c.Assert(z0.Name, Equals, "us-east-1a") + c.Assert(z0.Region, Equals, "us-east-1") + c.Assert(z0.State, Equals, "available") + c.Assert(z0.MessageSet, HasLen, 0) + + z1 := resp.Zones[1] + c.Assert(z1.Name, Equals, "us-east-1b") + c.Assert(z1.Region, Equals, "us-east-1") + c.Assert(z1.State, Equals, "available") + c.Assert(z1.MessageSet, HasLen, 0) + + z2 := resp.Zones[2] + c.Assert(z2.Name, Equals, "us-east-1c") + c.Assert(z2.Region, Equals, "us-east-1") + c.Assert(z2.State, Equals, "available") + c.Assert(z2.MessageSet, HasLen, 0) + + z3 := resp.Zones[3] + c.Assert(z3.Name, Equals, "us-east-1d") + c.Assert(z3.Region, Equals, "us-east-1") + c.Assert(z3.State, Equals, "available") + c.Assert(z3.MessageSet, HasLen, 0) +} + +func (s *S) TestDescribeAvailabilityZonesExample2(c *C) { + testServer.Response(200, nil, DescribeAvailabilityZonesExample2) + + resp, err := s.ec2.DescribeAvailabilityZones(nil) + + req := testServer.WaitRequest() + c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeAvailabilityZones"}) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") + c.Assert(resp.Zones, HasLen, 2) + + z0 := resp.Zones[0] + c.Assert(z0.Name, Equals, "us-east-1a") + c.Assert(z0.Region, Equals, "us-east-1") + c.Assert(z0.State, Equals, "impaired") + c.Assert(z0.MessageSet, HasLen, 0) + + z1 := resp.Zones[1] + c.Assert(z1.Name, Equals, "us-east-1b") + c.Assert(z1.Region, Equals, "us-east-1") + c.Assert(z1.State, Equals, "unavailable") + c.Assert(z1.MessageSet, DeepEquals, []string{"us-east-1b is currently down for maintenance."}) +} + +func (s *S) TestCreateNetworkAcl(c *C) { + testServer.Response(200, nil, CreateNetworkAclExample) + + options := &ec2.CreateNetworkAcl{ + VpcId: "vpc-11ad4878", + } + + resp, err := s.ec2.CreateNetworkAcl(options) + + req := testServer.WaitRequest() + c.Assert(req.Form["VpcId"], DeepEquals, []string{"vpc-11ad4878"}) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") + c.Assert(resp.NetworkAcl.VpcId, Equals, "vpc-11ad4878") + c.Assert(resp.NetworkAcl.NetworkAclId, Equals, "acl-5fb85d36") + c.Assert(resp.NetworkAcl.Default, Equals, "false") + c.Assert(resp.NetworkAcl.EntrySet, HasLen, 2) + c.Assert(resp.NetworkAcl.EntrySet[0].RuleNumber, Equals, 32767) + c.Assert(resp.NetworkAcl.EntrySet[0].Protocol, Equals, -1) + c.Assert(resp.NetworkAcl.EntrySet[0].RuleAction, Equals, "deny") + c.Assert(resp.NetworkAcl.EntrySet[0].Egress, Equals, true) + c.Assert(resp.NetworkAcl.EntrySet[0].CidrBlock, Equals, "0.0.0.0/0") +} + +func (s *S) TestCreateNetworkAclEntry(c *C) { + testServer.Response(200, nil, CreateNetworkAclEntryRespExample) + + options := &ec2.NetworkAclEntry{ + RuleNumber: 32767, + Protocol: 6, + RuleAction: "deny", + Egress: true, + CidrBlock: "0.0.0.0/0", + PortRange: ec2.PortRange{ + To: 22, + From: 22, + }, + } + + resp, err := s.ec2.CreateNetworkAclEntry("acl-11ad4878", options) + + req := testServer.WaitRequest() + + c.Assert(req.Form["NetworkAclId"], DeepEquals, []string{"acl-11ad4878"}) + c.Assert(req.Form["RuleNumber"], DeepEquals, []string{"32767"}) + c.Assert(req.Form["Protocol"], DeepEquals, []string{"6"}) + c.Assert(req.Form["RuleAction"], DeepEquals, []string{"deny"}) + c.Assert(req.Form["Egress"], DeepEquals, []string{"true"}) + c.Assert(req.Form["CidrBlock"], DeepEquals, []string{"0.0.0.0/0"}) + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") +} + +func (s *S) TestDescribeNetworkAcls(c *C) { + testServer.Response(200, nil, DescribeNetworkAclsExample) + + filter := ec2.NewFilter() + filter.Add("vpc-id", "vpc-5266953b") + + resp, err := s.ec2.NetworkAcls([]string{"acl-5566953c", "acl-5d659634"}, filter) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") + c.Assert(resp.NetworkAcls, HasLen, 2) + c.Assert(resp.NetworkAcls[1].AssociationSet, HasLen, 2) + c.Assert(resp.NetworkAcls[1].AssociationSet[0].NetworkAclAssociationId, Equals, "aclassoc-5c659635") + c.Assert(resp.NetworkAcls[1].AssociationSet[0].NetworkAclId, Equals, "acl-5d659634") + c.Assert(resp.NetworkAcls[1].AssociationSet[0].SubnetId, Equals, "subnet-ff669596") +} + +func (s *S) TestReplaceNetworkAclAssociation(c *C) { + testServer.Response(200, nil, ReplaceNetworkAclAssociationResponseExample) + + resp, err := s.ec2.ReplaceNetworkAclAssociation("aclassoc-e5b95c8c", "acl-5fb85d36") + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "59dbff89-35bd-4eac-99ed-be587EXAMPLE") + c.Assert(resp.NewAssociationId, Equals, "aclassoc-17b85d7e") +} + +func (s *S) TestCreateCustomerGateway(c *C) { + testServer.Response(200, nil, CreateCustomerGatewayResponseExample) + + options := &ec2.CreateCustomerGateway{ + Type: "ipsec.1", + IpAddress: "10.0.0.20", + BgpAsn: 65534, + } + + resp, err := s.ec2.CreateCustomerGateway(options) + + req := testServer.WaitRequest() + c.Assert(req.Form["Type"], DeepEquals, []string{"ipsec.1"}) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "7a62c49f-347e-4fc4-9331-6e8eEXAMPLE") + c.Assert(resp.CustomerGateway.Type, Equals, "ipsec.1") + c.Assert(resp.CustomerGateway.State, Equals, "pending") + c.Assert(resp.CustomerGateway.BgpAsn, Equals, 65534) + c.Assert(resp.CustomerGateway.IpAddress, Equals, "10.0.0.20") +} + +func (s *S) TestDescribeCustomerGateways(c *C) { + testServer.Response(200, nil, DescribeCustomerGatewaysResponseExample) + + filter := ec2.NewFilter() + filter.Add("state", "pending") + + resp, err := s.ec2.DescribeCustomerGateways([]string{"cgw-b4dc3961", "cgw-b4dc3962"}, filter) + + req := testServer.WaitRequest() + c.Assert(req.Form["Filter.1.Name"], DeepEquals, []string{"state"}) + c.Assert(req.Form["Filter.1.Value.1"], DeepEquals, []string{"pending"}) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "7a62c49f-347e-4fc4-9331-6e8eEXAMPLE") + c.Assert(resp.CustomerGateways, HasLen, 2) + c.Assert(resp.CustomerGateways[0].CustomerGatewayId, Equals, "cgw-b4dc3961") + c.Assert(resp.CustomerGateways[1].CustomerGatewayId, Equals, "cgw-b4dc3962") +} + +func (s *S) TestDeleteCustomerGateway(c *C) { + testServer.Response(200, nil, DeleteCustomerGatewayResponseExample) + + resp, err := s.ec2.DeleteCustomerGateway("cgw-b4dc3961") + + req := testServer.WaitRequest() + c.Assert(req.Form["CustomerGatewayId"], DeepEquals, []string{"cgw-b4dc3961"}) + + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "7a62c49f-347e-4fc4-9331-6e8eEXAMPLE") + c.Assert(resp.Return, Equals, true) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2i_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2i_test.go index 3773041b..8b025dfb 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2i_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/ec2i_test.go @@ -166,6 +166,7 @@ var allRegions = []aws.Region{ aws.USEast, aws.USWest, aws.EUWest, + aws.EUCentral, aws.APSoutheast, aws.APNortheast, } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/responses_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/responses_test.go index 3666f70d..66046eeb 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/responses_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/ec2/responses_test.go @@ -605,6 +605,19 @@ var DescribeSecurityGroupsExample = ` + + + tcp + 80 + 80 + + + + 0.0.0.0/0 + + + + 999988887777 @@ -991,3 +1004,260 @@ var ResetImageAttributeExample = ` true ` + +// http://goo.gl/ylxT4R +var DescribeAvailabilityZonesExample1 = ` + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + + + us-east-1a + available + us-east-1 + + + + us-east-1b + available + us-east-1 + + + + us-east-1c + available + us-east-1 + + + + us-east-1d + available + us-east-1 + + + + +` + +// http://goo.gl/ylxT4R +var DescribeAvailabilityZonesExample2 = ` + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + + + us-east-1a + impaired + us-east-1 + + + + us-east-1b + unavailable + us-east-1 + + us-east-1b is currently down for maintenance. + + + + +` + +// http://goo.gl/sdomyE +var CreateNetworkAclExample = ` + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + + acl-5fb85d36 + vpc-11ad4878 + false + + + 32767 + -1 + deny + true + 0.0.0.0/0 + + + 32767 + -1 + deny + false + 0.0.0.0/0 + + + + + + +` + +// http://goo.gl/6sYloC +var CreateNetworkAclEntryRespExample = ` + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + true + +` + +// http://goo.gl/5tqceF +var DescribeNetworkAclsExample = ` + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + + + acl-5566953c + vpc-5266953b + true + + + 100 + -1 + allow + true + 0.0.0.0/0 + + + 32767 + -1 + deny + true + 0.0.0.0/0 + + + 100 + -1 + allow + false + 0.0.0.0/0 + + + 32767 + -1 + deny + false + 0.0.0.0/0 + + + + + + + acl-5d659634 + vpc-5266953b + false + + + 110 + 6 + allow + true + 0.0.0.0/0 + + 49152 + 65535 + + + + 32767 + -1 + deny + true + 0.0.0.0/0 + + + 110 + 6 + allow + false + 0.0.0.0/0 + + 80 + 80 + + + + 120 + 6 + allow + false + 0.0.0.0/0 + + 443 + 443 + + + + 32767 + -1 + deny + false + 0.0.0.0/0 + + + + + aclassoc-5c659635 + acl-5d659634 + subnet-ff669596 + + + aclassoc-c26596ab + acl-5d659634 + subnet-f0669599 + + + + + + +` + +var ReplaceNetworkAclAssociationResponseExample = ` + + 59dbff89-35bd-4eac-99ed-be587EXAMPLE + aclassoc-17b85d7e + +` + +var CreateCustomerGatewayResponseExample = ` + + 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE + + cgw-b4dc3961 + pending + ipsec.1 + 10.0.0.20 + 65534 + + + +` + +var DescribeCustomerGatewaysResponseExample = ` + + 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE + + + cgw-b4dc3961 + available + ipsec.1 + 12.1.2.3 + 65534 + + + + cgw-b4dc3962 + pending + ipsec.1 + 12.1.2.4 + 65500 + + + + +` +var DeleteCustomerGatewayResponseExample = ` + + 7a62c49f-347e-4fc4-9331-6e8eEXAMPLE + true +` diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/elb/elb.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/elb/elb.go index 5d66f4a3..e0d53f38 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/elb/elb.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/elb/elb.go @@ -4,11 +4,12 @@ package elb import ( "encoding/xml" - "github.com/mitchellh/goamz/aws" "net/http" "net/url" "strconv" "time" + + "github.com/mitchellh/goamz/aws" ) // The ELB type encapsulates operations operations with the elb endpoint. @@ -91,11 +92,11 @@ func makeParams(action string) map[string]string { // A listener attaches to an elb type Listener struct { - InstancePort int64 `xml:"member>Listener>InstancePort"` - InstanceProtocol string `xml:"member>Listener>InstanceProtocol"` - SSLCertificateId string `xml:"member>Listener>SSLCertificateId"` - LoadBalancerPort int64 `xml:"member>Listener>LoadBalancerPort"` - Protocol string `xml:"member>Listener>Protocol"` + InstancePort int64 `xml:"Listener>InstancePort"` + InstanceProtocol string `xml:"Listener>InstanceProtocol"` + SSLCertificateId string `xml:"Listener>SSLCertificateId"` + LoadBalancerPort int64 `xml:"Listener>LoadBalancerPort"` + Protocol string `xml:"Listener>Protocol"` } // An Instance attaches to an elb @@ -117,11 +118,6 @@ type InstanceState struct { ReasonCode string `xml:"ReasonCode"` } -// An Instance attaches to an elb -type AvailabilityZone struct { - AvailabilityZone string `xml:"member"` -} - // ---------------------------------------------------------------------------- // AddTags @@ -276,15 +272,16 @@ func (elb *ELB) DeleteLoadBalancer(options *DeleteLoadBalancer) (resp *SimpleRes // An individual load balancer type LoadBalancer struct { - LoadBalancerName string `xml:"member>LoadBalancerName"` - Listeners []Listener `xml:"member>ListenerDescriptions"` - Instances []Instance `xml:"member>Instances>member"` - HealthCheck HealthCheck `xml:"member>HealthCheck"` - AvailabilityZones []AvailabilityZone `xml:"member>AvailabilityZones"` - DNSName string `xml:"member>DNSName"` - SecurityGroups []string `xml:"member>SecurityGroups>member"` - Scheme string `xml:"member>Scheme"` - Subnets []string `xml:"member>Subnets>member"` + LoadBalancerName string `xml:"LoadBalancerName"` + Listeners []Listener `xml:"ListenerDescriptions>member"` + Instances []Instance `xml:"Instances>member"` + HealthCheck HealthCheck `xml:"HealthCheck"` + AvailabilityZones []string `xml:"AvailabilityZones>member"` + HostedZoneNameID string `xml:"CanonicalHostedZoneNameID"` + DNSName string `xml:"DNSName"` + SecurityGroups []string `xml:"SecurityGroups>member"` + Scheme string `xml:"Scheme"` + Subnets []string `xml:"Subnets>member"` } // DescribeLoadBalancer request params @@ -294,7 +291,7 @@ type DescribeLoadBalancer struct { type DescribeLoadBalancersResp struct { RequestId string `xml:"ResponseMetadata>RequestId"` - LoadBalancers []LoadBalancer `xml:"DescribeLoadBalancersResult>LoadBalancerDescriptions"` + LoadBalancers []LoadBalancer `xml:"DescribeLoadBalancersResult>LoadBalancerDescriptions>member"` } func (elb *ELB) DescribeLoadBalancers(options *DescribeLoadBalancer) (resp *DescribeLoadBalancersResp, err error) { @@ -316,7 +313,64 @@ func (elb *ELB) DescribeLoadBalancers(options *DescribeLoadBalancer) (resp *Desc } // ---------------------------------------------------------------------------- -// Instance Registration / degregistration +// Attributes + +type AccessLog struct { + EmitInterval int64 + Enabled bool + S3BucketName string + S3BucketPrefix string +} + +type ConnectionDraining struct { + Enabled bool + Timeout int64 +} + +type LoadBalancerAttributes struct { + CrossZoneLoadBalancingEnabled bool + ConnectionSettingsIdleTimeout int64 + ConnectionDraining ConnectionDraining + AccessLog AccessLog +} + +type ModifyLoadBalancerAttributes struct { + LoadBalancerName string + LoadBalancerAttributes LoadBalancerAttributes +} + +func (elb *ELB) ModifyLoadBalancerAttributes(options *ModifyLoadBalancerAttributes) (resp *SimpleResp, err error) { + params := makeParams("ModifyLoadBalancerAttributes") + + params["LoadBalancerName"] = options.LoadBalancerName + params["LoadBalancerAttributes.CrossZoneLoadBalancing.Enabled"] = strconv.FormatBool(options.LoadBalancerAttributes.CrossZoneLoadBalancingEnabled) + if options.LoadBalancerAttributes.ConnectionSettingsIdleTimeout > 0 { + params["LoadBalancerAttributes.ConnectionSettings.IdleTimeout"] = strconv.Itoa(int(options.LoadBalancerAttributes.ConnectionSettingsIdleTimeout)) + } + if options.LoadBalancerAttributes.ConnectionDraining.Timeout > 0 { + params["LoadBalancerAttributes.ConnectionDraining.Timeout"] = strconv.Itoa(int(options.LoadBalancerAttributes.ConnectionDraining.Timeout)) + } + params["LoadBalancerAttributes.ConnectionDraining.Enabled"] = strconv.FormatBool(options.LoadBalancerAttributes.ConnectionDraining.Enabled) + params["LoadBalancerAttributes.AccessLog.Enabled"] = strconv.FormatBool(options.LoadBalancerAttributes.AccessLog.Enabled) + if options.LoadBalancerAttributes.AccessLog.Enabled { + params["LoadBalancerAttributes.AccessLog.EmitInterval"] = strconv.Itoa(int(options.LoadBalancerAttributes.AccessLog.EmitInterval)) + params["LoadBalancerAttributes.AccessLog.S3BucketName"] = options.LoadBalancerAttributes.AccessLog.S3BucketName + params["LoadBalancerAttributes.AccessLog.S3BucketPrefix"] = options.LoadBalancerAttributes.AccessLog.S3BucketPrefix + } + + resp = &SimpleResp{} + + err = elb.query(params, resp) + + if err != nil { + resp = nil + } + + return +} + +// ---------------------------------------------------------------------------- +// Instance Registration / deregistration // The RegisterInstancesWithLoadBalancer request parameters type RegisterInstancesWithLoadBalancer struct { @@ -325,7 +379,7 @@ type RegisterInstancesWithLoadBalancer struct { } type RegisterInstancesWithLoadBalancerResp struct { - Instances []Instance `xml:"RegisterInstancesWithLoadBalancerResult>Instances"` + Instances []Instance `xml:"RegisterInstancesWithLoadBalancerResult>Instances>member"` RequestId string `xml:"ResponseMetadata>RequestId"` } @@ -356,7 +410,7 @@ type DeregisterInstancesFromLoadBalancer struct { } type DeregisterInstancesFromLoadBalancerResp struct { - Instances []Instance `xml:"DeregisterInstancesFromLoadBalancerResult>Instances"` + Instances []Instance `xml:"DeregisterInstancesFromLoadBalancerResult>Instances>member"` RequestId string `xml:"ResponseMetadata>RequestId"` } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds.go index e2dbb72b..066bf7a1 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds.go @@ -4,11 +4,12 @@ package rds import ( "encoding/xml" - "github.com/mitchellh/goamz/aws" "net/http" "net/url" "strconv" "time" + + "github.com/mitchellh/goamz/aws" ) // The Rds type encapsulates operations operations with the Rds endpoint. @@ -18,7 +19,7 @@ type Rds struct { httpClient *http.Client } -const APIVersion = "2013-09-09" +const APIVersion = "2014-10-31" // New creates a new Rds instance. func New(auth aws.Auth, region aws.Region) *Rds { @@ -92,6 +93,7 @@ func makeParams(action string) map[string]string { type DBInstance struct { Address string `xml:"Endpoint>Address"` AllocatedStorage int `xml:"AllocatedStorage"` + StorageType string `xml:"StorageType"` AvailabilityZone string `xml:"AvailabilityZone"` BackupRetentionPeriod int `xml:"BackupRetentionPeriod"` DBInstanceClass string `xml:"DBInstanceClass"` @@ -100,19 +102,22 @@ type DBInstance struct { DBName string `xml:"DBName"` Engine string `xml:"Engine"` EngineVersion string `xml:"EngineVersion"` + StorageEncrypted bool `xml:"StorageEncrypted"` MasterUsername string `xml:"MasterUsername"` MultiAZ bool `xml:"MultiAZ"` Port int `xml:"Endpoint>Port"` PreferredBackupWindow string `xml:"PreferredBackupWindow"` PreferredMaintenanceWindow string `xml:"PreferredMaintenanceWindow"` - VpcSecurityGroupIds []string `xml:"VpcSecurityGroups"` + VpcSecurityGroupIds []string `xml:"VpcSecurityGroups>VpcSecurityGroupMembership>VpcSecurityGroupId"` DBSecurityGroupNames []string `xml:"DBSecurityGroups>DBSecurityGroup>DBSecurityGroupName"` DBSubnetGroup DBSubnetGroup `xml:"DBSubnetGroup"` + DBParameterGroupName string `xml:"DBParameterGroups>DBParameterGroup>DBParameterGroupName"` } type DBSecurityGroup struct { Description string `xml:"DBSecurityGroupDescription"` Name string `xml:"DBSecurityGroupName"` + EC2SecurityGroupNames []string `xml:"EC2SecurityGroups>EC2SecurityGroup>EC2SecurityGroupName"` EC2SecurityGroupIds []string `xml:"EC2SecurityGroups>EC2SecurityGroup>EC2SecurityGroupId"` EC2SecurityGroupOwnerIds []string `xml:"EC2SecurityGroups>EC2SecurityGroup>EC2SecurityGroupOwnerId"` EC2SecurityGroupStatuses []string `xml:"EC2SecurityGroups>EC2SecurityGroup>Status"` @@ -149,12 +154,25 @@ type DBSnapshot struct { VpcId string `xml:"VpcId"` } +type DBParameterGroup struct { + DBParameterGroupFamily string `xml:"DBParameterGroupFamily"` + DBParameterGroupName string `xml:"DBParameterGroupName"` + Description string `xml:"Description"` +} + +type Parameter struct { + ApplyMethod string `xml:"ApplyMethod"` + ParameterName string `xml:"ParameterName"` + ParameterValue string `xml:"ParameterValue"` +} + // ---------------------------------------------------------------------------- // Create // The CreateDBInstance request parameters type CreateDBInstance struct { AllocatedStorage int + StorageType string AvailabilityZone string BackupRetentionPeriod int DBInstanceClass string @@ -163,6 +181,7 @@ type CreateDBInstance struct { DBSubnetGroupName string Engine string EngineVersion string + StorageEncrypted bool Iops int MasterUsername string MasterUserPassword string @@ -173,6 +192,7 @@ type CreateDBInstance struct { PubliclyAccessible bool VpcSecurityGroupIds []string DBSecurityGroupNames []string + DBParameterGroupName string SetAllocatedStorage bool SetBackupRetentionPeriod bool @@ -187,6 +207,10 @@ func (rds *Rds) CreateDBInstance(options *CreateDBInstance) (resp *SimpleResp, e params["AllocatedStorage"] = strconv.Itoa(options.AllocatedStorage) } + if options.StorageType != "" { + params["StorageType"] = options.StorageType + } + if options.SetBackupRetentionPeriod { params["BackupRetentionPeriod"] = strconv.Itoa(options.BackupRetentionPeriod) } @@ -227,6 +251,10 @@ func (rds *Rds) CreateDBInstance(options *CreateDBInstance) (resp *SimpleResp, e params["EngineVersion"] = options.EngineVersion } + if options.StorageEncrypted { + params["StorageEncrypted"] = "true" + } + if options.MasterUsername != "" { params["MasterUsername"] = options.MasterUsername } @@ -259,6 +287,10 @@ func (rds *Rds) CreateDBInstance(options *CreateDBInstance) (resp *SimpleResp, e params["DBSecurityGroups.member."+strconv.Itoa(j+1)] = group } + if options.DBParameterGroupName != "" { + params["DBParameterGroupName"] = options.DBParameterGroupName + } + resp = &SimpleResp{} err = rds.query(params, resp) @@ -362,6 +394,31 @@ func (rds *Rds) AuthorizeDBSecurityGroupIngress(options *AuthorizeDBSecurityGrou return } +// The CreateDBParameterGroup request parameters +type CreateDBParameterGroup struct { + DBParameterGroupFamily string + DBParameterGroupName string + Description string +} + +func (rds *Rds) CreateDBParameterGroup(options *CreateDBParameterGroup) (resp *SimpleResp, err error) { + params := makeParams("CreateDBParameterGroup") + + params["DBParameterGroupFamily"] = options.DBParameterGroupFamily + params["DBParameterGroupName"] = options.DBParameterGroupName + params["Description"] = options.Description + + resp = &SimpleResp{} + + err = rds.query(params, resp) + + if err != nil { + resp = nil + } + + return +} + // Describe // DescribeDBInstances request params @@ -480,6 +537,63 @@ func (rds *Rds) DescribeDBSnapshots(options *DescribeDBSnapshots) (resp *Describ return } +// DescribeDBParameterGroups request params +type DescribeDBParameterGroups struct { + DBParameterGroupName string +} + +type DescribeDBParameterGroupsResp struct { + RequestId string `xml:"ResponseMetadata>RequestId"` + DBParameterGroups []DBParameterGroup `xml:"DescribeDBParameterGroupsResult>DBParameterGroups>DBParameterGroup"` +} + +func (rds *Rds) DescribeDBParameterGroups(options *DescribeDBParameterGroups) (resp *DescribeDBParameterGroupsResp, err error) { + params := makeParams("DescribeDBParameterGroups") + + params["DBParameterGroupName"] = options.DBParameterGroupName + + resp = &DescribeDBParameterGroupsResp{} + + err = rds.query(params, resp) + + if err != nil { + resp = nil + } + + return +} + +// DescribeDBParameters request params +type DescribeDBParameters struct { + DBParameterGroupName string + Source string +} + +type DescribeDBParametersResp struct { + RequestId string `xml:"ResponseMetadata>RequestId"` + Parameters []Parameter `xml:"DescribeDBParametersResult>Parameters>Parameter"` +} + +func (rds *Rds) DescribeDBParameters(options *DescribeDBParameters) (resp *DescribeDBParametersResp, err error) { + params := makeParams("DescribeDBParameters") + + params["DBParameterGroupName"] = options.DBParameterGroupName + + if attr := options.Source; attr != "" { + params["Source"] = attr + } + + resp = &DescribeDBParametersResp{} + + err = rds.query(params, resp) + + if err != nil { + resp = nil + } + + return +} + // DeleteDBInstance request params type DeleteDBInstance struct { FinalDBSnapshotIdentifier string @@ -553,6 +667,27 @@ func (rds *Rds) DeleteDBSubnetGroup(options *DeleteDBSubnetGroup) (resp *SimpleR return } +// DeleteDBParameterGroup request params +type DeleteDBParameterGroup struct { + DBParameterGroupName string +} + +func (rds *Rds) DeleteDBParameterGroup(options *DeleteDBParameterGroup) (resp *SimpleResp, err error) { + params := makeParams("DeleteDBParameterGroup") + + params["DBParameterGroupName"] = options.DBParameterGroupName + + resp = &SimpleResp{} + + err = rds.query(params, resp) + + if err != nil { + resp = nil + } + + return +} + type RestoreDBInstanceFromDBSnapshot struct { DBInstanceIdentifier string DBSnapshotIdentifier string @@ -638,6 +773,34 @@ func (rds *Rds) RestoreDBInstanceFromDBSnapshot(options *RestoreDBInstanceFromDB return } +// ModifyDBParameterGroup request parameters +type ModifyDBParameterGroup struct { + DBParameterGroupName string + Parameters []Parameter +} + +func (rds *Rds) ModifyDBParameterGroup(options *ModifyDBParameterGroup) (resp *SimpleResp, err error) { + params := makeParams("ModifyDBParameterGroup") + + params["DBParameterGroupName"] = options.DBParameterGroupName + + for j, group := range options.Parameters { + params["Parameters.member."+strconv.Itoa(j+1)+".ApplyMethod"] = group.ApplyMethod + params["Parameters.member."+strconv.Itoa(j+1)+".ParameterName"] = group.ParameterName + params["Parameters.member."+strconv.Itoa(j+1)+".ParameterValue"] = group.ParameterValue + } + + resp = &SimpleResp{} + + err = rds.query(params, resp) + + if err != nil { + resp = nil + } + + return +} + // Responses type SimpleResp struct { diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds_test.go index 0ccadb7c..fcc6dd93 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/rds_test.go @@ -44,10 +44,12 @@ func (s *S) Test_CreateDBInstance(c *C) { EngineVersion: "", DBName: "5.6.13", AllocatedStorage: 10, + StorageType: "gp2", MasterUsername: "foobar", MasterUserPassword: "bazbarbaz", DBInstanceClass: "db.m1.small", DBSecurityGroupNames: []string{"foo", "bar"}, + DBParameterGroupName: "default.mysql5.6", SetBackupRetentionPeriod: true, } @@ -57,6 +59,7 @@ func (s *S) Test_CreateDBInstance(c *C) { c.Assert(req.Form["Action"], DeepEquals, []string{"CreateDBInstance"}) c.Assert(req.Form["Engine"], DeepEquals, []string{"mysql"}) + c.Assert(req.Form["StorageType"], DeepEquals, []string{"gp2"}) c.Assert(req.Form["DBSecurityGroups.member.1"], DeepEquals, []string{"foo"}) c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "523e3218-afc7-11c3-90f5-f90431260ab4") @@ -101,6 +104,26 @@ func (s *S) Test_CreateDBSubnetGroup(c *C) { c.Assert(resp.RequestId, Equals, "3a401b3f-bb9e-11d3-f4c6-37db295f7674") } +func (s *S) Test_CreateDBParameterGroup(c *C) { + testServer.Response(200, nil, CreateDBParameterGroupExample) + + options := rds.CreateDBParameterGroup{ + DBParameterGroupFamily: "mysql5.6", + DBParameterGroupName: "mydbparamgroup3", + Description: "My new DB Parameter Group", + } + + resp, err := s.rds.CreateDBParameterGroup(&options) + req := testServer.WaitRequest() + + c.Assert(req.Form["Action"], DeepEquals, []string{"CreateDBParameterGroup"}) + c.Assert(req.Form["DBParameterGroupFamily"], DeepEquals, []string{"mysql5.6"}) + c.Assert(req.Form["DBParameterGroupName"], DeepEquals, []string{"mydbparamgroup3"}) + c.Assert(req.Form["Description"], DeepEquals, []string{"My new DB Parameter Group"}) + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "7805c127-af22-11c3-96ac-6999cc5f7e72") +} + func (s *S) Test_DescribeDBInstances(c *C) { testServer.Response(200, nil, DescribeDBInstancesExample) @@ -117,6 +140,9 @@ func (s *S) Test_DescribeDBInstances(c *C) { c.Assert(resp.RequestId, Equals, "01b2685a-b978-11d3-f272-7cd6cce12cc5") c.Assert(resp.DBInstances[0].DBName, Equals, "mysampledb") c.Assert(resp.DBInstances[0].DBSecurityGroupNames, DeepEquals, []string{"my-db-secgroup"}) + c.Assert(resp.DBInstances[0].DBParameterGroupName, Equals, "default.mysql5.6") + c.Assert(resp.DBInstances[0].StorageType, Equals, "gp2") + c.Assert(resp.DBInstances[1].VpcSecurityGroupIds, DeepEquals, []string{"my-vpc-secgroup"}) } func (s *S) Test_DescribeDBSecurityGroups(c *C) { @@ -159,6 +185,53 @@ func (s *S) Test_DescribeDBSubnetGroups(c *C) { c.Assert(resp.DBSubnetGroups[0].VpcId, DeepEquals, "vpc-e7abbdce") } +func (s *S) Test_DescribeDBParameterGroups(c *C) { + testServer.Response(200, nil, DescribeDBParameterGroupsExample) + + options := rds.DescribeDBParameterGroups{ + DBParameterGroupName: "mydbparamgroup3", + } + + resp, err := s.rds.DescribeDBParameterGroups(&options) + req := testServer.WaitRequest() + + c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeDBParameterGroups"}) + c.Assert(req.Form["DBParameterGroupName"], DeepEquals, []string{"mydbparamgroup3"}) + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "b75d527a-b98c-11d3-f272-7cd6cce12cc5") + c.Assert(resp.DBParameterGroups[0].DBParameterGroupFamily, Equals, "mysql5.6") + c.Assert(resp.DBParameterGroups[0].Description, Equals, "My new DB Parameter Group") + c.Assert(resp.DBParameterGroups[0].DBParameterGroupName, Equals, "mydbparamgroup3") +} + +func (s *S) Test_DescribeDBParameters(c *C) { + testServer.Response(200, nil, DescribeDBParametersExample) + + options := rds.DescribeDBParameters{ + DBParameterGroupName: "mydbparamgroup3", + Source: "user", + } + + resp, err := s.rds.DescribeDBParameters(&options) + req := testServer.WaitRequest() + + c.Assert(req.Form["Action"], DeepEquals, []string{"DescribeDBParameters"}) + c.Assert(req.Form["DBParameterGroupName"], DeepEquals, []string{"mydbparamgroup3"}) + c.Assert(req.Form["Source"], DeepEquals, []string{"user"}) + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "8c40488f-b9ff-11d3-a15e-7ac49293f4fa") + c.Assert(resp.Parameters[0].ParameterName, Equals, "character_set_server") + c.Assert(resp.Parameters[0].ParameterValue, Equals, "utf8") + c.Assert(resp.Parameters[1].ParameterName, Equals, "character_set_client") + c.Assert(resp.Parameters[1].ParameterValue, Equals, "utf8") + c.Assert(resp.Parameters[2].ParameterName, Equals, "character_set_results") + c.Assert(resp.Parameters[2].ParameterValue, Equals, "utf8") + c.Assert(resp.Parameters[3].ParameterName, Equals, "collation_server") + c.Assert(resp.Parameters[3].ParameterValue, Equals, "utf8_unicode_ci") + c.Assert(resp.Parameters[4].ParameterName, Equals, "collation_connection") + c.Assert(resp.Parameters[4].ParameterValue, Equals, "utf8_unicode_ci") +} + func (s *S) Test_DeleteDBInstance(c *C) { testServer.Response(200, nil, DeleteDBInstanceExample) @@ -229,6 +302,22 @@ func (s *S) Test_DeleteDBSubnetGroup(c *C) { c.Assert(resp.RequestId, Equals, "6295e5ab-bbf3-11d3-f4c6-37db295f7674") } +func (s *S) Test_DeleteDBParameterGroup(c *C) { + testServer.Response(200, nil, DeleteDBParameterGroupExample) + + options := rds.DeleteDBParameterGroup{ + DBParameterGroupName: "mydbparamgroup3", + } + + resp, err := s.rds.DeleteDBParameterGroup(&options) + req := testServer.WaitRequest() + + c.Assert(req.Form["Action"], DeepEquals, []string{"DeleteDBParameterGroup"}) + c.Assert(req.Form["DBParameterGroupName"], DeepEquals, []string{"mydbparamgroup3"}) + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "cad6c267-ba25-11d3-fe11-33d33a9bb7e3") +} + func (s *S) Test_AuthorizeDBSecurityGroupIngress(c *C) { testServer.Response(200, nil, AuthorizeDBSecurityGroupIngressExample) @@ -287,3 +376,61 @@ func (s *S) Test_RestoreDBInstanceFromDBSnapshot(c *C) { c.Assert(err, IsNil) c.Assert(resp.RequestId, Equals, "863fd73e-be2b-11d3-855b-576787000e19") } + +func (s *S) Test_ModifyDBParameterGroup(c *C) { + testServer.Response(200, nil, ModifyDBParameterGroupExample) + + options := rds.ModifyDBParameterGroup{ + DBParameterGroupName: "mydbparamgroup3", + Parameters: []rds.Parameter{ + rds.Parameter{ + ApplyMethod: "immediate", + ParameterName: "character_set_server", + ParameterValue: "utf8", + }, + rds.Parameter{ + ApplyMethod: "immediate", + ParameterName: "character_set_client", + ParameterValue: "utf8", + }, + rds.Parameter{ + ApplyMethod: "immediate", + ParameterName: "character_set_results", + ParameterValue: "utf8", + }, + rds.Parameter{ + ApplyMethod: "immediate", + ParameterName: "collation_server", + ParameterValue: "utf8_unicode_ci", + }, + rds.Parameter{ + ApplyMethod: "immediate", + ParameterName: "collation_connection", + ParameterValue: "utf8_unicode_ci", + }, + }, + } + + resp, err := s.rds.ModifyDBParameterGroup(&options) + req := testServer.WaitRequest() + + c.Assert(req.Form["Action"], DeepEquals, []string{"ModifyDBParameterGroup"}) + c.Assert(req.Form["DBParameterGroupName"], DeepEquals, []string{"mydbparamgroup3"}) + c.Assert(req.Form["Parameters.member.1.ApplyMethod"], DeepEquals, []string{"immediate"}) + c.Assert(req.Form["Parameters.member.1.ParameterName"], DeepEquals, []string{"character_set_server"}) + c.Assert(req.Form["Parameters.member.1.ParameterValue"], DeepEquals, []string{"utf8"}) + c.Assert(req.Form["Parameters.member.2.ApplyMethod"], DeepEquals, []string{"immediate"}) + c.Assert(req.Form["Parameters.member.2.ParameterName"], DeepEquals, []string{"character_set_client"}) + c.Assert(req.Form["Parameters.member.2.ParameterValue"], DeepEquals, []string{"utf8"}) + c.Assert(req.Form["Parameters.member.3.ApplyMethod"], DeepEquals, []string{"immediate"}) + c.Assert(req.Form["Parameters.member.3.ParameterName"], DeepEquals, []string{"character_set_results"}) + c.Assert(req.Form["Parameters.member.3.ParameterValue"], DeepEquals, []string{"utf8"}) + c.Assert(req.Form["Parameters.member.4.ApplyMethod"], DeepEquals, []string{"immediate"}) + c.Assert(req.Form["Parameters.member.4.ParameterName"], DeepEquals, []string{"collation_server"}) + c.Assert(req.Form["Parameters.member.4.ParameterValue"], DeepEquals, []string{"utf8_unicode_ci"}) + c.Assert(req.Form["Parameters.member.5.ApplyMethod"], DeepEquals, []string{"immediate"}) + c.Assert(req.Form["Parameters.member.5.ParameterName"], DeepEquals, []string{"collation_connection"}) + c.Assert(req.Form["Parameters.member.5.ParameterValue"], DeepEquals, []string{"utf8_unicode_ci"}) + c.Assert(err, IsNil) + c.Assert(resp.RequestId, Equals, "12d7435e-bba0-11d3-fe11-33d33a9bb7e3") +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/responses_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/responses_test.go index 39a1e771..048557f4 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/responses_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/rds/responses_test.go @@ -9,11 +9,11 @@ var ErrorDump = ` // http://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBInstances.html var DescribeDBInstancesExample = ` - + - 1 + 7 false available @@ -54,14 +54,20 @@ var DescribeDBInstancesExample = ` true 2014-01-29T22:58:24.231Z 5 + gp2 myawsuser db.t1.micro - 1 + 7 false available - + + + active + my-vpc-secgroup + + mysqlexampledb-restore 10:07-10:37 sun:06:13-sun:06:43 @@ -88,12 +94,7 @@ var DescribeDBInstancesExample = ` in-sync - - - active - default - - + true mysampledb true @@ -111,10 +112,10 @@ var DescribeDBInstancesExample = ` ` var CreateDBInstanceExample = ` - + - 1 + 7 creating false @@ -161,10 +162,10 @@ var CreateDBInstanceExample = ` ` var DeleteDBInstanceExample = ` - + - 2 + 7 deleting false @@ -212,10 +213,11 @@ var DeleteDBInstanceExample = ` 7369556f-b70d-11c3-faca-6ba18376ea1b -` + +` var DescribeDBSecurityGroupsExample = ` - + @@ -261,17 +263,19 @@ var DescribeDBSecurityGroupsExample = ` b76e692c-b98c-11d3-a907-5a2c468b9cb0 -` + +` var DeleteDBSecurityGroupExample = ` - + 7aec7454-ba25-11d3-855b-576787000e19 ` + var CreateDBSecurityGroupExample = ` - + @@ -288,7 +292,7 @@ var CreateDBSecurityGroupExample = ` ` var AuthorizeDBSecurityGroupIngressExample = ` - + @@ -329,7 +333,7 @@ var AuthorizeDBSecurityGroupIngressExample = ` ` var DescribeDBSubnetGroupsExample = ` - + @@ -397,7 +401,7 @@ var DescribeDBSubnetGroupsExample = ` ` var DeleteDBSubnetGroupExample = ` - + 6295e5ab-bbf3-11d3-f4c6-37db295f7674 @@ -405,7 +409,7 @@ var DeleteDBSubnetGroupExample = ` ` var CreateDBSubnetGroupExample = ` - + vpc-33dc97ea @@ -439,7 +443,7 @@ var CreateDBSubnetGroupExample = ` ` var DescribeDBSnapshotsExample = ` - + @@ -502,10 +506,10 @@ var DescribeDBSnapshotsExample = ` ` var RestoreDBInstanceFromDBSnapshotExample = ` - + - 2 + 7 false creating @@ -548,3 +552,88 @@ var RestoreDBInstanceFromDBSnapshotExample = ` ` + +var CreateDBParameterGroupExample = ` + + + + mysql5.1 + My new DB Parameter Group + mydbparamgroup3 + + + + 7805c127-af22-11c3-96ac-6999cc5f7e72 + + +` + +var DescribeDBParameterGroupsExample = ` + + + + + mysql5.6 + My new DB Parameter Group + mydbparamgroup3 + + + + + b75d527a-b98c-11d3-f272-7cd6cce12cc5 + + +` + + +var DeleteDBParameterGroupExample = ` + + + cad6c267-ba25-11d3-fe11-33d33a9bb7e3 + + +` + +var ModifyDBParameterGroupExample = ` + + + mydbparamgroup3 + + + 12d7435e-bba0-11d3-fe11-33d33a9bb7e3 + + +` + +var DescribeDBParametersExample = ` + + + bGlzdGVuZXJfbmV0d29ya3M= + + + utf8 + character_set_server + + + utf8 + character_set_client + + + utf8 + character_set_results + + + utf8_unicode_ci + collation_server + + + utf8_unicode_ci + collation_connection + + + + + 8c40488f-b9ff-11d3-a15e-7ac49293f4fa + + +` diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/route53.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/route53.go index a18788a9..92d623f6 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/route53.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/route53.go @@ -1,4 +1,4 @@ -// The elb package provides types and functions for interaction with the AWS +// The route53 package provides types and functions for interaction with the AWS // Route53 service package route53 @@ -105,6 +105,18 @@ func (r *Route53) query(method, path string, req, resp interface{}) error { bodyBuf = &newBuf } + // http://docs.aws.amazon.com/Route53/latest/APIReference/CreateAliasRRSAPI.html + if reflect.Indirect(reflect.ValueOf(req)).Type().Name() == "ChangeResourceRecordSetsRequest" { + for _, change := range req.(ChangeResourceRecordSetsRequest).Changes { + if change.Record.AliasTarget != nil { + replace := change.Record.Type + "0" + var newBuf bytes.Buffer + newBuf.WriteString(strings.Replace(bodyBuf.String(), replace, change.Record.Type+"", -1)) + bodyBuf = &newBuf + } + } + } + body = bodyBuf } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/sign.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/sign.go index 0a3648e1..0e056866 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/sign.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/route53/sign.go @@ -5,8 +5,9 @@ import ( "crypto/sha256" "encoding/base64" "fmt" - "github.com/mitchellh/goamz/aws" "time" + + "github.com/mitchellh/goamz/aws" ) var b64 = base64.StdEncoding @@ -22,4 +23,7 @@ func sign(auth aws.Auth, path string, params map[string]string) { header := fmt.Sprintf("AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s", auth.AccessKey, signature) params["X-Amzn-Authorization"] = string(header) + if auth.Token != "" { + params["X-Amz-Security-Token"] = auth.Token + } } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3.go index d05731be..dbeec6ef 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3.go @@ -35,6 +35,8 @@ const debug = false type S3 struct { aws.Auth aws.Region + HTTPClient func() *http.Client + private byte // Reserve the right of using private data. } @@ -58,7 +60,13 @@ var attempts = aws.AttemptStrategy{ // New creates a new S3. func New(auth aws.Auth, region aws.Region) *S3 { - return &S3{auth, region, 0} + return &S3{ + Auth: auth, + Region: region, + HTTPClient: func() *http.Client { + return http.DefaultClient + }, + private: 0} } // Bucket returns a Bucket with the given name. @@ -189,9 +197,36 @@ func (b *Bucket) GetReader(path string) (rc io.ReadCloser, err error) { // It is the caller's responsibility to call Close on rc when // finished reading. func (b *Bucket) GetResponse(path string) (*http.Response, error) { + return b.getResponseParams(path, nil) +} + +// GetTorrent retrieves an Torrent object from an S3 bucket an io.ReadCloser. +// It is the caller's responsibility to call Close on rc when finished reading. +func (b *Bucket) GetTorrentReader(path string) (io.ReadCloser, error) { + resp, err := b.getResponseParams(path, url.Values{"torrent": {""}}) + if err != nil { + return nil, err + } + return resp.Body, nil +} + +// GetTorrent retrieves an Torrent object from an S3, returning +// the torrent as a []byte. +func (b *Bucket) GetTorrent(path string) ([]byte, error) { + body, err := b.GetTorrentReader(path) + if err != nil { + return nil, err + } + defer body.Close() + + return ioutil.ReadAll(body) +} + +func (b *Bucket) getResponseParams(path string, params url.Values) (*http.Response, error) { req := &request{ bucket: b.Name, path: path, + params: params, } err := b.S3.prepare(req) if err != nil { @@ -768,7 +803,7 @@ func (s3 *S3) run(req *request, resp interface{}) (*http.Response, error) { hreq.Body = ioutil.NopCloser(req.payload) } - hresp, err := http.DefaultClient.Do(&hreq) + hresp, err := s3.HTTPClient().Do(&hreq) if err != nil { return nil, err } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3i_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3i_test.go index 24f9ad45..9b3145d8 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3i_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3i_test.go @@ -32,6 +32,7 @@ func (s *AmazonServer) SetUp(c *C) { var _ = Suite(&AmazonClientSuite{Region: aws.USEast}) var _ = Suite(&AmazonClientSuite{Region: aws.EUWest}) +var _ = Suite(&AmazonClientSuite{Region: aws.EUCentral}) var _ = Suite(&AmazonDomainClientSuite{Region: aws.USEast}) // AmazonClientSuite tests the client against a live S3 server. diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3test/server.go b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3test/server.go index 827d680d..40e915e9 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3test/server.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mitchellh/goamz/s3/s3test/server.go @@ -226,6 +226,13 @@ var pathRegexp = regexp.MustCompile("/(([^/]+)(/(.*))?)?") // resourceForURL returns a resource object for the given URL. func (srv *Server) resourceForURL(u *url.URL) (r resource) { + + if u.Path == "/" { + return serviceResource{ + buckets: srv.buckets, + } + } + m := pathRegexp.FindStringSubmatch(u.Path) if m == nil { fatalf(404, "InvalidURI", "Couldn't parse the specified URI") @@ -283,6 +290,37 @@ func (nullResource) delete(a *action) interface{} { return notAllowed() } const timeFormat = "2006-01-02T15:04:05.000Z07:00" +type serviceResource struct { + buckets map[string]*bucket +} + +func (serviceResource) put(a *action) interface{} { return notAllowed() } +func (serviceResource) post(a *action) interface{} { return notAllowed() } +func (serviceResource) delete(a *action) interface{} { return notAllowed() } + +// GET on an s3 service lists the buckets. +// http://docs.aws.amazon.com/AmazonS3/latest/API/RESTServiceGET.html +func (r serviceResource) get(a *action) interface{} { + type respBucket struct { + Name string + } + + type response struct { + Buckets []respBucket `xml:">Bucket"` + } + + resp := response{} + + for _, bucketPtr := range r.buckets { + bkt := respBucket{ + Name: bucketPtr.name, + } + resp.Buckets = append(resp.Buckets, bkt) + } + + return &resp +} + type bucketResource struct { name string bucket *bucket // non-nil if the bucket already exists. diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mkrautz/goar/Makefile b/src/github.com/smira/aptly/_vendor/src/github.com/mkrautz/goar/Makefile deleted file mode 100644 index 962b97e6..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mkrautz/goar/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -include $(GOROOT)/src/Make.inc - -TARG=github.com/mkrautz/goar - -GOFILES=\ - common.go\ - writer.go\ - reader.go - -include $(GOROOT)/src/Make.pkg diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mkrautz/goar/reader.go b/src/github.com/smira/aptly/_vendor/src/github.com/mkrautz/goar/reader.go index 848f6a7e..c5bd8fe6 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/mkrautz/goar/reader.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mkrautz/goar/reader.go @@ -21,7 +21,7 @@ import ( // tr := ar.NewReader(r) // for { // hdr, err := tr.Next() -// if err == os.EOF { +// if err == io.EOF { // // end of archive // break // } @@ -112,7 +112,7 @@ func (ar *Reader) Next() (hdr *Header, err error) { } // Read reads from the current entry in the archive. -// It returns 0, os.EOF when it reaches the end of that entry, +// It returns 0, io.EOF when it reaches the end of that entry, // until Next is called to advance to the next entry. func (ar *Reader) Read(b []byte) (n int, err error) { if ar.dataRemain == 0 { @@ -154,12 +154,12 @@ func (ar *Reader) consumeHeader() (*Header, error) { ar.offset += int64(nread) hdr := &Header{} - fileName := arString(string(fhdr[0:15])) - mtime := arString(string(fhdr[16:27])) - uid := arString(string(fhdr[28:33])) - gid := arString(string(fhdr[34:39])) - mode := arString(string(fhdr[40:47])) - size := arString(string(fhdr[48:57])) + fileName := arString(string(fhdr[0:16])) + mtime := arString(string(fhdr[16:28])) + uid := arString(string(fhdr[28:34])) + gid := arString(string(fhdr[34:40])) + mode := arString(string(fhdr[40:48])) + size := arString(string(fhdr[48:58])) magic := arString(string(fhdr[58:60])) if magic != fileHeaderMagic { diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/LICENSE similarity index 91% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/LICENSE rename to src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/LICENSE index 6f4403c4..e9f9f628 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/LICENSE +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013 Maxim Khitrov. All rights reserved. +Copyright (c) 2014 The Go-FlowRate Authors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are @@ -12,7 +12,7 @@ met: documentation and/or other materials provided with the distribution. - * Neither the name of the mxk project nor the names of its + * Neither the name of the go-flowrate project nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/README b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/README new file mode 100644 index 00000000..db428090 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/README @@ -0,0 +1,10 @@ +Data Flow Rate Control +====================== + +To download and install this package run: + +go get github.com/mxk/go-flowrate/flowrate + +The documentation is available at: + +http://godoc.org/github.com/mxk/go-flowrate/flowrate diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/flowcontrol.go b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/flowrate.go similarity index 98% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/flowcontrol.go rename to src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/flowrate.go index 40db5d89..1b727721 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/flowcontrol.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/flowrate.go @@ -2,9 +2,9 @@ // Written by Maxim Khitrov (November 2012) // -// Package flowcontrol provides the tools for monitoring and limiting the -// transfer rate of an arbitrary data stream. -package flowcontrol +// Package flowrate provides the tools for monitoring and limiting the flow rate +// of an arbitrary data stream. +package flowrate import ( "math" diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/io.go b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/io.go similarity index 97% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/io.go rename to src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/io.go index 12a753dd..fbe09097 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/io.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/io.go @@ -2,7 +2,7 @@ // Written by Maxim Khitrov (November 2012) // -package flowcontrol +package flowrate import ( "errors" @@ -11,7 +11,7 @@ import ( // ErrLimit is returned by the Writer when a non-blocking write is short due to // the transfer rate limit. -var ErrLimit = errors.New("flowcontrol: transfer rate limit exceeded") +var ErrLimit = errors.New("flowrate: flow rate limit exceeded") // Limiter is implemented by the Reader and Writer to provide a consistent // interface for monitoring and controlling data transfer. diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/io_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/io_test.go similarity index 99% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/io_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/io_test.go index 31806936..fa7f4b4a 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/io_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/io_test.go @@ -2,7 +2,7 @@ // Written by Maxim Khitrov (November 2012) // -package flowcontrol +package flowrate import ( "bytes" diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/util.go b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/util.go similarity index 98% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/util.go rename to src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/util.go index 91efd881..4caac583 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/mxk/go1/flowcontrol/util.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/mxk/go-flowrate/flowrate/util.go @@ -2,7 +2,7 @@ // Written by Maxim Khitrov (November 2012) // -package flowcontrol +package flowrate import ( "math" diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/CONTRIBUTORS b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/CONTRIBUTORS similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/CONTRIBUTORS rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/CONTRIBUTORS diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/lib/codereview/codereview.cfg b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/lib/codereview/codereview.cfg similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/lib/codereview/codereview.cfg rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/lib/codereview/codereview.cfg diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/lib/codereview/codereview.py b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/lib/codereview/codereview.py similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/lib/codereview/codereview.py rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/lib/codereview/codereview.py diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/LICENSE similarity index 95% rename from src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/LICENSE rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/LICENSE index 6050c10f..5dc68268 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/LICENSE +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2011 The Snappy-Go Authors. All rights reserved. +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 diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/dce.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/dce.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/dce.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/dce.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/doc.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/doc.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/doc.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/doc.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/hash.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/hash.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/hash.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/hash.go diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/json.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/json.go new file mode 100644 index 00000000..760580a5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/json.go @@ -0,0 +1,30 @@ +// 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/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/json_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/json_test.go new file mode 100644 index 00000000..b5eae092 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/json_test.go @@ -0,0 +1,32 @@ +// 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/json" + "reflect" + "testing" +) + +var testUUID = Parse("f47ac10b-58cc-0372-8567-0e02b2c3d479") + +func TestJSON(t *testing.T) { + type S struct { + ID1 UUID + ID2 UUID + } + s1 := S{ID1: testUUID} + data, err := json.Marshal(&s1) + if err != nil { + t.Fatal(err) + } + var s2 S + if err := json.Unmarshal(data, &s2); err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(&s1, &s2) { + t.Errorf("got %#v, want %#v", s2, s1) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/node.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/node.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/node.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/node.go diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/seq_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/seq_test.go new file mode 100644 index 00000000..3b3d1430 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/seq_test.go @@ -0,0 +1,66 @@ +// 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 ( + "flag" + "runtime" + "testing" + "time" +) + +// This test is only run when --regressions is passed on the go test line. +var regressions = flag.Bool("regressions", false, "run uuid regression tests") + +// TestClockSeqRace tests for a particular race condition of returning two +// identical Version1 UUIDs. The duration of 1 minute was chosen as the race +// condition, before being fixed, nearly always occured in under 30 seconds. +func TestClockSeqRace(t *testing.T) { + if !*regressions { + t.Skip("skipping regression tests") + } + duration := time.Minute + + done := make(chan struct{}) + defer close(done) + + ch := make(chan UUID, 10000) + ncpu := runtime.NumCPU() + switch ncpu { + case 0, 1: + // We can't run the test effectively. + t.Skip("skipping race test, only one CPU detected") + return + default: + runtime.GOMAXPROCS(ncpu) + } + for i := 0; i < ncpu; i++ { + go func() { + for { + select { + case <-done: + return + case ch <- NewUUID(): + } + } + }() + } + + uuids := make(map[string]bool) + cnt := 0 + start := time.Now() + for u := range ch { + s := u.String() + if uuids[s] { + t.Errorf("duplicate uuid after %d in %v: %s", cnt, time.Since(start), s) + return + } + uuids[s] = true + if time.Since(start) > duration { + return + } + cnt++ + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/time.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/time.go similarity index 83% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/time.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/time.go index ad467968..7ebc9bef 100755 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/time.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/time.go @@ -1,4 +1,4 @@ -// Copyright 2011 Google Inc. All rights reserved. +// 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. @@ -6,6 +6,7 @@ package uuid import ( "encoding/binary" + "sync" "time" ) @@ -22,6 +23,7 @@ const ( ) var ( + mu sync.Mutex lasttime uint64 // last time we returned clock_seq uint16 // clock sequence for this run @@ -38,14 +40,20 @@ func (t Time) UnixTime() (sec, nsec int64) { } // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and -// adjusts the clock sequence as needed. An error is returned if the current -// time cannot be determined. -func GetTime() (Time, error) { +// 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) + setClockSequence(-1) } now := uint64(t.UnixNano()/100) + g1582ns100 @@ -55,7 +63,7 @@ func GetTime() (Time, error) { clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000 } lasttime = now - return Time(now), nil + return Time(now), clock_seq, nil } // ClockSequence returns the current clock sequence, generating one if not @@ -67,8 +75,14 @@ func GetTime() (Time, error) { // 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) + setClockSequence(-1) } return int(clock_seq & 0x3fff) } @@ -76,6 +90,12 @@ func ClockSequence() int { // 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 diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/util.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/util.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/util.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/util.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/uuid.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/uuid.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/uuid.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/uuid.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/uuid_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/uuid_test.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/uuid_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/uuid_test.go diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/version1.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/version1.go similarity index 93% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/version1.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/version1.go index 63580044..0127eacf 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/version1.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/version1.go @@ -19,7 +19,7 @@ func NewUUID() UUID { SetNodeInterface("") } - now, err := GetTime() + now, seq, err := GetTime() if err != nil { return nil } @@ -34,7 +34,7 @@ func NewUUID() UUID { 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:], clock_seq) + binary.BigEndian.PutUint16(uuid[8:], seq) copy(uuid[10:], nodeID) return uuid diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/version4.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/version4.go similarity index 100% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/version4.go rename to src/github.com/smira/aptly/_vendor/src/github.com/smira/go-uuid/uuid/version4.go diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/.gitignore b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/.gitignore new file mode 100644 index 00000000..daf913b1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/.gitignore @@ -0,0 +1,24 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/.travis.yml b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/.travis.yml new file mode 100644 index 00000000..2712da42 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/.travis.yml @@ -0,0 +1,6 @@ +language: go + +go: + - 1.3.3 + - 1.4 + - tip diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/LICENSE new file mode 100644 index 00000000..d0b896b7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Andrey Smirnov + +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/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/README.md b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/README.md new file mode 100644 index 00000000..a01d937b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/README.md @@ -0,0 +1,17 @@ +# go-xz + +[![GoDoc](https://godoc.org/github.com/smira/go-xz?status.svg)](https://godoc.org/github.com/smira/go-xz) +[![Build Status](https://travis-ci.org/smira/go-xz.svg?branch=master)](https://travis-ci.org/smira/go-xz) + +Simple .xz decompression using external program (xz --decompress) + +## Why? + +All go implementation of .xz decompression rely on `liblzma` dependency providing +in-process decompression. + +This package uses external `xz` utility, so no depdendencies for the compiled binary. + +## License + +MIT \ No newline at end of file diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/testdata/spec b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/testdata/spec new file mode 100644 index 00000000..0e0ff7ad --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/testdata/spec @@ -0,0 +1,6434 @@ + + + + + + The Go Programming Language Specification - The Go Programming Language + + + + + + + + + + + +
+... +
+ + + + +
+
+
+
+ Run + Format + +
+
+ + +
+
+ + +

The Go Programming Language Specification

+ + +

Version of November 11, 2014

+ + + + + + + + + + + +

Introduction

+ +

+This is a reference manual for the Go programming language. For +more information and other documents, see golang.org. +

+ +

+Go is a general-purpose language designed with systems programming +in mind. It is strongly typed and garbage-collected and has explicit +support for concurrent programming. Programs are constructed from +packages, whose properties allow efficient management of +dependencies. The existing implementations use a traditional +compile/link model to generate executable binaries. +

+ +

+The grammar is compact and regular, allowing for easy analysis by +automatic tools such as integrated development environments. +

+ +

Notation

+

+The syntax is specified using Extended Backus-Naur Form (EBNF): +

+ +
+Production  = production_name "=" [ Expression ] "." .
+Expression  = Alternative { "|" Alternative } .
+Alternative = Term { Term } .
+Term        = production_name | token [ "…" token ] | Group | Option | Repetition .
+Group       = "(" Expression ")" .
+Option      = "[" Expression "]" .
+Repetition  = "{" Expression "}" .
+
+ +

+Productions are expressions constructed from terms and the following +operators, in increasing precedence: +

+
+|   alternation
+()  grouping
+[]  option (0 or 1 times)
+{}  repetition (0 to n times)
+
+ +

+Lower-case production names are used to identify lexical tokens. +Non-terminals are in CamelCase. Lexical tokens are enclosed in +double quotes "" or back quotes ``. +

+ +

+The form a … b represents the set of characters from +a through b as alternatives. The horizontal +ellipsis is also used elsewhere in the spec to informally denote various +enumerations or code snippets that are not further specified. The character +(as opposed to the three characters ...) is not a token of the Go +language. +

+ +

Source code representation

+ +

+Source code is Unicode text encoded in +UTF-8. The text is not +canonicalized, so a single accented code point is distinct from the +same character constructed from combining an accent and a letter; +those are treated as two code points. For simplicity, this document +will use the unqualified term character to refer to a Unicode code point +in the source text. +

+

+Each code point is distinct; for instance, upper and lower case letters +are different characters. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may disallow the NUL character (U+0000) in the source text. +

+

+Implementation restriction: For compatibility with other tools, a +compiler may ignore a UTF-8-encoded byte order mark +(U+FEFF) if it is the first Unicode code point in the source text. +A byte order mark may be disallowed anywhere else in the source. +

+ +

Characters

+ +

+The following terms are used to denote specific Unicode character classes: +

+
+newline        = /* the Unicode code point U+000A */ .
+unicode_char   = /* an arbitrary Unicode code point except newline */ .
+unicode_letter = /* a Unicode code point classified as "Letter" */ .
+unicode_digit  = /* a Unicode code point classified as "Decimal Digit" */ .
+
+ +

+In The Unicode Standard 6.3, +Section 4.5 "General Category" +defines a set of character categories. Go treats +those characters in category Lu, Ll, Lt, Lm, or Lo as Unicode letters, +and those in category Nd as Unicode digits. +

+ +

Letters and digits

+ +

+The underscore character _ (U+005F) is considered a letter. +

+
+letter        = unicode_letter | "_" .
+decimal_digit = "0" … "9" .
+octal_digit   = "0" … "7" .
+hex_digit     = "0" … "9" | "A" … "F" | "a" … "f" .
+
+ +

Lexical elements

+ +

Comments

+ +

+There are two forms of comments: +

+ +
    +
  1. +Line comments start with the character sequence // +and stop at the end of the line. A line comment acts like a newline. +
  2. +
  3. +General comments start with the character sequence /* +and continue through the character sequence */. A general +comment containing one or more newlines acts like a newline, otherwise it acts +like a space. +
  4. +
+ +

+Comments do not nest. +

+ + +

Tokens

+ +

+Tokens form the vocabulary of the Go language. +There are four classes: identifiers, keywords, operators +and delimiters, and literals. White space, formed from +spaces (U+0020), horizontal tabs (U+0009), +carriage returns (U+000D), and newlines (U+000A), +is ignored except as it separates tokens +that would otherwise combine into a single token. Also, a newline or end of file +may trigger the insertion of a semicolon. +While breaking the input into tokens, +the next token is the longest sequence of characters that form a +valid token. +

+ +

Semicolons

+ +

+The formal grammar uses semicolons ";" as terminators in +a number of productions. Go programs may omit most of these semicolons +using the following two rules: +

+ +
    +
  1. +

    +When the input is broken into tokens, a semicolon is automatically inserted +into the token stream at the end of a non-blank line if the line's final +token is +

    + +
  2. + +
  3. +To allow complex statements to occupy a single line, a semicolon +may be omitted before a closing ")" or "}". +
  4. +
+ +

+To reflect idiomatic use, code examples in this document elide semicolons +using these rules. +

+ + +

Identifiers

+ +

+Identifiers name program entities such as variables and types. +An identifier is a sequence of one or more letters and digits. +The first character in an identifier must be a letter. +

+
+identifier = letter { letter | unicode_digit } .
+
+
+a
+_x9
+ThisVariableIsExported
+αβ
+
+ +

+Some identifiers are predeclared. +

+ + +

Keywords

+ +

+The following keywords are reserved and may not be used as identifiers. +

+
+break        default      func         interface    select
+case         defer        go           map          struct
+chan         else         goto         package      switch
+const        fallthrough  if           range        type
+continue     for          import       return       var
+
+ +

Operators and Delimiters

+ +

+The following character sequences represent operators, delimiters, and other special tokens: +

+
++    &     +=    &=     &&    ==    !=    (    )
+-    |     -=    |=     ||    <     <=    [    ]
+*    ^     *=    ^=     <-    >     >=    {    }
+/    <<    /=    <<=    ++    =     :=    ,    ;
+%    >>    %=    >>=    --    !     ...   .    :
+     &^          &^=
+
+ +

Integer literals

+ +

+An integer literal is a sequence of digits representing an +integer constant. +An optional prefix sets a non-decimal base: 0 for octal, 0x or +0X for hexadecimal. In hexadecimal literals, letters +a-f and A-F represent values 10 through 15. +

+
+int_lit     = decimal_lit | octal_lit | hex_lit .
+decimal_lit = ( "1" … "9" ) { decimal_digit } .
+octal_lit   = "0" { octal_digit } .
+hex_lit     = "0" ( "x" | "X" ) hex_digit { hex_digit } .
+
+ +
+42
+0600
+0xBadFace
+170141183460469231731687303715884105727
+
+ +

Floating-point literals

+

+A floating-point literal is a decimal representation of a +floating-point constant. +It has an integer part, a decimal point, a fractional part, +and an exponent part. The integer and fractional part comprise +decimal digits; the exponent part is an e or E +followed by an optionally signed decimal exponent. One of the +integer part or the fractional part may be elided; one of the decimal +point or the exponent may be elided. +

+
+float_lit = decimals "." [ decimals ] [ exponent ] |
+            decimals exponent |
+            "." decimals [ exponent ] .
+decimals  = decimal_digit { decimal_digit } .
+exponent  = ( "e" | "E" ) [ "+" | "-" ] decimals .
+
+ +
+0.
+72.40
+072.40  // == 72.40
+2.71828
+1.e+0
+6.67428e-11
+1E6
+.25
+.12345E+5
+
+ +

Imaginary literals

+

+An imaginary literal is a decimal representation of the imaginary part of a +complex constant. +It consists of a +floating-point literal +or decimal integer followed +by the lower-case letter i. +

+
+imaginary_lit = (decimals | float_lit) "i" .
+
+ +
+0i
+011i  // == 11i
+0.i
+2.71828i
+1.e+0i
+6.67428e-11i
+1E6i
+.25i
+.12345E+5i
+
+ + +

Rune literals

+ +

+A rune literal represents a rune constant, +an integer value identifying a Unicode code point. +A rune literal is expressed as one or more characters enclosed in single quotes. +Within the quotes, any character may appear except single +quote and newline. A single quoted character represents the Unicode value +of the character itself, +while multi-character sequences beginning with a backslash encode +values in various formats. +

+

+The simplest form represents the single character within the quotes; +since Go source text is Unicode characters encoded in UTF-8, multiple +UTF-8-encoded bytes may represent a single integer value. For +instance, the literal 'a' holds a single byte representing +a literal a, Unicode U+0061, value 0x61, while +'ä' holds two bytes (0xc3 0xa4) representing +a literal a-dieresis, U+00E4, value 0xe4. +

+

+Several backslash escapes allow arbitrary values to be encoded as +ASCII text. There are four ways to represent the integer value +as a numeric constant: \x followed by exactly two hexadecimal +digits; \u followed by exactly four hexadecimal digits; +\U followed by exactly eight hexadecimal digits, and a +plain backslash \ followed by exactly three octal digits. +In each case the value of the literal is the value represented by +the digits in the corresponding base. +

+

+Although these representations all result in an integer, they have +different valid ranges. Octal escapes must represent a value between +0 and 255 inclusive. Hexadecimal escapes satisfy this condition +by construction. The escapes \u and \U +represent Unicode code points so within them some values are illegal, +in particular those above 0x10FFFF and surrogate halves. +

+

+After a backslash, certain single-character escapes represent special values: +

+
+\a   U+0007 alert or bell
+\b   U+0008 backspace
+\f   U+000C form feed
+\n   U+000A line feed or newline
+\r   U+000D carriage return
+\t   U+0009 horizontal tab
+\v   U+000b vertical tab
+\\   U+005c backslash
+\'   U+0027 single quote  (valid escape only within rune literals)
+\"   U+0022 double quote  (valid escape only within string literals)
+
+

+All other sequences starting with a backslash are illegal inside rune literals. +

+
+rune_lit         = "'" ( unicode_value | byte_value ) "'" .
+unicode_value    = unicode_char | little_u_value | big_u_value | escaped_char .
+byte_value       = octal_byte_value | hex_byte_value .
+octal_byte_value = `\` octal_digit octal_digit octal_digit .
+hex_byte_value   = `\` "x" hex_digit hex_digit .
+little_u_value   = `\` "u" hex_digit hex_digit hex_digit hex_digit .
+big_u_value      = `\` "U" hex_digit hex_digit hex_digit hex_digit
+                           hex_digit hex_digit hex_digit hex_digit .
+escaped_char     = `\` ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | `\` | "'" | `"` ) .
+
+ +
+'a'
+'ä'
+'本'
+'\t'
+'\000'
+'\007'
+'\377'
+'\x07'
+'\xff'
+'\u12e4'
+'\U00101234'
+'aa'         // illegal: too many characters
+'\xa'        // illegal: too few hexadecimal digits
+'\0'         // illegal: too few octal digits
+'\uDFFF'     // illegal: surrogate half
+'\U00110000' // illegal: invalid Unicode code point
+
+ + +

String literals

+ +

+A string literal represents a string constant +obtained from concatenating a sequence of characters. There are two forms: +raw string literals and interpreted string literals. +

+

+Raw string literals are character sequences between back quotes +``. Within the quotes, any character is legal except +back quote. The value of a raw string literal is the +string composed of the uninterpreted (implicitly UTF-8-encoded) characters +between the quotes; +in particular, backslashes have no special meaning and the string may +contain newlines. +Carriage return characters ('\r') inside raw string literals +are discarded from the raw string value. +

+

+Interpreted string literals are character sequences between double +quotes "". The text between the quotes, +which may not contain newlines, forms the +value of the literal, with backslash escapes interpreted as they +are in rune literals (except that \' is illegal and +\" is legal), with the same restrictions. +The three-digit octal (\nnn) +and two-digit hexadecimal (\xnn) escapes represent individual +bytes of the resulting string; all other escapes represent +the (possibly multi-byte) UTF-8 encoding of individual characters. +Thus inside a string literal \377 and \xFF represent +a single byte of value 0xFF=255, while ÿ, +\u00FF, \U000000FF and \xc3\xbf represent +the two bytes 0xc3 0xbf of the UTF-8 encoding of character +U+00FF. +

+ +
+string_lit             = raw_string_lit | interpreted_string_lit .
+raw_string_lit         = "`" { unicode_char | newline } "`" .
+interpreted_string_lit = `"` { unicode_value | byte_value } `"` .
+
+ +
+`abc`  // same as "abc"
+`\n
+\n`    // same as "\\n\n\\n"
+"\n"
+""
+"Hello, world!\n"
+"日本語"
+"\u65e5本\U00008a9e"
+"\xff\u00FF"
+"\uD800"       // illegal: surrogate half
+"\U00110000"   // illegal: invalid Unicode code point
+
+ +

+These examples all represent the same string: +

+ +
+"日本語"                                 // UTF-8 input text
+`日本語`                                 // UTF-8 input text as a raw literal
+"\u65e5\u672c\u8a9e"                    // the explicit Unicode code points
+"\U000065e5\U0000672c\U00008a9e"        // the explicit Unicode code points
+"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"  // the explicit UTF-8 bytes
+
+ +

+If the source code represents a character as two code points, such as +a combining form involving an accent and a letter, the result will be +an error if placed in a rune literal (it is not a single code +point), and will appear as two code points if placed in a string +literal. +

+ + +

Constants

+ +

There are boolean constants, +rune constants, +integer constants, +floating-point constants, complex constants, +and string constants. Rune, integer, floating-point, +and complex constants are +collectively called numeric constants. +

+ +

+A constant value is represented by a +rune, +integer, +floating-point, +imaginary, +or +string literal, +an identifier denoting a constant, +a constant expression, +a conversion with a result that is a constant, or +the result value of some built-in functions such as +unsafe.Sizeof applied to any value, +cap or len applied to +some expressions, +real and imag applied to a complex constant +and complex applied to numeric constants. +The boolean truth values are represented by the predeclared constants +true and false. The predeclared identifier +iota denotes an integer constant. +

+ +

+In general, complex constants are a form of +constant expression +and are discussed in that section. +

+ +

+Numeric constants represent values of arbitrary precision and do not overflow. +

+ +

+Constants may be typed or untyped. +Literal constants, true, false, iota, +and certain constant expressions +containing only untyped constant operands are untyped. +

+ +

+A constant may be given a type explicitly by a constant declaration +or conversion, or implicitly when used in a +variable declaration or an +assignment or as an +operand in an expression. +It is an error if the constant value +cannot be represented as a value of the respective type. +For instance, 3.0 can be given any integer or any +floating-point type, while 2147483648.0 (equal to 1<<31) +can be given the types float32, float64, or uint32 but +not int32 or string. +

+ +

+An untyped constant has a default type which is the type to which the +constant is implicitly converted in contexts where a typed value is required, +for instance, in a short variable declaration +such as i := 0 where there is no explicit type. +The default type of an untyped constant is bool, rune, +int, float64, complex128 or string +respectively, depending on whether it is a boolean, rune, integer, floating-point, +complex, or string constant. +

+ +

+There are no constants denoting the IEEE-754 infinity and not-a-number values, +but the math package's +Inf, +NaN, +IsInf, and +IsNaN +functions return and test for those values at run time. +

+ +

+Implementation restriction: Although numeric constants have arbitrary +precision in the language, a compiler may implement them using an +internal representation with limited precision. That said, every +implementation must: +

+
    +
  • Represent integer constants with at least 256 bits.
  • + +
  • Represent floating-point constants, including the parts of + a complex constant, with a mantissa of at least 256 bits + and a signed exponent of at least 32 bits.
  • + +
  • Give an error if unable to represent an integer constant + precisely.
  • + +
  • Give an error if unable to represent a floating-point or + complex constant due to overflow.
  • + +
  • Round to the nearest representable constant if unable to + represent a floating-point or complex constant due to limits + on precision.
  • +
+

+These requirements apply both to literal constants and to the result +of evaluating constant +expressions. +

+ +

Variables

+ +

+A variable is a storage location for holding a value. +The set of permissible values is determined by the +variable's type. +

+ +

+A variable declaration +or, for function parameters and results, the signature +of a function declaration +or function literal reserves +storage for a named variable. + +Calling the built-in function new +or taking the address of a composite literal +allocates storage for a variable at run time. +Such an anonymous variable is referred to via a (possibly implicit) +pointer indirection. +

+ +

+Structured variables of array, slice, +and struct types have elements and fields that may +be addressed individually. Each such element +acts like a variable. +

+ +

+The static type (or just type) of a variable is the +type given in its declaration, the type provided in the +new call or composite literal, or the type of +an element of a structured variable. +Variables of interface type also have a distinct dynamic type, +which is the concrete type of the value assigned to the variable at run time +(unless the value is the predeclared identifier nil, +which has no type). +The dynamic type may vary during execution but values stored in interface +variables are always assignable +to the static type of the variable. +

+ +
+var x interface{}  // x is nil and has static type interface{}
+var v *T           // v has value nil, static type *T
+x = 42             // x has value 42 and dynamic type int
+x = v              // x has value (*T)(nil) and dynamic type *T
+
+ +

+A variable's value is retrieved by referring to the variable in an +expression; it is the most recent value +assigned to the variable. +If a variable has not yet been assigned a value, its value is the +zero value for its type. +

+ + +

Types

+ +

+A type determines the set of values and operations specific to values of that +type. Types may be named or unnamed. Named types are specified +by a (possibly qualified) +type name; unnamed types are specified +using a type literal, which composes a new type from existing types. +

+ +
+Type      = TypeName | TypeLit | "(" Type ")" .
+TypeName  = identifier | QualifiedIdent .
+TypeLit   = ArrayType | StructType | PointerType | FunctionType | InterfaceType |
+	    SliceType | MapType | ChannelType .
+
+ +

+Named instances of the boolean, numeric, and string types are +predeclared. +Composite types—array, struct, pointer, function, +interface, slice, map, and channel types—may be constructed using +type literals. +

+ +

+Each type T has an underlying type: If T +is one of the predeclared boolean, numeric, or string types, or a type literal, +the corresponding underlying +type is T itself. Otherwise, T's underlying type +is the underlying type of the type to which T refers in its +type declaration. +

+ +
+   type T1 string
+   type T2 T1
+   type T3 []T1
+   type T4 T3
+
+ +

+The underlying type of string, T1, and T2 +is string. The underlying type of []T1, T3, +and T4 is []T1. +

+ +

Method sets

+

+A type may have a method set associated with it. +The method set of an interface type is its interface. +The method set of any other type T consists of all +methods declared with receiver type T. +The method set of the corresponding pointer type *T +is the set of all methods declared with receiver *T or T +(that is, it also contains the method set of T). +Further rules apply to structs containing anonymous fields, as described +in the section on struct types. +Any other type has an empty method set. +In a method set, each method must have a +unique +non-blank method name. +

+ +

+The method set of a type determines the interfaces that the +type implements +and the methods that can be called +using a receiver of that type. +

+ +

Boolean types

+ +

+A boolean type represents the set of Boolean truth values +denoted by the predeclared constants true +and false. The predeclared boolean type is bool. +

+ +

Numeric types

+ +

+A numeric type represents sets of integer or floating-point values. +The predeclared architecture-independent numeric types are: +

+ +
+uint8       the set of all unsigned  8-bit integers (0 to 255)
+uint16      the set of all unsigned 16-bit integers (0 to 65535)
+uint32      the set of all unsigned 32-bit integers (0 to 4294967295)
+uint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)
+
+int8        the set of all signed  8-bit integers (-128 to 127)
+int16       the set of all signed 16-bit integers (-32768 to 32767)
+int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
+int64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
+
+float32     the set of all IEEE-754 32-bit floating-point numbers
+float64     the set of all IEEE-754 64-bit floating-point numbers
+
+complex64   the set of all complex numbers with float32 real and imaginary parts
+complex128  the set of all complex numbers with float64 real and imaginary parts
+
+byte        alias for uint8
+rune        alias for int32
+
+ +

+The value of an n-bit integer is n bits wide and represented using +two's complement arithmetic. +

+ +

+There is also a set of predeclared numeric types with implementation-specific sizes: +

+ +
+uint     either 32 or 64 bits
+int      same size as uint
+uintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value
+
+ +

+To avoid portability issues all numeric types are distinct except +byte, which is an alias for uint8, and +rune, which is an alias for int32. +Conversions +are required when different numeric types are mixed in an expression +or assignment. For instance, int32 and int +are not the same type even though they may have the same size on a +particular architecture. + + +

String types

+ +

+A string type represents the set of string values. +A string value is a (possibly empty) sequence of bytes. +Strings are immutable: once created, +it is impossible to change the contents of a string. +The predeclared string type is string. +

+ +

+The length of a string s (its size in bytes) can be discovered using +the built-in function len. +The length is a compile-time constant if the string is a constant. +A string's bytes can be accessed by integer indices +0 through len(s)-1. +It is illegal to take the address of such an element; if +s[i] is the i'th byte of a +string, &s[i] is invalid. +

+ + +

Array types

+ +

+An array is a numbered sequence of elements of a single +type, called the element type. +The number of elements is called the length and is never +negative. +

+ +
+ArrayType   = "[" ArrayLength "]" ElementType .
+ArrayLength = Expression .
+ElementType = Type .
+
+ +

+The length is part of the array's type; it must evaluate to a +non-negative constant representable by a value +of type int. +The length of array a can be discovered +using the built-in function len. +The elements can be addressed by integer indices +0 through len(a)-1. +Array types are always one-dimensional but may be composed to form +multi-dimensional types. +

+ +
+[32]byte
+[2*N] struct { x, y int32 }
+[1000]*float64
+[3][5]int
+[2][2][2]float64  // same as [2]([2]([2]float64))
+
+ +

Slice types

+ +

+A slice is a descriptor for a contiguous segment of an underlying array and +provides access to a numbered sequence of elements from that array. +A slice type denotes the set of all slices of arrays of its element type. +The value of an uninitialized slice is nil. +

+ +
+SliceType = "[" "]" ElementType .
+
+ +

+Like arrays, slices are indexable and have a length. The length of a +slice s can be discovered by the built-in function +len; unlike with arrays it may change during +execution. The elements can be addressed by integer indices +0 through len(s)-1. The slice index of a +given element may be less than the index of the same element in the +underlying array. +

+

+A slice, once initialized, is always associated with an underlying +array that holds its elements. A slice therefore shares storage +with its array and with other slices of the same array; by contrast, +distinct arrays always represent distinct storage. +

+

+The array underlying a slice may extend past the end of the slice. +The capacity is a measure of that extent: it is the sum of +the length of the slice and the length of the array beyond the slice; +a slice of length up to that capacity can be created by +slicing a new one from the original slice. +The capacity of a slice a can be discovered using the +built-in function cap(a). +

+ +

+A new, initialized slice value for a given element type T is +made using the built-in function +make, +which takes a slice type +and parameters specifying the length and optionally the capacity. +A slice created with make always allocates a new, hidden array +to which the returned slice value refers. That is, executing +

+ +
+make([]T, length, capacity)
+
+ +

+produces the same slice as allocating an array and slicing +it, so these two expressions are equivalent: +

+ +
+make([]int, 50, 100)
+new([100]int)[0:50]
+
+ +

+Like arrays, slices are always one-dimensional but may be composed to construct +higher-dimensional objects. +With arrays of arrays, the inner arrays are, by construction, always the same length; +however with slices of slices (or arrays of slices), the inner lengths may vary dynamically. +Moreover, the inner slices must be initialized individually. +

+ +

Struct types

+ +

+A struct is a sequence of named elements, called fields, each of which has a +name and a type. Field names may be specified explicitly (IdentifierList) or +implicitly (AnonymousField). +Within a struct, non-blank field names must +be unique. +

+ +
+StructType     = "struct" "{" { FieldDecl ";" } "}" .
+FieldDecl      = (IdentifierList Type | AnonymousField) [ Tag ] .
+AnonymousField = [ "*" ] TypeName .
+Tag            = string_lit .
+
+ +
+// An empty struct.
+struct {}
+
+// A struct with 6 fields.
+struct {
+	x, y int
+	u float32
+	_ float32  // padding
+	A *[]int
+	F func()
+}
+
+ +

+A field declared with a type but no explicit field name is an anonymous field, +also called an embedded field or an embedding of the type in the struct. +An embedded type must be specified as +a type name T or as a pointer to a non-interface type name *T, +and T itself may not be +a pointer type. The unqualified type name acts as the field name. +

+ +
+// A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4
+struct {
+	T1        // field name is T1
+	*T2       // field name is T2
+	P.T3      // field name is T3
+	*P.T4     // field name is T4
+	x, y int  // field names are x and y
+}
+
+ +

+The following declaration is illegal because field names must be unique +in a struct type: +

+ +
+struct {
+	T     // conflicts with anonymous field *T and *P.T
+	*T    // conflicts with anonymous field T and *P.T
+	*P.T  // conflicts with anonymous field T and *T
+}
+
+ +

+A field or method f of an +anonymous field in a struct x is called promoted if +x.f is a legal selector that denotes +that field or method f. +

+ +

+Promoted fields act like ordinary fields +of a struct except that they cannot be used as field names in +composite literals of the struct. +

+ +

+Given a struct type S and a type named T, +promoted methods are included in the method set of the struct as follows: +

+
    +
  • + If S contains an anonymous field T, + the method sets of S + and *S both include promoted methods with receiver + T. The method set of *S also + includes promoted methods with receiver *T. +
  • + +
  • + If S contains an anonymous field *T, + the method sets of S and *S both + include promoted methods with receiver T or + *T. +
  • +
+ +

+A field declaration may be followed by an optional string literal tag, +which becomes an attribute for all the fields in the corresponding +field declaration. The tags are made +visible through a reflection interface +and take part in type identity for structs +but are otherwise ignored. +

+ +
+// A struct corresponding to the TimeStamp protocol buffer.
+// The tag strings define the protocol buffer field numbers.
+struct {
+	microsec  uint64 "field 1"
+	serverIP6 uint64 "field 2"
+	process   string "field 3"
+}
+
+ +

Pointer types

+ +

+A pointer type denotes the set of all pointers to variables of a given +type, called the base type of the pointer. +The value of an uninitialized pointer is nil. +

+ +
+PointerType = "*" BaseType .
+BaseType    = Type .
+
+ +
+*Point
+*[4]int
+
+ +

Function types

+ +

+A function type denotes the set of all functions with the same parameter +and result types. The value of an uninitialized variable of function type +is nil. +

+ +
+FunctionType   = "func" Signature .
+Signature      = Parameters [ Result ] .
+Result         = Parameters | Type .
+Parameters     = "(" [ ParameterList [ "," ] ] ")" .
+ParameterList  = ParameterDecl { "," ParameterDecl } .
+ParameterDecl  = [ IdentifierList ] [ "..." ] Type .
+
+ +

+Within a list of parameters or results, the names (IdentifierList) +must either all be present or all be absent. If present, each name +stands for one item (parameter or result) of the specified type and +all non-blank names in the signature +must be unique. +If absent, each type stands for one item of that type. +Parameter and result +lists are always parenthesized except that if there is exactly +one unnamed result it may be written as an unparenthesized type. +

+ +

+The final parameter in a function signature may have +a type prefixed with .... +A function with such a parameter is called variadic and +may be invoked with zero or more arguments for that parameter. +

+ +
+func()
+func(x int) int
+func(a, _ int, z float32) bool
+func(a, b int, z float32) (bool)
+func(prefix string, values ...int)
+func(a, b int, z float64, opt ...interface{}) (success bool)
+func(int, int, float64) (float64, *[]int)
+func(n int) func(p *T)
+
+ + +

Interface types

+ +

+An interface type specifies a method set called its interface. +A variable of interface type can store a value of any type with a method set +that is any superset of the interface. Such a type is said to +implement the interface. +The value of an uninitialized variable of interface type is nil. +

+ +
+InterfaceType      = "interface" "{" { MethodSpec ";" } "}" .
+MethodSpec         = MethodName Signature | InterfaceTypeName .
+MethodName         = identifier .
+InterfaceTypeName  = TypeName .
+
+ +

+As with all method sets, in an interface type, each method must have a +unique +non-blank name. +

+ +
+// A simple File interface
+interface {
+	Read(b Buffer) bool
+	Write(b Buffer) bool
+	Close()
+}
+
+ +

+More than one type may implement an interface. +For instance, if two types S1 and S2 +have the method set +

+ +
+func (p T) Read(b Buffer) bool { return … }
+func (p T) Write(b Buffer) bool { return … }
+func (p T) Close() { … }
+
+ +

+(where T stands for either S1 or S2) +then the File interface is implemented by both S1 and +S2, regardless of what other methods +S1 and S2 may have or share. +

+ +

+A type implements any interface comprising any subset of its methods +and may therefore implement several distinct interfaces. For +instance, all types implement the empty interface: +

+ +
+interface{}
+
+ +

+Similarly, consider this interface specification, +which appears within a type declaration +to define an interface called Locker: +

+ +
+type Locker interface {
+	Lock()
+	Unlock()
+}
+
+ +

+If S1 and S2 also implement +

+ +
+func (p T) Lock() { … }
+func (p T) Unlock() { … }
+
+ +

+they implement the Locker interface as well +as the File interface. +

+ +

+An interface T may use a (possibly qualified) interface type +name E in place of a method specification. This is called +embedding interface E in T; it adds +all (exported and non-exported) methods of E to the interface +T. +

+ +
+type ReadWriter interface {
+	Read(b Buffer) bool
+	Write(b Buffer) bool
+}
+
+type File interface {
+	ReadWriter  // same as adding the methods of ReadWriter
+	Locker      // same as adding the methods of Locker
+	Close()
+}
+
+type LockedFile interface {
+	Locker
+	File        // illegal: Lock, Unlock not unique
+	Lock()      // illegal: Lock not unique
+}
+
+ +

+An interface type T may not embed itself +or any interface type that embeds T, recursively. +

+ +
+// illegal: Bad cannot embed itself
+type Bad interface {
+	Bad
+}
+
+// illegal: Bad1 cannot embed itself using Bad2
+type Bad1 interface {
+	Bad2
+}
+type Bad2 interface {
+	Bad1
+}
+
+ +

Map types

+ +

+A map is an unordered group of elements of one type, called the +element type, indexed by a set of unique keys of another type, +called the key type. +The value of an uninitialized map is nil. +

+ +
+MapType     = "map" "[" KeyType "]" ElementType .
+KeyType     = Type .
+
+ +

+The comparison operators +== and != must be fully defined +for operands of the key type; thus the key type must not be a function, map, or +slice. +If the key type is an interface type, these +comparison operators must be defined for the dynamic key values; +failure will cause a run-time panic. + +

+ +
+map[string]int
+map[*T]struct{ x, y float64 }
+map[string]interface{}
+
+ +

+The number of map elements is called its length. +For a map m, it can be discovered using the +built-in function len +and may change during execution. Elements may be added during execution +using assignments and retrieved with +index expressions; they may be removed with the +delete built-in function. +

+

+A new, empty map value is made using the built-in +function make, +which takes the map type and an optional capacity hint as arguments: +

+ +
+make(map[string]int)
+make(map[string]int, 100)
+
+ +

+The initial capacity does not bound its size: +maps grow to accommodate the number of items +stored in them, with the exception of nil maps. +A nil map is equivalent to an empty map except that no elements +may be added. + +

Channel types

+ +

+A channel provides a mechanism for +concurrently executing functions +to communicate by +sending and +receiving +values of a specified element type. +The value of an uninitialized channel is nil. +

+ +
+ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .
+
+ +

+The optional <- operator specifies the channel direction, +send or receive. If no direction is given, the channel is +bidirectional. +A channel may be constrained only to send or only to receive by +conversion or assignment. +

+ +
+chan T          // can be used to send and receive values of type T
+chan<- float64  // can only be used to send float64s
+<-chan int      // can only be used to receive ints
+
+ +

+The <- operator associates with the leftmost chan +possible: +

+ +
+chan<- chan int    // same as chan<- (chan int)
+chan<- <-chan int  // same as chan<- (<-chan int)
+<-chan <-chan int  // same as <-chan (<-chan int)
+chan (<-chan int)
+
+ +

+A new, initialized channel +value can be made using the built-in function +make, +which takes the channel type and an optional capacity as arguments: +

+ +
+make(chan int, 100)
+
+ +

+The capacity, in number of elements, sets the size of the buffer in the channel. +If the capacity is zero or absent, the channel is unbuffered and communication +succeeds only when both a sender and receiver are ready. Otherwise, the channel +is buffered and communication succeeds without blocking if the buffer +is not full (sends) or not empty (receives). +A nil channel is never ready for communication. +

+ +

+A channel may be closed with the built-in function +close. +The multi-valued assignment form of the +receive operator +reports whether a received value was sent before +the channel was closed. +

+ +

+A single channel may be used in +send statements, +receive operations, +and calls to the built-in functions +cap and +len +by any number of goroutines without further synchronization. +Channels act as first-in-first-out queues. +For example, if one goroutine sends values on a channel +and a second goroutine receives them, the values are +received in the order sent. +

+ +

Properties of types and values

+ +

Type identity

+ +

+Two types are either identical or different. +

+ +

+Two named types are identical if their type names originate in the same +TypeSpec. +A named and an unnamed type are always different. Two unnamed types are identical +if the corresponding type literals are identical, that is, if they have the same +literal structure and corresponding components have identical types. In detail: +

+ +
    +
  • Two array types are identical if they have identical element types and + the same array length.
  • + +
  • Two slice types are identical if they have identical element types.
  • + +
  • Two struct types are identical if they have the same sequence of fields, + and if corresponding fields have the same names, and identical types, + and identical tags. + Two anonymous fields are considered to have the same name. Lower-case field + names from different packages are always different.
  • + +
  • Two pointer types are identical if they have identical base types.
  • + +
  • Two function types are identical if they have the same number of parameters + and result values, corresponding parameter and result types are + identical, and either both functions are variadic or neither is. + Parameter and result names are not required to match.
  • + +
  • Two interface types are identical if they have the same set of methods + with the same names and identical function types. Lower-case method names from + different packages are always different. The order of the methods is irrelevant.
  • + +
  • Two map types are identical if they have identical key and value types.
  • + +
  • Two channel types are identical if they have identical value types and + the same direction.
  • +
+ +

+Given the declarations +

+ +
+type (
+	T0 []string
+	T1 []string
+	T2 struct{ a, b int }
+	T3 struct{ a, c int }
+	T4 func(int, float64) *T0
+	T5 func(x int, y float64) *[]string
+)
+
+ +

+these types are identical: +

+ +
+T0 and T0
+[]int and []int
+struct{ a, b *T5 } and struct{ a, b *T5 }
+func(x int, y float64) *[]string and func(int, float64) (result *[]string)
+
+ +

+T0 and T1 are different because they are named types +with distinct declarations; func(int, float64) *T0 and +func(x int, y float64) *[]string are different because T0 +is different from []string. +

+ + +

Assignability

+ +

+A value x is assignable to a variable of type T +("x is assignable to T") in any of these cases: +

+ +
    +
  • +x's type is identical to T. +
  • +
  • +x's type V and T have identical +underlying types and at least one of V +or T is not a named type. +
  • +
  • +T is an interface type and +x implements T. +
  • +
  • +x is a bidirectional channel value, T is a channel type, +x's type V and T have identical element types, +and at least one of V or T is not a named type. +
  • +
  • +x is the predeclared identifier nil and T +is a pointer, function, slice, map, channel, or interface type. +
  • +
  • +x is an untyped constant representable +by a value of type T. +
  • +
+ + +

Blocks

+ +

+A block is a possibly empty sequence of declarations and statements +within matching brace brackets. +

+ +
+Block = "{" StatementList "}" .
+StatementList = { Statement ";" } .
+
+ +

+In addition to explicit blocks in the source code, there are implicit blocks: +

+ +
    +
  1. The universe block encompasses all Go source text.
  2. + +
  3. Each package has a package block containing all + Go source text for that package.
  4. + +
  5. Each file has a file block containing all Go source text + in that file.
  6. + +
  7. Each "if", + "for", and + "switch" + statement is considered to be in its own implicit block.
  8. + +
  9. Each clause in a "switch" + or "select" statement + acts as an implicit block.
  10. +
+ +

+Blocks nest and influence scoping. +

+ + +

Declarations and scope

+ +

+A declaration binds a non-blank identifier to a +constant, +type, +variable, +function, +label, or +package. +Every identifier in a program must be declared. +No identifier may be declared twice in the same block, and +no identifier may be declared in both the file and package block. +

+ +

+The blank identifier may be used like any other identifier +in a declaration, but it does not introduce a binding and thus is not declared. +In the package block, the identifier init may only be used for +init function declarations, +and like the blank identifier it does not introduce a new binding. +

+ +
+Declaration   = ConstDecl | TypeDecl | VarDecl .
+TopLevelDecl  = Declaration | FunctionDecl | MethodDecl .
+
+ +

+The scope of a declared identifier is the extent of source text in which +the identifier denotes the specified constant, type, variable, function, label, or package. +

+ +

+Go is lexically scoped using blocks: +

+ +
    +
  1. The scope of a predeclared identifier is the universe block.
  2. + +
  3. The scope of an identifier denoting a constant, type, variable, + or function (but not method) declared at top level (outside any + function) is the package block.
  4. + +
  5. The scope of the package name of an imported package is the file block + of the file containing the import declaration.
  6. + +
  7. The scope of an identifier denoting a method receiver, function parameter, + or result variable is the function body.
  8. + +
  9. The scope of a constant or variable identifier declared + inside a function begins at the end of the ConstSpec or VarSpec + (ShortVarDecl for short variable declarations) + and ends at the end of the innermost containing block.
  10. + +
  11. The scope of a type identifier declared inside a function + begins at the identifier in the TypeSpec + and ends at the end of the innermost containing block.
  12. +
+ +

+An identifier declared in a block may be redeclared in an inner block. +While the identifier of the inner declaration is in scope, it denotes +the entity declared by the inner declaration. +

+ +

+The package clause is not a declaration; the package name +does not appear in any scope. Its purpose is to identify the files belonging +to the same package and to specify the default package name for import +declarations. +

+ + +

Label scopes

+ +

+Labels are declared by labeled statements and are +used in the "break", +"continue", and +"goto" statements. +It is illegal to define a label that is never used. +In contrast to other identifiers, labels are not block scoped and do +not conflict with identifiers that are not labels. The scope of a label +is the body of the function in which it is declared and excludes +the body of any nested function. +

+ + +

Blank identifier

+ +

+The blank identifier is represented by the underscore character _. +It serves as an anonymous placeholder instead of a regular (non-blank) +identifier and has special meaning in declarations, +as an operand, and in assignments. +

+ + +

Predeclared identifiers

+ +

+The following identifiers are implicitly declared in the +universe block: +

+
+Types:
+	bool byte complex64 complex128 error float32 float64
+	int int8 int16 int32 int64 rune string
+	uint uint8 uint16 uint32 uint64 uintptr
+
+Constants:
+	true false iota
+
+Zero value:
+	nil
+
+Functions:
+	append cap close complex copy delete imag len
+	make new panic print println real recover
+
+ + +

Exported identifiers

+ +

+An identifier may be exported to permit access to it from another package. +An identifier is exported if both: +

+
    +
  1. the first character of the identifier's name is a Unicode upper case + letter (Unicode class "Lu"); and
  2. +
  3. the identifier is declared in the package block + or it is a field name or + method name.
  4. +
+

+All other identifiers are not exported. +

+ + +

Uniqueness of identifiers

+ +

+Given a set of identifiers, an identifier is called unique if it is +different from every other in the set. +Two identifiers are different if they are spelled differently, or if they +appear in different packages and are not +exported. Otherwise, they are the same. +

+ +

Constant declarations

+ +

+A constant declaration binds a list of identifiers (the names of +the constants) to the values of a list of constant expressions. +The number of identifiers must be equal +to the number of expressions, and the nth identifier on +the left is bound to the value of the nth expression on the +right. +

+ +
+ConstDecl      = "const" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
+ConstSpec      = IdentifierList [ [ Type ] "=" ExpressionList ] .
+
+IdentifierList = identifier { "," identifier } .
+ExpressionList = Expression { "," Expression } .
+
+ +

+If the type is present, all constants take the type specified, and +the expressions must be assignable to that type. +If the type is omitted, the constants take the +individual types of the corresponding expressions. +If the expression values are untyped constants, +the declared constants remain untyped and the constant identifiers +denote the constant values. For instance, if the expression is a +floating-point literal, the constant identifier denotes a floating-point +constant, even if the literal's fractional part is zero. +

+ +
+const Pi float64 = 3.14159265358979323846
+const zero = 0.0         // untyped floating-point constant
+const (
+	size int64 = 1024
+	eof        = -1  // untyped integer constant
+)
+const a, b, c = 3, 4, "foo"  // a = 3, b = 4, c = "foo", untyped integer and string constants
+const u, v float32 = 0, 3    // u = 0.0, v = 3.0
+
+ +

+Within a parenthesized const declaration list the +expression list may be omitted from any but the first declaration. +Such an empty list is equivalent to the textual substitution of the +first preceding non-empty expression list and its type if any. +Omitting the list of expressions is therefore equivalent to +repeating the previous list. The number of identifiers must be equal +to the number of expressions in the previous list. +Together with the iota constant generator +this mechanism permits light-weight declaration of sequential values: +

+ +
+const (
+	Sunday = iota
+	Monday
+	Tuesday
+	Wednesday
+	Thursday
+	Friday
+	Partyday
+	numberOfDays  // this constant is not exported
+)
+
+ + +

Iota

+ +

+Within a constant declaration, the predeclared identifier +iota represents successive untyped integer +constants. It is reset to 0 whenever the reserved word const +appears in the source and increments after each ConstSpec. +It can be used to construct a set of related constants: +

+ +
+const (  // iota is reset to 0
+	c0 = iota  // c0 == 0
+	c1 = iota  // c1 == 1
+	c2 = iota  // c2 == 2
+)
+
+const (
+	a = 1 << iota  // a == 1 (iota has been reset)
+	b = 1 << iota  // b == 2
+	c = 1 << iota  // c == 4
+)
+
+const (
+	u         = iota * 42  // u == 0     (untyped integer constant)
+	v float64 = iota * 42  // v == 42.0  (float64 constant)
+	w         = iota * 42  // w == 84    (untyped integer constant)
+)
+
+const x = iota  // x == 0 (iota has been reset)
+const y = iota  // y == 0 (iota has been reset)
+
+ +

+Within an ExpressionList, the value of each iota is the same because +it is only incremented after each ConstSpec: +

+ +
+const (
+	bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0
+	bit1, mask1                           // bit1 == 2, mask1 == 1
+	_, _                                  // skips iota == 2
+	bit3, mask3                           // bit3 == 8, mask3 == 7
+)
+
+ +

+This last example exploits the implicit repetition of the +last non-empty expression list. +

+ + +

Type declarations

+ +

+A type declaration binds an identifier, the type name, to a new type +that has the same underlying type as an existing type, +and operations defined for the existing type are also defined for the new type. +The new type is different from the existing type. +

+ +
+TypeDecl     = "type" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
+TypeSpec     = identifier Type .
+
+ +
+type IntArray [16]int
+
+type (
+	Point struct{ x, y float64 }
+	Polar Point
+)
+
+type TreeNode struct {
+	left, right *TreeNode
+	value *Comparable
+}
+
+type Block interface {
+	BlockSize() int
+	Encrypt(src, dst []byte)
+	Decrypt(src, dst []byte)
+}
+
+ +

+The declared type does not inherit any methods +bound to the existing type, but the method set +of an interface type or of elements of a composite type remains unchanged: +

+ +
+// A Mutex is a data type with two methods, Lock and Unlock.
+type Mutex struct         { /* Mutex fields */ }
+func (m *Mutex) Lock()    { /* Lock implementation */ }
+func (m *Mutex) Unlock()  { /* Unlock implementation */ }
+
+// NewMutex has the same composition as Mutex but its method set is empty.
+type NewMutex Mutex
+
+// The method set of the base type of PtrMutex remains unchanged,
+// but the method set of PtrMutex is empty.
+type PtrMutex *Mutex
+
+// The method set of *PrintableMutex contains the methods
+// Lock and Unlock bound to its anonymous field Mutex.
+type PrintableMutex struct {
+	Mutex
+}
+
+// MyBlock is an interface type that has the same method set as Block.
+type MyBlock Block
+
+ +

+A type declaration may be used to define a different boolean, numeric, or string +type and attach methods to it: +

+ +
+type TimeZone int
+
+const (
+	EST TimeZone = -(5 + iota)
+	CST
+	MST
+	PST
+)
+
+func (tz TimeZone) String() string {
+	return fmt.Sprintf("GMT+%dh", tz)
+}
+
+ + +

Variable declarations

+ +

+A variable declaration creates one or more variables, binds corresponding +identifiers to them, and gives each a type and an initial value. +

+ +
+VarDecl     = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
+VarSpec     = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
+
+ +
+var i int
+var U, V, W float64
+var k = 0
+var x, y float32 = -1, -2
+var (
+	i       int
+	u, v, s = 2.0, 3.0, "bar"
+)
+var re, im = complexSqrt(-1)
+var _, found = entries[name]  // map lookup; only interested in "found"
+
+ +

+If a list of expressions is given, the variables are initialized +with the expressions following the rules for assignments. +Otherwise, each variable is initialized to its zero value. +

+ +

+If a type is present, each variable is given that type. +Otherwise, each variable is given the type of the corresponding +initialization value in the assignment. +If that value is an untyped constant, it is first +converted to its default type; +if it is an untyped boolean value, it is first converted to type bool. +The predeclared value nil cannot be used to initialize a variable +with no explicit type. +

+ +
+var d = math.Sin(0.5)  // d is int64
+var i = 42             // i is int
+var t, ok = x.(T)      // t is T, ok is bool
+var n = nil            // illegal
+
+ +

+Implementation restriction: A compiler may make it illegal to declare a variable +inside a function body if the variable is +never used. +

+ +

Short variable declarations

+ +

+A short variable declaration uses the syntax: +

+ +
+ShortVarDecl = IdentifierList ":=" ExpressionList .
+
+ +

+It is shorthand for a regular variable declaration +with initializer expressions but no types: +

+ +
+"var" IdentifierList = ExpressionList .
+
+ +
+i, j := 0, 10
+f := func() int { return 7 }
+ch := make(chan int)
+r, w := os.Pipe(fd)  // os.Pipe() returns two values
+_, y, _ := coord(p)  // coord() returns three values; only interested in y coordinate
+
+ +

+Unlike regular variable declarations, a short variable declaration may redeclare variables provided they +were originally declared earlier in the same block with the same type, and at +least one of the non-blank variables is new. As a consequence, redeclaration +can only appear in a multi-variable short declaration. +Redeclaration does not introduce a new +variable; it just assigns a new value to the original. +

+ +
+field1, offset := nextField(str, 0)
+field2, offset := nextField(str, offset)  // redeclares offset
+a, a := 1, 2                              // illegal: double declaration of a or no new variable if a was declared elsewhere
+
+ +

+Short variable declarations may appear only inside functions. +In some contexts such as the initializers for +"if", +"for", or +"switch" statements, +they can be used to declare local temporary variables. +

+ +

Function declarations

+ +

+A function declaration binds an identifier, the function name, +to a function. +

+ +
+FunctionDecl = "func" FunctionName ( Function | Signature ) .
+FunctionName = identifier .
+Function     = Signature FunctionBody .
+FunctionBody = Block .
+
+ +

+If the function's signature declares +result parameters, the function body's statement list must end in +a terminating statement. +

+ +
+func findMarker(c <-chan int) int {
+	for i := range c {
+		if x := <-c; isMarker(x) {
+			return x
+		}
+	}
+	// invalid: missing return statement.
+}
+
+ +

+A function declaration may omit the body. Such a declaration provides the +signature for a function implemented outside Go, such as an assembly routine. +

+ +
+func min(x int, y int) int {
+	if x < y {
+		return x
+	}
+	return y
+}
+
+func flushICache(begin, end uintptr)  // implemented externally
+
+ +

Method declarations

+ +

+A method is a function with a receiver. +A method declaration binds an identifier, the method name, to a method, +and associates the method with the receiver's base type. +

+ +
+MethodDecl   = "func" Receiver MethodName ( Function | Signature ) .
+Receiver     = Parameters .
+
+ +

+The receiver is specified via an extra parameter section preceeding the method +name. That parameter section must declare a single parameter, the receiver. +Its type must be of the form T or *T (possibly using +parentheses) where T is a type name. The type denoted by T is called +the receiver base type; it must not be a pointer or interface type and +it must be declared in the same package as the method. +The method is said to be bound to the base type and the method name +is visible only within selectors for that type. +

+ +

+A non-blank receiver identifier must be +unique in the method signature. +If the receiver's value is not referenced inside the body of the method, +its identifier may be omitted in the declaration. The same applies in +general to parameters of functions and methods. +

+ +

+For a base type, the non-blank names of methods bound to it must be unique. +If the base type is a struct type, +the non-blank method and field names must be distinct. +

+ +

+Given type Point, the declarations +

+ +
+func (p *Point) Length() float64 {
+	return math.Sqrt(p.x * p.x + p.y * p.y)
+}
+
+func (p *Point) Scale(factor float64) {
+	p.x *= factor
+	p.y *= factor
+}
+
+ +

+bind the methods Length and Scale, +with receiver type *Point, +to the base type Point. +

+ +

+The type of a method is the type of a function with the receiver as first +argument. For instance, the method Scale has type +

+ +
+func(p *Point, factor float64)
+
+ +

+However, a function declared this way is not a method. +

+ + +

Expressions

+ +

+An expression specifies the computation of a value by applying +operators and functions to operands. +

+ +

Operands

+ +

+Operands denote the elementary values in an expression. An operand may be a +literal, a (possibly qualified) +non-blank identifier denoting a +constant, +variable, or +function, +a method expression yielding a function, +or a parenthesized expression. +

+ +

+The blank identifier may appear as an +operand only on the left-hand side of an assignment. +

+ +
+Operand     = Literal | OperandName | MethodExpr | "(" Expression ")" .
+Literal     = BasicLit | CompositeLit | FunctionLit .
+BasicLit    = int_lit | float_lit | imaginary_lit | rune_lit | string_lit .
+OperandName = identifier | QualifiedIdent.
+
+ +

Qualified identifiers

+ +

+A qualified identifier is an identifier qualified with a package name prefix. +Both the package name and the identifier must not be +blank. +

+ +
+QualifiedIdent = PackageName "." identifier .
+
+ +

+A qualified identifier accesses an identifier in a different package, which +must be imported. +The identifier must be exported and +declared in the package block of that package. +

+ +
+math.Sin	// denotes the Sin function in package math
+
+ +

Composite literals

+ +

+Composite literals construct values for structs, arrays, slices, and maps +and create a new value each time they are evaluated. +They consist of the type of the value +followed by a brace-bound list of composite elements. An element may be +a single expression or a key-value pair. +

+ +
+CompositeLit  = LiteralType LiteralValue .
+LiteralType   = StructType | ArrayType | "[" "..." "]" ElementType |
+                SliceType | MapType | TypeName .
+LiteralValue  = "{" [ ElementList [ "," ] ] "}" .
+ElementList   = Element { "," Element } .
+Element       = [ Key ":" ] Value .
+Key           = FieldName | ElementIndex .
+FieldName     = identifier .
+ElementIndex  = Expression .
+Value         = Expression | LiteralValue .
+
+ +

+The LiteralType must be a struct, array, slice, or map type +(the grammar enforces this constraint except when the type is given +as a TypeName). +The types of the expressions must be assignable +to the respective field, element, and key types of the LiteralType; +there is no additional conversion. +The key is interpreted as a field name for struct literals, +an index for array and slice literals, and a key for map literals. +For map literals, all elements must have a key. It is an error +to specify multiple elements with the same field name or +constant key value. +

+ +

+For struct literals the following rules apply: +

+
    +
  • A key must be a field name declared in the LiteralType. +
  • +
  • An element list that does not contain any keys must + list an element for each struct field in the + order in which the fields are declared. +
  • +
  • If any element has a key, every element must have a key. +
  • +
  • An element list that contains keys does not need to + have an element for each struct field. Omitted fields + get the zero value for that field. +
  • +
  • A literal may omit the element list; such a literal evaluates + to the zero value for its type. +
  • +
  • It is an error to specify an element for a non-exported + field of a struct belonging to a different package. +
  • +
+ +

+Given the declarations +

+
+type Point3D struct { x, y, z float64 }
+type Line struct { p, q Point3D }
+
+ +

+one may write +

+ +
+origin := Point3D{}                            // zero value for Point3D
+line := Line{origin, Point3D{y: -4, z: 12.3}}  // zero value for line.q.x
+
+ +

+For array and slice literals the following rules apply: +

+
    +
  • Each element has an associated integer index marking + its position in the array. +
  • +
  • An element with a key uses the key as its index; the + key must be a constant integer expression. +
  • +
  • An element without a key uses the previous element's index plus one. + If the first element has no key, its index is zero. +
  • +
+ +

+Taking the address of a composite literal +generates a pointer to a unique variable initialized +with the literal's value. +

+
+var pointer *Point3D = &Point3D{y: 1000}
+
+ +

+The length of an array literal is the length specified in the LiteralType. +If fewer elements than the length are provided in the literal, the missing +elements are set to the zero value for the array element type. +It is an error to provide elements with index values outside the index range +of the array. The notation ... specifies an array length equal +to the maximum element index plus one. +

+ +
+buffer := [10]string{}             // len(buffer) == 10
+intSet := [6]int{1, 2, 3, 5}       // len(intSet) == 6
+days := [...]string{"Sat", "Sun"}  // len(days) == 2
+
+ +

+A slice literal describes the entire underlying array literal. +Thus, the length and capacity of a slice literal are the maximum +element index plus one. A slice literal has the form +

+ +
+[]T{x1, x2, … xn}
+
+ +

+and is shorthand for a slice operation applied to an array: +

+ +
+tmp := [n]T{x1, x2, … xn}
+tmp[0 : n]
+
+ +

+Within a composite literal of array, slice, or map type T, +elements that are themselves composite literals may elide the respective +literal type if it is identical to the element type of T. +Similarly, elements that are addresses of composite literals may elide +the &T when the element type is *T. +

+ +
+[...]Point{{1.5, -3.5}, {0, 0}}   // same as [...]Point{Point{1.5, -3.5}, Point{0, 0}}
+[][]int{{1, 2, 3}, {4, 5}}        // same as [][]int{[]int{1, 2, 3}, []int{4, 5}}
+
+[...]*Point{{1.5, -3.5}, {0, 0}}  // same as [...]*Point{&Point{1.5, -3.5}, &Point{0, 0}}
+
+ +

+A parsing ambiguity arises when a composite literal using the +TypeName form of the LiteralType appears as an operand between the +keyword and the opening brace of the block +of an "if", "for", or "switch" statement, and the composite literal +is not enclosed in parentheses, square brackets, or curly braces. +In this rare case, the opening brace of the literal is erroneously parsed +as the one introducing the block of statements. To resolve the ambiguity, +the composite literal must appear within parentheses. +

+ +
+if x == (T{a,b,c}[i]) { … }
+if (x == T{a,b,c}[i]) { … }
+
+ +

+Examples of valid array, slice, and map literals: +

+ +
+// list of prime numbers
+primes := []int{2, 3, 5, 7, 9, 2147483647}
+
+// vowels[ch] is true if ch is a vowel
+vowels := [128]bool{'a': true, 'e': true, 'i': true, 'o': true, 'u': true, 'y': true}
+
+// the array [10]float32{-1, 0, 0, 0, -0.1, -0.1, 0, 0, 0, -1}
+filter := [10]float32{-1, 4: -0.1, -0.1, 9: -1}
+
+// frequencies in Hz for equal-tempered scale (A4 = 440Hz)
+noteFrequency := map[string]float32{
+	"C0": 16.35, "D0": 18.35, "E0": 20.60, "F0": 21.83,
+	"G0": 24.50, "A0": 27.50, "B0": 30.87,
+}
+
+ + +

Function literals

+ +

+A function literal represents an anonymous function. +

+ +
+FunctionLit = "func" Function .
+
+ +
+func(a, b int, z float64) bool { return a*b < int(z) }
+
+ +

+A function literal can be assigned to a variable or invoked directly. +

+ +
+f := func(x, y int) int { return x + y }
+func(ch chan int) { ch <- ACK }(replyChan)
+
+ +

+Function literals are closures: they may refer to variables +defined in a surrounding function. Those variables are then shared between +the surrounding function and the function literal, and they survive as long +as they are accessible. +

+ + +

Primary expressions

+ +

+Primary expressions are the operands for unary and binary expressions. +

+ +
+PrimaryExpr =
+	Operand |
+	Conversion |
+	PrimaryExpr Selector |
+	PrimaryExpr Index |
+	PrimaryExpr Slice |
+	PrimaryExpr TypeAssertion |
+	PrimaryExpr Arguments .
+
+Selector       = "." identifier .
+Index          = "[" Expression "]" .
+Slice          = "[" ( [ Expression ] ":" [ Expression ] ) |
+                     ( [ Expression ] ":" Expression ":" Expression )
+                 "]" .
+TypeAssertion  = "." "(" Type ")" .
+Arguments      = "(" [ ( ExpressionList | Type [ "," ExpressionList ] ) [ "..." ] [ "," ] ] ")" .
+
+ + +
+x
+2
+(s + ".txt")
+f(3.1415, true)
+Point{1, 2}
+m["foo"]
+s[i : j + 1]
+obj.color
+f.p[i].x()
+
+ + +

Selectors

+ +

+For a primary expression x +that is not a package name, the +selector expression +

+ +
+x.f
+
+ +

+denotes the field or method f of the value x +(or sometimes *x; see below). +The identifier f is called the (field or method) selector; +it must not be the blank identifier. +The type of the selector expression is the type of f. +If x is a package name, see the section on +qualified identifiers. +

+ +

+A selector f may denote a field or method f of +a type T, or it may refer +to a field or method f of a nested +anonymous field of T. +The number of anonymous fields traversed +to reach f is called its depth in T. +The depth of a field or method f +declared in T is zero. +The depth of a field or method f declared in +an anonymous field A in T is the +depth of f in A plus one. +

+ +

+The following rules apply to selectors: +

+ +
    +
  1. +For a value x of type T or *T +where T is not a pointer or interface type, +x.f denotes the field or method at the shallowest depth +in T where there +is such an f. +If there is not exactly one f +with shallowest depth, the selector expression is illegal. +
  2. + +
  3. +For a value x of type I where I +is an interface type, x.f denotes the actual method with name +f of the dynamic value of x. +If there is no method with name f in the +method set of I, the selector +expression is illegal. +
  4. + +
  5. +As an exception, if the type of x is a named pointer type +and (*x).f is a valid selector expression denoting a field +(but not a method), x.f is shorthand for (*x).f. +
  6. + +
  7. +In all other cases, x.f is illegal. +
  8. + +
  9. +If x is of pointer type and has the value +nil and x.f denotes a struct field, +assigning to or evaluating x.f +causes a run-time panic. +
  10. + +
  11. +If x is of interface type and has the value +nil, calling or +evaluating the method x.f +causes a run-time panic. +
  12. +
+ +

+For example, given the declarations: +

+ +
+type T0 struct {
+	x int
+}
+
+func (*T0) M0()
+
+type T1 struct {
+	y int
+}
+
+func (T1) M1()
+
+type T2 struct {
+	z int
+	T1
+	*T0
+}
+
+func (*T2) M2()
+
+type Q *T2
+
+var t T2     // with t.T0 != nil
+var p *T2    // with p != nil and (*p).T0 != nil
+var q Q = p
+
+ +

+one may write: +

+ +
+t.z          // t.z
+t.y          // t.T1.y
+t.x          // (*t.TO).x
+
+p.z          // (*p).z
+p.y          // (*p).T1.y
+p.x          // (*(*p).T0).x
+
+q.x          // (*(*q).T0).x        (*q).x is a valid field selector
+
+p.M2()       // p.M2()              M2 expects *T2 receiver
+p.M1()       // ((*p).T1).M1()      M1 expects T1 receiver
+p.M0()       // ((&(*p).T0)).M0()   M0 expects *T0 receiver, see section on Calls
+
+ +

+but the following is invalid: +

+ +
+q.M0()       // (*q).M0 is valid but not a field selector
+
+ + +

Method expressions

+ +

+If M is in the method set of type T, +T.M is a function that is callable as a regular function +with the same arguments as M prefixed by an additional +argument that is the receiver of the method. +

+ +
+MethodExpr    = ReceiverType "." MethodName .
+ReceiverType  = TypeName | "(" "*" TypeName ")" | "(" ReceiverType ")" .
+
+ +

+Consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+
+ +

+The expression +

+ +
+T.Mv
+
+ +

+yields a function equivalent to Mv but +with an explicit receiver as its first argument; it has signature +

+ +
+func(tv T, a int) int
+
+ +

+That function may be called normally with an explicit receiver, so +these five invocations are equivalent: +

+ +
+t.Mv(7)
+T.Mv(t, 7)
+(T).Mv(t, 7)
+f1 := T.Mv; f1(t, 7)
+f2 := (T).Mv; f2(t, 7)
+
+ +

+Similarly, the expression +

+ +
+(*T).Mp
+
+ +

+yields a function value representing Mp with signature +

+ +
+func(tp *T, f float32) float32
+
+ +

+For a method with a value receiver, one can derive a function +with an explicit pointer receiver, so +

+ +
+(*T).Mv
+
+ +

+yields a function value representing Mv with signature +

+ +
+func(tv *T, a int) int
+
+ +

+Such a function indirects through the receiver to create a value +to pass as the receiver to the underlying method; +the method does not overwrite the value whose address is passed in +the function call. +

+ +

+The final case, a value-receiver function for a pointer-receiver method, +is illegal because pointer-receiver methods are not in the method set +of the value type. +

+ +

+Function values derived from methods are called with function call syntax; +the receiver is provided as the first argument to the call. +That is, given f := T.Mv, f is invoked +as f(t, 7) not t.f(7). +To construct a function that binds the receiver, use a +function literal or +method value. +

+ +

+It is legal to derive a function value from a method of an interface type. +The resulting function takes an explicit receiver of that interface type. +

+ +

Method values

+ +

+If the expression x has static type T and +M is in the method set of type T, +x.M is called a method value. +The method value x.M is a function value that is callable +with the same arguments as a method call of x.M. +The expression x is evaluated and saved during the evaluation of the +method value; the saved copy is then used as the receiver in any calls, +which may be executed later. +

+ +

+The type T may be an interface or non-interface type. +

+ +

+As in the discussion of method expressions above, +consider a struct type T with two methods, +Mv, whose receiver is of type T, and +Mp, whose receiver is of type *T. +

+ +
+type T struct {
+	a int
+}
+func (tv  T) Mv(a int) int         { return 0 }  // value receiver
+func (tp *T) Mp(f float32) float32 { return 1 }  // pointer receiver
+
+var t T
+var pt *T
+func makeT() T
+
+ +

+The expression +

+ +
+t.Mv
+
+ +

+yields a function value of type +

+ +
+func(int) int
+
+ +

+These two invocations are equivalent: +

+ +
+t.Mv(7)
+f := t.Mv; f(7)
+
+ +

+Similarly, the expression +

+ +
+pt.Mp
+
+ +

+yields a function value of type +

+ +
+func(float32) float32
+
+ +

+As with selectors, a reference to a non-interface method with a value receiver +using a pointer will automatically dereference that pointer: pt.Mv is equivalent to (*pt).Mv. +

+ +

+As with method calls, a reference to a non-interface method with a pointer receiver +using an addressable value will automatically take the address of that value: t.Mp is equivalent to (&t).Mp. +

+ +
+f := t.Mv; f(7)   // like t.Mv(7)
+f := pt.Mp; f(7)  // like pt.Mp(7)
+f := pt.Mv; f(7)  // like (*pt).Mv(7)
+f := t.Mp; f(7)   // like (&t).Mp(7)
+f := makeT().Mp   // invalid: result of makeT() is not addressable
+
+ +

+Although the examples above use non-interface types, it is also legal to create a method value +from a value of interface type. +

+ +
+var i interface { M(int) } = myVal
+f := i.M; f(7)  // like i.M(7)
+
+ + +

Index expressions

+ +

+A primary expression of the form +

+ +
+a[x]
+
+ +

+denotes the element of the array, pointer to array, slice, string or map a indexed by x. +The value x is called the index or map key, respectively. +The following rules apply: +

+ +

+If a is not a map: +

+
    +
  • the index x must be of integer type or untyped; + it is in range if 0 <= x < len(a), + otherwise it is out of range
  • +
  • a constant index must be non-negative + and representable by a value of type int +
+ +

+For a of array type A: +

+
    +
  • a constant index must be in range
  • +
  • if x is out of range at run time, + a run-time panic occurs
  • +
  • a[x] is the array element at index x and the type of + a[x] is the element type of A
  • +
+ +

+For a of pointer to array type: +

+
    +
  • a[x] is shorthand for (*a)[x]
  • +
+ +

+For a of slice type S: +

+
    +
  • if x is out of range at run time, + a run-time panic occurs
  • +
  • a[x] is the slice element at index x and the type of + a[x] is the element type of S
  • +
+ +

+For a of string type: +

+
    +
  • a constant index must be in range + if the string a is also constant
  • +
  • if x is out of range at run time, + a run-time panic occurs
  • +
  • a[x] is the non-constant byte value at index x and the type of + a[x] is byte
  • +
  • a[x] may not be assigned to
  • +
+ +

+For a of map type M: +

+
    +
  • x's type must be + assignable + to the key type of M
  • +
  • if the map contains an entry with key x, + a[x] is the map value with key x + and the type of a[x] is the value type of M
  • +
  • if the map is nil or does not contain such an entry, + a[x] is the zero value + for the value type of M
  • +
+ +

+Otherwise a[x] is illegal. +

+ +

+An index expression on a map a of type map[K]V +used in an assignment or initialization of the special form +

+ +
+v, ok = a[x]
+v, ok := a[x]
+var v, ok = a[x]
+
+ +

+yields an additional untyped boolean value. The value of ok is +true if the key x is present in the map, and +false otherwise. +

+ +

+Assigning to an element of a nil map causes a +run-time panic. +

+ + +

Slice expressions

+ +

+Slice expressions construct a substring or slice from a string, array, pointer +to array, or slice. There are two variants: a simple form that specifies a low +and high bound, and a full form that also specifies a bound on the capacity. +

+ +

Simple slice expressions

+ +

+For a string, array, pointer to array, or slice a, the primary expression +

+ +
+a[low : high]
+
+ +

+constructs a substring or slice. The indices low and +high select which elements of operand a appear +in the result. The result has indices starting at 0 and length equal to +high - low. +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+s := a[1:4]
+
+ +

+the slice s has type []int, length 3, capacity 4, and elements +

+ +
+s[0] == 2
+s[1] == 3
+s[2] == 4
+
+ +

+For convenience, any of the indices may be omitted. A missing low +index defaults to zero; a missing high index defaults to the length of the +sliced operand: +

+ +
+a[2:]  // same as a[2 : len(a)]
+a[:3]  // same as a[0 : 3]
+a[:]   // same as a[0 : len(a)]
+
+ +

+If a is a pointer to an array, a[low : high] is shorthand for +(*a)[low : high]. +

+ +

+For arrays or strings, the indices are in range if +0 <= low <= high <= len(a), +otherwise they are out of range. +For slices, the upper index bound is the slice capacity cap(a) rather than the length. +A constant index must be non-negative and representable by a value of type +int; for arrays or constant strings, constant indices must also be in range. +If both indices are constant, they must satisfy low <= high. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

+Except for untyped strings, if the sliced operand is a string or slice, +the result of the slice operation is a non-constant value of the same type as the operand. +For untyped string operands the result is a non-constant value of type string. +If the sliced operand is an array, it must be addressable +and the result of the slice operation is a slice with the same element type as the array. +

+ +

+If the sliced operand of a valid slice expression is a nil slice, the result +is a nil slice. Otherwise, the result shares its underlying array with the +operand. +

+ +

Full slice expressions

+ +

+For an array, pointer to array, or slice a (but not a string), the primary expression +

+ +
+a[low : high : max]
+
+ +

+constructs a slice of the same type, and with the same length and elements as the simple slice +expression a[low : high]. Additionally, it controls the resulting slice's capacity +by setting it to max - low. Only the first index may be omitted; it defaults to 0. +After slicing the array a +

+ +
+a := [5]int{1, 2, 3, 4, 5}
+t := a[1:3:5]
+
+ +

+the slice t has type []int, length 2, capacity 4, and elements +

+ +
+t[0] == 2
+t[1] == 3
+
+ +

+As for simple slice expressions, if a is a pointer to an array, +a[low : high : max] is shorthand for (*a)[low : high : max]. +If the sliced operand is an array, it must be addressable. +

+ +

+The indices are in range if 0 <= low <= high <= max <= cap(a), +otherwise they are out of range. +A constant index must be non-negative and representable by a value of type +int; for arrays, constant indices must also be in range. +If multiple indices are constant, the constants that are present must be in range relative to each +other. +If the indices are out of range at run time, a run-time panic occurs. +

+ +

Type assertions

+ +

+For an expression x of interface type +and a type T, the primary expression +

+ +
+x.(T)
+
+ +

+asserts that x is not nil +and that the value stored in x is of type T. +The notation x.(T) is called a type assertion. +

+

+More precisely, if T is not an interface type, x.(T) asserts +that the dynamic type of x is identical +to the type T. +In this case, T must implement the (interface) type of x; +otherwise the type assertion is invalid since it is not possible for x +to store a value of type T. +If T is an interface type, x.(T) asserts that the dynamic type +of x implements the interface T. +

+

+If the type assertion holds, the value of the expression is the value +stored in x and its type is T. If the type assertion is false, +a run-time panic occurs. +In other words, even though the dynamic type of x +is known only at run time, the type of x.(T) is +known to be T in a correct program. +

+ +
+var x interface{} = 7  // x has dynamic type int and value 7
+i := x.(int)           // i has type int and value 7
+
+type I interface { m() }
+var y I
+s := y.(string)        // illegal: string does not implement I (missing method m)
+r := y.(io.Reader)     // r has type io.Reader and y must implement both I and io.Reader
+
+ +

+A type assertion used in an assignment or initialization of the special form +

+ +
+v, ok = x.(T)
+v, ok := x.(T)
+var v, ok = x.(T)
+
+ +

+yields an additional untyped boolean value. The value of ok is true +if the assertion holds. Otherwise it is false and the value of v is +the zero value for type T. +No run-time panic occurs in this case. +

+ + +

Calls

+ +

+Given an expression f of function type +F, +

+ +
+f(a1, a2, … an)
+
+ +

+calls f with arguments a1, a2, … an. +Except for one special case, arguments must be single-valued expressions +assignable to the parameter types of +F and are evaluated before the function is called. +The type of the expression is the result type +of F. +A method invocation is similar but the method itself +is specified as a selector upon a value of the receiver type for +the method. +

+ +
+math.Atan2(x, y)  // function call
+var pt *Point
+pt.Scale(3.5)     // method call with receiver pt
+
+ +

+In a function call, the function value and arguments are evaluated in +the usual order. +After they are evaluated, the parameters of the call are passed by value to the function +and the called function begins execution. +The return parameters of the function are passed by value +back to the calling function when the function returns. +

+ +

+Calling a nil function value +causes a run-time panic. +

+ +

+As a special case, if the return values of a function or method +g are equal in number and individually +assignable to the parameters of another function or method +f, then the call f(g(parameters_of_g)) +will invoke f after binding the return values of +g to the parameters of f in order. The call +of f must contain no parameters other than the call of g, +and g must have at least one return value. +If f has a final ... parameter, it is +assigned the return values of g that remain after +assignment of regular parameters. +

+ +
+func Split(s string, pos int) (string, string) {
+	return s[0:pos], s[pos:]
+}
+
+func Join(s, t string) string {
+	return s + t
+}
+
+if Join(Split(value, len(value)/2)) != value {
+	log.Panic("test fails")
+}
+
+ +

+A method call x.m() is valid if the method set +of (the type of) x contains m and the +argument list can be assigned to the parameter list of m. +If x is addressable and &x's method +set contains m, x.m() is shorthand +for (&x).m(): +

+ +
+var p Point
+p.Scale(3.5)
+
+ +

+There is no distinct method type and there are no method literals. +

+ +

Passing arguments to ... parameters

+ +

+If f is variadic with a final +parameter p of type ...T, then within f +the type of p is equivalent to type []T. +If f is invoked with no actual arguments for p, +the value passed to p is nil. +Otherwise, the value passed is a new slice +of type []T with a new underlying array whose successive elements +are the actual arguments, which all must be assignable +to T. The length and capacity of the slice is therefore +the number of arguments bound to p and may differ for each +call site. +

+ +

+Given the function and calls +

+
+func Greeting(prefix string, who ...string)
+Greeting("nobody")
+Greeting("hello:", "Joe", "Anna", "Eileen")
+
+ +

+within Greeting, who will have the value +nil in the first call, and +[]string{"Joe", "Anna", "Eileen"} in the second. +

+ +

+If the final argument is assignable to a slice type []T, it may be +passed unchanged as the value for a ...T parameter if the argument +is followed by .... In this case no new slice is created. +

+ +

+Given the slice s and call +

+ +
+s := []string{"James", "Jasmine"}
+Greeting("goodbye:", s...)
+
+ +

+within Greeting, who will have the same value as s +with the same underlying array. +

+ + +

Operators

+ +

+Operators combine operands into expressions. +

+ +
+Expression = UnaryExpr | Expression binary_op UnaryExpr .
+UnaryExpr  = PrimaryExpr | unary_op UnaryExpr .
+
+binary_op  = "||" | "&&" | rel_op | add_op | mul_op .
+rel_op     = "==" | "!=" | "<" | "<=" | ">" | ">=" .
+add_op     = "+" | "-" | "|" | "^" .
+mul_op     = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
+
+unary_op   = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
+
+ +

+Comparisons are discussed elsewhere. +For other binary operators, the operand types must be identical +unless the operation involves shifts or untyped constants. +For operations involving constants only, see the section on +constant expressions. +

+ +

+Except for shift operations, if one operand is an untyped constant +and the other operand is not, the constant is converted +to the type of the other operand. +

+ +

+The right operand in a shift expression must have unsigned integer type +or be an untyped constant that can be converted to unsigned integer type. +If the left operand of a non-constant shift expression is an untyped constant, +the type of the constant is what it would be if the shift expression were +replaced by its left operand alone. +

+ +
+var s uint = 33
+var i = 1<<s           // 1 has type int
+var j int32 = 1<<s     // 1 has type int32; j == 0
+var k = uint64(1<<s)   // 1 has type uint64; k == 1<<33
+var m int = 1.0<<s     // 1.0 has type int
+var n = 1.0<<s != i    // 1.0 has type int; n == false if ints are 32bits in size
+var o = 1<<s == 2<<s   // 1 and 2 have type int; o == true if ints are 32bits in size
+var p = 1<<s == 1<<33  // illegal if ints are 32bits in size: 1 has type int, but 1<<33 overflows int
+var u = 1.0<<s         // illegal: 1.0 has type float64, cannot shift
+var u1 = 1.0<<s != 0   // illegal: 1.0 has type float64, cannot shift
+var u2 = 1<<s != 1.0   // illegal: 1 has type float64, cannot shift
+var v float32 = 1<<s   // illegal: 1 has type float32, cannot shift
+var w int64 = 1.0<<33  // 1.0<<33 is a constant shift expression
+
+ +

Operator precedence

+

+Unary operators have the highest precedence. +As the ++ and -- operators form +statements, not expressions, they fall +outside the operator hierarchy. +As a consequence, statement *p++ is the same as (*p)++. +

+There are five precedence levels for binary operators. +Multiplication operators bind strongest, followed by addition +operators, comparison operators, && (logical AND), +and finally || (logical OR): +

+ +
+Precedence    Operator
+    5             *  /  %  <<  >>  &  &^
+    4             +  -  |  ^
+    3             ==  !=  <  <=  >  >=
+    2             &&
+    1             ||
+
+ +

+Binary operators of the same precedence associate from left to right. +For instance, x / y * z is the same as (x / y) * z. +

+ +
++x
+23 + 3*x[i]
+x <= f()
+^a >> b
+f() || g()
+x == y+1 && <-chanPtr > 0
+
+ + +

Arithmetic operators

+

+Arithmetic operators apply to numeric values and yield a result of the same +type as the first operand. The four standard arithmetic operators (+, +-, *, /) apply to integer, +floating-point, and complex types; + also applies +to strings. All other arithmetic operators apply to integers only. +

+ +
++    sum                    integers, floats, complex values, strings
+-    difference             integers, floats, complex values
+*    product                integers, floats, complex values
+/    quotient               integers, floats, complex values
+%    remainder              integers
+
+&    bitwise AND            integers
+|    bitwise OR             integers
+^    bitwise XOR            integers
+&^   bit clear (AND NOT)    integers
+
+<<   left shift             integer << unsigned integer
+>>   right shift            integer >> unsigned integer
+
+ +

+Strings can be concatenated using the + operator +or the += assignment operator: +

+ +
+s := "hi" + string(c)
+s += " and good bye"
+
+ +

+String addition creates a new string by concatenating the operands. +

+

+For two integer values x and y, the integer quotient +q = x / y and remainder r = x % y satisfy the following +relationships: +

+ +
+x = q*y + r  and  |r| < |y|
+
+ +

+with x / y truncated towards zero +("truncated division"). +

+ +
+ x     y     x / y     x % y
+ 5     3       1         2
+-5     3      -1        -2
+ 5    -3      -1         2
+-5    -3       1        -2
+
+ +

+As an exception to this rule, if the dividend x is the most +negative value for the int type of x, the quotient +q = x / -1 is equal to x (and r = 0). +

+ +
+			 x, q
+int8                     -128
+int16                  -32768
+int32             -2147483648
+int64    -9223372036854775808
+
+ +

+If the divisor is a constant, it must not be zero. +If the divisor is zero at run time, a run-time panic occurs. +If the dividend is non-negative and the divisor is a constant power of 2, +the division may be replaced by a right shift, and computing the remainder may +be replaced by a bitwise AND operation: +

+ +
+ x     x / 4     x % 4     x >> 2     x & 3
+ 11      2         3         2          3
+-11     -2        -3        -3          1
+
+ +

+The shift operators shift the left operand by the shift count specified by the +right operand. They implement arithmetic shifts if the left operand is a signed +integer and logical shifts if it is an unsigned integer. +There is no upper limit on the shift count. Shifts behave +as if the left operand is shifted n times by 1 for a shift +count of n. +As a result, x << 1 is the same as x*2 +and x >> 1 is the same as +x/2 but truncated towards negative infinity. +

+ +

+For integer operands, the unary operators ++, -, and ^ are defined as +follows: +

+ +
++x                          is 0 + x
+-x    negation              is 0 - x
+^x    bitwise complement    is m ^ x  with m = "all bits set to 1" for unsigned x
+                                      and  m = -1 for signed x
+
+ +

+For floating-point and complex numbers, ++x is the same as x, +while -x is the negation of x. +The result of a floating-point or complex division by zero is not specified beyond the +IEEE-754 standard; whether a run-time panic +occurs is implementation-specific. +

+ +

Integer overflow

+ +

+For unsigned integer values, the operations +, +-, *, and << are +computed modulo 2n, where n is the bit width of +the unsigned integer's type. +Loosely speaking, these unsigned integer operations +discard high bits upon overflow, and programs may rely on ``wrap around''. +

+

+For signed integers, the operations +, +-, *, and << may legally +overflow and the resulting value exists and is deterministically defined +by the signed integer representation, the operation, and its operands. +No exception is raised as a result of overflow. A +compiler may not optimize code under the assumption that overflow does +not occur. For instance, it may not assume that x < x + 1 is always true. +

+ + +

Comparison operators

+ +

+Comparison operators compare two operands and yield an untyped boolean value. +

+ +
+==    equal
+!=    not equal
+<     less
+<=    less or equal
+>     greater
+>=    greater or equal
+
+ +

+In any comparison, the first operand +must be assignable +to the type of the second operand, or vice versa. +

+

+The equality operators == and != apply +to operands that are comparable. +The ordering operators <, <=, >, and >= +apply to operands that are ordered. +These terms and the result of the comparisons are defined as follows: +

+ +
    +
  • + Boolean values are comparable. + Two boolean values are equal if they are either both + true or both false. +
  • + +
  • + Integer values are comparable and ordered, in the usual way. +
  • + +
  • + Floating point values are comparable and ordered, + as defined by the IEEE-754 standard. +
  • + +
  • + Complex values are comparable. + Two complex values u and v are + equal if both real(u) == real(v) and + imag(u) == imag(v). +
  • + +
  • + String values are comparable and ordered, lexically byte-wise. +
  • + +
  • + Pointer values are comparable. + Two pointer values are equal if they point to the same variable or if both have value nil. + Pointers to distinct zero-size variables may or may not be equal. +
  • + +
  • + Channel values are comparable. + Two channel values are equal if they were created by the same call to + make + or if both have value nil. +
  • + +
  • + Interface values are comparable. + Two interface values are equal if they have identical dynamic types + and equal dynamic values or if both have value nil. +
  • + +
  • + A value x of non-interface type X and + a value t of interface type T are comparable when values + of type X are comparable and + X implements T. + They are equal if t's dynamic type is identical to X + and t's dynamic value is equal to x. +
  • + +
  • + Struct values are comparable if all their fields are comparable. + Two struct values are equal if their corresponding + non-blank fields are equal. +
  • + +
  • + Array values are comparable if values of the array element type are comparable. + Two array values are equal if their corresponding elements are equal. +
  • +
+ +

+A comparison of two interface values with identical dynamic types +causes a run-time panic if values +of that type are not comparable. This behavior applies not only to direct interface +value comparisons but also when comparing arrays of interface values +or structs with interface-valued fields. +

+ +

+Slice, map, and function values are not comparable. +However, as a special case, a slice, map, or function value may +be compared to the predeclared identifier nil. +Comparison of pointer, channel, and interface values to nil +is also allowed and follows from the general rules above. +

+ +
+const c = 3 < 4            // c is the untyped bool constant true
+
+type MyBool bool
+var x, y int
+var (
+	// The result of a comparison is an untyped bool.
+	// The usual assignment rules apply.
+	b3        = x == y // b3 has type bool
+	b4 bool   = x == y // b4 has type bool
+	b5 MyBool = x == y // b5 has type MyBool
+)
+
+ +

Logical operators

+ +

+Logical operators apply to boolean values +and yield a result of the same type as the operands. +The right operand is evaluated conditionally. +

+ +
+&&    conditional AND    p && q  is  "if p then q else false"
+||    conditional OR     p || q  is  "if p then true else q"
+!     NOT                !p      is  "not p"
+
+ + +

Address operators

+ +

+For an operand x of type T, the address operation +&x generates a pointer of type *T to x. +The operand must be addressable, +that is, either a variable, pointer indirection, or slice indexing +operation; or a field selector of an addressable struct operand; +or an array indexing operation of an addressable array. +As an exception to the addressability requirement, x may also be a +(possibly parenthesized) +composite literal. +If the evaluation of x would cause a run-time panic, +then the evaluation of &x does too. +

+ +

+For an operand x of pointer type *T, the pointer +indirection *x denotes the variable of type T pointed +to by x. +If x is nil, an attempt to evaluate *x +will cause a run-time panic. +

+ +
+&x
+&a[f(2)]
+&Point{2, 3}
+*p
+*pf(x)
+
+var x *int = nil
+*x   // causes a run-time panic
+&*x  // causes a run-time panic
+
+ + +

Receive operator

+ +

+For an operand ch of channel type, +the value of the receive operation <-ch is the value received +from the channel ch. The channel direction must permit receive operations, +and the type of the receive operation is the element type of the channel. +The expression blocks until a value is available. +Receiving from a nil channel blocks forever. +A receive operation on a closed channel can always proceed +immediately, yielding the element type's zero value +after any previously sent values have been received. +

+ +
+v1 := <-ch
+v2 = <-ch
+f(<-ch)
+<-strobe  // wait until clock pulse and discard received value
+
+ +

+A receive expression used in an assignment or initialization of the special form +

+ +
+x, ok = <-ch
+x, ok := <-ch
+var x, ok = <-ch
+
+ +

+yields an additional untyped boolean result reporting whether the +communication succeeded. The value of ok is true +if the value received was delivered by a successful send operation to the +channel, or false if it is a zero value generated because the +channel is closed and empty. +

+ + +

Conversions

+ +

+Conversions are expressions of the form T(x) +where T is a type and x is an expression +that can be converted to type T. +

+ +
+Conversion = Type "(" Expression [ "," ] ")" .
+
+ +

+If the type starts with the operator * or <-, +or if the type starts with the keyword func +and has no result list, it must be parenthesized when +necessary to avoid ambiguity: +

+ +
+*Point(p)        // same as *(Point(p))
+(*Point)(p)      // p is converted to *Point
+<-chan int(c)    // same as <-(chan int(c))
+(<-chan int)(c)  // c is converted to <-chan int
+func()(x)        // function signature func() x
+(func())(x)      // x is converted to func()
+(func() int)(x)  // x is converted to func() int
+func() int(x)    // x is converted to func() int (unambiguous)
+
+ +

+A constant value x can be converted to +type T in any of these cases: +

+ +
    +
  • + x is representable by a value of type T. +
  • +
  • + x is a floating-point constant, + T is a floating-point type, + and x is representable by a value + of type T after rounding using + IEEE 754 round-to-even rules. + The constant T(x) is the rounded value. +
  • +
  • + x is an integer constant and T is a + string type. + The same rule + as for non-constant x applies in this case. +
  • +
+ +

+Converting a constant yields a typed constant as result. +

+ +
+uint(iota)               // iota value of type uint
+float32(2.718281828)     // 2.718281828 of type float32
+complex128(1)            // 1.0 + 0.0i of type complex128
+float32(0.49999999)      // 0.5 of type float32
+string('x')              // "x" of type string
+string(0x266c)           // "♬" of type string
+MyString("foo" + "bar")  // "foobar" of type MyString
+string([]byte{'a'})      // not a constant: []byte{'a'} is not a constant
+(*int)(nil)              // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type
+int(1.2)                 // illegal: 1.2 cannot be represented as an int
+string(65.0)             // illegal: 65.0 is not an integer constant
+
+ +

+A non-constant value x can be converted to type T +in any of these cases: +

+ +
    +
  • + x is assignable + to T. +
  • +
  • + x's type and T have identical + underlying types. +
  • +
  • + x's type and T are unnamed pointer types + and their pointer base types have identical underlying types. +
  • +
  • + x's type and T are both integer or floating + point types. +
  • +
  • + x's type and T are both complex types. +
  • +
  • + x is an integer or a slice of bytes or runes + and T is a string type. +
  • +
  • + x is a string and T is a slice of bytes or runes. +
  • +
+ +

+Specific rules apply to (non-constant) conversions between numeric types or +to and from a string type. +These conversions may change the representation of x +and incur a run-time cost. +All other conversions only change the type but not the representation +of x. +

+ +

+There is no linguistic mechanism to convert between pointers and integers. +The package unsafe +implements this functionality under +restricted circumstances. +

+ +

Conversions between numeric types

+ +

+For the conversion of non-constant numeric values, the following rules apply: +

+ +
    +
  1. +When converting between integer types, if the value is a signed integer, it is +sign extended to implicit infinite precision; otherwise it is zero extended. +It is then truncated to fit in the result type's size. +For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0. +The conversion always yields a valid value; there is no indication of overflow. +
  2. +
  3. +When converting a floating-point number to an integer, the fraction is discarded +(truncation towards zero). +
  4. +
  5. +When converting an integer or floating-point number to a floating-point type, +or a complex number to another complex type, the result value is rounded +to the precision specified by the destination type. +For instance, the value of a variable x of type float32 +may be stored using additional precision beyond that of an IEEE-754 32-bit number, +but float32(x) represents the result of rounding x's value to +32-bit precision. Similarly, x + 0.1 may use more than 32 bits +of precision, but float32(x + 0.1) does not. +
  6. +
+ +

+In all non-constant conversions involving floating-point or complex values, +if the result type cannot represent the value the conversion +succeeds but the result value is implementation-dependent. +

+ +

Conversions to and from a string type

+ +
    +
  1. +Converting a signed or unsigned integer value to a string type yields a +string containing the UTF-8 representation of the integer. Values outside +the range of valid Unicode code points are converted to "\uFFFD". + +
    +string('a')       // "a"
    +string(-1)        // "\ufffd" == "\xef\xbf\xbd"
    +string(0xf8)      // "\u00f8" == "ø" == "\xc3\xb8"
    +type MyString string
    +MyString(0x65e5)  // "\u65e5" == "日" == "\xe6\x97\xa5"
    +
    +
  2. + +
  3. +Converting a slice of bytes to a string type yields +a string whose successive bytes are the elements of the slice. + +
    +string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'})   // "hellø"
    +string([]byte{})                                     // ""
    +string([]byte(nil))                                  // ""
    +
    +type MyBytes []byte
    +string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'})  // "hellø"
    +
    +
  4. + +
  5. +Converting a slice of runes to a string type yields +a string that is the concatenation of the individual rune values +converted to strings. + +
    +string([]rune{0x767d, 0x9d6c, 0x7fd4})   // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +string([]rune{})                         // ""
    +string([]rune(nil))                      // ""
    +
    +type MyRunes []rune
    +string(MyRunes{0x767d, 0x9d6c, 0x7fd4})  // "\u767d\u9d6c\u7fd4" == "白鵬翔"
    +
    +
  6. + +
  7. +Converting a value of a string type to a slice of bytes type +yields a slice whose successive elements are the bytes of the string. + +
    +[]byte("hellø")   // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +[]byte("")        // []byte{}
    +
    +MyBytes("hellø")  // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
    +
    +
  8. + +
  9. +Converting a value of a string type to a slice of runes type +yields a slice containing the individual Unicode code points of the string. + +
    +[]rune(MyString("白鵬翔"))  // []rune{0x767d, 0x9d6c, 0x7fd4}
    +[]rune("")                 // []rune{}
    +
    +MyRunes("白鵬翔")           // []rune{0x767d, 0x9d6c, 0x7fd4}
    +
    +
  10. +
+ + +

Constant expressions

+ +

+Constant expressions may contain only constant +operands and are evaluated at compile time. +

+ +

+Untyped boolean, numeric, and string constants may be used as operands +wherever it is legal to use an operand of boolean, numeric, or string type, +respectively. +Except for shift operations, if the operands of a binary operation are +different kinds of untyped constants, the operation and, for non-boolean operations, the result use +the kind that appears later in this list: integer, rune, floating-point, complex. +For example, an untyped integer constant divided by an +untyped complex constant yields an untyped complex constant. +

+ +

+A constant comparison always yields +an untyped boolean constant. If the left operand of a constant +shift expression is an untyped constant, the +result is an integer constant; otherwise it is a constant of the same +type as the left operand, which must be of +integer type. +Applying all other operators to untyped constants results in an untyped +constant of the same kind (that is, a boolean, integer, floating-point, +complex, or string constant). +

+ +
+const a = 2 + 3.0          // a == 5.0   (untyped floating-point constant)
+const b = 15 / 4           // b == 3     (untyped integer constant)
+const c = 15 / 4.0         // c == 3.75  (untyped floating-point constant)
+const Θ float64 = 3/2      // Θ == 1.0   (type float64, 3/2 is integer division)
+const Π float64 = 3/2.     // Π == 1.5   (type float64, 3/2. is float division)
+const d = 1 << 3.0         // d == 8     (untyped integer constant)
+const e = 1.0 << 3         // e == 8     (untyped integer constant)
+const f = int32(1) << 33   // illegal    (constant 8589934592 overflows int32)
+const g = float64(2) >> 1  // illegal    (float64(2) is a typed floating-point constant)
+const h = "foo" > "bar"    // h == true  (untyped boolean constant)
+const j = true             // j == true  (untyped boolean constant)
+const k = 'w' + 1          // k == 'x'   (untyped rune constant)
+const l = "hi"             // l == "hi"  (untyped string constant)
+const m = string(k)        // m == "x"   (type string)
+const Σ = 1 - 0.707i       //            (untyped complex constant)
+const Δ = Σ + 2.0e-4       //            (untyped complex constant)
+const Φ = iota*1i - 1/1i   //            (untyped complex constant)
+
+ +

+Applying the built-in function complex to untyped +integer, rune, or floating-point constants yields +an untyped complex constant. +

+ +
+const ic = complex(0, c)   // ic == 3.75i  (untyped complex constant)
+const iΘ = complex(0, Θ)   // iΘ == 1i     (type complex128)
+
+ +

+Constant expressions are always evaluated exactly; intermediate values and the +constants themselves may require precision significantly larger than supported +by any predeclared type in the language. The following are legal declarations: +

+ +
+const Huge = 1 << 100         // Huge == 1267650600228229401496703205376  (untyped integer constant)
+const Four int8 = Huge >> 98  // Four == 4                                (type int8)
+
+ +

+The divisor of a constant division or remainder operation must not be zero: +

+ +
+3.14 / 0.0   // illegal: division by zero
+
+ +

+The values of typed constants must always be accurately representable as values +of the constant type. The following constant expressions are illegal: +

+ +
+uint(-1)     // -1 cannot be represented as a uint
+int(3.14)    // 3.14 cannot be represented as an int
+int64(Huge)  // 1267650600228229401496703205376 cannot be represented as an int64
+Four * 300   // operand 300 cannot be represented as an int8 (type of Four)
+Four * 100   // product 400 cannot be represented as an int8 (type of Four)
+
+ +

+The mask used by the unary bitwise complement operator ^ matches +the rule for non-constants: the mask is all 1s for unsigned constants +and -1 for signed and untyped constants. +

+ +
+^1         // untyped integer constant, equal to -2
+uint8(^1)  // illegal: same as uint8(-2), -2 cannot be represented as a uint8
+^uint8(1)  // typed uint8 constant, same as 0xFF ^ uint8(1) = uint8(0xFE)
+int8(^1)   // same as int8(-2)
+^int8(1)   // same as -1 ^ int8(1) = -2
+
+ +

+Implementation restriction: A compiler may use rounding while +computing untyped floating-point or complex constant expressions; see +the implementation restriction in the section +on constants. This rounding may cause a +floating-point constant expression to be invalid in an integer +context, even if it would be integral when calculated using infinite +precision. +

+ + +

Order of evaluation

+ +

+At package level, initialization dependencies +determine the evaluation order of individual initialization expressions in +variable declarations. +Otherwise, when evaluating the operands of an +expression, assignment, or +return statement, +all function calls, method calls, and +communication operations are evaluated in lexical left-to-right +order. +

+ +

+For example, in the (function-local) assignment +

+
+y[f()], ok = g(h(), i()+x[j()], <-c), k()
+
+

+the function calls and communication happen in the order +f(), h(), i(), j(), +<-c, g(), and k(). +However, the order of those events compared to the evaluation +and indexing of x and the evaluation +of y is not specified. +

+ +
+a := 1
+f := func() int { a++; return a }
+x := []int{a, f()}            // x may be [1, 2] or [2, 2]: evaluation order between a and f() is not specified
+m := map[int]int{a: 1, a: 2}  // m may be {2: 1} or {2: 2}: evaluation order between the two map assignments is not specified
+n := map[int]int{a: f()}      // n may be {2: 3} or {3: 3}: evaluation order between the key and the value is not specified
+
+ +

+At package level, initialization dependencies override the left-to-right rule +for individual initialization expressions, but not for operands within each +expression: +

+ +
+var a, b, c = f() + v(), g(), sqr(u()) + v()
+
+func f() int        { return c }
+func g() int        { return a }
+func sqr(x int) int { return x*x }
+
+// functions u and v are independent of all other variables and functions
+
+ +

+The function calls happen in the order +u(), sqr(), v(), +f(), v(), and g(). +

+ +

+Floating-point operations within a single expression are evaluated according to +the associativity of the operators. Explicit parentheses affect the evaluation +by overriding the default associativity. +In the expression x + (y + z) the addition y + z +is performed before adding x. +

+ +

Statements

+ +

+Statements control execution. +

+ +
+Statement =
+	Declaration | LabeledStmt | SimpleStmt |
+	GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
+	FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |
+	DeferStmt .
+
+SimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .
+
+ +

Terminating statements

+ +

+A terminating statement is one of the following: +

+ +
    +
  1. + A "return" or + "goto" statement. + +
    +
  2. + +
  3. + A call to the built-in function + panic. + +
    +
  4. + +
  5. + A block in which the statement list ends in a terminating statement. + +
    +
  6. + +
  7. + An "if" statement in which: +
      +
    • the "else" branch is present, and
    • +
    • both branches are terminating statements.
    • +
    +
  8. + +
  9. + A "for" statement in which: +
      +
    • there are no "break" statements referring to the "for" statement, and
    • +
    • the loop condition is absent.
    • +
    +
  10. + +
  11. + A "switch" statement in which: +
      +
    • there are no "break" statements referring to the "switch" statement,
    • +
    • there is a default case, and
    • +
    • the statement lists in each case, including the default, end in a terminating + statement, or a possibly labeled "fallthrough" + statement.
    • +
    +
  12. + +
  13. + A "select" statement in which: +
      +
    • there are no "break" statements referring to the "select" statement, and
    • +
    • the statement lists in each case, including the default if present, + end in a terminating statement.
    • +
    +
  14. + +
  15. + A labeled statement labeling + a terminating statement. +
  16. +
+ +

+All other statements are not terminating. +

+ +

+A statement list ends in a terminating statement if the list +is not empty and its final statement is terminating. +

+ + +

Empty statements

+ +

+The empty statement does nothing. +

+ +
+EmptyStmt = .
+
+ + +

Labeled statements

+ +

+A labeled statement may be the target of a goto, +break or continue statement. +

+ +
+LabeledStmt = Label ":" Statement .
+Label       = identifier .
+
+ +
+Error: log.Panic("error encountered")
+
+ + +

Expression statements

+ +

+With the exception of specific built-in functions, +function and method calls and +receive operations +can appear in statement context. Such statements may be parenthesized. +

+ +
+ExpressionStmt = Expression .
+
+ +

+The following built-in functions are not permitted in statement context: +

+ +
+append cap complex imag len make new real
+unsafe.Alignof unsafe.Offsetof unsafe.Sizeof
+
+ +
+h(x+y)
+f.Close()
+<-ch
+(<-ch)
+len("foo")  // illegal if len is the built-in function
+
+ + +

Send statements

+ +

+A send statement sends a value on a channel. +The channel expression must be of channel type, +the channel direction must permit send operations, +and the type of the value to be sent must be assignable +to the channel's element type. +

+ +
+SendStmt = Channel "<-" Expression .
+Channel  = Expression .
+
+ +

+Both the channel and the value expression are evaluated before communication +begins. Communication blocks until the send can proceed. +A send on an unbuffered channel can proceed if a receiver is ready. +A send on a buffered channel can proceed if there is room in the buffer. +A send on a closed channel proceeds by causing a run-time panic. +A send on a nil channel blocks forever. +

+ +
+ch <- 3  // send value 3 to channel ch
+
+ + +

IncDec statements

+ +

+The "++" and "--" statements increment or decrement their operands +by the untyped constant 1. +As with an assignment, the operand must be addressable +or a map index expression. +

+ +
+IncDecStmt = Expression ( "++" | "--" ) .
+
+ +

+The following assignment statements are semantically +equivalent: +

+ +
+IncDec statement    Assignment
+x++                 x += 1
+x--                 x -= 1
+
+ + +

Assignments

+ +
+Assignment = ExpressionList assign_op ExpressionList .
+
+assign_op = [ add_op | mul_op ] "=" .
+
+ +

+Each left-hand side operand must be addressable, +a map index expression, or (for = assignments only) the +blank identifier. +Operands may be parenthesized. +

+ +
+x = 1
+*p = f()
+a[i] = 23
+(k) = <-ch  // same as: k = <-ch
+
+ +

+An assignment operation x op= +y where op is a binary arithmetic operation is equivalent +to x = x op +y but evaluates x +only once. The op= construct is a single token. +In assignment operations, both the left- and right-hand expression lists +must contain exactly one single-valued expression, and the left-hand +expression must not be the blank identifier. +

+ +
+a[i] <<= 2
+i &^= 1<<n
+
+ +

+A tuple assignment assigns the individual elements of a multi-valued +operation to a list of variables. There are two forms. In the +first, the right hand operand is a single multi-valued expression +such as a function call, a channel or +map operation, or a type assertion. +The number of operands on the left +hand side must match the number of values. For instance, if +f is a function returning two values, +

+ +
+x, y = f()
+
+ +

+assigns the first value to x and the second to y. +In the second form, the number of operands on the left must equal the number +of expressions on the right, each of which must be single-valued, and the +nth expression on the right is assigned to the nth +operand on the left: +

+ +
+one, two, three = '一', '二', '三'
+
+ +

+The blank identifier provides a way to +ignore right-hand side values in an assignment: +

+ +
+_ = x       // evaluate x but ignore it
+x, _ = f()  // evaluate f() but ignore second result value
+
+ +

+The assignment proceeds in two phases. +First, the operands of index expressions +and pointer indirections +(including implicit pointer indirections in selectors) +on the left and the expressions on the right are all +evaluated in the usual order. +Second, the assignments are carried out in left-to-right order. +

+ +
+a, b = b, a  // exchange a and b
+
+x := []int{1, 2, 3}
+i := 0
+i, x[i] = 1, 2  // set i = 1, x[0] = 2
+
+i = 0
+x[i], i = 2, 1  // set x[0] = 2, i = 1
+
+x[0], x[0] = 1, 2  // set x[0] = 1, then x[0] = 2 (so x[0] == 2 at end)
+
+x[1], x[3] = 4, 5  // set x[1] = 4, then panic setting x[3] = 5.
+
+type Point struct { x, y int }
+var p *Point
+x[2], p.x = 6, 7  // set x[2] = 6, then panic setting p.x = 7
+
+i = 2
+x = []int{3, 5, 7}
+for i, x[i] = range x {  // set i, x[2] = 0, x[0]
+	break
+}
+// after this loop, i == 0 and x == []int{3, 5, 3}
+
+ +

+In assignments, each value must be assignable +to the type of the operand to which it is assigned, with the following special cases: +

+ +
    +
  1. + Any typed value may be assigned to the blank identifier. +
  2. + +
  3. + If an untyped constant + is assigned to a variable of interface type or the blank identifier, + the constant is first converted to its + default type. +
  4. + +
  5. + If an untyped boolean value is assigned to a variable of interface type or + the blank identifier, it is first converted to type bool. +
  6. +
+ +

If statements

+ +

+"If" statements specify the conditional execution of two branches +according to the value of a boolean expression. If the expression +evaluates to true, the "if" branch is executed, otherwise, if +present, the "else" branch is executed. +

+ +
+IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .
+
+ +
+if x > max {
+	x = max
+}
+
+ +

+The expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+if x := f(); x < y {
+	return x
+} else if x > z {
+	return z
+} else {
+	return y
+}
+
+ + +

Switch statements

+ +

+"Switch" statements provide multi-way execution. +An expression or type specifier is compared to the "cases" +inside the "switch" to determine which branch +to execute. +

+ +
+SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
+
+ +

+There are two forms: expression switches and type switches. +In an expression switch, the cases contain expressions that are compared +against the value of the switch expression. +In a type switch, the cases contain types that are compared against the +type of a specially annotated switch expression. +

+ +

Expression switches

+ +

+In an expression switch, +the switch expression is evaluated and +the case expressions, which need not be constants, +are evaluated left-to-right and top-to-bottom; the first one that equals the +switch expression +triggers execution of the statements of the associated case; +the other cases are skipped. +If no case matches and there is a "default" case, +its statements are executed. +There can be at most one default case and it may appear anywhere in the +"switch" statement. +A missing switch expression is equivalent to the boolean value +true. +

+ +
+ExprSwitchStmt = "switch" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
+ExprCaseClause = ExprSwitchCase ":" StatementList .
+ExprSwitchCase = "case" ExpressionList | "default" .
+
+ +

+In a case or default clause, the last non-empty statement +may be a (possibly labeled) +"fallthrough" statement to +indicate that control should flow from the end of this clause to +the first statement of the next clause. +Otherwise control flows to the end of the "switch" statement. +A "fallthrough" statement may appear as the last statement of all +but the last clause of an expression switch. +

+ +

+The expression may be preceded by a simple statement, which +executes before the expression is evaluated. +

+ +
+switch tag {
+default: s3()
+case 0, 1, 2, 3: s1()
+case 4, 5, 6, 7: s2()
+}
+
+switch x := f(); {  // missing switch expression means "true"
+case x < 0: return -x
+default: return x
+}
+
+switch {
+case x < y: f1()
+case x < z: f2()
+case x == 4: f3()
+}
+
+ +

Type switches

+ +

+A type switch compares types rather than values. It is otherwise similar +to an expression switch. It is marked by a special switch expression that +has the form of a type assertion +using the reserved word type rather than an actual type: +

+ +
+switch x.(type) {
+// cases
+}
+
+ +

+Cases then match actual types T against the dynamic type of the +expression x. As with type assertions, x must be of +interface type, and each non-interface type +T listed in a case must implement the type of x. +

+ +
+TypeSwitchStmt  = "switch" [ SimpleStmt ";" ] TypeSwitchGuard "{" { TypeCaseClause } "}" .
+TypeSwitchGuard = [ identifier ":=" ] PrimaryExpr "." "(" "type" ")" .
+TypeCaseClause  = TypeSwitchCase ":" StatementList .
+TypeSwitchCase  = "case" TypeList | "default" .
+TypeList        = Type { "," Type } .
+
+ +

+The TypeSwitchGuard may include a +short variable declaration. +When that form is used, the variable is declared at the beginning of +the implicit block in each clause. +In clauses with a case listing exactly one type, the variable +has that type; otherwise, the variable has the type of the expression +in the TypeSwitchGuard. +

+ +

+The type in a case may be nil; +that case is used when the expression in the TypeSwitchGuard +is a nil interface value. +

+ +

+Given an expression x of type interface{}, +the following type switch: +

+ +
+switch i := x.(type) {
+case nil:
+	printString("x is nil")                // type of i is type of x (interface{})
+case int:
+	printInt(i)                            // type of i is int
+case float64:
+	printFloat64(i)                        // type of i is float64
+case func(int) float64:
+	printFunction(i)                       // type of i is func(int) float64
+case bool, string:
+	printString("type is bool or string")  // type of i is type of x (interface{})
+default:
+	printString("don't know the type")     // type of i is type of x (interface{})
+}
+
+ +

+could be rewritten: +

+ +
+v := x  // x is evaluated exactly once
+if v == nil {
+	i := v                                 // type of i is type of x (interface{})
+	printString("x is nil")
+} else if i, isInt := v.(int); isInt {
+	printInt(i)                            // type of i is int
+} else if i, isFloat64 := v.(float64); isFloat64 {
+	printFloat64(i)                        // type of i is float64
+} else if i, isFunc := v.(func(int) float64); isFunc {
+	printFunction(i)                       // type of i is func(int) float64
+} else {
+	_, isBool := v.(bool)
+	_, isString := v.(string)
+	if isBool || isString {
+		i := v                         // type of i is type of x (interface{})
+		printString("type is bool or string")
+	} else {
+		i := v                         // type of i is type of x (interface{})
+		printString("don't know the type")
+	}
+}
+
+ +

+The type switch guard may be preceded by a simple statement, which +executes before the guard is evaluated. +

+ +

+The "fallthrough" statement is not permitted in a type switch. +

+ +

For statements

+ +

+A "for" statement specifies repeated execution of a block. The iteration is +controlled by a condition, a "for" clause, or a "range" clause. +

+ +
+ForStmt = "for" [ Condition | ForClause | RangeClause ] Block .
+Condition = Expression .
+
+ +

+In its simplest form, a "for" statement specifies the repeated execution of +a block as long as a boolean condition evaluates to true. +The condition is evaluated before each iteration. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for a < b {
+	a *= 2
+}
+
+ +

+A "for" statement with a ForClause is also controlled by its condition, but +additionally it may specify an init +and a post statement, such as an assignment, +an increment or decrement statement. The init statement may be a +short variable declaration, but the post statement must not. +Variables declared by the init statement are re-used in each iteration. +

+ +
+ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
+InitStmt = SimpleStmt .
+PostStmt = SimpleStmt .
+
+ +
+for i := 0; i < 10; i++ {
+	f(i)
+}
+
+ +

+If non-empty, the init statement is executed once before evaluating the +condition for the first iteration; +the post statement is executed after each execution of the block (and +only if the block was executed). +Any element of the ForClause may be empty but the +semicolons are +required unless there is only a condition. +If the condition is absent, it is equivalent to the boolean value +true. +

+ +
+for cond { S() }    is the same as    for ; cond ; { S() }
+for      { S() }    is the same as    for true     { S() }
+
+ +

+A "for" statement with a "range" clause +iterates through all entries of an array, slice, string or map, +or values received on a channel. For each entry it assigns iteration values +to corresponding iteration variables if present and then executes the block. +

+ +
+RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
+
+ +

+The expression on the right in the "range" clause is called the range expression, +which may be an array, pointer to an array, slice, string, map, or channel permitting +receive operations. +As with an assignment, if present the operands on the left must be +addressable or map index expressions; they +denote the iteration variables. If the range expression is a channel, at most +one iteration variable is permitted, otherwise there may be up to two. +If the last iteration variable is the blank identifier, +the range clause is equivalent to the same clause without that identifier. +

+ +

+The range expression is evaluated once before beginning the loop, +with one exception: if the range expression is an array or a pointer to an array +and at most one iteration variable is present, only the range expression's +length is evaluated; if that length is constant, +by definition +the range expression itself will not be evaluated. +

+ +

+Function calls on the left are evaluated once per iteration. +For each iteration, iteration values are produced as follows +if the respective iteration variables are present: +

+ +
+Range expression                          1st value          2nd value
+
+array or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E
+string          s  string type            index    i  int    see below  rune
+map             m  map[K]V                key      k  K      m[k]       V
+channel         c  chan E, <-chan E       element  e  E
+
+ +
    +
  1. +For an array, pointer to array, or slice value a, the index iteration +values are produced in increasing order, starting at element index 0. +If at most one iteration variable is present, the range loop produces +iteration values from 0 up to len(a)-1 and does not index into the array +or slice itself. For a nil slice, the number of iterations is 0. +
  2. + +
  3. +For a string value, the "range" clause iterates over the Unicode code points +in the string starting at byte index 0. On successive iterations, the index value will be the +index of the first byte of successive UTF-8-encoded code points in the string, +and the second value, of type rune, will be the value of +the corresponding code point. If the iteration encounters an invalid +UTF-8 sequence, the second value will be 0xFFFD, +the Unicode replacement character, and the next iteration will advance +a single byte in the string. +
  4. + +
  5. +The iteration order over maps is not specified +and is not guaranteed to be the same from one iteration to the next. +If map entries that have not yet been reached are removed during iteration, +the corresponding iteration values will not be produced. If map entries are +created during iteration, that entry may be produced during the iteration or +may be skipped. The choice may vary for each entry created and from one +iteration to the next. +If the map is nil, the number of iterations is 0. +
  6. + +
  7. +For channels, the iteration values produced are the successive values sent on +the channel until the channel is closed. If the channel +is nil, the range expression blocks forever. +
  8. +
+ +

+The iteration values are assigned to the respective +iteration variables as in an assignment statement. +

+ +

+The iteration variables may be declared by the "range" clause using a form of +short variable declaration +(:=). +In this case their types are set to the types of the respective iteration values +and their scope is the block of the "for" +statement; they are re-used in each iteration. +If the iteration variables are declared outside the "for" statement, +after execution their values will be those of the last iteration. +

+ +
+var testdata *struct {
+	a *[7]int
+}
+for i, _ := range testdata.a {
+	// testdata.a is never evaluated; len(testdata.a) is constant
+	// i ranges from 0 to 6
+	f(i)
+}
+
+var a [10]string
+for i, s := range a {
+	// type of i is int
+	// type of s is string
+	// s == a[i]
+	g(i, s)
+}
+
+var key string
+var val interface {}  // value type of m is assignable to val
+m := map[string]int{"mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6}
+for key, val = range m {
+	h(key, val)
+}
+// key == last map key encountered in iteration
+// val == map[key]
+
+var ch chan Work = producer()
+for w := range ch {
+	doWork(w)
+}
+
+// empty a channel
+for range ch {}
+
+ + +

Go statements

+ +

+A "go" statement starts the execution of a function call +as an independent concurrent thread of control, or goroutine, +within the same address space. +

+ +
+GoStmt = "go" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+The function value and parameters are +evaluated as usual +in the calling goroutine, but +unlike with a regular call, program execution does not wait +for the invoked function to complete. +Instead, the function begins executing independently +in a new goroutine. +When the function terminates, its goroutine also terminates. +If the function has any return values, they are discarded when the +function completes. +

+ +
+go Server()
+go func(ch chan<- bool) { for { sleep(10); ch <- true; }} (c)
+
+ + +

Select statements

+ +

+A "select" statement chooses which of a set of possible +send or +receive +operations will proceed. +It looks similar to a +"switch" statement but with the +cases all referring to communication operations. +

+ +
+SelectStmt = "select" "{" { CommClause } "}" .
+CommClause = CommCase ":" StatementList .
+CommCase   = "case" ( SendStmt | RecvStmt ) | "default" .
+RecvStmt   = [ ExpressionList "=" | IdentifierList ":=" ] RecvExpr .
+RecvExpr   = Expression .
+
+ +

+A case with a RecvStmt may assign the result of a RecvExpr to one or +two variables, which may be declared using a +short variable declaration. +The RecvExpr must be a (possibly parenthesized) receive operation. +There can be at most one default case and it may appear anywhere +in the list of cases. +

+ +

+Execution of a "select" statement proceeds in several steps: +

+ +
    +
  1. +For all the cases in the statement, the channel operands of receive operations +and the channel and right-hand-side expressions of send statements are +evaluated exactly once, in source order, upon entering the "select" statement. +The result is a set of channels to receive from or send to, +and the corresponding values to send. +Any side effects in that evaluation will occur irrespective of which (if any) +communication operation is selected to proceed. +Expressions on the left-hand side of a RecvStmt with a short variable declaration +or assignment are not yet evaluated. +
  2. + +
  3. +If one or more of the communications can proceed, +a single one that can proceed is chosen via a uniform pseudo-random selection. +Otherwise, if there is a default case, that case is chosen. +If there is no default case, the "select" statement blocks until +at least one of the communications can proceed. +
  4. + +
  5. +Unless the selected case is the default case, the respective communication +operation is executed. +
  6. + +
  7. +If the selected case is a RecvStmt with a short variable declaration or +an assignment, the left-hand side expressions are evaluated and the +received value (or values) are assigned. +
  8. + +
  9. +The statement list of the selected case is executed. +
  10. +
+ +

+Since communication on nil channels can never proceed, +a select with only nil channels and no default case blocks forever. +

+ +
+var a []int
+var c, c1, c2, c3, c4 chan int
+var i1, i2 int
+select {
+case i1 = <-c1:
+	print("received ", i1, " from c1\n")
+case c2 <- i2:
+	print("sent ", i2, " to c2\n")
+case i3, ok := (<-c3):  // same as: i3, ok := <-c3
+	if ok {
+		print("received ", i3, " from c3\n")
+	} else {
+		print("c3 is closed\n")
+	}
+case a[f()] = <-c4:
+	// same as:
+	// case t := <-c4
+	//	a[f()] = t
+default:
+	print("no communication\n")
+}
+
+for {  // send random sequence of bits to c
+	select {
+	case c <- 0:  // note: no statement, no fallthrough, no folding of cases
+	case c <- 1:
+	}
+}
+
+select {}  // block forever
+
+ + +

Return statements

+ +

+A "return" statement in a function F terminates the execution +of F, and optionally provides one or more result values. +Any functions deferred by F +are executed before F returns to its caller. +

+ +
+ReturnStmt = "return" [ ExpressionList ] .
+
+ +

+In a function without a result type, a "return" statement must not +specify any result values. +

+
+func noResult() {
+	return
+}
+
+ +

+There are three ways to return values from a function with a result +type: +

+ +
    +
  1. The return value or values may be explicitly listed + in the "return" statement. Each expression must be single-valued + and assignable + to the corresponding element of the function's result type. +
    +func simpleF() int {
    +	return 2
    +}
    +
    +func complexF1() (re float64, im float64) {
    +	return -7.0, -4.0
    +}
    +
    +
  2. +
  3. The expression list in the "return" statement may be a single + call to a multi-valued function. The effect is as if each value + returned from that function were assigned to a temporary + variable with the type of the respective value, followed by a + "return" statement listing these variables, at which point the + rules of the previous case apply. +
    +func complexF2() (re float64, im float64) {
    +	return complexF1()
    +}
    +
    +
  4. +
  5. The expression list may be empty if the function's result + type specifies names for its result parameters. + The result parameters act as ordinary local variables + and the function may assign values to them as necessary. + The "return" statement returns the values of these variables. +
    +func complexF3() (re float64, im float64) {
    +	re = 7.0
    +	im = 4.0
    +	return
    +}
    +
    +func (devnull) Write(p []byte) (n int, _ error) {
    +	n = len(p)
    +	return
    +}
    +
    +
  6. +
+ +

+Regardless of how they are declared, all the result values are initialized to +the zero values for their type upon entry to the +function. A "return" statement that specifies results sets the result parameters before +any deferred functions are executed. +

+ +

+Implementation restriction: A compiler may disallow an empty expression list +in a "return" statement if a different entity (constant, type, or variable) +with the same name as a result parameter is in +scope at the place of the return. +

+ +
+func f(n int) (res int, err error) {
+	if _, err := f(n-1); err != nil {
+		return  // invalid return statement: err is shadowed
+	}
+	return
+}
+
+ +

Break statements

+ +

+A "break" statement terminates execution of the innermost +"for", +"switch", or +"select" statement +within the same function. +

+ +
+BreakStmt = "break" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for", "switch", or "select" statement, +and that is the one whose execution terminates. +

+ +
+OuterLoop:
+	for i = 0; i < n; i++ {
+		for j = 0; j < m; j++ {
+			switch a[i][j] {
+			case nil:
+				state = Error
+				break OuterLoop
+			case item:
+				state = Found
+				break OuterLoop
+			}
+		}
+	}
+
+ +

Continue statements

+ +

+A "continue" statement begins the next iteration of the +innermost "for" loop at its post statement. +The "for" loop must be within the same function. +

+ +
+ContinueStmt = "continue" [ Label ] .
+
+ +

+If there is a label, it must be that of an enclosing +"for" statement, and that is the one whose execution +advances. +

+ +
+RowLoop:
+	for y, row := range rows {
+		for x, data := range row {
+			if data == endOfRow {
+				continue RowLoop
+			}
+			row[x] = data + bias(x, y)
+		}
+	}
+
+ +

Goto statements

+ +

+A "goto" statement transfers control to the statement with the corresponding label +within the same function. +

+ +
+GotoStmt = "goto" Label .
+
+ +
+goto Error
+
+ +

+Executing the "goto" statement must not cause any variables to come into +scope that were not already in scope at the point of the goto. +For instance, this example: +

+ +
+	goto L  // BAD
+	v := 3
+L:
+
+ +

+is erroneous because the jump to label L skips +the creation of v. +

+ +

+A "goto" statement outside a block cannot jump to a label inside that block. +For instance, this example: +

+ +
+if n%2 == 1 {
+	goto L1
+}
+for n > 0 {
+	f()
+	n--
+L1:
+	f()
+	n--
+}
+
+ +

+is erroneous because the label L1 is inside +the "for" statement's block but the goto is not. +

+ +

Fallthrough statements

+ +

+A "fallthrough" statement transfers control to the first statement of the +next case clause in a expression "switch" statement. +It may be used only as the final non-empty statement in such a clause. +

+ +
+FallthroughStmt = "fallthrough" .
+
+ + +

Defer statements

+ +

+A "defer" statement invokes a function whose execution is deferred +to the moment the surrounding function returns, either because the +surrounding function executed a return statement, +reached the end of its function body, +or because the corresponding goroutine is panicking. +

+ +
+DeferStmt = "defer" Expression .
+
+ +

+The expression must be a function or method call; it cannot be parenthesized. +Calls of built-in functions are restricted as for +expression statements. +

+ +

+Each time a "defer" statement +executes, the function value and parameters to the call are +evaluated as usual +and saved anew but the actual function is not invoked. +Instead, deferred functions are invoked immediately before +the surrounding function returns, in the reverse order +they were deferred. +If a deferred function value evaluates +to nil, execution panics +when the function is invoked, not when the "defer" statement is executed. +

+ +

+For instance, if the deferred function is +a function literal and the surrounding +function has named result parameters that +are in scope within the literal, the deferred function may access and modify +the result parameters before they are returned. +If the deferred function has any return values, they are discarded when +the function completes. +(See also the section on handling panics.) +

+ +
+lock(l)
+defer unlock(l)  // unlocking happens before surrounding function returns
+
+// prints 3 2 1 0 before surrounding function returns
+for i := 0; i <= 3; i++ {
+	defer fmt.Print(i)
+}
+
+// f returns 1
+func f() (result int) {
+	defer func() {
+		result++
+	}()
+	return 0
+}
+
+ +

Built-in functions

+ +

+Built-in functions are +predeclared. +They are called like any other function but some of them +accept a type instead of an expression as the first argument. +

+ +

+The built-in functions do not have standard Go types, +so they can only appear in call expressions; +they cannot be used as function values. +

+ +

Close

+ +

+For a channel c, the built-in function close(c) +records that no more values will be sent on the channel. +It is an error if c is a receive-only channel. +Sending to or closing a closed channel causes a run-time panic. +Closing the nil channel also causes a run-time panic. +After calling close, and after any previously +sent values have been received, receive operations will return +the zero value for the channel's type without blocking. +The multi-valued receive operation +returns a received value along with an indication of whether the channel is closed. +

+ + +

Length and capacity

+ +

+The built-in functions len and cap take arguments +of various types and return a result of type int. +The implementation guarantees that the result always fits into an int. +

+ +
+Call      Argument type    Result
+
+len(s)    string type      string length in bytes
+          [n]T, *[n]T      array length (== n)
+          []T              slice length
+          map[K]T          map length (number of defined keys)
+          chan T           number of elements queued in channel buffer
+
+cap(s)    [n]T, *[n]T      array length (== n)
+          []T              slice capacity
+          chan T           channel buffer capacity
+
+ +

+The capacity of a slice is the number of elements for which there is +space allocated in the underlying array. +At any time the following relationship holds: +

+ +
+0 <= len(s) <= cap(s)
+
+ +

+The length of a nil slice, map or channel is 0. +The capacity of a nil slice or channel is 0. +

+ +

+The expression len(s) is constant if +s is a string constant. The expressions len(s) and +cap(s) are constants if the type of s is an array +or pointer to an array and the expression s does not contain +channel receives or (non-constant) +function calls; in this case s is not evaluated. +Otherwise, invocations of len and cap are not +constant and s is evaluated. +

+ +
+const (
+	c1 = imag(2i)                    // imag(2i) = 2.0 is a constant
+	c2 = len([10]float64{2})         // [10]float64{2} contains no function calls
+	c3 = len([10]float64{c1})        // [10]float64{c1} contains no function calls
+	c4 = len([10]float64{imag(2i)})  // imag(2i) is a constant and no function call is issued
+	c5 = len([10]float64{imag(z)})   // invalid: imag(x) is a (non-constant) function call
+)
+var z complex128
+
+ +

Allocation

+ +

+The built-in function new takes a type T, +allocates storage for a variable of that type +at run time, and returns a value of type *T +pointing to it. +The variable is initialized as described in the section on +initial values. +

+ +
+new(T)
+
+ +

+For instance +

+ +
+type S struct { a int; b float64 }
+new(S)
+
+ +

+allocates storage for a variable of type S, +initializes it (a=0, b=0.0), +and returns a value of type *S containing the address +of the location. +

+ +

Making slices, maps and channels

+ +

+The built-in function make takes a type T, +which must be a slice, map or channel type, +optionally followed by a type-specific list of expressions. +It returns a value of type T (not *T). +The memory is initialized as described in the section on +initial values. +

+ +
+Call             Type T     Result
+
+make(T, n)       slice      slice of type T with length n and capacity n
+make(T, n, m)    slice      slice of type T with length n and capacity m
+
+make(T)          map        map of type T
+make(T, n)       map        map of type T with initial space for n elements
+
+make(T)          channel    unbuffered channel of type T
+make(T, n)       channel    buffered channel of type T, buffer size n
+
+ + +

+The size arguments n and m must be of integer type or untyped. +A constant size argument must be non-negative and +representable by a value of type int. +If both n and m are provided and are constant, then +n must be no larger than m. +If n is negative or larger than m at run time, +a run-time panic occurs. +

+ +
+s := make([]int, 10, 100)       // slice with len(s) == 10, cap(s) == 100
+s := make([]int, 1e3)           // slice with len(s) == cap(s) == 1000
+s := make([]int, 1<<63)         // illegal: len(s) is not representable by a value of type int
+s := make([]int, 10, 0)         // illegal: len(s) > cap(s)
+c := make(chan int, 10)         // channel with a buffer size of 10
+m := make(map[string]int, 100)  // map with initial space for 100 elements
+
+ + +

Appending to and copying slices

+ +

+The built-in functions append and copy assist in +common slice operations. +For both functions, the result is independent of whether the memory referenced +by the arguments overlaps. +

+ +

+The variadic function append +appends zero or more values x +to s of type S, which must be a slice type, and +returns the resulting slice, also of type S. +The values x are passed to a parameter of type ...T +where T is the element type of +S and the respective +parameter passing rules apply. +As a special case, append also accepts a first argument +assignable to type []byte with a second argument of +string type followed by .... This form appends the +bytes of the string. +

+ +
+append(s S, x ...T) S  // T is the element type of S
+
+ +

+If the capacity of s is not large enough to fit the additional +values, append allocates a new, sufficiently large underlying +array that fits both the existing slice elements and the additional values. +Otherwise, append re-uses the underlying array. +

+ +
+s0 := []int{0, 0}
+s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}
+s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}
+s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}
+s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}
+
+var t []interface{}
+t = append(t, 42, 3.1415, "foo")                                  t == []interface{}{42, 3.1415, "foo"}
+
+var b []byte
+b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }
+
+ +

+The function copy copies slice elements from +a source src to a destination dst and returns the +number of elements copied. +Both arguments must have identical element type T and must be +assignable to a slice of type []T. +The number of elements copied is the minimum of +len(src) and len(dst). +As a special case, copy also accepts a destination argument assignable +to type []byte with a source argument of a string type. +This form copies the bytes from the string into the byte slice. +

+ +
+copy(dst, src []T) int
+copy(dst []byte, src string) int
+
+ +

+Examples: +

+ +
+var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}
+var s = make([]int, 6)
+var b = make([]byte, 5)
+n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}
+n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}
+n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")
+
+ + +

Deletion of map elements

+ +

+The built-in function delete removes the element with key +k from a map m. The +type of k must be assignable +to the key type of m. +

+ +
+delete(m, k)  // remove element m[k] from map m
+
+ +

+If the map m is nil or the element m[k] +does not exist, delete is a no-op. +

+ + +

Manipulating complex numbers

+ +

+Three functions assemble and disassemble complex numbers. +The built-in function complex constructs a complex +value from a floating-point real and imaginary part, while +real and imag +extract the real and imaginary parts of a complex value. +

+ +
+complex(realPart, imaginaryPart floatT) complexT
+real(complexT) floatT
+imag(complexT) floatT
+
+ +

+The type of the arguments and return value correspond. +For complex, the two arguments must be of the same +floating-point type and the return type is the complex type +with the corresponding floating-point constituents: +complex64 for float32, +complex128 for float64. +The real and imag functions +together form the inverse, so for a complex value z, +z == complex(real(z), imag(z)). +

+ +

+If the operands of these functions are all constants, the return +value is a constant. +

+ +
+var a = complex(2, -2)             // complex128
+var b = complex(1.0, -1.4)         // complex128
+x := float32(math.Cos(math.Pi/2))  // float32
+var c64 = complex(5, -x)           // complex64
+var im = imag(b)                   // float64
+var rl = real(c64)                 // float32
+
+ +

Handling panics

+ +

Two built-in functions, panic and recover, +assist in reporting and handling run-time panics +and program-defined error conditions. +

+ +
+func panic(interface{})
+func recover() interface{}
+
+ +

+While executing a function F, +an explicit call to panic or a run-time panic +terminates the execution of F. +Any functions deferred by F +are then executed as usual. +Next, any deferred functions run by F's caller are run, +and so on up to any deferred by the top-level function in the executing goroutine. +At that point, the program is terminated and the error +condition is reported, including the value of the argument to panic. +This termination sequence is called panicking. +

+ +
+panic(42)
+panic("unreachable")
+panic(Error("cannot parse"))
+
+ +

+The recover function allows a program to manage behavior +of a panicking goroutine. +Suppose a function G defers a function D that calls +recover and a panic occurs in a function on the same goroutine in which G +is executing. +When the running of deferred functions reaches D, +the return value of D's call to recover will be the value passed to the call of panic. +If D returns normally, without starting a new +panic, the panicking sequence stops. In that case, +the state of functions called between G and the call to panic +is discarded, and normal execution resumes. +Any functions deferred by G before D are then run and G's +execution terminates by returning to its caller. +

+ +

+The return value of recover is nil if any of the following conditions holds: +

+
    +
  • +panic's argument was nil; +
  • +
  • +the goroutine is not panicking; +
  • +
  • +recover was not called directly by a deferred function. +
  • +
+ +

+The protect function in the example below invokes +the function argument g and protects callers from +run-time panics raised by g. +

+ +
+func protect(g func()) {
+	defer func() {
+		log.Println("done")  // Println executes normally even if there is a panic
+		if x := recover(); x != nil {
+			log.Printf("run time panic: %v", x)
+		}
+	}()
+	log.Println("start")
+	g()
+}
+
+ + +

Bootstrapping

+ +

+Current implementations provide several built-in functions useful during +bootstrapping. These functions are documented for completeness but are not +guaranteed to stay in the language. They do not return a result. +

+ +
+Function   Behavior
+
+print      prints all arguments; formatting of arguments is implementation-specific
+println    like print but prints spaces between arguments and a newline at the end
+
+ + +

Packages

+ +

+Go programs are constructed by linking together packages. +A package in turn is constructed from one or more source files +that together declare constants, types, variables and functions +belonging to the package and which are accessible in all files +of the same package. Those elements may be +exported and used in another package. +

+ +

Source file organization

+ +

+Each source file consists of a package clause defining the package +to which it belongs, followed by a possibly empty set of import +declarations that declare packages whose contents it wishes to use, +followed by a possibly empty set of declarations of functions, +types, variables, and constants. +

+ +
+SourceFile       = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
+
+ +

Package clause

+ +

+A package clause begins each source file and defines the package +to which the file belongs. +

+ +
+PackageClause  = "package" PackageName .
+PackageName    = identifier .
+
+ +

+The PackageName must not be the blank identifier. +

+ +
+package math
+
+ +

+A set of files sharing the same PackageName form the implementation of a package. +An implementation may require that all source files for a package inhabit the same directory. +

+ +

Import declarations

+ +

+An import declaration states that the source file containing the declaration +depends on functionality of the imported package +(§Program initialization and execution) +and enables access to exported identifiers +of that package. +The import names an identifier (PackageName) to be used for access and an ImportPath +that specifies the package to be imported. +

+ +
+ImportDecl       = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
+ImportSpec       = [ "." | PackageName ] ImportPath .
+ImportPath       = string_lit .
+
+ +

+The PackageName is used in qualified identifiers +to access exported identifiers of the package within the importing source file. +It is declared in the file block. +If the PackageName is omitted, it defaults to the identifier specified in the +package clause of the imported package. +If an explicit period (.) appears instead of a name, all the +package's exported identifiers declared in that package's +package block will be declared in the importing source +file's file block and must be accessed without a qualifier. +

+ +

+The interpretation of the ImportPath is implementation-dependent but +it is typically a substring of the full file name of the compiled +package and may be relative to a repository of installed packages. +

+ +

+Implementation restriction: A compiler may restrict ImportPaths to +non-empty strings using only characters belonging to +Unicode's +L, M, N, P, and S general categories (the Graphic characters without +spaces) and may also exclude the characters +!"#$%&'()*,:;<=>?[\]^`{|} +and the Unicode replacement character U+FFFD. +

+ +

+Assume we have compiled a package containing the package clause +package math, which exports function Sin, and +installed the compiled package in the file identified by +"lib/math". +This table illustrates how Sin is accessed in files +that import the package after the +various types of import declaration. +

+ +
+Import declaration          Local name of Sin
+
+import   "lib/math"         math.Sin
+import m "lib/math"         m.Sin
+import . "lib/math"         Sin
+
+ +

+An import declaration declares a dependency relation between +the importing and imported package. +It is illegal for a package to import itself, directly or indirectly, +or to directly import a package without +referring to any of its exported identifiers. To import a package solely for +its side-effects (initialization), use the blank +identifier as explicit package name: +

+ +
+import _ "lib/math"
+
+ + +

An example package

+ +

+Here is a complete Go package that implements a concurrent prime sieve. +

+ +
+package main
+
+import "fmt"
+
+// Send the sequence 2, 3, 4, … to channel 'ch'.
+func generate(ch chan<- int) {
+	for i := 2; ; i++ {
+		ch <- i  // Send 'i' to channel 'ch'.
+	}
+}
+
+// Copy the values from channel 'src' to channel 'dst',
+// removing those divisible by 'prime'.
+func filter(src <-chan int, dst chan<- int, prime int) {
+	for i := range src {  // Loop over values received from 'src'.
+		if i%prime != 0 {
+			dst <- i  // Send 'i' to channel 'dst'.
+		}
+	}
+}
+
+// The prime sieve: Daisy-chain filter processes together.
+func sieve() {
+	ch := make(chan int)  // Create a new channel.
+	go generate(ch)       // Start generate() as a subprocess.
+	for {
+		prime := <-ch
+		fmt.Print(prime, "\n")
+		ch1 := make(chan int)
+		go filter(ch, ch1, prime)
+		ch = ch1
+	}
+}
+
+func main() {
+	sieve()
+}
+
+ +

Program initialization and execution

+ +

The zero value

+

+When storage is allocated for a variable, +either through a declaration or a call of new, or when +a new value is created, either through a composite literal or a call +of make, +and no explicit initialization is provided, the variable or value is +given a default value. Each element of such a variable or value is +set to the zero value for its type: false for booleans, +0 for integers, 0.0 for floats, "" +for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. +This initialization is done recursively, so for instance each element of an +array of structs will have its fields zeroed if no value is specified. +

+

+These two simple declarations are equivalent: +

+ +
+var i int
+var i int = 0
+
+ +

+After +

+ +
+type T struct { i int; f float64; next *T }
+t := new(T)
+
+ +

+the following holds: +

+ +
+t.i == 0
+t.f == 0.0
+t.next == nil
+
+ +

+The same would also be true after +

+ +
+var t T
+
+ +

Package initialization

+ +

+Within a package, package-level variables are initialized in +declaration order but after any of the variables +they depend on. +

+ +

+More precisely, a package-level variable is considered ready for +initialization if it is not yet initialized and either has +no initialization expression or +its initialization expression has no dependencies on uninitialized variables. +Initialization proceeds by repeatedly initializing the next package-level +variable that is earliest in declaration order and ready for initialization, +until there are no variables ready for initialization. +

+ +

+If any variables are still uninitialized when this +process ends, those variables are part of one or more initialization cycles, +and the program is not valid. +

+ +

+The declaration order of variables declared in multiple files is determined +by the order in which the files are presented to the compiler: Variables +declared in the first file are declared before any of the variables declared +in the second file, and so on. +

+ +

+Dependency analysis does not rely on the actual values of the +variables, only on lexical references to them in the source, +analyzed transitively. For instance, if a variable x's +initialization expression refers to a function whose body refers to +variable y then x depends on y. +Specifically: +

+ +
    +
  • +A reference to a variable or function is an identifier denoting that +variable or function. +
  • + +
  • +A reference to a method m is a +method value or +method expression of the form +t.m, where the (static) type of t is +not an interface type, and the method m is in the +method set of t. +It is immaterial whether the resulting function value +t.m is invoked. +
  • + +
  • +A variable, function, or method x depends on a variable +y if x's initialization expression or body +(for functions and methods) contains a reference to y +or to a function or method that depends on y. +
  • +
+ +

+Dependency analysis is performed per package; only references referring +to variables, functions, and methods declared in the current package +are considered. +

+ +

+For example, given the declarations +

+ +
+var (
+	a = c + b
+	b = f()
+	c = f()
+	d = 3
+)
+
+func f() int {
+	d++
+	return d
+}
+
+ +

+the initialization order is d, b, c, a. +

+ +

+Variables may also be initialized using functions named init +declared in the package block, with no arguments and no result parameters. +

+ +
+func init() { … }
+
+ +

+Multiple such functions may be defined, even within a single +source file. The init identifier is not +declared and thus +init functions cannot be referred to from anywhere +in a program. +

+ +

+A package with no imports is initialized by assigning initial values +to all its package-level variables followed by calling all init +functions in the order they appear in the source, possibly in multiple files, +as presented to the compiler. +If a package has imports, the imported packages are initialized +before initializing the package itself. If multiple packages import +a package, the imported package will be initialized only once. +The importing of packages, by construction, guarantees that there +can be no cyclic initialization dependencies. +

+ +

+Package initialization—variable initialization and the invocation of +init functions—happens in a single goroutine, +sequentially, one package at a time. +An init function may launch other goroutines, which can run +concurrently with the initialization code. However, initialization +always sequences +the init functions: it will not invoke the next one +until the previous one has returned. +

+ +

+To ensure reproducible initialization behavior, build systems are encouraged +to present multiple files belonging to the same package in lexical file name +order to a compiler. +

+ + +

Program execution

+

+A complete program is created by linking a single, unimported package +called the main package with all the packages it imports, transitively. +The main package must +have package name main and +declare a function main that takes no +arguments and returns no value. +

+ +
+func main() { … }
+
+ +

+Program execution begins by initializing the main package and then +invoking the function main. +When that function invocation returns, the program exits. +It does not wait for other (non-main) goroutines to complete. +

+ +

Errors

+ +

+The predeclared type error is defined as +

+ +
+type error interface {
+	Error() string
+}
+
+ +

+It is the conventional interface for representing an error condition, +with the nil value representing no error. +For instance, a function to read data from a file might be defined: +

+ +
+func Read(f *File, b []byte) (n int, err error)
+
+ +

Run-time panics

+ +

+Execution errors such as attempting to index an array out +of bounds trigger a run-time panic equivalent to a call of +the built-in function panic +with a value of the implementation-defined interface type runtime.Error. +That type satisfies the predeclared interface type +error. +The exact error values that +represent distinct run-time error conditions are unspecified. +

+ +
+package runtime
+
+type Error interface {
+	error
+	// and perhaps other methods
+}
+
+ +

System considerations

+ +

Package unsafe

+ +

+The built-in package unsafe, known to the compiler, +provides facilities for low-level programming including operations +that violate the type system. A package using unsafe +must be vetted manually for type safety and may not be portable. +The package provides the following interface: +

+ +
+package unsafe
+
+type ArbitraryType int  // shorthand for an arbitrary Go type; it is not a real type
+type Pointer *ArbitraryType
+
+func Alignof(variable ArbitraryType) uintptr
+func Offsetof(selector ArbitraryType) uintptr
+func Sizeof(variable ArbitraryType) uintptr
+
+ +

+A Pointer is a pointer type but a Pointer +value may not be dereferenced. +Any pointer or value of underlying type uintptr can be converted to +a Pointer type and vice versa. +The effect of converting between Pointer and uintptr is implementation-defined. +

+ +
+var f float64
+bits = *(*uint64)(unsafe.Pointer(&f))
+
+type ptr unsafe.Pointer
+bits = *(*uint64)(ptr(&f))
+
+var p ptr = nil
+
+ +

+The functions Alignof and Sizeof take an expression x +of any type and return the alignment or size, respectively, of a hypothetical variable v +as if v was declared via var v = x. +

+

+The function Offsetof takes a (possibly parenthesized) selector +s.f, denoting a field f of the struct denoted by s +or *s, and returns the field offset in bytes relative to the struct's address. +If f is an embedded field, it must be reachable +without pointer indirections through fields of the struct. +For a struct s with field f: +

+ +
+uintptr(unsafe.Pointer(&s)) + unsafe.Offsetof(s.f) == uintptr(unsafe.Pointer(&s.f))
+
+ +

+Computer architectures may require memory addresses to be aligned; +that is, for addresses of a variable to be a multiple of a factor, +the variable's type's alignment. The function Alignof +takes an expression denoting a variable of any type and returns the +alignment of the (type of the) variable in bytes. For a variable +x: +

+ +
+uintptr(unsafe.Pointer(&x)) % unsafe.Alignof(x) == 0
+
+ +

+Calls to Alignof, Offsetof, and +Sizeof are compile-time constant expressions of type uintptr. +

+ +

Size and alignment guarantees

+ +

+For the numeric types, the following sizes are guaranteed: +

+ +
+type                                 size in bytes
+
+byte, uint8, int8                     1
+uint16, int16                         2
+uint32, int32, float32                4
+uint64, int64, float64, complex64     8
+complex128                           16
+
+ +

+The following minimal alignment properties are guaranteed: +

+
    +
  1. For a variable x of any type: unsafe.Alignof(x) is at least 1. +
  2. + +
  3. For a variable x of struct type: unsafe.Alignof(x) is the largest of + all the values unsafe.Alignof(x.f) for each field f of x, but at least 1. +
  4. + +
  5. For a variable x of array type: unsafe.Alignof(x) is the same as + unsafe.Alignof(x[0]), but at least 1. +
  6. +
+ +

+A struct or array type has size zero if it contains no fields (or elements, respectively) that have a size greater than zero. Two distinct zero-size variables may have the same address in memory. +

+ + + + +
+
+ + + + + + + + + + + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/testdata/spec.xz b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/testdata/spec.xz new file mode 100644 index 00000000..b4e5fcc8 Binary files /dev/null and b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/testdata/spec.xz differ diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/xz.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/xz.go new file mode 100644 index 00000000..d78e1a1d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/xz.go @@ -0,0 +1,71 @@ +// Package xz implements simple .xz decompression using external xz program +// +// No shared library (liblzma) dependencies. +package xz + +import ( + "io" + "os/exec" +) + +// Reader does decompression using xz utility +type Reader struct { + cmd *exec.Cmd + input io.WriteCloser + output io.ReadCloser +} + +// NewReader creates .xz decompression reader +// +// Internally it starts xz program, sets up input and output pipes +func NewReader(src io.Reader) (*Reader, error) { + var err error + + result := &Reader{} + + result.cmd = exec.Command("xz", "--decompress", "--stdout") + result.input, err = result.cmd.StdinPipe() + if err != nil { + return nil, err + } + result.output, err = result.cmd.StdoutPipe() + if err != nil { + return nil, err + } + + err = result.cmd.Start() + if err != nil { + return nil, err + } + + go func() { + io.Copy(result.input, src) + result.input.Close() + }() + + return result, nil +} + +// Read implements io.Reader interface +func (r *Reader) Read(p []byte) (n int, err error) { + return r.output.Read(p) +} + +// Close implements io.Closer interface +func (r *Reader) Close() error { + if r.input != nil { + r.input.Close() + } + if r.output != nil { + r.output.Close() + } + if r.cmd != nil { + return r.cmd.Wait() + } + return nil +} + +// Check interface +var ( + _ io.ReadCloser = &Reader{} +) diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/xz_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/xz_test.go new file mode 100644 index 00000000..c0a38b9d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/go-xz/xz_test.go @@ -0,0 +1,48 @@ +package xz + +import ( + "bytes" + "io" + "os" + "testing" +) + +func TestDecompress(T *testing.T) { + orig, err := os.Open("testdata/spec") + if err != nil { + T.Fatal(err) + } + defer orig.Close() + + expected := &bytes.Buffer{} + _, err = io.Copy(expected, orig) + if err != nil { + T.Fatal(err) + } + + source, err := os.Open("testdata/spec.xz") + if err != nil { + T.Fatal(err) + } + defer source.Close() + + r, err := NewReader(source) + if err != nil { + T.Fatal(err) + } + + buf := &bytes.Buffer{} + n, err := io.Copy(buf, r) + if n != int64(expected.Len()) { + T.Fail() + } + + if bytes.Compare(buf.Bytes(), expected.Bytes()) != 0 { + T.Fail() + } + + err = r.Close() + if err != nil { + T.Fail() + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/LICENSE b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/LICENSE new file mode 100644 index 00000000..091d84f3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/LICENSE @@ -0,0 +1,27 @@ +// Copyright (c) 2010, Andrei Vieru. 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/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/data/data.eos.l3.lzma b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/data/data.eos.l3.lzma new file mode 100644 index 00000000..6d7e7deb Binary files /dev/null and b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/data/data.eos.l3.lzma differ diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/data/data.txt b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/data/data.txt new file mode 100644 index 00000000..b44681ce --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/data/data.txt @@ -0,0 +1,3982 @@ +2010-05-01 19:06:07 startup archives unpack +2010-05-01 19:06:13 upgrade chromium-codecs-ffmpeg 0.5+svn20100423r45437+45451+45639-0ubuntu1~ucd1 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-01 19:06:13 status half-configured chromium-codecs-ffmpeg 0.5+svn20100423r45437+45451+45639-0ubuntu1~ucd1 +2010-05-01 19:06:13 status unpacked chromium-codecs-ffmpeg 0.5+svn20100423r45437+45451+45639-0ubuntu1~ucd1 +2010-05-01 19:06:13 status half-installed chromium-codecs-ffmpeg 0.5+svn20100423r45437+45451+45639-0ubuntu1~ucd1 +2010-05-01 19:06:13 status half-installed chromium-codecs-ffmpeg 0.5+svn20100423r45437+45451+45639-0ubuntu1~ucd1 +2010-05-01 19:06:13 status unpacked chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-01 19:06:14 status unpacked chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-01 19:06:14 upgrade chromium-browser-inspector 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:06:14 status half-configured chromium-browser-inspector 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:14 status unpacked chromium-browser-inspector 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:14 status half-installed chromium-browser-inspector 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:20 status half-installed chromium-browser-inspector 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:20 status unpacked chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:06:20 status unpacked chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:06:21 upgrade chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:06:21 status half-configured chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:21 status unpacked chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:21 status half-installed chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:23 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:06:23 status half-installed chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:23 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-01 19:06:23 status half-installed chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:23 status triggers-pending man-db 2.5.7-2 +2010-05-01 19:06:23 status half-installed chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:24 status triggers-pending hicolor-icon-theme 0.11-1 +2010-05-01 19:06:24 status half-installed chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:27 status half-installed chromium-browser 5.0.389.0~svn20100427r45661-0ubuntu1~ucd1 +2010-05-01 19:06:28 status unpacked chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:06:28 status unpacked chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:06:28 upgrade language-pack-en 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:06:28 status half-configured language-pack-en 1:10.04+20100421 +2010-05-01 19:06:28 status unpacked language-pack-en 1:10.04+20100421 +2010-05-01 19:06:28 status half-installed language-pack-en 1:10.04+20100421 +2010-05-01 19:06:28 status triggers-pending software-center 2.0.2 +2010-05-01 19:06:28 status half-installed language-pack-en 1:10.04+20100421 +2010-05-01 19:06:29 status half-installed language-pack-en 1:10.04+20100421 +2010-05-01 19:06:29 status unpacked language-pack-en 1:10.04+20100422 +2010-05-01 19:06:29 status unpacked language-pack-en 1:10.04+20100422 +2010-05-01 19:06:29 upgrade language-pack-en-base 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:06:29 status half-configured language-pack-en-base 1:10.04+20100421 +2010-05-01 19:06:29 status unpacked language-pack-en-base 1:10.04+20100421 +2010-05-01 19:06:29 status half-installed language-pack-en-base 1:10.04+20100421 +2010-05-01 19:06:29 status half-installed language-pack-en-base 1:10.04+20100421 +2010-05-01 19:06:45 status half-installed language-pack-en-base 1:10.04+20100421 +2010-05-01 19:06:45 status unpacked language-pack-en-base 1:10.04+20100422 +2010-05-01 19:06:45 status unpacked language-pack-en-base 1:10.04+20100422 +2010-05-01 19:06:45 upgrade language-pack-gnome-en 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:06:45 status half-configured language-pack-gnome-en 1:10.04+20100421 +2010-05-01 19:06:45 status unpacked language-pack-gnome-en 1:10.04+20100421 +2010-05-01 19:06:46 status half-installed language-pack-gnome-en 1:10.04+20100421 +2010-05-01 19:06:46 status half-installed language-pack-gnome-en 1:10.04+20100421 +2010-05-01 19:06:47 status half-installed language-pack-gnome-en 1:10.04+20100421 +2010-05-01 19:06:47 status unpacked language-pack-gnome-en 1:10.04+20100422 +2010-05-01 19:06:47 status unpacked language-pack-gnome-en 1:10.04+20100422 +2010-05-01 19:06:47 upgrade language-pack-gnome-en-base 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:06:47 status half-configured language-pack-gnome-en-base 1:10.04+20100421 +2010-05-01 19:06:47 status unpacked language-pack-gnome-en-base 1:10.04+20100421 +2010-05-01 19:06:47 status half-installed language-pack-gnome-en-base 1:10.04+20100421 +2010-05-01 19:06:47 status half-installed language-pack-gnome-en-base 1:10.04+20100421 +2010-05-01 19:07:21 status half-installed language-pack-gnome-en-base 1:10.04+20100421 +2010-05-01 19:07:21 status unpacked language-pack-gnome-en-base 1:10.04+20100422 +2010-05-01 19:07:22 status unpacked language-pack-gnome-en-base 1:10.04+20100422 +2010-05-01 19:07:22 upgrade language-pack-ro 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:07:22 status half-configured language-pack-ro 1:10.04+20100421 +2010-05-01 19:07:22 status unpacked language-pack-ro 1:10.04+20100421 +2010-05-01 19:07:22 status half-installed language-pack-ro 1:10.04+20100421 +2010-05-01 19:07:22 status half-installed language-pack-ro 1:10.04+20100421 +2010-05-01 19:07:22 status half-installed language-pack-ro 1:10.04+20100421 +2010-05-01 19:07:22 status unpacked language-pack-ro 1:10.04+20100422 +2010-05-01 19:07:22 status unpacked language-pack-ro 1:10.04+20100422 +2010-05-01 19:07:23 upgrade language-pack-ro-base 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:07:23 status half-configured language-pack-ro-base 1:10.04+20100421 +2010-05-01 19:07:23 status unpacked language-pack-ro-base 1:10.04+20100421 +2010-05-01 19:07:23 status half-installed language-pack-ro-base 1:10.04+20100421 +2010-05-01 19:07:23 status half-installed language-pack-ro-base 1:10.04+20100421 +2010-05-01 19:07:31 status half-installed language-pack-ro-base 1:10.04+20100421 +2010-05-01 19:07:31 status unpacked language-pack-ro-base 1:10.04+20100422 +2010-05-01 19:07:31 status unpacked language-pack-ro-base 1:10.04+20100422 +2010-05-01 19:07:31 upgrade language-pack-gnome-ro 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:07:31 status half-configured language-pack-gnome-ro 1:10.04+20100421 +2010-05-01 19:07:31 status unpacked language-pack-gnome-ro 1:10.04+20100421 +2010-05-01 19:07:31 status half-installed language-pack-gnome-ro 1:10.04+20100421 +2010-05-01 19:07:31 status half-installed language-pack-gnome-ro 1:10.04+20100421 +2010-05-01 19:07:32 status half-installed language-pack-gnome-ro 1:10.04+20100421 +2010-05-01 19:07:32 status unpacked language-pack-gnome-ro 1:10.04+20100422 +2010-05-01 19:07:32 status unpacked language-pack-gnome-ro 1:10.04+20100422 +2010-05-01 19:07:32 upgrade language-pack-gnome-ro-base 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:07:32 status half-configured language-pack-gnome-ro-base 1:10.04+20100421 +2010-05-01 19:07:32 status unpacked language-pack-gnome-ro-base 1:10.04+20100421 +2010-05-01 19:07:32 status half-installed language-pack-gnome-ro-base 1:10.04+20100421 +2010-05-01 19:07:32 status half-installed language-pack-gnome-ro-base 1:10.04+20100421 +2010-05-01 19:07:45 status half-installed language-pack-gnome-ro-base 1:10.04+20100421 +2010-05-01 19:07:45 status unpacked language-pack-gnome-ro-base 1:10.04+20100422 +2010-05-01 19:07:45 status unpacked language-pack-gnome-ro-base 1:10.04+20100422 +2010-05-01 19:07:45 upgrade language-pack-ru 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:07:45 status half-configured language-pack-ru 1:10.04+20100421 +2010-05-01 19:07:45 status unpacked language-pack-ru 1:10.04+20100421 +2010-05-01 19:07:45 status half-installed language-pack-ru 1:10.04+20100421 +2010-05-01 19:07:45 status half-installed language-pack-ru 1:10.04+20100421 +2010-05-01 19:07:46 status half-installed language-pack-ru 1:10.04+20100421 +2010-05-01 19:07:46 status unpacked language-pack-ru 1:10.04+20100422 +2010-05-01 19:07:46 status unpacked language-pack-ru 1:10.04+20100422 +2010-05-01 19:07:46 upgrade language-pack-ru-base 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:07:46 status half-configured language-pack-ru-base 1:10.04+20100421 +2010-05-01 19:07:46 status unpacked language-pack-ru-base 1:10.04+20100421 +2010-05-01 19:07:46 status half-installed language-pack-ru-base 1:10.04+20100421 +2010-05-01 19:07:46 status half-installed language-pack-ru-base 1:10.04+20100421 +2010-05-01 19:07:59 status half-installed language-pack-ru-base 1:10.04+20100421 +2010-05-01 19:07:59 status unpacked language-pack-ru-base 1:10.04+20100422 +2010-05-01 19:07:59 status unpacked language-pack-ru-base 1:10.04+20100422 +2010-05-01 19:07:59 upgrade language-pack-gnome-ru 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:07:59 status half-configured language-pack-gnome-ru 1:10.04+20100421 +2010-05-01 19:07:59 status unpacked language-pack-gnome-ru 1:10.04+20100421 +2010-05-01 19:07:59 status half-installed language-pack-gnome-ru 1:10.04+20100421 +2010-05-01 19:07:59 status half-installed language-pack-gnome-ru 1:10.04+20100421 +2010-05-01 19:08:00 status half-installed language-pack-gnome-ru 1:10.04+20100421 +2010-05-01 19:08:00 status unpacked language-pack-gnome-ru 1:10.04+20100422 +2010-05-01 19:08:00 status unpacked language-pack-gnome-ru 1:10.04+20100422 +2010-05-01 19:08:00 upgrade language-pack-gnome-ru-base 1:10.04+20100421 1:10.04+20100422 +2010-05-01 19:08:00 status half-configured language-pack-gnome-ru-base 1:10.04+20100421 +2010-05-01 19:08:00 status unpacked language-pack-gnome-ru-base 1:10.04+20100421 +2010-05-01 19:08:00 status half-installed language-pack-gnome-ru-base 1:10.04+20100421 +2010-05-01 19:08:00 status half-installed language-pack-gnome-ru-base 1:10.04+20100421 +2010-05-01 19:08:20 status half-installed language-pack-gnome-ru-base 1:10.04+20100421 +2010-05-01 19:08:20 status unpacked language-pack-gnome-ru-base 1:10.04+20100422 +2010-05-01 19:08:20 status unpacked language-pack-gnome-ru-base 1:10.04+20100422 +2010-05-01 19:08:20 install linux-image-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:08:20 status half-installed linux-image-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:09:05 status unpacked linux-image-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:09:05 status unpacked linux-image-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:09:05 upgrade acpid 1.0.10-5ubuntu2 1.0.10-5ubuntu2.1 +2010-05-01 19:09:05 status half-configured acpid 1.0.10-5ubuntu2 +2010-05-01 19:09:05 status unpacked acpid 1.0.10-5ubuntu2 +2010-05-01 19:09:05 status half-installed acpid 1.0.10-5ubuntu2 +2010-05-01 19:09:05 status triggers-pending ureadahead 0.100.0-4.1 +2010-05-01 19:09:05 status half-installed acpid 1.0.10-5ubuntu2 +2010-05-01 19:09:05 status triggers-pending ureadahead 0.100.0-4.1 +2010-05-01 19:09:05 status half-installed acpid 1.0.10-5ubuntu2 +2010-05-01 19:09:06 status half-installed acpid 1.0.10-5ubuntu2 +2010-05-01 19:09:06 status unpacked acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:09:06 status unpacked acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:09:06 upgrade gnome-control-center 1:2.30.0-0ubuntu4 1:2.30.1-0ubuntu1 +2010-05-01 19:09:06 status half-configured gnome-control-center 1:2.30.0-0ubuntu4 +2010-05-01 19:09:06 status unpacked gnome-control-center 1:2.30.0-0ubuntu4 +2010-05-01 19:09:06 status half-installed gnome-control-center 1:2.30.0-0ubuntu4 +2010-05-01 19:09:07 status half-installed gnome-control-center 1:2.30.0-0ubuntu4 +2010-05-01 19:09:08 status half-installed gnome-control-center 1:2.30.0-0ubuntu4 +2010-05-01 19:09:08 status unpacked gnome-control-center 1:2.30.1-0ubuntu1 +2010-05-01 19:09:08 status unpacked gnome-control-center 1:2.30.1-0ubuntu1 +2010-05-01 19:09:09 upgrade capplets-data 1:2.30.0-0ubuntu4 1:2.30.1-0ubuntu1 +2010-05-01 19:09:09 status half-configured capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:15 status unpacked capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:15 status half-installed capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:15 status half-installed capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:15 status half-installed capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:15 status triggers-pending shared-mime-info 0.71-1ubuntu2 +2010-05-01 19:09:15 status half-installed capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:15 status half-installed capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:21 status half-installed capplets-data 1:2.30.0-0ubuntu4 +2010-05-01 19:09:21 status unpacked capplets-data 1:2.30.1-0ubuntu1 +2010-05-01 19:09:21 status unpacked capplets-data 1:2.30.1-0ubuntu1 +2010-05-01 19:09:21 upgrade libgnome-window-settings1 1:2.30.0-0ubuntu4 1:2.30.1-0ubuntu1 +2010-05-01 19:09:21 status half-configured libgnome-window-settings1 1:2.30.0-0ubuntu4 +2010-05-01 19:09:21 status unpacked libgnome-window-settings1 1:2.30.0-0ubuntu4 +2010-05-01 19:09:21 status half-installed libgnome-window-settings1 1:2.30.0-0ubuntu4 +2010-05-01 19:09:22 status half-installed libgnome-window-settings1 1:2.30.0-0ubuntu4 +2010-05-01 19:09:22 status unpacked libgnome-window-settings1 1:2.30.1-0ubuntu1 +2010-05-01 19:09:22 status unpacked libgnome-window-settings1 1:2.30.1-0ubuntu1 +2010-05-01 19:09:22 upgrade gnome-settings-daemon 2.30.0-0ubuntu6 2.30.1-0ubuntu1 +2010-05-01 19:09:22 status half-configured gnome-settings-daemon 2.30.0-0ubuntu6 +2010-05-01 19:09:29 status unpacked gnome-settings-daemon 2.30.0-0ubuntu6 +2010-05-01 19:09:29 status half-installed gnome-settings-daemon 2.30.0-0ubuntu6 +2010-05-01 19:09:29 status half-installed gnome-settings-daemon 2.30.0-0ubuntu6 +2010-05-01 19:09:29 status half-installed gnome-settings-daemon 2.30.0-0ubuntu6 +2010-05-01 19:09:31 status half-installed gnome-settings-daemon 2.30.0-0ubuntu6 +2010-05-01 19:09:32 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:09:32 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:09:32 upgrade ubuntu-system-service 0.1.20 0.1.20.1 +2010-05-01 19:09:32 status half-configured ubuntu-system-service 0.1.20 +2010-05-01 19:09:32 status unpacked ubuntu-system-service 0.1.20 +2010-05-01 19:09:33 status half-installed ubuntu-system-service 0.1.20 +2010-05-01 19:09:33 status half-installed ubuntu-system-service 0.1.20 +2010-05-01 19:09:33 status unpacked ubuntu-system-service 0.1.20.1 +2010-05-01 19:09:34 status unpacked ubuntu-system-service 0.1.20.1 +2010-05-01 19:09:34 upgrade cheese-common 2.30.0-0ubuntu2 2.30.1-0ubuntu1 +2010-05-01 19:09:34 status half-configured cheese-common 2.30.0-0ubuntu2 +2010-05-01 19:09:40 status unpacked cheese-common 2.30.0-0ubuntu2 +2010-05-01 19:09:40 status half-installed cheese-common 2.30.0-0ubuntu2 +2010-05-01 19:09:40 status half-installed cheese-common 2.30.0-0ubuntu2 +2010-05-01 19:09:45 status half-installed cheese-common 2.30.0-0ubuntu2 +2010-05-01 19:09:45 status unpacked cheese-common 2.30.1-0ubuntu1 +2010-05-01 19:09:45 status unpacked cheese-common 2.30.1-0ubuntu1 +2010-05-01 19:09:45 upgrade libcheese-gtk18 2.30.0-0ubuntu2 2.30.1-0ubuntu1 +2010-05-01 19:09:45 status half-configured libcheese-gtk18 2.30.0-0ubuntu2 +2010-05-01 19:09:45 status unpacked libcheese-gtk18 2.30.0-0ubuntu2 +2010-05-01 19:09:45 status half-installed libcheese-gtk18 2.30.0-0ubuntu2 +2010-05-01 19:09:46 status half-installed libcheese-gtk18 2.30.0-0ubuntu2 +2010-05-01 19:09:46 status unpacked libcheese-gtk18 2.30.1-0ubuntu1 +2010-05-01 19:09:46 status unpacked libcheese-gtk18 2.30.1-0ubuntu1 +2010-05-01 19:09:46 upgrade cheese 2.30.0-0ubuntu2 2.30.1-0ubuntu1 +2010-05-01 19:09:46 status half-configured cheese 2.30.0-0ubuntu2 +2010-05-01 19:09:46 status unpacked cheese 2.30.0-0ubuntu2 +2010-05-01 19:09:46 status half-installed cheese 2.30.0-0ubuntu2 +2010-05-01 19:09:46 status half-installed cheese 2.30.0-0ubuntu2 +2010-05-01 19:09:47 status half-installed cheese 2.30.0-0ubuntu2 +2010-05-01 19:09:47 status half-installed cheese 2.30.0-0ubuntu2 +2010-05-01 19:09:47 status half-installed cheese 2.30.0-0ubuntu2 +2010-05-01 19:09:47 status unpacked cheese 2.30.1-0ubuntu1 +2010-05-01 19:09:47 status unpacked cheese 2.30.1-0ubuntu1 +2010-05-01 19:09:47 upgrade libsoup2.4-dev 2.30.0-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:09:47 status half-configured libsoup2.4-dev 2.30.0-0ubuntu1 +2010-05-01 19:09:47 status unpacked libsoup2.4-dev 2.30.0-0ubuntu1 +2010-05-01 19:09:47 status half-installed libsoup2.4-dev 2.30.0-0ubuntu1 +2010-05-01 19:09:49 status half-installed libsoup2.4-dev 2.30.0-0ubuntu1 +2010-05-01 19:09:49 status unpacked libsoup2.4-dev 2.30.1-0ubuntu1 +2010-05-01 19:09:49 status unpacked libsoup2.4-dev 2.30.1-0ubuntu1 +2010-05-01 19:09:49 upgrade libsoup2.4-1 2.30.0-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:09:49 status half-configured libsoup2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:09:49 status unpacked libsoup2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:09:49 status half-installed libsoup2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:09:50 status half-installed libsoup2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:09:50 status unpacked libsoup2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:09:50 status unpacked libsoup2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:09:50 upgrade nautilus-sendto-empathy 2.30.0.1-0ubuntu3 2.30.1-0ubuntu1 +2010-05-01 19:09:50 status half-configured nautilus-sendto-empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:50 status unpacked nautilus-sendto-empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:51 status half-installed nautilus-sendto-empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:51 status half-installed nautilus-sendto-empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:51 status unpacked nautilus-sendto-empathy 2.30.1-0ubuntu1 +2010-05-01 19:09:51 status unpacked nautilus-sendto-empathy 2.30.1-0ubuntu1 +2010-05-01 19:09:51 upgrade empathy 2.30.0.1-0ubuntu3 2.30.1-0ubuntu1 +2010-05-01 19:09:51 status half-configured empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:57 status unpacked empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:58 status half-installed empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:58 status half-installed empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:58 status half-installed empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:58 status half-installed empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:59 status half-installed empathy 2.30.0.1-0ubuntu3 +2010-05-01 19:09:59 status unpacked empathy 2.30.1-0ubuntu1 +2010-05-01 19:09:59 status unpacked empathy 2.30.1-0ubuntu1 +2010-05-01 19:09:59 upgrade empathy-common 2.30.0.1-0ubuntu3 2.30.1-0ubuntu1 +2010-05-01 19:09:59 status half-configured empathy-common 2.30.0.1-0ubuntu3 +2010-05-01 19:10:00 status unpacked empathy-common 2.30.0.1-0ubuntu3 +2010-05-01 19:10:00 status half-installed empathy-common 2.30.0.1-0ubuntu3 +2010-05-01 19:10:00 status half-installed empathy-common 2.30.0.1-0ubuntu3 +2010-05-01 19:10:12 status half-installed empathy-common 2.30.0.1-0ubuntu3 +2010-05-01 19:10:12 status unpacked empathy-common 2.30.1-0ubuntu1 +2010-05-01 19:10:12 status unpacked empathy-common 2.30.1-0ubuntu1 +2010-05-01 19:10:12 upgrade libevdocument2 2.30.0-0ubuntu1 2.30.1-0ubuntu2 +2010-05-01 19:10:12 status half-configured libevdocument2 2.30.0-0ubuntu1 +2010-05-01 19:10:12 status unpacked libevdocument2 2.30.0-0ubuntu1 +2010-05-01 19:10:12 status half-installed libevdocument2 2.30.0-0ubuntu1 +2010-05-01 19:10:13 status half-installed libevdocument2 2.30.0-0ubuntu1 +2010-05-01 19:10:13 status unpacked libevdocument2 2.30.1-0ubuntu2 +2010-05-01 19:10:13 status unpacked libevdocument2 2.30.1-0ubuntu2 +2010-05-01 19:10:13 upgrade libevview2 2.30.0-0ubuntu1 2.30.1-0ubuntu2 +2010-05-01 19:10:13 status half-configured libevview2 2.30.0-0ubuntu1 +2010-05-01 19:10:14 status unpacked libevview2 2.30.0-0ubuntu1 +2010-05-01 19:10:14 status half-installed libevview2 2.30.0-0ubuntu1 +2010-05-01 19:10:14 status half-installed libevview2 2.30.0-0ubuntu1 +2010-05-01 19:10:15 status unpacked libevview2 2.30.1-0ubuntu2 +2010-05-01 19:10:15 status unpacked libevview2 2.30.1-0ubuntu2 +2010-05-01 19:10:15 upgrade evince 2.30.0-0ubuntu1 2.30.1-0ubuntu2 +2010-05-01 19:10:15 status half-configured evince 2.30.0-0ubuntu1 +2010-05-01 19:10:21 status unpacked evince 2.30.0-0ubuntu1 +2010-05-01 19:10:21 status half-installed evince 2.30.0-0ubuntu1 +2010-05-01 19:10:21 status half-installed evince 2.30.0-0ubuntu1 +2010-05-01 19:10:21 status half-installed evince 2.30.0-0ubuntu1 +2010-05-01 19:10:21 status half-installed evince 2.30.0-0ubuntu1 +2010-05-01 19:10:21 status half-installed evince 2.30.0-0ubuntu1 +2010-05-01 19:10:27 status half-installed evince 2.30.0-0ubuntu1 +2010-05-01 19:10:28 status unpacked evince 2.30.1-0ubuntu2 +2010-05-01 19:10:28 status unpacked evince 2.30.1-0ubuntu2 +2010-05-01 19:10:28 upgrade libnautilus-extension1 1:2.30.0-0ubuntu4 1:2.30.1-0ubuntu1 +2010-05-01 19:10:28 status half-configured libnautilus-extension1 1:2.30.0-0ubuntu4 +2010-05-01 19:10:28 status unpacked libnautilus-extension1 1:2.30.0-0ubuntu4 +2010-05-01 19:10:28 status half-installed libnautilus-extension1 1:2.30.0-0ubuntu4 +2010-05-01 19:10:29 status half-installed libnautilus-extension1 1:2.30.0-0ubuntu4 +2010-05-01 19:10:29 status unpacked libnautilus-extension1 1:2.30.1-0ubuntu1 +2010-05-01 19:10:29 status unpacked libnautilus-extension1 1:2.30.1-0ubuntu1 +2010-05-01 19:10:29 upgrade file-roller 2.30.0-0ubuntu1 2.30.1.1-0ubuntu2 +2010-05-01 19:10:29 status half-configured file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:35 status unpacked file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:36 status half-installed file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:36 status half-installed file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:36 status half-installed file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:36 status half-installed file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:36 status half-installed file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:38 status half-installed file-roller 2.30.0-0ubuntu1 +2010-05-01 19:10:38 status unpacked file-roller 2.30.1.1-0ubuntu2 +2010-05-01 19:10:38 status unpacked file-roller 2.30.1.1-0ubuntu2 +2010-05-01 19:10:39 upgrade firefox-branding 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:39 status half-configured firefox-branding 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:39 status unpacked firefox-branding 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:39 status half-installed firefox-branding 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:39 status half-installed firefox-branding 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:39 status half-installed firefox-branding 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:40 status half-installed firefox-branding 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:40 status unpacked firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:40 status unpacked firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:40 upgrade firefox 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:40 status half-configured firefox 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:40 status unpacked firefox 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:40 status half-installed firefox 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:52 status half-installed firefox 3.6.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:10:53 upgrade libgtksourceview2.0-common 2.10.0-0ubuntu1 2.10.1-0ubuntu1 +2010-05-01 19:10:53 status half-configured libgtksourceview2.0-common 2.10.0-0ubuntu1 +2010-05-01 19:10:53 status unpacked libgtksourceview2.0-common 2.10.0-0ubuntu1 +2010-05-01 19:10:53 status half-installed libgtksourceview2.0-common 2.10.0-0ubuntu1 +2010-05-01 19:10:58 status half-installed libgtksourceview2.0-common 2.10.0-0ubuntu1 +2010-05-01 19:10:58 status unpacked libgtksourceview2.0-common 2.10.1-0ubuntu1 +2010-05-01 19:10:58 status unpacked libgtksourceview2.0-common 2.10.1-0ubuntu1 +2010-05-01 19:10:58 upgrade libgtksourceview2.0-0 2.10.0-0ubuntu1 2.10.1-0ubuntu1 +2010-05-01 19:10:58 status half-configured libgtksourceview2.0-0 2.10.0-0ubuntu1 +2010-05-01 19:10:58 status unpacked libgtksourceview2.0-0 2.10.0-0ubuntu1 +2010-05-01 19:10:58 status half-installed libgtksourceview2.0-0 2.10.0-0ubuntu1 +2010-05-01 19:10:58 status half-installed libgtksourceview2.0-0 2.10.0-0ubuntu1 +2010-05-01 19:10:59 status unpacked libgtksourceview2.0-0 2.10.1-0ubuntu1 +2010-05-01 19:10:59 status unpacked libgtksourceview2.0-0 2.10.1-0ubuntu1 +2010-05-01 19:10:59 upgrade gedit-common 2.30.0git20100413-0ubuntu1 2.30.2-0ubuntu1 +2010-05-01 19:10:59 status half-configured gedit-common 2.30.0git20100413-0ubuntu1 +2010-05-01 19:10:59 status unpacked gedit-common 2.30.0git20100413-0ubuntu1 +2010-05-01 19:10:59 status half-installed gedit-common 2.30.0git20100413-0ubuntu1 +2010-05-01 19:10:59 status half-installed gedit-common 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:02 status half-installed gedit-common 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:03 status unpacked gedit-common 2.30.2-0ubuntu1 +2010-05-01 19:11:03 status unpacked gedit-common 2.30.2-0ubuntu1 +2010-05-01 19:11:03 upgrade gedit 2.30.0git20100413-0ubuntu1 2.30.2-0ubuntu1 +2010-05-01 19:11:03 status half-configured gedit 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:04 update-alternatives: run with --remove gnome-text-editor /usr/bin/gedit +2010-05-01 19:11:04 update-alternatives: link group gnome-text-editor updated to point to /usr/bin/vim.gnome +2010-05-01 19:11:12 status unpacked gedit 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:12 status half-installed gedit 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:12 status half-installed gedit 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:12 status half-installed gedit 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:15 status half-installed gedit 2.30.0git20100413-0ubuntu1 +2010-05-01 19:11:15 status unpacked gedit 2.30.2-0ubuntu1 +2010-05-01 19:11:15 status unpacked gedit 2.30.2-0ubuntu1 +2010-05-01 19:11:16 upgrade libgimp2.0 2.6.8-2ubuntu1 2.6.8-2ubuntu1.1 +2010-05-01 19:11:16 status half-configured libgimp2.0 2.6.8-2ubuntu1 +2010-05-01 19:11:16 status unpacked libgimp2.0 2.6.8-2ubuntu1 +2010-05-01 19:11:16 status half-installed libgimp2.0 2.6.8-2ubuntu1 +2010-05-01 19:11:17 status half-installed libgimp2.0 2.6.8-2ubuntu1 +2010-05-01 19:11:17 status unpacked libgimp2.0 2.6.8-2ubuntu1.1 +2010-05-01 19:11:17 status unpacked libgimp2.0 2.6.8-2ubuntu1.1 +2010-05-01 19:11:17 upgrade gimp-data 2.6.8-2ubuntu1 2.6.8-2ubuntu1.1 +2010-05-01 19:11:17 status half-configured gimp-data 2.6.8-2ubuntu1 +2010-05-01 19:11:17 status unpacked gimp-data 2.6.8-2ubuntu1 +2010-05-01 19:11:18 status half-installed gimp-data 2.6.8-2ubuntu1 +2010-05-01 19:11:18 status half-installed gimp-data 2.6.8-2ubuntu1 +2010-05-01 19:11:18 status half-installed gimp-data 2.6.8-2ubuntu1 +2010-05-01 19:11:42 status half-installed gimp-data 2.6.8-2ubuntu1 +2010-05-01 19:11:43 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:11:43 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:11:43 upgrade gimp 2.6.8-2ubuntu1 2.6.8-2ubuntu1.1 +2010-05-01 19:11:43 status half-configured gimp 2.6.8-2ubuntu1 +2010-05-01 19:11:43 status unpacked gimp 2.6.8-2ubuntu1 +2010-05-01 19:11:43 status half-installed gimp 2.6.8-2ubuntu1 +2010-05-01 19:11:44 status half-installed gimp 2.6.8-2ubuntu1 +2010-05-01 19:11:44 status half-installed gimp 2.6.8-2ubuntu1 +2010-05-01 19:11:44 status half-installed gimp 2.6.8-2ubuntu1 +2010-05-01 19:11:55 status half-installed gimp 2.6.8-2ubuntu1 +2010-05-01 19:11:55 status unpacked gimp 2.6.8-2ubuntu1.1 +2010-05-01 19:11:55 status unpacked gimp 2.6.8-2ubuntu1.1 +2010-05-01 19:11:56 upgrade grub-pc 1.98-1ubuntu5 1.98-1ubuntu6 +2010-05-01 19:11:56 status half-configured grub-pc 1.98-1ubuntu5 +2010-05-01 19:11:56 status unpacked grub-pc 1.98-1ubuntu5 +2010-05-01 19:11:56 status half-installed grub-pc 1.98-1ubuntu5 +2010-05-01 19:11:56 status half-installed grub-pc 1.98-1ubuntu5 +2010-05-01 19:12:05 status half-installed grub-pc 1.98-1ubuntu5 +2010-05-01 19:12:05 status unpacked grub-pc 1.98-1ubuntu6 +2010-05-01 19:12:05 status unpacked grub-pc 1.98-1ubuntu6 +2010-05-01 19:12:05 upgrade grub-common 1.98-1ubuntu5 1.98-1ubuntu6 +2010-05-01 19:12:05 status half-configured grub-common 1.98-1ubuntu5 +2010-05-01 19:12:05 status unpacked grub-common 1.98-1ubuntu5 +2010-05-01 19:12:05 status half-installed grub-common 1.98-1ubuntu5 +2010-05-01 19:12:05 status half-installed grub-common 1.98-1ubuntu5 +2010-05-01 19:12:05 status triggers-pending install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-01 19:12:06 status half-installed grub-common 1.98-1ubuntu5 +2010-05-01 19:12:06 status half-installed grub-common 1.98-1ubuntu5 +2010-05-01 19:12:07 status half-installed grub-common 1.98-1ubuntu5 +2010-05-01 19:12:08 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:12:08 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:12:08 upgrade python-cupshelpers 1.2.0+20100408-0ubuntu5 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:08 status half-configured python-cupshelpers 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:08 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-01 19:12:08 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:08 status half-installed python-cupshelpers 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:09 status half-installed python-cupshelpers 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:09 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:09 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:09 upgrade system-config-printer-udev 1.2.0+20100408-0ubuntu5 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:09 status half-configured system-config-printer-udev 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:09 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:09 status half-installed system-config-printer-udev 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:09 status half-installed system-config-printer-udev 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:10 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:10 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:10 upgrade hal-cups-utils 1.2.0+20100408-0ubuntu5 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:10 status half-configured hal-cups-utils 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:10 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:10 status half-installed hal-cups-utils 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:10 status half-installed hal-cups-utils 1.2.0+20100408-0ubuntu5 +2010-05-01 19:12:10 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:10 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:12:11 upgrade libgl1-mesa-dri 7.7.1-1ubuntu2 7.7.1-1ubuntu3 +2010-05-01 19:12:11 status half-configured libgl1-mesa-dri 7.7.1-1ubuntu2 +2010-05-01 19:12:11 status unpacked libgl1-mesa-dri 7.7.1-1ubuntu2 +2010-05-01 19:12:11 status half-installed libgl1-mesa-dri 7.7.1-1ubuntu2 +2010-05-01 19:12:13 status half-installed libgl1-mesa-dri 7.7.1-1ubuntu2 +2010-05-01 19:12:14 status unpacked libgl1-mesa-dri 7.7.1-1ubuntu3 +2010-05-01 19:12:14 status unpacked libgl1-mesa-dri 7.7.1-1ubuntu3 +2010-05-01 19:12:14 upgrade libgl1-mesa-glx 7.7.1-1ubuntu2 7.7.1-1ubuntu3 +2010-05-01 19:12:14 status half-configured libgl1-mesa-glx 7.7.1-1ubuntu2 +2010-05-01 19:12:14 status unpacked libgl1-mesa-glx 7.7.1-1ubuntu2 +2010-05-01 19:12:14 status half-installed libgl1-mesa-glx 7.7.1-1ubuntu2 +2010-05-01 19:12:14 status half-installed libgl1-mesa-glx 7.7.1-1ubuntu2 +2010-05-01 19:12:14 status unpacked libgl1-mesa-glx 7.7.1-1ubuntu3 +2010-05-01 19:12:15 status unpacked libgl1-mesa-glx 7.7.1-1ubuntu3 +2010-05-01 19:12:15 upgrade libsoup-gnome2.4-1 2.30.0-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:12:15 status half-configured libsoup-gnome2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:12:15 status unpacked libsoup-gnome2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:12:15 status half-installed libsoup-gnome2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:12:15 status half-installed libsoup-gnome2.4-1 2.30.0-0ubuntu1 +2010-05-01 19:12:15 status unpacked libsoup-gnome2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:12:15 status unpacked libsoup-gnome2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:12:16 install linux-headers-2.6.32-22 2.6.32-22.33 +2010-05-01 19:12:16 status half-installed linux-headers-2.6.32-22 2.6.32-22.33 +2010-05-01 19:12:53 status unpacked linux-headers-2.6.32-22 2.6.32-22.33 +2010-05-01 19:12:53 status unpacked linux-headers-2.6.32-22 2.6.32-22.33 +2010-05-01 19:12:53 install linux-headers-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:12:53 status half-installed linux-headers-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:12:59 status unpacked linux-headers-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:12:59 status unpacked linux-headers-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:12:59 upgrade linux-headers-generic 2.6.32.21.22 2.6.32.22.23 +2010-05-01 19:12:59 status half-configured linux-headers-generic 2.6.32.21.22 +2010-05-01 19:12:59 status unpacked linux-headers-generic 2.6.32.21.22 +2010-05-01 19:12:59 status half-installed linux-headers-generic 2.6.32.21.22 +2010-05-01 19:12:59 status half-installed linux-headers-generic 2.6.32.21.22 +2010-05-01 19:12:59 status unpacked linux-headers-generic 2.6.32.22.23 +2010-05-01 19:12:59 status unpacked linux-headers-generic 2.6.32.22.23 +2010-05-01 19:12:59 upgrade linux-image-generic 2.6.32.21.22 2.6.32.22.23 +2010-05-01 19:12:59 status half-configured linux-image-generic 2.6.32.21.22 +2010-05-01 19:13:00 status unpacked linux-image-generic 2.6.32.21.22 +2010-05-01 19:13:00 status half-installed linux-image-generic 2.6.32.21.22 +2010-05-01 19:13:00 status half-installed linux-image-generic 2.6.32.21.22 +2010-05-01 19:13:00 status unpacked linux-image-generic 2.6.32.22.23 +2010-05-01 19:13:00 status unpacked linux-image-generic 2.6.32.22.23 +2010-05-01 19:13:00 upgrade linux-libc-dev 2.6.32-21.32 2.6.32-22.33 +2010-05-01 19:13:00 status half-configured linux-libc-dev 2.6.32-21.32 +2010-05-01 19:13:00 status unpacked linux-libc-dev 2.6.32-21.32 +2010-05-01 19:13:00 status half-installed linux-libc-dev 2.6.32-21.32 +2010-05-01 19:13:26 status half-installed linux-libc-dev 2.6.32-21.32 +2010-05-01 19:13:26 status unpacked linux-libc-dev 2.6.32-22.33 +2010-05-01 19:13:26 status unpacked linux-libc-dev 2.6.32-22.33 +2010-05-01 19:13:26 upgrade nautilus-data 1:2.30.0-0ubuntu4 1:2.30.1-0ubuntu1 +2010-05-01 19:13:26 status half-configured nautilus-data 1:2.30.0-0ubuntu4 +2010-05-01 19:13:32 status unpacked nautilus-data 1:2.30.0-0ubuntu4 +2010-05-01 19:13:32 status half-installed nautilus-data 1:2.30.0-0ubuntu4 +2010-05-01 19:13:33 status half-installed nautilus-data 1:2.30.0-0ubuntu4 +2010-05-01 19:13:33 status half-installed nautilus-data 1:2.30.0-0ubuntu4 +2010-05-01 19:13:35 status half-installed nautilus-data 1:2.30.0-0ubuntu4 +2010-05-01 19:13:35 status unpacked nautilus-data 1:2.30.1-0ubuntu1 +2010-05-01 19:13:35 status unpacked nautilus-data 1:2.30.1-0ubuntu1 +2010-05-01 19:13:35 upgrade nautilus 1:2.30.0-0ubuntu4 1:2.30.1-0ubuntu1 +2010-05-01 19:13:35 status half-configured nautilus 1:2.30.0-0ubuntu4 +2010-05-01 19:13:36 status unpacked nautilus 1:2.30.0-0ubuntu4 +2010-05-01 19:13:36 status half-installed nautilus 1:2.30.0-0ubuntu4 +2010-05-01 19:13:36 status half-installed nautilus 1:2.30.0-0ubuntu4 +2010-05-01 19:13:36 status half-installed nautilus 1:2.30.0-0ubuntu4 +2010-05-01 19:13:36 status half-installed nautilus 1:2.30.0-0ubuntu4 +2010-05-01 19:13:37 status half-installed nautilus 1:2.30.0-0ubuntu4 +2010-05-01 19:13:37 status unpacked nautilus 1:2.30.1-0ubuntu1 +2010-05-01 19:13:37 status unpacked nautilus 1:2.30.1-0ubuntu1 +2010-05-01 19:13:37 upgrade pm-utils 1.3.0-1ubuntu1 1.3.0-1ubuntu2 +2010-05-01 19:13:37 status half-configured pm-utils 1.3.0-1ubuntu1 +2010-05-01 19:13:37 status unpacked pm-utils 1.3.0-1ubuntu1 +2010-05-01 19:13:37 status half-installed pm-utils 1.3.0-1ubuntu1 +2010-05-01 19:13:38 status half-installed pm-utils 1.3.0-1ubuntu1 +2010-05-01 19:13:39 status half-installed pm-utils 1.3.0-1ubuntu1 +2010-05-01 19:13:40 status unpacked pm-utils 1.3.0-1ubuntu2 +2010-05-01 19:13:40 status unpacked pm-utils 1.3.0-1ubuntu2 +2010-05-01 19:13:40 upgrade ubuntuone-client-gnome 1.2.1-0ubuntu1 1.2.1-0ubuntu2 +2010-05-01 19:13:40 status half-configured ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:40 status unpacked ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:40 status half-installed ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:40 status half-installed ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:40 status half-installed ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:40 status half-installed ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:40 status half-installed ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:42 status half-installed ubuntuone-client-gnome 1.2.1-0ubuntu1 +2010-05-01 19:13:42 status unpacked ubuntuone-client-gnome 1.2.1-0ubuntu2 +2010-05-01 19:13:42 status unpacked ubuntuone-client-gnome 1.2.1-0ubuntu2 +2010-05-01 19:13:42 upgrade ubuntuone-client 1.2.1-0ubuntu1 1.2.1-0ubuntu2 +2010-05-01 19:13:42 status half-configured ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:42 status unpacked ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:43 status half-installed ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:43 status half-installed ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:43 status half-installed ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:43 status unpacked ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:13:43 status unpacked ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:13:43 upgrade python-ubuntuone-client 1.2.1-0ubuntu1 1.2.1-0ubuntu2 +2010-05-01 19:13:43 status half-configured python-ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:44 status unpacked python-ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:44 status half-installed python-ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:45 status half-installed python-ubuntuone-client 1.2.1-0ubuntu1 +2010-05-01 19:13:45 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:13:45 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:13:46 upgrade rhythmbox-plugins 0.12.8-0ubuntu3 0.12.8-0ubuntu4 +2010-05-01 19:13:46 status half-configured rhythmbox-plugins 0.12.8-0ubuntu3 +2010-05-01 19:13:46 status unpacked rhythmbox-plugins 0.12.8-0ubuntu3 +2010-05-01 19:13:46 status half-installed rhythmbox-plugins 0.12.8-0ubuntu3 +2010-05-01 19:13:51 status half-installed rhythmbox-plugins 0.12.8-0ubuntu3 +2010-05-01 19:13:51 status unpacked rhythmbox-plugins 0.12.8-0ubuntu4 +2010-05-01 19:13:51 status unpacked rhythmbox-plugins 0.12.8-0ubuntu4 +2010-05-01 19:13:51 upgrade rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu3 0.12.8-0ubuntu4 +2010-05-01 19:13:51 status half-configured rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu3 +2010-05-01 19:13:51 status unpacked rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu3 +2010-05-01 19:13:51 status half-installed rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu3 +2010-05-01 19:13:51 status half-installed rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu3 +2010-05-01 19:13:51 status unpacked rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu4 +2010-05-01 19:13:52 status unpacked rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu4 +2010-05-01 19:13:52 upgrade rhythmbox 0.12.8-0ubuntu3 0.12.8-0ubuntu4 +2010-05-01 19:13:52 status half-configured rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:13:57 status unpacked rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:13:58 status half-installed rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:13:58 status half-installed rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:13:58 status half-installed rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:13:58 status half-installed rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:13:58 status half-installed rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:14:08 status half-installed rhythmbox 0.12.8-0ubuntu3 +2010-05-01 19:14:09 status unpacked rhythmbox 0.12.8-0ubuntu4 +2010-05-01 19:14:09 status unpacked rhythmbox 0.12.8-0ubuntu4 +2010-05-01 19:14:09 upgrade software-center 2.0.2 2.0.3 +2010-05-01 19:14:09 status half-configured software-center 2.0.2 +2010-05-01 19:14:09 status unpacked software-center 2.0.2 +2010-05-01 19:14:09 status half-installed software-center 2.0.2 +2010-05-01 19:14:10 status half-installed software-center 2.0.2 +2010-05-01 19:14:10 status half-installed software-center 2.0.2 +2010-05-01 19:14:10 status half-installed software-center 2.0.2 +2010-05-01 19:14:10 status half-installed software-center 2.0.2 +2010-05-01 19:14:14 status half-installed software-center 2.0.2 +2010-05-01 19:14:14 status unpacked software-center 2.0.3 +2010-05-01 19:14:14 status unpacked software-center 2.0.3 +2010-05-01 19:14:14 upgrade system-config-printer-common 1.2.0+20100408-0ubuntu5 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:14:14 status half-configured system-config-printer-common 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:14 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:14 status half-installed system-config-printer-common 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:15 status half-installed system-config-printer-common 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:15 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:14:16 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:14:16 upgrade system-config-printer-gnome 1.2.0+20100408-0ubuntu5 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:14:16 status half-configured system-config-printer-gnome 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:16 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:16 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:17 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:17 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:17 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:20 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5 +2010-05-01 19:14:20 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:14:20 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:14:20 upgrade thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:14:20 status half-configured thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 +2010-05-01 19:14:20 status unpacked thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 +2010-05-01 19:14:20 status half-installed thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 +2010-05-01 19:14:21 status half-installed thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 +2010-05-01 19:14:21 status half-installed thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 +2010-05-01 19:14:21 status half-installed thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 +2010-05-01 19:14:37 status half-installed thunderbird 3.0.5~hg20100421r4815+nobinonly-0ubuntu1~umd2 +2010-05-01 19:14:38 status unpacked thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:14:38 status unpacked thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:14:38 upgrade tomboy 1.2.0-0ubuntu1 1.2.1-0ubuntu1 +2010-05-01 19:14:38 status half-configured tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:44 status unpacked tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:44 status half-installed tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:45 status half-installed tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:45 status half-installed tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:45 status half-installed tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:45 status half-installed tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:45 status half-installed tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:49 status half-installed tomboy 1.2.0-0ubuntu1 +2010-05-01 19:14:49 status unpacked tomboy 1.2.1-0ubuntu1 +2010-05-01 19:14:49 status unpacked tomboy 1.2.1-0ubuntu1 +2010-05-01 19:14:49 upgrade transmission-gtk 1.92-0ubuntu2 1.92-0ubuntu2.1 +2010-05-01 19:14:49 status half-configured transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:49 status unpacked transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:50 status half-installed transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:50 status half-installed transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:50 status half-installed transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:50 status half-installed transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:50 status half-installed transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:50 status half-installed transmission-gtk 1.92-0ubuntu2 +2010-05-01 19:14:51 status unpacked transmission-gtk 1.92-0ubuntu2.1 +2010-05-01 19:14:51 status unpacked transmission-gtk 1.92-0ubuntu2.1 +2010-05-01 19:14:52 upgrade transmission-common 1.92-0ubuntu2 1.92-0ubuntu2.1 +2010-05-01 19:14:52 status half-configured transmission-common 1.92-0ubuntu2 +2010-05-01 19:14:52 status unpacked transmission-common 1.92-0ubuntu2 +2010-05-01 19:14:52 status half-installed transmission-common 1.92-0ubuntu2 +2010-05-01 19:14:54 status half-installed transmission-common 1.92-0ubuntu2 +2010-05-01 19:14:54 status unpacked transmission-common 1.92-0ubuntu2.1 +2010-05-01 19:14:54 status unpacked transmission-common 1.92-0ubuntu2.1 +2010-05-01 19:14:54 upgrade unattended-upgrades 0.55ubuntu3 0.55ubuntu4 +2010-05-01 19:14:54 status half-configured unattended-upgrades 0.55ubuntu3 +2010-05-01 19:14:54 status unpacked unattended-upgrades 0.55ubuntu3 +2010-05-01 19:14:54 status half-installed unattended-upgrades 0.55ubuntu3 +2010-05-01 19:14:55 status half-installed unattended-upgrades 0.55ubuntu3 +2010-05-01 19:14:55 status half-installed unattended-upgrades 0.55ubuntu3 +2010-05-01 19:14:55 status half-installed unattended-upgrades 0.55ubuntu3 +2010-05-01 19:14:55 status unpacked unattended-upgrades 0.55ubuntu4 +2010-05-01 19:14:55 status unpacked unattended-upgrades 0.55ubuntu4 +2010-05-01 19:14:56 upgrade xsane 0.996-2ubuntu1.1 0.996-2ubuntu2 +2010-05-01 19:14:56 status half-configured xsane 0.996-2ubuntu1.1 +2010-05-01 19:14:56 status unpacked xsane 0.996-2ubuntu1.1 +2010-05-01 19:14:56 status half-installed xsane 0.996-2ubuntu1.1 +2010-05-01 19:14:56 status half-installed xsane 0.996-2ubuntu1.1 +2010-05-01 19:14:56 status half-installed xsane 0.996-2ubuntu1.1 +2010-05-01 19:14:56 status half-installed xsane 0.996-2ubuntu1.1 +2010-05-01 19:14:57 status half-installed xsane 0.996-2ubuntu1.1 +2010-05-01 19:14:57 status unpacked xsane 0.996-2ubuntu2 +2010-05-01 19:14:57 status unpacked xsane 0.996-2ubuntu2 +2010-05-01 19:14:57 upgrade xsane-common 0.996-2ubuntu1.1 0.996-2ubuntu2 +2010-05-01 19:14:57 status half-configured xsane-common 0.996-2ubuntu1.1 +2010-05-01 19:14:58 status unpacked xsane-common 0.996-2ubuntu1.1 +2010-05-01 19:14:58 status half-installed xsane-common 0.996-2ubuntu1.1 +2010-05-01 19:15:00 status half-installed xsane-common 0.996-2ubuntu1.1 +2010-05-01 19:15:00 status unpacked xsane-common 0.996-2ubuntu2 +2010-05-01 19:15:00 status unpacked xsane-common 0.996-2ubuntu2 +2010-05-01 19:15:00 upgrade xulrunner-1.9.2 1.9.2.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:15:00 status half-configured xulrunner-1.9.2 1.9.2.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:15:01 update-alternatives: run with --remove xulrunner /usr/bin/xulrunner-1.9.2 +2010-05-01 19:15:01 update-alternatives: link group xulrunner updated to point to /usr/lib/xulrunner/xulrunner +2010-05-01 19:15:01 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:15:01 status half-installed xulrunner-1.9.2 1.9.2.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:15:10 status half-installed xulrunner-1.9.2 1.9.2.5~hg20100427r34130+nobinonly-0ubuntu1~umd1 +2010-05-01 19:15:10 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:15:10 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:15:10 upgrade fglrx-modaliases 2:8.723.1-0ubuntu3 2:8.723.1-0ubuntu4 +2010-05-01 19:15:10 status half-configured fglrx-modaliases 2:8.723.1-0ubuntu3 +2010-05-01 19:15:10 status unpacked fglrx-modaliases 2:8.723.1-0ubuntu3 +2010-05-01 19:15:10 status half-installed fglrx-modaliases 2:8.723.1-0ubuntu3 +2010-05-01 19:15:11 status half-installed fglrx-modaliases 2:8.723.1-0ubuntu3 +2010-05-01 19:15:11 status unpacked fglrx-modaliases 2:8.723.1-0ubuntu4 +2010-05-01 19:15:11 status unpacked fglrx-modaliases 2:8.723.1-0ubuntu4 +2010-05-01 19:15:12 upgrade indicator-sound 0.2.2-0ubuntu1 0.2.3-0ubuntu1 +2010-05-01 19:15:12 status half-configured indicator-sound 0.2.2-0ubuntu1 +2010-05-01 19:15:18 status unpacked indicator-sound 0.2.2-0ubuntu1 +2010-05-01 19:15:18 status half-installed indicator-sound 0.2.2-0ubuntu1 +2010-05-01 19:15:19 status half-installed indicator-sound 0.2.2-0ubuntu1 +2010-05-01 19:15:19 status unpacked indicator-sound 0.2.3-0ubuntu1 +2010-05-01 19:15:19 status unpacked indicator-sound 0.2.3-0ubuntu1 +2010-05-01 19:15:19 upgrade libglu1-mesa 7.7.1-1ubuntu2 7.7.1-1ubuntu3 +2010-05-01 19:15:19 status half-configured libglu1-mesa 7.7.1-1ubuntu2 +2010-05-01 19:15:19 status unpacked libglu1-mesa 7.7.1-1ubuntu2 +2010-05-01 19:15:19 status half-installed libglu1-mesa 7.7.1-1ubuntu2 +2010-05-01 19:15:20 status half-installed libglu1-mesa 7.7.1-1ubuntu2 +2010-05-01 19:15:20 status unpacked libglu1-mesa 7.7.1-1ubuntu3 +2010-05-01 19:15:20 status unpacked libglu1-mesa 7.7.1-1ubuntu3 +2010-05-01 19:15:20 upgrade mesa-utils 7.7.1-1ubuntu2 7.7.1-1ubuntu3 +2010-05-01 19:15:20 status half-configured mesa-utils 7.7.1-1ubuntu2 +2010-05-01 19:15:20 status unpacked mesa-utils 7.7.1-1ubuntu2 +2010-05-01 19:15:20 status half-installed mesa-utils 7.7.1-1ubuntu2 +2010-05-01 19:15:20 status half-installed mesa-utils 7.7.1-1ubuntu2 +2010-05-01 19:15:21 status half-installed mesa-utils 7.7.1-1ubuntu2 +2010-05-01 19:15:21 status unpacked mesa-utils 7.7.1-1ubuntu3 +2010-05-01 19:15:21 status unpacked mesa-utils 7.7.1-1ubuntu3 +2010-05-01 19:15:21 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-01 19:15:21 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:15:22 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:15:23 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-01 19:15:23 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-01 19:15:23 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-01 19:15:23 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-01 19:15:23 status half-configured man-db 2.5.7-2 +2010-05-01 19:15:24 status installed man-db 2.5.7-2 +2010-05-01 19:15:24 trigproc hicolor-icon-theme 0.11-1 0.11-1 +2010-05-01 19:15:24 status half-configured hicolor-icon-theme 0.11-1 +2010-05-01 19:15:26 status installed hicolor-icon-theme 0.11-1 +2010-05-01 19:15:26 trigproc ureadahead 0.100.0-4.1 0.100.0-4.1 +2010-05-01 19:15:26 status half-configured ureadahead 0.100.0-4.1 +2010-05-01 19:15:26 status installed ureadahead 0.100.0-4.1 +2010-05-01 19:15:26 trigproc shared-mime-info 0.71-1ubuntu2 0.71-1ubuntu2 +2010-05-01 19:15:26 status half-configured shared-mime-info 0.71-1ubuntu2 +2010-05-01 19:15:27 status installed shared-mime-info 0.71-1ubuntu2 +2010-05-01 19:15:28 trigproc install-info 4.13a.dfsg.1-5ubuntu1 4.13a.dfsg.1-5ubuntu1 +2010-05-01 19:15:28 status half-configured install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-01 19:15:28 status installed install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-01 19:15:28 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-01 19:15:28 status half-configured python-support 1.0.4ubuntu1 +2010-05-01 19:15:33 status installed python-support 1.0.4ubuntu1 +2010-05-01 19:15:34 startup packages configure +2010-05-01 19:15:34 configure linux-image-2.6.32-22-generic 2.6.32-22.33 2.6.32-22.33 +2010-05-01 19:15:34 status unpacked linux-image-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:15:34 status half-configured linux-image-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:15:57 status installed linux-image-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:15:57 configure acpid 1.0.10-5ubuntu2.1 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 status unpacked acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 status unpacked acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 status unpacked acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 status unpacked acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 status unpacked acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 status half-configured acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 status installed acpid 1.0.10-5ubuntu2.1 +2010-05-01 19:15:57 configure libgnome-window-settings1 1:2.30.1-0ubuntu1 1:2.30.1-0ubuntu1 +2010-05-01 19:15:57 status unpacked libgnome-window-settings1 1:2.30.1-0ubuntu1 +2010-05-01 19:15:57 status half-configured libgnome-window-settings1 1:2.30.1-0ubuntu1 +2010-05-01 19:15:58 status installed libgnome-window-settings1 1:2.30.1-0ubuntu1 +2010-05-01 19:15:58 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-01 19:15:58 configure capplets-data 1:2.30.1-0ubuntu1 1:2.30.1-0ubuntu1 +2010-05-01 19:15:58 status unpacked capplets-data 1:2.30.1-0ubuntu1 +2010-05-01 19:15:58 status unpacked capplets-data 1:2.30.1-0ubuntu1 +2010-05-01 19:15:58 status unpacked capplets-data 1:2.30.1-0ubuntu1 +2010-05-01 19:15:58 status half-configured capplets-data 1:2.30.1-0ubuntu1 +2010-05-01 19:16:02 status installed capplets-data 1:2.30.1-0ubuntu1 +2010-05-01 19:16:02 configure gnome-settings-daemon 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:02 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:02 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:03 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:03 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:03 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:03 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:03 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:03 status unpacked gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:03 status half-configured gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:07 status installed gnome-settings-daemon 2.30.1-0ubuntu1 +2010-05-01 19:16:08 configure ubuntu-system-service 0.1.20.1 0.1.20.1 +2010-05-01 19:16:08 status unpacked ubuntu-system-service 0.1.20.1 +2010-05-01 19:16:08 status unpacked ubuntu-system-service 0.1.20.1 +2010-05-01 19:16:08 status half-configured ubuntu-system-service 0.1.20.1 +2010-05-01 19:16:08 status installed ubuntu-system-service 0.1.20.1 +2010-05-01 19:16:08 status triggers-pending python-central 0.6.15ubuntu1 +2010-05-01 19:16:08 status triggers-awaited ubuntu-system-service 0.1.20.1 +2010-05-01 19:16:08 configure cheese-common 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:08 status unpacked cheese-common 2.30.1-0ubuntu1 +2010-05-01 19:16:08 status half-configured cheese-common 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status installed cheese-common 2.30.1-0ubuntu1 +2010-05-01 19:16:09 configure libcheese-gtk18 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status unpacked libcheese-gtk18 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status half-configured libcheese-gtk18 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status installed libcheese-gtk18 2.30.1-0ubuntu1 +2010-05-01 19:16:09 configure cheese 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status unpacked cheese 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status half-configured cheese 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status installed cheese 2.30.1-0ubuntu1 +2010-05-01 19:16:09 configure libsoup2.4-1 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status unpacked libsoup2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:16:09 status half-configured libsoup2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status installed libsoup2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:16:10 configure libsoup2.4-dev 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status unpacked libsoup2.4-dev 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status half-configured libsoup2.4-dev 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status installed libsoup2.4-dev 2.30.1-0ubuntu1 +2010-05-01 19:16:10 configure empathy-common 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status unpacked empathy-common 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status half-configured empathy-common 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status installed empathy-common 2.30.1-0ubuntu1 +2010-05-01 19:16:10 configure nautilus-sendto-empathy 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status unpacked nautilus-sendto-empathy 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status half-configured nautilus-sendto-empathy 2.30.1-0ubuntu1 +2010-05-01 19:16:10 status installed nautilus-sendto-empathy 2.30.1-0ubuntu1 +2010-05-01 19:16:11 configure empathy 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:11 status unpacked empathy 2.30.1-0ubuntu1 +2010-05-01 19:16:11 status half-configured empathy 2.30.1-0ubuntu1 +2010-05-01 19:16:11 status installed empathy 2.30.1-0ubuntu1 +2010-05-01 19:16:11 configure libevdocument2 2.30.1-0ubuntu2 2.30.1-0ubuntu2 +2010-05-01 19:16:11 status unpacked libevdocument2 2.30.1-0ubuntu2 +2010-05-01 19:16:11 status half-configured libevdocument2 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status installed libevdocument2 2.30.1-0ubuntu2 +2010-05-01 19:16:12 configure libevview2 2.30.1-0ubuntu2 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status unpacked libevview2 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status half-configured libevview2 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status installed libevview2 2.30.1-0ubuntu2 +2010-05-01 19:16:12 configure evince 2.30.1-0ubuntu2 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status unpacked evince 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status unpacked evince 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status unpacked evince 2.30.1-0ubuntu2 +2010-05-01 19:16:12 status half-configured evince 2.30.1-0ubuntu2 +2010-05-01 19:16:18 status installed evince 2.30.1-0ubuntu2 +2010-05-01 19:16:18 configure libnautilus-extension1 1:2.30.1-0ubuntu1 1:2.30.1-0ubuntu1 +2010-05-01 19:16:18 status unpacked libnautilus-extension1 1:2.30.1-0ubuntu1 +2010-05-01 19:16:18 status half-configured libnautilus-extension1 1:2.30.1-0ubuntu1 +2010-05-01 19:16:18 status installed libnautilus-extension1 1:2.30.1-0ubuntu1 +2010-05-01 19:16:18 configure file-roller 2.30.1.1-0ubuntu2 2.30.1.1-0ubuntu2 +2010-05-01 19:16:18 status unpacked file-roller 2.30.1.1-0ubuntu2 +2010-05-01 19:16:18 status half-configured file-roller 2.30.1.1-0ubuntu2 +2010-05-01 19:16:19 status installed file-roller 2.30.1.1-0ubuntu2 +2010-05-01 19:16:19 configure libgtksourceview2.0-common 2.10.1-0ubuntu1 2.10.1-0ubuntu1 +2010-05-01 19:16:19 status unpacked libgtksourceview2.0-common 2.10.1-0ubuntu1 +2010-05-01 19:16:19 status half-configured libgtksourceview2.0-common 2.10.1-0ubuntu1 +2010-05-01 19:16:19 status installed libgtksourceview2.0-common 2.10.1-0ubuntu1 +2010-05-01 19:16:19 configure libgtksourceview2.0-0 2.10.1-0ubuntu1 2.10.1-0ubuntu1 +2010-05-01 19:16:19 status unpacked libgtksourceview2.0-0 2.10.1-0ubuntu1 +2010-05-01 19:16:19 status half-configured libgtksourceview2.0-0 2.10.1-0ubuntu1 +2010-05-01 19:16:19 status installed libgtksourceview2.0-0 2.10.1-0ubuntu1 +2010-05-01 19:16:19 configure gedit-common 2.30.2-0ubuntu1 2.30.2-0ubuntu1 +2010-05-01 19:16:19 status unpacked gedit-common 2.30.2-0ubuntu1 +2010-05-01 19:16:19 status half-configured gedit-common 2.30.2-0ubuntu1 +2010-05-01 19:16:19 status installed gedit-common 2.30.2-0ubuntu1 +2010-05-01 19:16:19 configure gedit 2.30.2-0ubuntu1 2.30.2-0ubuntu1 +2010-05-01 19:16:19 status unpacked gedit 2.30.2-0ubuntu1 +2010-05-01 19:16:19 status half-configured gedit 2.30.2-0ubuntu1 +2010-05-01 19:16:20 update-alternatives: run with --install /usr/bin/gnome-text-editor gnome-text-editor /usr/bin/gedit 50 --slave /usr/share/man/man1/gnome-text-editor.1.gz gnome-text-editor.1.gz /usr/share/man/man1/gedit.1.gz +2010-05-01 19:16:20 update-alternatives: link group gnome-text-editor updated to point to /usr/bin/gedit +2010-05-01 19:16:25 status installed gedit 2.30.2-0ubuntu1 +2010-05-01 19:16:25 configure libgimp2.0 2.6.8-2ubuntu1.1 2.6.8-2ubuntu1.1 +2010-05-01 19:16:25 status unpacked libgimp2.0 2.6.8-2ubuntu1.1 +2010-05-01 19:16:25 status half-configured libgimp2.0 2.6.8-2ubuntu1.1 +2010-05-01 19:16:25 status installed libgimp2.0 2.6.8-2ubuntu1.1 +2010-05-01 19:16:25 configure gimp-data 2.6.8-2ubuntu1.1 2.6.8-2ubuntu1.1 +2010-05-01 19:16:25 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:25 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:25 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status unpacked gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status half-configured gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:26 status installed gimp-data 2.6.8-2ubuntu1.1 +2010-05-01 19:16:27 configure gimp 2.6.8-2ubuntu1.1 2.6.8-2ubuntu1.1 +2010-05-01 19:16:27 status unpacked gimp 2.6.8-2ubuntu1.1 +2010-05-01 19:16:27 status half-configured gimp 2.6.8-2ubuntu1.1 +2010-05-01 19:16:27 status installed gimp 2.6.8-2ubuntu1.1 +2010-05-01 19:16:27 configure grub-common 1.98-1ubuntu6 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status unpacked grub-common 1.98-1ubuntu6 +2010-05-01 19:16:27 status half-configured grub-common 1.98-1ubuntu6 +2010-05-01 19:16:28 status installed grub-common 1.98-1ubuntu6 +2010-05-01 19:16:28 configure grub-pc 1.98-1ubuntu6 1.98-1ubuntu6 +2010-05-01 19:16:28 status unpacked grub-pc 1.98-1ubuntu6 +2010-05-01 19:16:28 status unpacked grub-pc 1.98-1ubuntu6 +2010-05-01 19:16:28 status half-configured grub-pc 1.98-1ubuntu6 +2010-05-01 19:16:42 status installed grub-pc 1.98-1ubuntu6 +2010-05-01 19:16:42 configure python-cupshelpers 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:42 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:42 status half-configured python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:42 status installed python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:42 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-01 19:16:42 configure system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:42 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:42 status half-configured system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:42 status installed system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:43 configure hal-cups-utils 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:43 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:43 status half-configured hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:43 status installed hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:16:43 configure libgl1-mesa-dri 7.7.1-1ubuntu3 7.7.1-1ubuntu3 +2010-05-01 19:16:43 status unpacked libgl1-mesa-dri 7.7.1-1ubuntu3 +2010-05-01 19:16:43 status half-configured libgl1-mesa-dri 7.7.1-1ubuntu3 +2010-05-01 19:16:43 status installed libgl1-mesa-dri 7.7.1-1ubuntu3 +2010-05-01 19:16:43 configure libgl1-mesa-glx 7.7.1-1ubuntu3 7.7.1-1ubuntu3 +2010-05-01 19:16:43 status unpacked libgl1-mesa-glx 7.7.1-1ubuntu3 +2010-05-01 19:16:43 status half-configured libgl1-mesa-glx 7.7.1-1ubuntu3 +2010-05-01 19:16:43 update-alternatives: run with --force --install /etc/ld.so.conf.d/GL.conf gl_conf /usr/lib/mesa/ld.so.conf 500 --slave /usr/lib/xorg/extra-modules xorg_extra_modules /usr/lib/xorg/x11-extra-modules +2010-05-01 19:16:44 status installed libgl1-mesa-glx 7.7.1-1ubuntu3 +2010-05-01 19:16:44 configure libsoup-gnome2.4-1 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-01 19:16:44 status unpacked libsoup-gnome2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:16:44 status half-configured libsoup-gnome2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:16:44 status installed libsoup-gnome2.4-1 2.30.1-0ubuntu1 +2010-05-01 19:16:44 configure linux-headers-2.6.32-22 2.6.32-22.33 2.6.32-22.33 +2010-05-01 19:16:44 status unpacked linux-headers-2.6.32-22 2.6.32-22.33 +2010-05-01 19:16:44 status half-configured linux-headers-2.6.32-22 2.6.32-22.33 +2010-05-01 19:16:44 status installed linux-headers-2.6.32-22 2.6.32-22.33 +2010-05-01 19:16:44 configure linux-headers-2.6.32-22-generic 2.6.32-22.33 2.6.32-22.33 +2010-05-01 19:16:44 status unpacked linux-headers-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:16:44 status half-configured linux-headers-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:16:45 status installed linux-headers-2.6.32-22-generic 2.6.32-22.33 +2010-05-01 19:16:45 configure linux-headers-generic 2.6.32.22.23 2.6.32.22.23 +2010-05-01 19:16:45 status unpacked linux-headers-generic 2.6.32.22.23 +2010-05-01 19:16:45 status half-configured linux-headers-generic 2.6.32.22.23 +2010-05-01 19:16:45 status installed linux-headers-generic 2.6.32.22.23 +2010-05-01 19:16:45 configure linux-image-generic 2.6.32.22.23 2.6.32.22.23 +2010-05-01 19:16:45 status unpacked linux-image-generic 2.6.32.22.23 +2010-05-01 19:16:45 status half-configured linux-image-generic 2.6.32.22.23 +2010-05-01 19:16:46 status installed linux-image-generic 2.6.32.22.23 +2010-05-01 19:16:46 configure linux-libc-dev 2.6.32-22.33 2.6.32-22.33 +2010-05-01 19:16:46 status unpacked linux-libc-dev 2.6.32-22.33 +2010-05-01 19:16:46 status half-configured linux-libc-dev 2.6.32-22.33 +2010-05-01 19:16:46 status installed linux-libc-dev 2.6.32-22.33 +2010-05-01 19:16:46 configure nautilus-data 1:2.30.1-0ubuntu1 1:2.30.1-0ubuntu1 +2010-05-01 19:16:46 status unpacked nautilus-data 1:2.30.1-0ubuntu1 +2010-05-01 19:16:46 status half-configured nautilus-data 1:2.30.1-0ubuntu1 +2010-05-01 19:16:51 status installed nautilus-data 1:2.30.1-0ubuntu1 +2010-05-01 19:16:51 configure nautilus 1:2.30.1-0ubuntu1 1:2.30.1-0ubuntu1 +2010-05-01 19:16:51 status unpacked nautilus 1:2.30.1-0ubuntu1 +2010-05-01 19:16:51 status half-configured nautilus 1:2.30.1-0ubuntu1 +2010-05-01 19:16:51 status installed nautilus 1:2.30.1-0ubuntu1 +2010-05-01 19:16:51 configure pm-utils 1.3.0-1ubuntu2 1.3.0-1ubuntu2 +2010-05-01 19:16:51 status unpacked pm-utils 1.3.0-1ubuntu2 +2010-05-01 19:16:51 status unpacked pm-utils 1.3.0-1ubuntu2 +2010-05-01 19:16:51 status unpacked pm-utils 1.3.0-1ubuntu2 +2010-05-01 19:16:52 status half-configured pm-utils 1.3.0-1ubuntu2 +2010-05-01 19:16:52 status installed pm-utils 1.3.0-1ubuntu2 +2010-05-01 19:16:52 configure python-ubuntuone-client 1.2.1-0ubuntu2 1.2.1-0ubuntu2 +2010-05-01 19:16:52 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:52 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:52 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:52 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:52 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:52 status unpacked python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:52 status half-configured python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:53 status installed python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:53 status triggers-awaited python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:16:53 configure rhythmbox 0.12.8-0ubuntu4 0.12.8-0ubuntu4 +2010-05-01 19:16:53 status unpacked rhythmbox 0.12.8-0ubuntu4 +2010-05-01 19:16:53 status half-configured rhythmbox 0.12.8-0ubuntu4 +2010-05-01 19:16:54 status installed rhythmbox 0.12.8-0ubuntu4 +2010-05-01 19:16:54 configure rhythmbox-plugins 0.12.8-0ubuntu4 0.12.8-0ubuntu4 +2010-05-01 19:16:54 status unpacked rhythmbox-plugins 0.12.8-0ubuntu4 +2010-05-01 19:16:54 status half-configured rhythmbox-plugins 0.12.8-0ubuntu4 +2010-05-01 19:16:54 status installed rhythmbox-plugins 0.12.8-0ubuntu4 +2010-05-01 19:16:54 configure rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu4 0.12.8-0ubuntu4 +2010-05-01 19:16:54 status unpacked rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu4 +2010-05-01 19:16:54 status half-configured rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu4 +2010-05-01 19:16:54 status installed rhythmbox-plugin-cdrecorder 0.12.8-0ubuntu4 +2010-05-01 19:16:54 configure software-center 2.0.3 2.0.3 +2010-05-01 19:16:54 status unpacked software-center 2.0.3 +2010-05-01 19:16:54 status unpacked software-center 2.0.3 +2010-05-01 19:16:55 status half-configured software-center 2.0.3 +2010-05-01 19:17:15 status installed software-center 2.0.3 +2010-05-01 19:17:15 status triggers-awaited software-center 2.0.3 +2010-05-01 19:17:15 configure system-config-printer-common 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:15 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:15 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:15 status half-configured system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:15 status installed system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:15 configure system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:15 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:15 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:16 status half-configured system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:16 status installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-01 19:17:16 configure thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:16 status unpacked thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:16 status unpacked thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:16 status half-configured thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:16 status installed thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:16 configure tomboy 1.2.1-0ubuntu1 1.2.1-0ubuntu1 +2010-05-01 19:17:16 status unpacked tomboy 1.2.1-0ubuntu1 +2010-05-01 19:17:16 status half-configured tomboy 1.2.1-0ubuntu1 +2010-05-01 19:17:17 status installed tomboy 1.2.1-0ubuntu1 +2010-05-01 19:17:17 configure transmission-common 1.92-0ubuntu2.1 1.92-0ubuntu2.1 +2010-05-01 19:17:17 status unpacked transmission-common 1.92-0ubuntu2.1 +2010-05-01 19:17:17 status half-configured transmission-common 1.92-0ubuntu2.1 +2010-05-01 19:17:17 status installed transmission-common 1.92-0ubuntu2.1 +2010-05-01 19:17:17 configure transmission-gtk 1.92-0ubuntu2.1 1.92-0ubuntu2.1 +2010-05-01 19:17:17 status unpacked transmission-gtk 1.92-0ubuntu2.1 +2010-05-01 19:17:17 status half-configured transmission-gtk 1.92-0ubuntu2.1 +2010-05-01 19:17:17 status installed transmission-gtk 1.92-0ubuntu2.1 +2010-05-01 19:17:17 configure unattended-upgrades 0.55ubuntu4 0.55ubuntu4 +2010-05-01 19:17:17 status unpacked unattended-upgrades 0.55ubuntu4 +2010-05-01 19:17:18 status unpacked unattended-upgrades 0.55ubuntu4 +2010-05-01 19:17:18 status unpacked unattended-upgrades 0.55ubuntu4 +2010-05-01 19:17:18 status unpacked unattended-upgrades 0.55ubuntu4 +2010-05-01 19:17:18 status unpacked unattended-upgrades 0.55ubuntu4 +2010-05-01 19:17:18 status half-configured unattended-upgrades 0.55ubuntu4 +2010-05-01 19:17:19 status installed unattended-upgrades 0.55ubuntu4 +2010-05-01 19:17:19 configure xsane-common 0.996-2ubuntu2 0.996-2ubuntu2 +2010-05-01 19:17:19 status unpacked xsane-common 0.996-2ubuntu2 +2010-05-01 19:17:19 status half-configured xsane-common 0.996-2ubuntu2 +2010-05-01 19:17:19 status installed xsane-common 0.996-2ubuntu2 +2010-05-01 19:17:19 configure xsane 0.996-2ubuntu2 0.996-2ubuntu2 +2010-05-01 19:17:19 status unpacked xsane 0.996-2ubuntu2 +2010-05-01 19:17:19 status half-configured xsane 0.996-2ubuntu2 +2010-05-01 19:17:19 status installed xsane 0.996-2ubuntu2 +2010-05-01 19:17:19 configure xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:19 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:19 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:19 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:19 status half-configured xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:20 update-alternatives: run with --install /usr/bin/xulrunner xulrunner /usr/bin/xulrunner-1.9.2 50 +2010-05-01 19:17:20 update-alternatives: link group xulrunner updated to point to /usr/bin/xulrunner-1.9.2 +2010-05-01 19:17:20 status installed xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:20 configure fglrx-modaliases 2:8.723.1-0ubuntu4 2:8.723.1-0ubuntu4 +2010-05-01 19:17:20 status unpacked fglrx-modaliases 2:8.723.1-0ubuntu4 +2010-05-01 19:17:20 status half-configured fglrx-modaliases 2:8.723.1-0ubuntu4 +2010-05-01 19:17:20 status installed fglrx-modaliases 2:8.723.1-0ubuntu4 +2010-05-01 19:17:20 configure indicator-sound 0.2.3-0ubuntu1 0.2.3-0ubuntu1 +2010-05-01 19:17:20 status unpacked indicator-sound 0.2.3-0ubuntu1 +2010-05-01 19:17:20 status half-configured indicator-sound 0.2.3-0ubuntu1 +2010-05-01 19:17:21 status installed indicator-sound 0.2.3-0ubuntu1 +2010-05-01 19:17:21 configure libglu1-mesa 7.7.1-1ubuntu3 7.7.1-1ubuntu3 +2010-05-01 19:17:21 status unpacked libglu1-mesa 7.7.1-1ubuntu3 +2010-05-01 19:17:21 status half-configured libglu1-mesa 7.7.1-1ubuntu3 +2010-05-01 19:17:21 status installed libglu1-mesa 7.7.1-1ubuntu3 +2010-05-01 19:17:21 configure mesa-utils 7.7.1-1ubuntu3 7.7.1-1ubuntu3 +2010-05-01 19:17:21 status unpacked mesa-utils 7.7.1-1ubuntu3 +2010-05-01 19:17:21 status half-configured mesa-utils 7.7.1-1ubuntu3 +2010-05-01 19:17:21 status installed mesa-utils 7.7.1-1ubuntu3 +2010-05-01 19:17:21 trigproc python-central 0.6.15ubuntu1 0.6.15ubuntu1 +2010-05-01 19:17:21 status half-configured python-central 0.6.15ubuntu1 +2010-05-01 19:17:21 status installed software-center 2.0.3 +2010-05-01 19:17:21 status installed python-ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:17:21 status installed ubuntu-system-service 0.1.20.1 +2010-05-01 19:17:21 status installed python-central 0.6.15ubuntu1 +2010-05-01 19:17:22 configure gnome-control-center 1:2.30.1-0ubuntu1 1:2.30.1-0ubuntu1 +2010-05-01 19:17:22 status unpacked gnome-control-center 1:2.30.1-0ubuntu1 +2010-05-01 19:17:22 status half-configured gnome-control-center 1:2.30.1-0ubuntu1 +2010-05-01 19:17:22 status installed gnome-control-center 1:2.30.1-0ubuntu1 +2010-05-01 19:17:22 configure ubuntuone-client 1.2.1-0ubuntu2 1.2.1-0ubuntu2 +2010-05-01 19:17:22 status unpacked ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:17:22 status unpacked ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:17:22 status half-configured ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:17:22 status installed ubuntuone-client 1.2.1-0ubuntu2 +2010-05-01 19:17:22 configure ubuntuone-client-gnome 1.2.1-0ubuntu2 1.2.1-0ubuntu2 +2010-05-01 19:17:22 status unpacked ubuntuone-client-gnome 1.2.1-0ubuntu2 +2010-05-01 19:17:22 status half-configured ubuntuone-client-gnome 1.2.1-0ubuntu2 +2010-05-01 19:17:22 status installed ubuntuone-client-gnome 1.2.1-0ubuntu2 +2010-05-01 19:17:22 configure language-pack-ru 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:22 status unpacked language-pack-ru 1:10.04+20100422 +2010-05-01 19:17:22 status half-configured language-pack-ru 1:10.04+20100422 +2010-05-01 19:17:22 status installed language-pack-ru 1:10.04+20100422 +2010-05-01 19:17:23 configure language-pack-en 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:23 status unpacked language-pack-en 1:10.04+20100422 +2010-05-01 19:17:23 status half-configured language-pack-en 1:10.04+20100422 +2010-05-01 19:17:23 status installed language-pack-en 1:10.04+20100422 +2010-05-01 19:17:23 configure language-pack-ro 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:23 status unpacked language-pack-ro 1:10.04+20100422 +2010-05-01 19:17:23 status half-configured language-pack-ro 1:10.04+20100422 +2010-05-01 19:17:23 status installed language-pack-ro 1:10.04+20100422 +2010-05-01 19:17:23 configure language-pack-ru-base 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:23 status unpacked language-pack-ru-base 1:10.04+20100422 +2010-05-01 19:17:23 status half-configured language-pack-ru-base 1:10.04+20100422 +2010-05-01 19:17:24 status installed language-pack-ru-base 1:10.04+20100422 +2010-05-01 19:17:24 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:17:24 status triggers-awaited language-pack-ru-base 1:10.04+20100422 +2010-05-01 19:17:24 configure firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:24 status unpacked firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:24 status half-configured firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:24 status installed firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:24 configure chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:24 status unpacked chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:24 status half-configured chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:24 status installed chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:24 configure chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-01 19:17:24 status unpacked chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-01 19:17:25 status half-configured chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-01 19:17:25 status installed chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-01 19:17:25 configure language-pack-en-base 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:25 status unpacked language-pack-en-base 1:10.04+20100422 +2010-05-01 19:17:25 status half-configured language-pack-en-base 1:10.04+20100422 +2010-05-01 19:17:50 status installed language-pack-en-base 1:10.04+20100422 +2010-05-01 19:17:50 status triggers-awaited language-pack-en-base 1:10.04+20100422 +2010-05-01 19:17:51 configure language-pack-ro-base 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:51 status unpacked language-pack-ro-base 1:10.04+20100422 +2010-05-01 19:17:51 status half-configured language-pack-ro-base 1:10.04+20100422 +2010-05-01 19:17:52 status installed language-pack-ro-base 1:10.04+20100422 +2010-05-01 19:17:52 status triggers-awaited language-pack-ro-base 1:10.04+20100422 +2010-05-01 19:17:52 configure firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:52 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 status half-configured firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:53 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox 40 +2010-05-01 19:17:55 status installed firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-01 19:17:55 configure chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:55 status unpacked chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:55 status unpacked chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:55 status half-configured chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:55 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/chromium-browser 40 +2010-05-01 19:17:55 update-alternatives: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/chromium-browser 40 +2010-05-01 19:17:55 update-alternatives: link group gnome-www-browser updated to point to /usr/bin/chromium-browser +2010-05-01 19:17:55 status installed chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-01 19:17:55 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-01 19:17:55 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:17:55 status installed language-pack-ro-base 1:10.04+20100422 +2010-05-01 19:17:55 status installed language-pack-en-base 1:10.04+20100422 +2010-05-01 19:17:56 status installed language-pack-ru-base 1:10.04+20100422 +2010-05-01 19:17:56 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:17:56 configure language-pack-gnome-ro 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:56 status unpacked language-pack-gnome-ro 1:10.04+20100422 +2010-05-01 19:17:56 status half-configured language-pack-gnome-ro 1:10.04+20100422 +2010-05-01 19:17:56 status installed language-pack-gnome-ro 1:10.04+20100422 +2010-05-01 19:17:56 configure language-pack-gnome-ru 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:56 status unpacked language-pack-gnome-ru 1:10.04+20100422 +2010-05-01 19:17:56 status half-configured language-pack-gnome-ru 1:10.04+20100422 +2010-05-01 19:17:56 status installed language-pack-gnome-ru 1:10.04+20100422 +2010-05-01 19:17:56 configure language-pack-gnome-en 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:56 status unpacked language-pack-gnome-en 1:10.04+20100422 +2010-05-01 19:17:56 status half-configured language-pack-gnome-en 1:10.04+20100422 +2010-05-01 19:17:57 status installed language-pack-gnome-en 1:10.04+20100422 +2010-05-01 19:17:57 configure language-pack-gnome-ro-base 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:57 status unpacked language-pack-gnome-ro-base 1:10.04+20100422 +2010-05-01 19:17:57 status half-configured language-pack-gnome-ro-base 1:10.04+20100422 +2010-05-01 19:17:57 status installed language-pack-gnome-ro-base 1:10.04+20100422 +2010-05-01 19:17:57 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:17:57 status triggers-awaited language-pack-gnome-ro-base 1:10.04+20100422 +2010-05-01 19:17:57 configure language-pack-gnome-ru-base 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:57 status unpacked language-pack-gnome-ru-base 1:10.04+20100422 +2010-05-01 19:17:57 status half-configured language-pack-gnome-ru-base 1:10.04+20100422 +2010-05-01 19:17:57 status installed language-pack-gnome-ru-base 1:10.04+20100422 +2010-05-01 19:17:57 status triggers-awaited language-pack-gnome-ru-base 1:10.04+20100422 +2010-05-01 19:17:57 configure language-pack-gnome-en-base 1:10.04+20100422 1:10.04+20100422 +2010-05-01 19:17:57 status unpacked language-pack-gnome-en-base 1:10.04+20100422 +2010-05-01 19:17:58 status half-configured language-pack-gnome-en-base 1:10.04+20100422 +2010-05-01 19:17:58 status installed language-pack-gnome-en-base 1:10.04+20100422 +2010-05-01 19:17:58 status triggers-awaited language-pack-gnome-en-base 1:10.04+20100422 +2010-05-01 19:17:58 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-01 19:17:58 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-01 19:17:58 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-01 19:17:58 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-01 19:17:58 status half-configured python-support 1.0.4ubuntu1 +2010-05-01 19:17:59 status installed python-support 1.0.4ubuntu1 +2010-05-01 19:17:59 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-01 19:17:59 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:17:59 status installed language-pack-gnome-en-base 1:10.04+20100422 +2010-05-01 19:17:59 status installed language-pack-gnome-ru-base 1:10.04+20100422 +2010-05-01 19:17:59 status installed language-pack-gnome-ro-base 1:10.04+20100422 +2010-05-01 19:18:00 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-01 19:18:00 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-01 19:18:00 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-01 19:18:00 status half-configured python-support 1.0.4ubuntu1 +2010-05-01 19:18:01 status installed python-support 1.0.4ubuntu1 +2010-05-01 19:35:31 update-alternatives: run with --config gnome-www-browser +2010-05-01 19:36:29 update-alternatives: run with --set gnome-www-browser /usr/bin/firefox +2010-05-03 21:47:45 startup archives unpack +2010-05-03 21:47:52 upgrade update-manager 1:0.134.7 1:0.134.8 +2010-05-03 21:47:52 status half-configured update-manager 1:0.134.7 +2010-05-03 21:47:56 status unpacked update-manager 1:0.134.7 +2010-05-03 21:47:56 status half-installed update-manager 1:0.134.7 +2010-05-03 21:47:56 status triggers-pending hicolor-icon-theme 0.11-1 +2010-05-03 21:47:56 status half-installed update-manager 1:0.134.7 +2010-05-03 21:47:57 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-03 21:47:57 status half-installed update-manager 1:0.134.7 +2010-05-03 21:47:57 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-03 21:47:57 status half-installed update-manager 1:0.134.7 +2010-05-03 21:47:57 status triggers-pending man-db 2.5.7-2 +2010-05-03 21:47:57 status half-installed update-manager 1:0.134.7 +2010-05-03 21:47:59 status half-installed update-manager 1:0.134.7 +2010-05-03 21:47:59 status unpacked update-manager 1:0.134.8 +2010-05-03 21:48:00 status unpacked update-manager 1:0.134.8 +2010-05-03 21:48:00 upgrade update-manager-core 1:0.134.7 1:0.134.8 +2010-05-03 21:48:00 status half-configured update-manager-core 1:0.134.7 +2010-05-03 21:48:00 status unpacked update-manager-core 1:0.134.7 +2010-05-03 21:48:00 status half-installed update-manager-core 1:0.134.7 +2010-05-03 21:48:03 status half-installed update-manager-core 1:0.134.7 +2010-05-03 21:48:03 status unpacked update-manager-core 1:0.134.8 +2010-05-03 21:48:03 status unpacked update-manager-core 1:0.134.8 +2010-05-03 21:48:03 upgrade chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-03 21:48:03 status half-configured chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-03 21:48:03 status unpacked chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-03 21:48:04 status half-installed chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-03 21:48:04 status half-installed chromium-codecs-ffmpeg 0.5+svn20100427r45726+45733+46026-0ubuntu1~ucd1 +2010-05-03 21:48:04 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-03 21:48:04 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-03 21:48:04 upgrade ghostscript 8.71.dfsg.1-0ubuntu5 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:04 status half-configured ghostscript 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:09 update-alternatives: run with --remove-all ps2pdf +2010-05-03 21:48:09 update-alternatives: link group ps2pdf fully removed +2010-05-03 21:48:09 status unpacked ghostscript 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:09 status half-installed ghostscript 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:09 status half-installed ghostscript 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:22 status half-installed ghostscript 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:23 status unpacked ghostscript 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:23 status unpacked ghostscript 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:23 upgrade libgs8 8.71.dfsg.1-0ubuntu5 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:23 status half-configured libgs8 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:23 status unpacked libgs8 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:23 status half-installed libgs8 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:24 status half-installed libgs8 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:24 status unpacked libgs8 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:24 status unpacked libgs8 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:24 upgrade ghostscript-cups 8.71.dfsg.1-0ubuntu5 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:24 status half-configured ghostscript-cups 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:24 status unpacked ghostscript-cups 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:24 status half-installed ghostscript-cups 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:25 status half-installed ghostscript-cups 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:25 status unpacked ghostscript-cups 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:25 status unpacked ghostscript-cups 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:25 upgrade ghostscript-x 8.71.dfsg.1-0ubuntu5 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:25 status half-configured ghostscript-x 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:25 status unpacked ghostscript-x 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:25 status half-installed ghostscript-x 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:25 status half-installed ghostscript-x 8.71.dfsg.1-0ubuntu5 +2010-05-03 21:48:25 status unpacked ghostscript-x 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:26 status unpacked ghostscript-x 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:48:26 upgrade gwibber 2.30.0.1-0ubuntu1 2.30.0.1-0ubuntu2 +2010-05-03 21:48:26 status half-configured gwibber 2.30.0.1-0ubuntu1 +2010-05-03 21:48:26 status unpacked gwibber 2.30.0.1-0ubuntu1 +2010-05-03 21:48:26 status half-installed gwibber 2.30.0.1-0ubuntu1 +2010-05-03 21:48:26 status half-installed gwibber 2.30.0.1-0ubuntu1 +2010-05-03 21:48:27 status half-installed gwibber 2.30.0.1-0ubuntu1 +2010-05-03 21:48:27 status half-installed gwibber 2.30.0.1-0ubuntu1 +2010-05-03 21:48:34 status half-installed gwibber 2.30.0.1-0ubuntu1 +2010-05-03 21:48:34 status unpacked gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:48:34 status unpacked gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:48:34 upgrade gwibber-service 2.30.0.1-0ubuntu1 2.30.0.1-0ubuntu2 +2010-05-03 21:48:34 status half-configured gwibber-service 2.30.0.1-0ubuntu1 +2010-05-03 21:48:35 status unpacked gwibber-service 2.30.0.1-0ubuntu1 +2010-05-03 21:48:35 status half-installed gwibber-service 2.30.0.1-0ubuntu1 +2010-05-03 21:48:37 status half-installed gwibber-service 2.30.0.1-0ubuntu1 +2010-05-03 21:48:37 status unpacked gwibber-service 2.30.0.1-0ubuntu2 +2010-05-03 21:48:37 status unpacked gwibber-service 2.30.0.1-0ubuntu2 +2010-05-03 21:48:37 upgrade python-cupshelpers 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:37 status half-configured python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:37 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-03 21:48:37 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:37 status half-installed python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:38 status half-installed python-cupshelpers 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:38 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:38 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:38 upgrade system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:38 status half-configured system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:38 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:38 status half-installed system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:39 status half-installed system-config-printer-udev 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:39 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:39 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:39 upgrade hal-cups-utils 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:39 status half-configured hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:39 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:39 status half-installed hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:39 status half-installed hal-cups-utils 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:39 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:39 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:40 upgrade obexd-client 0.22-0ubuntu1 0.22-0ubuntu2 +2010-05-03 21:48:40 status half-configured obexd-client 0.22-0ubuntu1 +2010-05-03 21:48:40 status unpacked obexd-client 0.22-0ubuntu1 +2010-05-03 21:48:40 status half-installed obexd-client 0.22-0ubuntu1 +2010-05-03 21:48:40 status half-installed obexd-client 0.22-0ubuntu1 +2010-05-03 21:48:41 status unpacked obexd-client 0.22-0ubuntu2 +2010-05-03 21:48:41 status unpacked obexd-client 0.22-0ubuntu2 +2010-05-03 21:48:41 upgrade system-config-printer-common 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:41 status half-configured system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:41 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:41 status half-installed system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:42 status half-installed system-config-printer-common 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:42 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:42 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:42 upgrade system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:42 status half-configured system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:43 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:43 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:43 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:43 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:43 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:46 status half-installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5.1 +2010-05-03 21:48:46 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:46 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:48:46 trigproc hicolor-icon-theme 0.11-1 0.11-1 +2010-05-03 21:48:46 status half-configured hicolor-icon-theme 0.11-1 +2010-05-03 21:48:48 status installed hicolor-icon-theme 0.11-1 +2010-05-03 21:48:49 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-03 21:48:49 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-03 21:48:50 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-03 21:48:50 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-03 21:48:50 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-03 21:48:50 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-03 21:48:50 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-03 21:48:50 status half-configured man-db 2.5.7-2 +2010-05-03 21:48:53 status installed man-db 2.5.7-2 +2010-05-03 21:48:53 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-03 21:48:53 status half-configured python-support 1.0.4ubuntu1 +2010-05-03 21:48:57 status installed python-support 1.0.4ubuntu1 +2010-05-03 21:48:58 startup packages configure +2010-05-03 21:48:58 configure update-manager-core 1:0.134.8 1:0.134.8 +2010-05-03 21:48:58 status unpacked update-manager-core 1:0.134.8 +2010-05-03 21:48:58 status unpacked update-manager-core 1:0.134.8 +2010-05-03 21:48:59 status unpacked update-manager-core 1:0.134.8 +2010-05-03 21:48:59 status unpacked update-manager-core 1:0.134.8 +2010-05-03 21:48:59 status half-configured update-manager-core 1:0.134.8 +2010-05-03 21:48:59 status installed update-manager-core 1:0.134.8 +2010-05-03 21:48:59 status triggers-pending python-central 0.6.15ubuntu1 +2010-05-03 21:48:59 status triggers-awaited update-manager-core 1:0.134.8 +2010-05-03 21:48:59 configure chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-03 21:48:59 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-03 21:48:59 status half-configured chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-03 21:49:00 status installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-03 21:49:00 configure libgs8 8.71.dfsg.1-0ubuntu5.1 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:00 status unpacked libgs8 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:00 status half-configured libgs8 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:00 status installed libgs8 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:00 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-03 21:49:00 configure ghostscript 8.71.dfsg.1-0ubuntu5.1 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:00 status unpacked ghostscript 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:00 status half-configured ghostscript 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:00 update-alternatives: run with --install /usr/bin/ps2pdf ps2pdf /usr/bin/ps2pdf14 50 +2010-05-03 21:49:00 update-alternatives: link group ps2pdf updated to point to /usr/bin/ps2pdf14 +2010-05-03 21:49:00 update-alternatives: run with --install /usr/bin/ps2pdf ps2pdf /usr/bin/ps2pdf12 30 +2010-05-03 21:49:00 update-alternatives: run with --install /usr/bin/ps2pdf ps2pdf /usr/bin/ps2pdf13 40 +2010-05-03 21:49:03 status installed ghostscript 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:03 configure ghostscript-cups 8.71.dfsg.1-0ubuntu5.1 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:03 status unpacked ghostscript-cups 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:03 status half-configured ghostscript-cups 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:14 status installed ghostscript-cups 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:14 configure ghostscript-x 8.71.dfsg.1-0ubuntu5.1 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:14 status unpacked ghostscript-x 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:14 status half-configured ghostscript-x 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:14 status installed ghostscript-x 8.71.dfsg.1-0ubuntu5.1 +2010-05-03 21:49:14 configure gwibber-service 2.30.0.1-0ubuntu2 2.30.0.1-0ubuntu2 +2010-05-03 21:49:14 status unpacked gwibber-service 2.30.0.1-0ubuntu2 +2010-05-03 21:49:14 status half-configured gwibber-service 2.30.0.1-0ubuntu2 +2010-05-03 21:49:15 status installed gwibber-service 2.30.0.1-0ubuntu2 +2010-05-03 21:49:15 status triggers-awaited gwibber-service 2.30.0.1-0ubuntu2 +2010-05-03 21:49:15 configure python-cupshelpers 1.2.0+20100408-0ubuntu5.2 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status unpacked python-cupshelpers 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status half-configured python-cupshelpers 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status installed python-cupshelpers 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-03 21:49:15 configure system-config-printer-udev 1.2.0+20100408-0ubuntu5.2 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status unpacked system-config-printer-udev 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status half-configured system-config-printer-udev 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status installed system-config-printer-udev 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 configure hal-cups-utils 1.2.0+20100408-0ubuntu5.2 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status unpacked hal-cups-utils 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status half-configured hal-cups-utils 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status installed hal-cups-utils 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 configure obexd-client 0.22-0ubuntu2 0.22-0ubuntu2 +2010-05-03 21:49:15 status unpacked obexd-client 0.22-0ubuntu2 +2010-05-03 21:49:15 status half-configured obexd-client 0.22-0ubuntu2 +2010-05-03 21:49:15 status installed obexd-client 0.22-0ubuntu2 +2010-05-03 21:49:15 configure system-config-printer-common 1.2.0+20100408-0ubuntu5.2 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status unpacked system-config-printer-common 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:15 status half-configured system-config-printer-common 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:16 status installed system-config-printer-common 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:16 configure system-config-printer-gnome 1.2.0+20100408-0ubuntu5.2 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:16 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:16 status unpacked system-config-printer-gnome 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:16 status half-configured system-config-printer-gnome 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:16 status installed system-config-printer-gnome 1.2.0+20100408-0ubuntu5.2 +2010-05-03 21:49:16 trigproc python-central 0.6.15ubuntu1 0.6.15ubuntu1 +2010-05-03 21:49:16 status half-configured python-central 0.6.15ubuntu1 +2010-05-03 21:49:16 status installed gwibber-service 2.30.0.1-0ubuntu2 +2010-05-03 21:49:16 status installed update-manager-core 1:0.134.8 +2010-05-03 21:49:16 status installed python-central 0.6.15ubuntu1 +2010-05-03 21:49:16 configure update-manager 1:0.134.8 1:0.134.8 +2010-05-03 21:49:16 status unpacked update-manager 1:0.134.8 +2010-05-03 21:49:16 status half-configured update-manager 1:0.134.8 +2010-05-03 21:49:20 status installed update-manager 1:0.134.8 +2010-05-03 21:49:20 status triggers-pending python-central 0.6.15ubuntu1 +2010-05-03 21:49:20 status triggers-awaited update-manager 1:0.134.8 +2010-05-03 21:49:20 configure gwibber 2.30.0.1-0ubuntu2 2.30.0.1-0ubuntu2 +2010-05-03 21:49:20 status unpacked gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:49:20 status unpacked gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:49:20 status half-configured gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:49:21 status installed gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:49:21 status triggers-awaited gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:49:21 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-03 21:49:21 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-03 21:49:21 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-03 21:49:21 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-03 21:49:21 status half-configured python-support 1.0.4ubuntu1 +2010-05-03 21:49:22 status installed python-support 1.0.4ubuntu1 +2010-05-03 21:49:22 trigproc python-central 0.6.15ubuntu1 0.6.15ubuntu1 +2010-05-03 21:49:22 status half-configured python-central 0.6.15ubuntu1 +2010-05-03 21:49:22 status installed gwibber 2.30.0.1-0ubuntu2 +2010-05-03 21:49:22 status installed update-manager 1:0.134.8 +2010-05-03 21:49:22 status installed python-central 0.6.15ubuntu1 +2010-05-03 22:52:22 startup archives install +2010-05-03 22:59:23 startup packages remove +2010-05-03 22:59:23 status installed flashplugin-nonfree 10.0.45.2ubuntu1 +2010-05-03 22:59:23 remove flashplugin-nonfree 10.0.45.2ubuntu1 10.0.45.2ubuntu1 +2010-05-03 22:59:23 status half-configured flashplugin-nonfree 10.0.45.2ubuntu1 +2010-05-03 22:59:23 status half-installed flashplugin-nonfree 10.0.45.2ubuntu1 +2010-05-03 22:59:23 status config-files flashplugin-nonfree 10.0.45.2ubuntu1 +2010-05-03 22:59:24 status config-files flashplugin-nonfree 10.0.45.2ubuntu1 +2010-05-03 22:59:24 status config-files flashplugin-nonfree 10.0.45.2ubuntu1 +2010-05-03 22:59:24 status not-installed flashplugin-nonfree +2010-05-06 00:14:39 startup archives install +2010-05-06 00:14:39 upgrade libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:14:39 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:39 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:39 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:40 status triggers-pending man-db 2.5.7-2 +2010-05-06 00:14:40 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:42 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:42 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:42 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:42 configure libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:14:42 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:43 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:43 status triggers-awaited libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:43 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:14:43 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-06 00:14:43 status half-configured man-db 2.5.7-2 +2010-05-06 00:14:43 status installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:14:44 status installed man-db 2.5.7-2 +2010-05-06 00:14:45 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-06 00:14:45 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:14:45 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:14:55 startup archives install +2010-05-06 00:14:55 upgrade libpurple-bin 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:14:55 status half-configured libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:55 status unpacked libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:55 status half-installed libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:55 status triggers-pending man-db 2.5.7-2 +2010-05-06 00:14:55 status half-installed libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 status half-installed libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 status unpacked libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 status unpacked libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 configure libpurple-bin 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 status unpacked libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 status half-configured libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 status triggers-awaited libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:56 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-06 00:14:56 status half-configured man-db 2.5.7-2 +2010-05-06 00:14:56 status installed libpurple-bin 1:2.6.6-1ubuntu4 +2010-05-06 00:14:57 status installed man-db 2.5.7-2 +2010-05-06 00:19:54 startup archives unpack +2010-05-06 00:19:54 upgrade chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-06 00:19:54 status half-configured chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-06 00:19:54 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-06 00:19:54 status half-installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-06 00:19:55 status half-installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46030-0ubuntu1~ucd1 +2010-05-06 00:19:55 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-06 00:19:55 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-06 00:19:55 upgrade chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-06 00:19:55 status half-configured chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:19:55 status unpacked chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:19:55 status half-installed chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:02 status half-installed chromium-browser-inspector 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:03 status unpacked chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-06 00:20:03 status unpacked chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-06 00:20:03 upgrade chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:20:03 status half-configured chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:03 status unpacked chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:03 status half-installed chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:05 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-06 00:20:06 status half-installed chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:06 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-06 00:20:06 status half-installed chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:06 status triggers-pending man-db 2.5.7-2 +2010-05-06 00:20:06 status half-installed chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:06 status triggers-pending hicolor-icon-theme 0.11-1 +2010-05-06 00:20:06 status half-installed chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:10 status half-installed chromium-browser 5.0.393.0~svn20100430r46027-0ubuntu1~ucd1 +2010-05-06 00:20:10 status unpacked chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:20:10 status unpacked chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:20:11 upgrade libclamav6 0.96+dfsg-2ubuntu1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:11 status half-configured libclamav6 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:11 status unpacked libclamav6 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:11 status half-installed libclamav6 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:12 status half-installed libclamav6 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:12 status unpacked libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:12 status unpacked libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:12 upgrade clamav-daemon 0.96+dfsg-2ubuntu1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:12 status half-configured clamav-daemon 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:13 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:13 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:13 status triggers-pending ureadahead 0.100.0-4.1 +2010-05-06 00:20:13 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:13 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:14 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:14 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:14 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:14 upgrade clamav-base 0.96+dfsg-2ubuntu1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:14 status half-configured clamav-base 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:14 status unpacked clamav-base 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:14 status half-installed clamav-base 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:14 status half-installed clamav-base 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:15 status half-installed clamav-base 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:15 status unpacked clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:15 status unpacked clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:15 upgrade clamav-freshclam 0.96+dfsg-2ubuntu1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:15 status half-configured clamav-freshclam 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:16 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:16 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:16 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:16 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:16 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:17 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:17 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:17 upgrade clamav 0.96+dfsg-2ubuntu1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:17 status half-configured clamav 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:17 status unpacked clamav 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:17 status half-installed clamav 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:17 status half-installed clamav 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:18 status half-installed clamav 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:18 status unpacked clamav 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:18 status unpacked clamav 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:18 upgrade clamav-docs 0.96+dfsg-2ubuntu1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:18 status half-configured clamav-docs 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:18 status unpacked clamav-docs 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:18 status half-installed clamav-docs 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:22 status half-installed clamav-docs 0.96+dfsg-2ubuntu1 +2010-05-06 00:20:23 status unpacked clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:23 status unpacked clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:20:23 upgrade firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:20:23 status half-configured firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:23 status unpacked firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:23 status half-installed firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:23 status half-installed firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:23 status half-installed firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:24 status half-installed firefox-branding 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:24 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:20:24 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:20:24 upgrade firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:20:24 status half-configured firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:24 status unpacked firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:24 status half-installed firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:36 status half-installed firefox 3.6.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:20:37 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:20:37 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:20:37 upgrade libgp11-0 2.92.92.is.2.30.0-0ubuntu3 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:37 status half-configured libgp11-0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:37 status unpacked libgp11-0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:37 status half-installed libgp11-0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:38 status half-installed libgp11-0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:38 status unpacked libgp11-0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:38 status unpacked libgp11-0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:38 upgrade libgcr0 2.92.92.is.2.30.0-0ubuntu3 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:38 status half-configured libgcr0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:38 status unpacked libgcr0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:38 status half-installed libgcr0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:39 status half-installed libgcr0 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:39 status unpacked libgcr0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:39 status unpacked libgcr0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:39 upgrade gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:39 status half-configured gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:45 status unpacked gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:45 status half-installed gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:45 status half-installed gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:47 status half-installed gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:20:47 status unpacked gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:47 status unpacked gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:20:47 upgrade libgvfscommon0 1.6.0+git20100414-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:20:47 status half-configured libgvfscommon0 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:47 status unpacked libgvfscommon0 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:47 status half-installed libgvfscommon0 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:48 status half-installed libgvfscommon0 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:48 status unpacked libgvfscommon0 1.6.1-0ubuntu1 +2010-05-06 00:20:48 status unpacked libgvfscommon0 1.6.1-0ubuntu1 +2010-05-06 00:20:48 upgrade gvfs-fuse 1.6.0+git20100414-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:20:48 status half-configured gvfs-fuse 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:48 status unpacked gvfs-fuse 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:48 status half-installed gvfs-fuse 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:48 status half-installed gvfs-fuse 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:48 status unpacked gvfs-fuse 1.6.1-0ubuntu1 +2010-05-06 00:20:49 status unpacked gvfs-fuse 1.6.1-0ubuntu1 +2010-05-06 00:20:49 upgrade gvfs-bin 1.6.0+git20100414-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:20:49 status half-configured gvfs-bin 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:49 status unpacked gvfs-bin 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:49 status half-installed gvfs-bin 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:50 status half-installed gvfs-bin 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:50 status unpacked gvfs-bin 1.6.1-0ubuntu1 +2010-05-06 00:20:50 status unpacked gvfs-bin 1.6.1-0ubuntu1 +2010-05-06 00:20:50 upgrade gvfs-backends 1.6.0+git20100414-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:20:50 status half-configured gvfs-backends 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:50 status unpacked gvfs-backends 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:50 status half-installed gvfs-backends 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:52 status half-installed gvfs-backends 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:52 status unpacked gvfs-backends 1.6.1-0ubuntu1 +2010-05-06 00:20:53 status unpacked gvfs-backends 1.6.1-0ubuntu1 +2010-05-06 00:20:53 upgrade gvfs 1.6.0+git20100414-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:20:53 status half-configured gvfs 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:53 status unpacked gvfs 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:53 status half-installed gvfs 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:53 status triggers-pending libglib2.0-0 2.24.0-0ubuntu4 +2010-05-06 00:20:53 status half-installed gvfs 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:54 status half-installed gvfs 1.6.0+git20100414-0ubuntu1 +2010-05-06 00:20:54 status unpacked gvfs 1.6.1-0ubuntu1 +2010-05-06 00:20:54 status unpacked gvfs 1.6.1-0ubuntu1 +2010-05-06 00:20:54 upgrade gwibber 2.30.0.1-0ubuntu2 2.30.0.1-0ubuntu3 +2010-05-06 00:20:54 status half-configured gwibber 2.30.0.1-0ubuntu2 +2010-05-06 00:20:55 status unpacked gwibber 2.30.0.1-0ubuntu2 +2010-05-06 00:20:55 status half-installed gwibber 2.30.0.1-0ubuntu2 +2010-05-06 00:20:55 status half-installed gwibber 2.30.0.1-0ubuntu2 +2010-05-06 00:20:55 status half-installed gwibber 2.30.0.1-0ubuntu2 +2010-05-06 00:20:55 status half-installed gwibber 2.30.0.1-0ubuntu2 +2010-05-06 00:21:04 status half-installed gwibber 2.30.0.1-0ubuntu2 +2010-05-06 00:21:04 status unpacked gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:21:04 status unpacked gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:21:04 upgrade gwibber-service 2.30.0.1-0ubuntu2 2.30.0.1-0ubuntu3 +2010-05-06 00:21:04 status half-configured gwibber-service 2.30.0.1-0ubuntu2 +2010-05-06 00:21:05 status unpacked gwibber-service 2.30.0.1-0ubuntu2 +2010-05-06 00:21:05 status half-installed gwibber-service 2.30.0.1-0ubuntu2 +2010-05-06 00:21:07 status half-installed gwibber-service 2.30.0.1-0ubuntu2 +2010-05-06 00:21:07 status unpacked gwibber-service 2.30.0.1-0ubuntu3 +2010-05-06 00:21:07 status unpacked gwibber-service 2.30.0.1-0ubuntu3 +2010-05-06 00:21:07 upgrade php5-mysql 5.3.2-1ubuntu4 5.3.2-1ubuntu4.1 +2010-05-06 00:21:07 status half-configured php5-mysql 5.3.2-1ubuntu4 +2010-05-06 00:21:07 status unpacked php5-mysql 5.3.2-1ubuntu4 +2010-05-06 00:21:07 status half-installed php5-mysql 5.3.2-1ubuntu4 +2010-05-06 00:21:08 status triggers-pending libapache2-mod-php5 5.3.2-1ubuntu4 +2010-05-06 00:21:08 status half-installed php5-mysql 5.3.2-1ubuntu4 +2010-05-06 00:21:08 status half-installed php5-mysql 5.3.2-1ubuntu4 +2010-05-06 00:21:08 status unpacked php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:21:08 status unpacked php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:21:08 upgrade php5-gd 5.3.2-1ubuntu4 5.3.2-1ubuntu4.1 +2010-05-06 00:21:08 status half-configured php5-gd 5.3.2-1ubuntu4 +2010-05-06 00:21:09 status unpacked php5-gd 5.3.2-1ubuntu4 +2010-05-06 00:21:09 status half-installed php5-gd 5.3.2-1ubuntu4 +2010-05-06 00:21:09 status half-installed php5-gd 5.3.2-1ubuntu4 +2010-05-06 00:21:09 status half-installed php5-gd 5.3.2-1ubuntu4 +2010-05-06 00:21:09 status unpacked php5-gd 5.3.2-1ubuntu4.1 +2010-05-06 00:21:09 status unpacked php5-gd 5.3.2-1ubuntu4.1 +2010-05-06 00:21:09 upgrade libapache2-mod-php5 5.3.2-1ubuntu4 5.3.2-1ubuntu4.1 +2010-05-06 00:21:09 status half-configured libapache2-mod-php5 5.3.2-1ubuntu4 +2010-05-06 00:21:09 status unpacked libapache2-mod-php5 5.3.2-1ubuntu4 +2010-05-06 00:21:09 status half-installed libapache2-mod-php5 5.3.2-1ubuntu4 +2010-05-06 00:21:10 status half-installed libapache2-mod-php5 5.3.2-1ubuntu4 +2010-05-06 00:21:10 status unpacked libapache2-mod-php5 5.3.2-1ubuntu4.1 +2010-05-06 00:21:10 status unpacked libapache2-mod-php5 5.3.2-1ubuntu4.1 +2010-05-06 00:21:10 upgrade php5-common 5.3.2-1ubuntu4 5.3.2-1ubuntu4.1 +2010-05-06 00:21:10 status half-configured php5-common 5.3.2-1ubuntu4 +2010-05-06 00:21:10 status unpacked php5-common 5.3.2-1ubuntu4 +2010-05-06 00:21:10 status half-installed php5-common 5.3.2-1ubuntu4 +2010-05-06 00:21:11 status half-installed php5-common 5.3.2-1ubuntu4 +2010-05-06 00:21:11 status unpacked php5-common 5.3.2-1ubuntu4.1 +2010-05-06 00:21:12 status unpacked php5-common 5.3.2-1ubuntu4.1 +2010-05-06 00:21:12 upgrade libgdata-common 0.5.1-1 0.5.2-0ubuntu1 +2010-05-06 00:21:12 status half-configured libgdata-common 0.5.1-1 +2010-05-06 00:21:12 status unpacked libgdata-common 0.5.1-1 +2010-05-06 00:21:12 status half-installed libgdata-common 0.5.1-1 +2010-05-06 00:21:12 status half-installed libgdata-common 0.5.1-1 +2010-05-06 00:21:12 status unpacked libgdata-common 0.5.2-0ubuntu1 +2010-05-06 00:21:12 status unpacked libgdata-common 0.5.2-0ubuntu1 +2010-05-06 00:21:13 upgrade libgdata6 0.5.1-1 0.5.2-0ubuntu1 +2010-05-06 00:21:13 status half-configured libgdata6 0.5.1-1 +2010-05-06 00:21:13 status unpacked libgdata6 0.5.1-1 +2010-05-06 00:21:13 status half-installed libgdata6 0.5.1-1 +2010-05-06 00:21:13 status half-installed libgdata6 0.5.1-1 +2010-05-06 00:21:13 status unpacked libgdata6 0.5.2-0ubuntu1 +2010-05-06 00:21:13 status unpacked libgdata6 0.5.2-0ubuntu1 +2010-05-06 00:21:13 upgrade libpam-gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:21:13 status half-configured libpam-gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:21:14 status unpacked libpam-gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:21:14 status half-installed libpam-gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:21:14 status half-installed libpam-gnome-keyring 2.92.92.is.2.30.0-0ubuntu3 +2010-05-06 00:21:14 status unpacked libpam-gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:21:14 status unpacked libpam-gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:21:15 upgrade libpoppler5 0.12.4-0ubuntu4 0.12.4-0ubuntu5 +2010-05-06 00:21:15 status half-configured libpoppler5 0.12.4-0ubuntu4 +2010-05-06 00:21:15 status unpacked libpoppler5 0.12.4-0ubuntu4 +2010-05-06 00:21:15 status half-installed libpoppler5 0.12.4-0ubuntu4 +2010-05-06 00:21:15 status half-installed libpoppler5 0.12.4-0ubuntu4 +2010-05-06 00:21:15 status unpacked libpoppler5 0.12.4-0ubuntu5 +2010-05-06 00:21:15 status unpacked libpoppler5 0.12.4-0ubuntu5 +2010-05-06 00:21:16 upgrade libpoppler-glib4 0.12.4-0ubuntu4 0.12.4-0ubuntu5 +2010-05-06 00:21:16 status half-configured libpoppler-glib4 0.12.4-0ubuntu4 +2010-05-06 00:21:16 status unpacked libpoppler-glib4 0.12.4-0ubuntu4 +2010-05-06 00:21:16 status half-installed libpoppler-glib4 0.12.4-0ubuntu4 +2010-05-06 00:21:16 status half-installed libpoppler-glib4 0.12.4-0ubuntu4 +2010-05-06 00:21:17 status unpacked libpoppler-glib4 0.12.4-0ubuntu5 +2010-05-06 00:21:17 status unpacked libpoppler-glib4 0.12.4-0ubuntu5 +2010-05-06 00:21:17 upgrade libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:21:17 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:21:17 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:21:17 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:21:17 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:21:21 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:21:21 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:21:21 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:21:21 upgrade nvidia-current-modaliases 195.36.15-0ubuntu2 195.36.15-0ubuntu3 +2010-05-06 00:21:21 status half-configured nvidia-current-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:21 status unpacked nvidia-current-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:21 status half-installed nvidia-current-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:21 status half-installed nvidia-current-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:22 status unpacked nvidia-current-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:21:22 status unpacked nvidia-current-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:21:22 upgrade nvidia-185-modaliases 195.36.15-0ubuntu2 195.36.15-0ubuntu3 +2010-05-06 00:21:22 status half-configured nvidia-185-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:22 status unpacked nvidia-185-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:22 status half-installed nvidia-185-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:22 status half-installed nvidia-185-modaliases 195.36.15-0ubuntu2 +2010-05-06 00:21:22 status unpacked nvidia-185-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:21:22 status unpacked nvidia-185-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:21:22 upgrade poppler-utils 0.12.4-0ubuntu4 0.12.4-0ubuntu5 +2010-05-06 00:21:22 status half-configured poppler-utils 0.12.4-0ubuntu4 +2010-05-06 00:21:23 status unpacked poppler-utils 0.12.4-0ubuntu4 +2010-05-06 00:21:23 status half-installed poppler-utils 0.12.4-0ubuntu4 +2010-05-06 00:21:23 status half-installed poppler-utils 0.12.4-0ubuntu4 +2010-05-06 00:21:23 status half-installed poppler-utils 0.12.4-0ubuntu4 +2010-05-06 00:21:24 status unpacked poppler-utils 0.12.4-0ubuntu5 +2010-05-06 00:21:24 status unpacked poppler-utils 0.12.4-0ubuntu5 +2010-05-06 00:21:24 upgrade synaptic 0.63.1ubuntu6 0.63.1ubuntu7 +2010-05-06 00:21:24 status half-configured synaptic 0.63.1ubuntu6 +2010-05-06 00:21:24 status unpacked synaptic 0.63.1ubuntu6 +2010-05-06 00:21:24 status half-installed synaptic 0.63.1ubuntu6 +2010-05-06 00:21:24 status half-installed synaptic 0.63.1ubuntu6 +2010-05-06 00:21:24 status half-installed synaptic 0.63.1ubuntu6 +2010-05-06 00:21:24 status half-installed synaptic 0.63.1ubuntu6 +2010-05-06 00:21:24 status half-installed synaptic 0.63.1ubuntu6 +2010-05-06 00:21:29 status half-installed synaptic 0.63.1ubuntu6 +2010-05-06 00:21:29 status unpacked synaptic 0.63.1ubuntu7 +2010-05-06 00:21:29 status unpacked synaptic 0.63.1ubuntu7 +2010-05-06 00:21:29 upgrade thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:29 status half-configured thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:29 status unpacked thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:30 status half-installed thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:30 status half-installed thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:30 status half-installed thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:30 status half-installed thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:51 status half-installed thunderbird 3.0.5~hg20100429r4820+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:51 status unpacked thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:51 status unpacked thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:21:52 upgrade totem-plugins 2.30.0git20100413-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:21:52 status half-configured totem-plugins 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:52 status unpacked totem-plugins 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:52 status half-installed totem-plugins 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:54 status half-installed totem-plugins 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:54 status unpacked totem-plugins 2.30.1-0ubuntu1 +2010-05-06 00:21:54 status unpacked totem-plugins 2.30.1-0ubuntu1 +2010-05-06 00:21:55 upgrade totem-mozilla 2.30.0git20100413-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:21:55 status half-configured totem-mozilla 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:55 status unpacked totem-mozilla 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:55 status half-installed totem-mozilla 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:55 status half-installed totem-mozilla 2.30.0git20100413-0ubuntu1 +2010-05-06 00:21:55 status unpacked totem-mozilla 2.30.1-0ubuntu1 +2010-05-06 00:21:55 status unpacked totem-mozilla 2.30.1-0ubuntu1 +2010-05-06 00:21:56 upgrade totem-common 2.30.0git20100413-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:21:56 status half-configured totem-common 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:02 status unpacked totem-common 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:02 status half-installed totem-common 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:02 status half-installed totem-common 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:02 status half-installed totem-common 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:05 status half-installed totem-common 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:05 status unpacked totem-common 2.30.1-0ubuntu1 +2010-05-06 00:22:06 status unpacked totem-common 2.30.1-0ubuntu1 +2010-05-06 00:22:06 upgrade totem 2.30.0git20100413-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:22:06 status half-configured totem 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:06 status unpacked totem 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:06 status half-installed totem 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:08 status half-installed totem 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:08 status half-installed totem 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:09 status half-installed totem 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:09 status unpacked totem 2.30.1-0ubuntu1 +2010-05-06 00:22:09 status unpacked totem 2.30.1-0ubuntu1 +2010-05-06 00:22:09 upgrade totem-gstreamer 2.30.0git20100413-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:22:09 status half-configured totem-gstreamer 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:10 status unpacked totem-gstreamer 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:10 status half-installed totem-gstreamer 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:10 status half-installed totem-gstreamer 2.30.0git20100413-0ubuntu1 +2010-05-06 00:22:10 status unpacked totem-gstreamer 2.30.1-0ubuntu1 +2010-05-06 00:22:10 status unpacked totem-gstreamer 2.30.1-0ubuntu1 +2010-05-06 00:22:10 upgrade xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:10 status half-configured xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:11 update-alternatives: run with --remove xulrunner /usr/bin/xulrunner-1.9.2 +2010-05-06 00:22:11 update-alternatives: link group xulrunner updated to point to /usr/lib/xulrunner/xulrunner +2010-05-06 00:22:11 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:11 status half-installed xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:19 status half-installed xulrunner-1.9.2 1.9.2.5~hg20100429r34148+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:20 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:20 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:20 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-06 00:22:20 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-06 00:22:21 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-06 00:22:21 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-06 00:22:21 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-06 00:22:21 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-06 00:22:22 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-06 00:22:22 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-06 00:22:22 status half-configured man-db 2.5.7-2 +2010-05-06 00:22:24 status installed man-db 2.5.7-2 +2010-05-06 00:22:24 trigproc hicolor-icon-theme 0.11-1 0.11-1 +2010-05-06 00:22:24 status half-configured hicolor-icon-theme 0.11-1 +2010-05-06 00:22:27 status installed hicolor-icon-theme 0.11-1 +2010-05-06 00:22:27 trigproc ureadahead 0.100.0-4.1 0.100.0-4.1 +2010-05-06 00:22:27 status half-configured ureadahead 0.100.0-4.1 +2010-05-06 00:22:27 status installed ureadahead 0.100.0-4.1 +2010-05-06 00:22:27 trigproc libglib2.0-0 2.24.0-0ubuntu4 2.24.0-0ubuntu4 +2010-05-06 00:22:27 status half-configured libglib2.0-0 2.24.0-0ubuntu4 +2010-05-06 00:22:27 status installed libglib2.0-0 2.24.0-0ubuntu4 +2010-05-06 00:22:27 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-06 00:22:27 status half-configured python-support 1.0.4ubuntu1 +2010-05-06 00:22:31 status installed python-support 1.0.4ubuntu1 +2010-05-06 00:22:32 startup packages configure +2010-05-06 00:22:32 configure libclamav6 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:32 status unpacked libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:32 status half-configured libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:33 status installed libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:33 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:22:33 configure clamav-base 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:33 status unpacked clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:33 status half-configured clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:34 status installed clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:34 configure clamav-freshclam 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:34 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:34 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:35 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:35 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:35 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:35 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:35 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:35 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:35 status half-configured clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 status installed clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 configure clamav-daemon 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:37 status half-configured clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:38 status installed clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 configure clamav 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 status unpacked clamav 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 status half-configured clamav 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 status installed clamav 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 configure clamav-docs 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 status unpacked clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 status half-configured clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 status installed clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-06 00:22:39 configure libgp11-0 2.92.92.is.2.30.1-0ubuntu1 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:39 status unpacked libgp11-0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:39 status half-configured libgp11-0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:39 status installed libgp11-0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:39 configure libgcr0 2.92.92.is.2.30.1-0ubuntu1 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:39 status unpacked libgcr0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:39 status half-configured libgcr0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:39 status installed libgcr0 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 configure gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 status unpacked gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 status unpacked gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 status unpacked gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 status unpacked gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 status half-configured gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 status installed gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:40 configure libgvfscommon0 1.6.1-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:22:40 status unpacked libgvfscommon0 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status half-configured libgvfscommon0 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status installed libgvfscommon0 1.6.1-0ubuntu1 +2010-05-06 00:22:41 configure gvfs 1.6.1-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status unpacked gvfs 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status half-configured gvfs 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status installed gvfs 1.6.1-0ubuntu1 +2010-05-06 00:22:41 configure gvfs-fuse 1.6.1-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status unpacked gvfs-fuse 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status half-configured gvfs-fuse 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status installed gvfs-fuse 1.6.1-0ubuntu1 +2010-05-06 00:22:41 configure gvfs-bin 1.6.1-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status unpacked gvfs-bin 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status unpacked gvfs-bin 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status half-configured gvfs-bin 1.6.1-0ubuntu1 +2010-05-06 00:22:41 status installed gvfs-bin 1.6.1-0ubuntu1 +2010-05-06 00:22:43 configure gvfs-backends 1.6.1-0ubuntu1 1.6.1-0ubuntu1 +2010-05-06 00:22:43 status unpacked gvfs-backends 1.6.1-0ubuntu1 +2010-05-06 00:22:43 status half-configured gvfs-backends 1.6.1-0ubuntu1 +2010-05-06 00:22:44 status installed gvfs-backends 1.6.1-0ubuntu1 +2010-05-06 00:22:44 configure gwibber-service 2.30.0.1-0ubuntu3 2.30.0.1-0ubuntu3 +2010-05-06 00:22:44 status unpacked gwibber-service 2.30.0.1-0ubuntu3 +2010-05-06 00:22:44 status half-configured gwibber-service 2.30.0.1-0ubuntu3 +2010-05-06 00:22:44 status installed gwibber-service 2.30.0.1-0ubuntu3 +2010-05-06 00:22:44 status triggers-pending python-central 0.6.15ubuntu1 +2010-05-06 00:22:44 status triggers-awaited gwibber-service 2.30.0.1-0ubuntu3 +2010-05-06 00:22:44 configure php5-common 5.3.2-1ubuntu4.1 5.3.2-1ubuntu4.1 +2010-05-06 00:22:44 status unpacked php5-common 5.3.2-1ubuntu4.1 +2010-05-06 00:22:44 status unpacked php5-common 5.3.2-1ubuntu4.1 +2010-05-06 00:22:44 status unpacked php5-common 5.3.2-1ubuntu4.1 +2010-05-06 00:22:45 status half-configured php5-common 5.3.2-1ubuntu4.1 +2010-05-06 00:22:45 status installed php5-common 5.3.2-1ubuntu4.1 +2010-05-06 00:22:45 configure libapache2-mod-php5 5.3.2-1ubuntu4.1 5.3.2-1ubuntu4.1 +2010-05-06 00:22:45 status unpacked libapache2-mod-php5 5.3.2-1ubuntu4.1 +2010-05-06 00:22:45 status unpacked libapache2-mod-php5 5.3.2-1ubuntu4.1 +2010-05-06 00:22:45 status unpacked libapache2-mod-php5 5.3.2-1ubuntu4.1 +2010-05-06 00:22:45 status half-configured libapache2-mod-php5 5.3.2-1ubuntu4.1 +2010-05-06 00:22:46 status installed libapache2-mod-php5 5.3.2-1ubuntu4.1 +2010-05-06 00:22:46 configure php5-mysql 5.3.2-1ubuntu4.1 5.3.2-1ubuntu4.1 +2010-05-06 00:22:46 status unpacked php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:22:46 status unpacked php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:22:46 status unpacked php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:22:46 status unpacked php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:22:46 status half-configured php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:22:47 status installed php5-mysql 5.3.2-1ubuntu4.1 +2010-05-06 00:22:47 configure php5-gd 5.3.2-1ubuntu4.1 5.3.2-1ubuntu4.1 +2010-05-06 00:22:47 status unpacked php5-gd 5.3.2-1ubuntu4.1 +2010-05-06 00:22:47 status unpacked php5-gd 5.3.2-1ubuntu4.1 +2010-05-06 00:22:47 status half-configured php5-gd 5.3.2-1ubuntu4.1 +2010-05-06 00:22:47 status installed php5-gd 5.3.2-1ubuntu4.1 +2010-05-06 00:22:47 configure libgdata-common 0.5.2-0ubuntu1 0.5.2-0ubuntu1 +2010-05-06 00:22:47 status unpacked libgdata-common 0.5.2-0ubuntu1 +2010-05-06 00:22:47 status half-configured libgdata-common 0.5.2-0ubuntu1 +2010-05-06 00:22:47 status installed libgdata-common 0.5.2-0ubuntu1 +2010-05-06 00:22:47 configure libgdata6 0.5.2-0ubuntu1 0.5.2-0ubuntu1 +2010-05-06 00:22:47 status unpacked libgdata6 0.5.2-0ubuntu1 +2010-05-06 00:22:47 status half-configured libgdata6 0.5.2-0ubuntu1 +2010-05-06 00:22:47 status installed libgdata6 0.5.2-0ubuntu1 +2010-05-06 00:22:47 configure libpam-gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:47 status unpacked libpam-gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:47 status half-configured libpam-gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:48 status installed libpam-gnome-keyring 2.92.92.is.2.30.1-0ubuntu1 +2010-05-06 00:22:49 configure libpoppler5 0.12.4-0ubuntu5 0.12.4-0ubuntu5 +2010-05-06 00:22:49 status unpacked libpoppler5 0.12.4-0ubuntu5 +2010-05-06 00:22:49 status half-configured libpoppler5 0.12.4-0ubuntu5 +2010-05-06 00:22:49 status installed libpoppler5 0.12.4-0ubuntu5 +2010-05-06 00:22:49 configure libpoppler-glib4 0.12.4-0ubuntu5 0.12.4-0ubuntu5 +2010-05-06 00:22:49 status unpacked libpoppler-glib4 0.12.4-0ubuntu5 +2010-05-06 00:22:49 status half-configured libpoppler-glib4 0.12.4-0ubuntu5 +2010-05-06 00:22:49 status installed libpoppler-glib4 0.12.4-0ubuntu5 +2010-05-06 00:22:49 configure libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:22:49 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:22:49 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:22:49 status installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:22:49 configure nvidia-current-modaliases 195.36.15-0ubuntu3 195.36.15-0ubuntu3 +2010-05-06 00:22:49 status unpacked nvidia-current-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:22:49 status half-configured nvidia-current-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:22:49 status installed nvidia-current-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:22:49 configure nvidia-185-modaliases 195.36.15-0ubuntu3 195.36.15-0ubuntu3 +2010-05-06 00:22:49 status unpacked nvidia-185-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:22:49 status half-configured nvidia-185-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:22:49 status installed nvidia-185-modaliases 195.36.15-0ubuntu3 +2010-05-06 00:22:50 configure poppler-utils 0.12.4-0ubuntu5 0.12.4-0ubuntu5 +2010-05-06 00:22:50 status unpacked poppler-utils 0.12.4-0ubuntu5 +2010-05-06 00:22:50 status half-configured poppler-utils 0.12.4-0ubuntu5 +2010-05-06 00:22:50 status installed poppler-utils 0.12.4-0ubuntu5 +2010-05-06 00:22:50 configure synaptic 0.63.1ubuntu7 0.63.1ubuntu7 +2010-05-06 00:22:50 status unpacked synaptic 0.63.1ubuntu7 +2010-05-06 00:22:50 status half-configured synaptic 0.63.1ubuntu7 +2010-05-06 00:22:50 status installed synaptic 0.63.1ubuntu7 +2010-05-06 00:22:50 configure thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:50 status unpacked thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:50 status unpacked thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:50 status half-configured thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:50 status installed thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-06 00:22:50 configure totem-common 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:22:50 status unpacked totem-common 2.30.1-0ubuntu1 +2010-05-06 00:22:50 status half-configured totem-common 2.30.1-0ubuntu1 +2010-05-06 00:22:55 status installed totem-common 2.30.1-0ubuntu1 +2010-05-06 00:22:55 configure totem 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:22:55 status unpacked totem 2.30.1-0ubuntu1 +2010-05-06 00:22:55 status half-configured totem 2.30.1-0ubuntu1 +2010-05-06 00:22:55 status installed totem 2.30.1-0ubuntu1 +2010-05-06 00:22:56 configure totem-plugins 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status unpacked totem-plugins 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status half-configured totem-plugins 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status installed totem-plugins 2.30.1-0ubuntu1 +2010-05-06 00:22:56 configure totem-mozilla 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status unpacked totem-mozilla 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status half-configured totem-mozilla 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status installed totem-mozilla 2.30.1-0ubuntu1 +2010-05-06 00:22:56 configure totem-gstreamer 2.30.1-0ubuntu1 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status unpacked totem-gstreamer 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status half-configured totem-gstreamer 2.30.1-0ubuntu1 +2010-05-06 00:22:56 status installed totem-gstreamer 2.30.1-0ubuntu1 +2010-05-06 00:22:56 configure xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:56 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:56 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:56 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:56 status half-configured xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:57 update-alternatives: run with --install /usr/bin/xulrunner xulrunner /usr/bin/xulrunner-1.9.2 50 +2010-05-06 00:22:57 update-alternatives: link group xulrunner updated to point to /usr/bin/xulrunner-1.9.2 +2010-05-06 00:22:57 status installed xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:57 trigproc python-central 0.6.15ubuntu1 0.6.15ubuntu1 +2010-05-06 00:22:57 status half-configured python-central 0.6.15ubuntu1 +2010-05-06 00:22:57 status installed gwibber-service 2.30.0.1-0ubuntu3 +2010-05-06 00:22:57 status installed python-central 0.6.15ubuntu1 +2010-05-06 00:22:57 configure gwibber 2.30.0.1-0ubuntu3 2.30.0.1-0ubuntu3 +2010-05-06 00:22:57 status unpacked gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:22:57 status unpacked gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:22:57 status half-configured gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:22:58 status installed gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:22:58 status triggers-pending python-central 0.6.15ubuntu1 +2010-05-06 00:22:58 status triggers-awaited gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:22:58 trigproc python-central 0.6.15ubuntu1 0.6.15ubuntu1 +2010-05-06 00:22:58 status half-configured python-central 0.6.15ubuntu1 +2010-05-06 00:22:58 status installed gwibber 2.30.0.1-0ubuntu3 +2010-05-06 00:22:58 status installed python-central 0.6.15ubuntu1 +2010-05-06 00:22:59 configure firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:59 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:59 status half-configured firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:59 status installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:59 configure chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-06 00:22:59 status unpacked chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-06 00:22:59 status half-configured chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-06 00:22:59 status installed chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-06 00:22:59 configure chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-06 00:22:59 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-06 00:22:59 status half-configured chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-06 00:22:59 status installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-06 00:22:59 configure firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:59 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:59 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:22:59 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 status half-configured firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:00 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox 40 +2010-05-06 00:23:02 status installed firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-06 00:23:02 configure chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:23:02 status unpacked chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:23:02 status unpacked chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:23:02 status half-configured chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:23:02 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/chromium-browser 40 +2010-05-06 00:23:02 update-alternatives: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/chromium-browser 40 +2010-05-06 00:23:02 status installed chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-06 00:23:02 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-06 00:23:02 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:23:02 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:32:21 startup archives install +2010-05-06 00:32:21 upgrade libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:32:21 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:21 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:21 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:22 status triggers-pending man-db 2.5.7-2 +2010-05-06 00:32:22 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 configure libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 status triggers-awaited libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:25 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:32:25 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-06 00:32:25 status half-configured man-db 2.5.7-2 +2010-05-06 00:32:25 status installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-06 00:32:26 status installed man-db 2.5.7-2 +2010-05-06 00:32:27 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-06 00:32:27 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:32:27 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:35:56 startup packages remove +2010-05-06 00:35:56 status installed purifyeps 1.0-1 +2010-05-06 00:35:57 remove purifyeps 1.0-1 1.0-1 +2010-05-06 00:35:57 status half-configured purifyeps 1.0-1 +2010-05-06 00:35:57 status half-installed purifyeps 1.0-1 +2010-05-06 00:35:57 status triggers-pending man-db 2.5.7-2 +2010-05-06 00:35:57 status half-installed purifyeps 1.0-1 +2010-05-06 00:35:57 status config-files purifyeps 1.0-1 +2010-05-06 00:35:57 status config-files purifyeps 1.0-1 +2010-05-06 00:35:57 status config-files purifyeps 1.0-1 +2010-05-06 00:35:57 status config-files purifyeps 1.0-1 +2010-05-06 00:35:58 status not-installed purifyeps +2010-05-06 00:35:58 status installed pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 remove pstoedit 3.50-0ubuntu1 3.50-0ubuntu1 +2010-05-06 00:35:58 status half-configured pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status half-installed pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status triggers-pending doc-base 0.9.5 +2010-05-06 00:35:58 status half-installed pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status half-installed pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status config-files pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status config-files pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status config-files pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status config-files pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status config-files pstoedit 3.50-0ubuntu1 +2010-05-06 00:35:58 status not-installed pstoedit +2010-05-06 00:35:58 status installed libpstoedit0c2a 3.50-0ubuntu1 +2010-05-06 00:35:58 remove libpstoedit0c2a 3.50-0ubuntu1 3.50-0ubuntu1 +2010-05-06 00:35:58 status half-configured libpstoedit0c2a 3.50-0ubuntu1 +2010-05-06 00:35:58 status half-installed libpstoedit0c2a 3.50-0ubuntu1 +2010-05-06 00:35:59 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:35:59 status config-files libpstoedit0c2a 3.50-0ubuntu1 +2010-05-06 00:35:59 status config-files libpstoedit0c2a 3.50-0ubuntu1 +2010-05-06 00:35:59 status installed libmagick++2 7:6.5.7.8-1ubuntu1 +2010-05-06 00:35:59 remove libmagick++2 7:6.5.7.8-1ubuntu1 7:6.5.7.8-1ubuntu1 +2010-05-06 00:35:59 status half-configured libmagick++2 7:6.5.7.8-1ubuntu1 +2010-05-06 00:35:59 status half-installed libmagick++2 7:6.5.7.8-1ubuntu1 +2010-05-06 00:35:59 status config-files libmagick++2 7:6.5.7.8-1ubuntu1 +2010-05-06 00:35:59 status config-files libmagick++2 7:6.5.7.8-1ubuntu1 +2010-05-06 00:35:59 status installed libplot2c2 2.6-0ubuntu1 +2010-05-06 00:36:00 remove libplot2c2 2.6-0ubuntu1 2.6-0ubuntu1 +2010-05-06 00:36:00 status half-configured libplot2c2 2.6-0ubuntu1 +2010-05-06 00:36:00 status half-installed libplot2c2 2.6-0ubuntu1 +2010-05-06 00:36:00 status config-files libplot2c2 2.6-0ubuntu1 +2010-05-06 00:36:00 status config-files libplot2c2 2.6-0ubuntu1 +2010-05-06 00:36:00 status installed linux-headers-2.6.32-21-generic 2.6.32-21.32 +2010-05-06 00:36:00 remove linux-headers-2.6.32-21-generic 2.6.32-21.32 2.6.32-21.32 +2010-05-06 00:36:00 status half-configured linux-headers-2.6.32-21-generic 2.6.32-21.32 +2010-05-06 00:36:00 status half-installed linux-headers-2.6.32-21-generic 2.6.32-21.32 +2010-05-06 00:36:02 status config-files linux-headers-2.6.32-21-generic 2.6.32-21.32 +2010-05-06 00:36:02 status config-files linux-headers-2.6.32-21-generic 2.6.32-21.32 +2010-05-06 00:36:02 status config-files linux-headers-2.6.32-21-generic 2.6.32-21.32 +2010-05-06 00:36:02 status not-installed linux-headers-2.6.32-21-generic +2010-05-06 00:36:02 status installed linux-headers-2.6.32-21 2.6.32-21.32 +2010-05-06 00:36:02 remove linux-headers-2.6.32-21 2.6.32-21.32 2.6.32-21.32 +2010-05-06 00:36:02 status half-configured linux-headers-2.6.32-21 2.6.32-21.32 +2010-05-06 00:36:02 status half-installed linux-headers-2.6.32-21 2.6.32-21.32 +2010-05-06 00:36:04 status config-files linux-headers-2.6.32-21 2.6.32-21.32 +2010-05-06 00:36:04 status config-files linux-headers-2.6.32-21 2.6.32-21.32 +2010-05-06 00:36:04 status config-files linux-headers-2.6.32-21 2.6.32-21.32 +2010-05-06 00:36:04 status not-installed linux-headers-2.6.32-21 +2010-05-06 00:36:04 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-06 00:36:04 status half-configured man-db 2.5.7-2 +2010-05-06 00:36:05 status installed man-db 2.5.7-2 +2010-05-06 00:36:06 trigproc doc-base 0.9.5 0.9.5 +2010-05-06 00:36:06 status half-configured doc-base 0.9.5 +2010-05-06 00:36:06 status installed doc-base 0.9.5 +2010-05-06 00:36:06 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-06 00:36:06 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-06 00:36:07 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-07 01:28:28 startup archives unpack +2010-05-07 01:28:35 upgrade chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:28:35 status half-configured chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-07 01:28:36 status unpacked chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-07 01:28:36 status half-installed chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-07 01:28:42 status half-installed chromium-browser-inspector 5.0.396.0~svn20100504r46318-0ubuntu1~ucd1 +2010-05-07 01:28:42 status unpacked chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:28:42 status unpacked chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:28:43 upgrade chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:28:43 status half-configured chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:43 status unpacked chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:43 status half-installed chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:45 status triggers-pending man-db 2.5.7-2 +2010-05-07 01:28:45 status half-installed chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:45 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-07 01:28:45 status half-installed chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:45 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-07 01:28:45 status half-installed chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:45 status triggers-pending hicolor-icon-theme 0.11-1 +2010-05-07 01:28:45 status half-installed chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:51 status half-installed chromium-browser 6.0.396.0~svn20100505r46428-0ubuntu1~ucd1 +2010-05-07 01:28:51 status unpacked chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:28:51 status unpacked chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:28:51 upgrade libclamav6 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:51 status half-configured libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:51 status unpacked libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:51 status half-installed libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:52 status half-installed libclamav6 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:53 status unpacked libclamav6 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:53 status unpacked libclamav6 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:53 upgrade clamav-daemon 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:53 status half-configured clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:54 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:54 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:54 status triggers-pending ureadahead 0.100.0-4.1 +2010-05-07 01:28:54 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:54 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:55 status half-installed clamav-daemon 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:55 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:55 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:55 upgrade clamav-base 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:55 status half-configured clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:55 status unpacked clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:55 status half-installed clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:55 status half-installed clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:56 status half-installed clamav-base 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:56 status unpacked clamav-base 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:56 status unpacked clamav-base 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:56 upgrade clamav-freshclam 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:56 status half-configured clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:57 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:57 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:57 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:57 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:57 status half-installed clamav-freshclam 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:58 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:58 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:58 upgrade clamav 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:58 status half-configured clamav 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:58 status unpacked clamav 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:58 status half-installed clamav 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:58 status half-installed clamav 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:59 status half-installed clamav 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:59 status unpacked clamav 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:59 status unpacked clamav 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:59 upgrade clamav-docs 0.96+dfsg-2ubuntu1.1 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:28:59 status half-configured clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:59 status unpacked clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:28:59 status half-installed clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:29:04 status half-installed clamav-docs 0.96+dfsg-2ubuntu1.1 +2010-05-07 01:29:04 status unpacked clamav-docs 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:29:04 status unpacked clamav-docs 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:29:04 upgrade libkpathsea5 2009-5 2009-5ubuntu0.1 +2010-05-07 01:29:04 status half-configured libkpathsea5 2009-5 +2010-05-07 01:29:04 status unpacked libkpathsea5 2009-5 +2010-05-07 01:29:04 status half-installed libkpathsea5 2009-5 +2010-05-07 01:29:05 status half-installed libkpathsea5 2009-5 +2010-05-07 01:29:05 status unpacked libkpathsea5 2009-5ubuntu0.1 +2010-05-07 01:29:05 status unpacked libkpathsea5 2009-5ubuntu0.1 +2010-05-07 01:29:05 upgrade texlive-binaries 2009-5 2009-5ubuntu0.1 +2010-05-07 01:29:05 status half-configured texlive-binaries 2009-5 +2010-05-07 01:29:05 status unpacked texlive-binaries 2009-5 +2010-05-07 01:29:05 status half-installed texlive-binaries 2009-5 +2010-05-07 01:29:05 status half-installed texlive-binaries 2009-5 +2010-05-07 01:29:14 status half-installed texlive-binaries 2009-5 +2010-05-07 01:29:15 status unpacked texlive-binaries 2009-5ubuntu0.1 +2010-05-07 01:29:15 status unpacked texlive-binaries 2009-5ubuntu0.1 +2010-05-07 01:29:15 upgrade dvipng 1.12-3build1 1.12-3ubuntu0.1 +2010-05-07 01:29:15 status half-configured dvipng 1.12-3build1 +2010-05-07 01:29:15 status unpacked dvipng 1.12-3build1 +2010-05-07 01:29:15 status half-installed dvipng 1.12-3build1 +2010-05-07 01:29:15 status triggers-pending install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-07 01:29:15 status half-installed dvipng 1.12-3build1 +2010-05-07 01:29:15 status half-installed dvipng 1.12-3build1 +2010-05-07 01:29:16 status half-installed dvipng 1.12-3build1 +2010-05-07 01:29:16 status unpacked dvipng 1.12-3ubuntu0.1 +2010-05-07 01:29:16 status unpacked dvipng 1.12-3ubuntu0.1 +2010-05-07 01:29:16 upgrade firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:29:16 status half-configured firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:16 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:17 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:17 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:17 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:17 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:18 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:29:18 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:29:18 upgrade firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:29:18 status half-configured firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:18 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:18 status half-installed firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:29 status half-installed firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-07 01:29:29 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:29:29 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:29:30 upgrade libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-07 01:29:30 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:29:30 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:29:30 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:29:30 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:29:33 status half-installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:29:33 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:29:34 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:29:34 upgrade libvlccore2 1.0.6-1ubuntu1 1.0.6-1ubuntu1.1 +2010-05-07 01:29:34 status half-configured libvlccore2 1.0.6-1ubuntu1 +2010-05-07 01:29:34 status unpacked libvlccore2 1.0.6-1ubuntu1 +2010-05-07 01:29:34 status half-installed libvlccore2 1.0.6-1ubuntu1 +2010-05-07 01:29:34 status half-installed libvlccore2 1.0.6-1ubuntu1 +2010-05-07 01:29:34 status unpacked libvlccore2 1.0.6-1ubuntu1.1 +2010-05-07 01:29:34 status unpacked libvlccore2 1.0.6-1ubuntu1.1 +2010-05-07 01:29:35 upgrade vlc-data 1.0.6-1ubuntu1 1.0.6-1ubuntu1.1 +2010-05-07 01:29:35 status half-configured vlc-data 1.0.6-1ubuntu1 +2010-05-07 01:29:35 status unpacked vlc-data 1.0.6-1ubuntu1 +2010-05-07 01:29:35 status half-installed vlc-data 1.0.6-1ubuntu1 +2010-05-07 01:29:36 status half-installed vlc-data 1.0.6-1ubuntu1 +2010-05-07 01:29:47 status half-installed vlc-data 1.0.6-1ubuntu1 +2010-05-07 01:29:47 status unpacked vlc-data 1.0.6-1ubuntu1.1 +2010-05-07 01:29:47 status unpacked vlc-data 1.0.6-1ubuntu1.1 +2010-05-07 01:29:48 upgrade libvlc2 1.0.6-1ubuntu1 1.0.6-1ubuntu1.1 +2010-05-07 01:29:48 status half-configured libvlc2 1.0.6-1ubuntu1 +2010-05-07 01:29:48 status unpacked libvlc2 1.0.6-1ubuntu1 +2010-05-07 01:29:48 status half-installed libvlc2 1.0.6-1ubuntu1 +2010-05-07 01:29:48 status half-installed libvlc2 1.0.6-1ubuntu1 +2010-05-07 01:29:48 status unpacked libvlc2 1.0.6-1ubuntu1.1 +2010-05-07 01:29:48 status unpacked libvlc2 1.0.6-1ubuntu1.1 +2010-05-07 01:29:48 upgrade thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:29:48 status half-configured thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-07 01:29:49 status unpacked thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-07 01:29:49 status half-installed thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-07 01:29:50 status half-installed thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-07 01:29:50 status half-installed thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-07 01:29:50 status half-installed thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-07 01:30:06 status half-installed thunderbird 3.0.5~hg20100504r4828+nobinonly-0ubuntu1~umd1 +2010-05-07 01:30:06 status unpacked thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:30:06 status unpacked thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:30:07 upgrade vlc-plugin-pulse 1.0.6-1ubuntu1 1.0.6-1ubuntu1.1 +2010-05-07 01:30:07 status half-configured vlc-plugin-pulse 1.0.6-1ubuntu1 +2010-05-07 01:30:07 status unpacked vlc-plugin-pulse 1.0.6-1ubuntu1 +2010-05-07 01:30:07 status half-installed vlc-plugin-pulse 1.0.6-1ubuntu1 +2010-05-07 01:30:07 status half-installed vlc-plugin-pulse 1.0.6-1ubuntu1 +2010-05-07 01:30:07 status unpacked vlc-plugin-pulse 1.0.6-1ubuntu1.1 +2010-05-07 01:30:07 status unpacked vlc-plugin-pulse 1.0.6-1ubuntu1.1 +2010-05-07 01:30:07 upgrade vlc 1.0.6-1ubuntu1 1.0.6-1ubuntu1.1 +2010-05-07 01:30:07 status half-configured vlc 1.0.6-1ubuntu1 +2010-05-07 01:30:08 status unpacked vlc 1.0.6-1ubuntu1 +2010-05-07 01:30:08 status half-installed vlc 1.0.6-1ubuntu1 +2010-05-07 01:30:08 status half-installed vlc 1.0.6-1ubuntu1 +2010-05-07 01:30:08 status half-installed vlc 1.0.6-1ubuntu1 +2010-05-07 01:30:08 status half-installed vlc 1.0.6-1ubuntu1 +2010-05-07 01:30:10 status half-installed vlc 1.0.6-1ubuntu1 +2010-05-07 01:30:11 status unpacked vlc 1.0.6-1ubuntu1.1 +2010-05-07 01:30:11 status unpacked vlc 1.0.6-1ubuntu1.1 +2010-05-07 01:30:11 upgrade vlc-nox 1.0.6-1ubuntu1 1.0.6-1ubuntu1.1 +2010-05-07 01:30:11 status half-configured vlc-nox 1.0.6-1ubuntu1 +2010-05-07 01:30:11 status unpacked vlc-nox 1.0.6-1ubuntu1 +2010-05-07 01:30:11 status half-installed vlc-nox 1.0.6-1ubuntu1 +2010-05-07 01:30:11 status half-installed vlc-nox 1.0.6-1ubuntu1 +2010-05-07 01:30:28 status half-installed vlc-nox 1.0.6-1ubuntu1 +2010-05-07 01:30:28 status unpacked vlc-nox 1.0.6-1ubuntu1.1 +2010-05-07 01:30:28 status unpacked vlc-nox 1.0.6-1ubuntu1.1 +2010-05-07 01:30:28 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-07 01:30:28 status half-configured man-db 2.5.7-2 +2010-05-07 01:30:31 status installed man-db 2.5.7-2 +2010-05-07 01:30:31 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-07 01:30:31 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-07 01:30:33 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-07 01:30:33 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-07 01:30:33 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-07 01:30:33 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-07 01:30:33 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-07 01:30:33 trigproc hicolor-icon-theme 0.11-1 0.11-1 +2010-05-07 01:30:33 status half-configured hicolor-icon-theme 0.11-1 +2010-05-07 01:30:36 status installed hicolor-icon-theme 0.11-1 +2010-05-07 01:30:37 trigproc ureadahead 0.100.0-4.1 0.100.0-4.1 +2010-05-07 01:30:37 status half-configured ureadahead 0.100.0-4.1 +2010-05-07 01:30:37 status installed ureadahead 0.100.0-4.1 +2010-05-07 01:30:37 trigproc install-info 4.13a.dfsg.1-5ubuntu1 4.13a.dfsg.1-5ubuntu1 +2010-05-07 01:30:37 status half-configured install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-07 01:30:38 status installed install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-07 01:30:38 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-07 01:30:38 status half-configured python-support 1.0.4ubuntu1 +2010-05-07 01:30:43 status installed python-support 1.0.4ubuntu1 +2010-05-07 01:30:44 startup packages configure +2010-05-07 01:30:44 configure libclamav6 0.96+dfsg-2ubuntu1.2 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:44 status unpacked libclamav6 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:44 status half-configured libclamav6 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:45 status installed libclamav6 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:45 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-07 01:30:45 configure clamav-base 0.96+dfsg-2ubuntu1.2 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:45 status unpacked clamav-base 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:45 status half-configured clamav-base 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status installed clamav-base 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 configure clamav-freshclam 0.96+dfsg-2ubuntu1.2 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:47 status unpacked clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:48 status half-configured clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 status installed clamav-freshclam 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 configure clamav-daemon 0.96+dfsg-2ubuntu1.2 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 status unpacked clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:50 status half-configured clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 status installed clamav-daemon 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 configure clamav 0.96+dfsg-2ubuntu1.2 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 status unpacked clamav 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 status half-configured clamav 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 status installed clamav 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 configure clamav-docs 0.96+dfsg-2ubuntu1.2 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 status unpacked clamav-docs 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 status half-configured clamav-docs 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 status installed clamav-docs 0.96+dfsg-2ubuntu1.2 +2010-05-07 01:30:52 configure libkpathsea5 2009-5ubuntu0.1 2009-5ubuntu0.1 +2010-05-07 01:30:52 status unpacked libkpathsea5 2009-5ubuntu0.1 +2010-05-07 01:30:52 status half-configured libkpathsea5 2009-5ubuntu0.1 +2010-05-07 01:30:52 status installed libkpathsea5 2009-5ubuntu0.1 +2010-05-07 01:30:52 configure texlive-binaries 2009-5ubuntu0.1 2009-5ubuntu0.1 +2010-05-07 01:30:52 status unpacked texlive-binaries 2009-5ubuntu0.1 +2010-05-07 01:30:52 status half-configured texlive-binaries 2009-5ubuntu0.1 +2010-05-07 01:30:53 update-alternatives: run with --install /usr/bin/xdvi.bin xdvi.bin /usr/bin/xdvi-xaw 30 +2010-05-07 01:30:54 update-alternatives: run with --install /usr/bin/bibtex bibtex /usr/bin/bibtex.original 100 --slave /usr/share/man/man1/bibtex.1.gz bibtex.1.gz /usr/share/man/man1/bibtex.original.1.gz +2010-05-07 01:32:19 status installed texlive-binaries 2009-5ubuntu0.1 +2010-05-07 01:32:19 configure dvipng 1.12-3ubuntu0.1 1.12-3ubuntu0.1 +2010-05-07 01:32:19 status unpacked dvipng 1.12-3ubuntu0.1 +2010-05-07 01:32:19 status half-configured dvipng 1.12-3ubuntu0.1 +2010-05-07 01:32:19 status installed dvipng 1.12-3ubuntu0.1 +2010-05-07 01:32:19 configure libpurple0 1:2.6.6-1ubuntu4 1:2.6.6-1ubuntu4 +2010-05-07 01:32:19 status unpacked libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:32:19 status half-configured libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:32:20 status installed libpurple0 1:2.6.6-1ubuntu4 +2010-05-07 01:32:20 configure vlc-data 1.0.6-1ubuntu1.1 1.0.6-1ubuntu1.1 +2010-05-07 01:32:20 status unpacked vlc-data 1.0.6-1ubuntu1.1 +2010-05-07 01:32:20 status unpacked vlc-data 1.0.6-1ubuntu1.1 +2010-05-07 01:32:20 status half-configured vlc-data 1.0.6-1ubuntu1.1 +2010-05-07 01:32:20 status installed vlc-data 1.0.6-1ubuntu1.1 +2010-05-07 01:32:20 configure libvlccore2 1.0.6-1ubuntu1.1 1.0.6-1ubuntu1.1 +2010-05-07 01:32:20 status unpacked libvlccore2 1.0.6-1ubuntu1.1 +2010-05-07 01:32:20 status half-configured libvlccore2 1.0.6-1ubuntu1.1 +2010-05-07 01:32:21 status installed libvlccore2 1.0.6-1ubuntu1.1 +2010-05-07 01:32:21 configure libvlc2 1.0.6-1ubuntu1.1 1.0.6-1ubuntu1.1 +2010-05-07 01:32:21 status unpacked libvlc2 1.0.6-1ubuntu1.1 +2010-05-07 01:32:21 status half-configured libvlc2 1.0.6-1ubuntu1.1 +2010-05-07 01:32:21 status installed libvlc2 1.0.6-1ubuntu1.1 +2010-05-07 01:32:21 configure thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:32:21 status unpacked thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:32:21 status unpacked thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:32:22 status half-configured thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:32:22 status installed thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-07 01:32:22 configure vlc-nox 1.0.6-1ubuntu1.1 1.0.6-1ubuntu1.1 +2010-05-07 01:32:22 status unpacked vlc-nox 1.0.6-1ubuntu1.1 +2010-05-07 01:32:22 status half-configured vlc-nox 1.0.6-1ubuntu1.1 +2010-05-07 01:32:23 status installed vlc-nox 1.0.6-1ubuntu1.1 +2010-05-07 01:32:23 configure vlc-plugin-pulse 1.0.6-1ubuntu1.1 1.0.6-1ubuntu1.1 +2010-05-07 01:32:23 status unpacked vlc-plugin-pulse 1.0.6-1ubuntu1.1 +2010-05-07 01:32:23 status half-configured vlc-plugin-pulse 1.0.6-1ubuntu1.1 +2010-05-07 01:32:23 status installed vlc-plugin-pulse 1.0.6-1ubuntu1.1 +2010-05-07 01:32:23 configure vlc 1.0.6-1ubuntu1.1 1.0.6-1ubuntu1.1 +2010-05-07 01:32:23 status unpacked vlc 1.0.6-1ubuntu1.1 +2010-05-07 01:32:24 status half-configured vlc 1.0.6-1ubuntu1.1 +2010-05-07 01:32:24 status installed vlc 1.0.6-1ubuntu1.1 +2010-05-07 01:32:24 configure firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status half-configured firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 configure firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:24 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:25 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:25 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:25 status half-configured firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:25 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox 40 +2010-05-07 01:32:28 status installed firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-07 01:32:28 configure chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:28 status unpacked chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:28 status half-configured chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:29 status installed chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:29 configure chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:29 status unpacked chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:29 status unpacked chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:29 status half-configured chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:29 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/chromium-browser 40 +2010-05-07 01:32:29 update-alternatives: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/chromium-browser 40 +2010-05-07 01:32:29 status installed chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-07 01:32:29 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-07 01:32:29 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-07 01:32:30 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-09 02:34:34 startup archives unpack +2010-05-09 02:34:40 upgrade chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-09 02:34:40 status half-configured chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-09 02:34:41 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-09 02:34:41 status half-installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-09 02:34:41 status half-installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46413-0ubuntu1~ucd1 +2010-05-09 02:34:41 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-09 02:34:41 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-09 02:34:41 upgrade chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-09 02:34:41 status half-configured chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:42 status unpacked chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:42 status half-installed chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:47 status half-installed chromium-browser-inspector 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:47 status unpacked chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-09 02:34:47 status unpacked chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-09 02:34:48 upgrade chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:34:48 status half-configured chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:48 status unpacked chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:48 status half-installed chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:50 status triggers-pending man-db 2.5.7-2 +2010-05-09 02:34:50 status half-installed chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:50 status triggers-pending hicolor-icon-theme 0.11-1 +2010-05-09 02:34:50 status half-installed chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:50 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-09 02:34:50 status half-installed chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:50 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-09 02:34:50 status half-installed chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:55 status half-installed chromium-browser 6.0.397.0~svn20100506r46539-0ubuntu1~ucd1 +2010-05-09 02:34:55 status unpacked chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:34:55 status unpacked chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:34:56 upgrade apt 0.7.25.3ubuntu7 0.7.25.3ubuntu8 +2010-05-09 02:34:56 status half-configured apt 0.7.25.3ubuntu7 +2010-05-09 02:34:56 status unpacked apt 0.7.25.3ubuntu7 +2010-05-09 02:34:56 status half-installed apt 0.7.25.3ubuntu7 +2010-05-09 02:34:56 status half-installed apt 0.7.25.3ubuntu7 +2010-05-09 02:35:04 status half-installed apt 0.7.25.3ubuntu7 +2010-05-09 02:35:04 status unpacked apt 0.7.25.3ubuntu8 +2010-05-09 02:35:04 status unpacked apt 0.7.25.3ubuntu8 +2010-05-09 02:35:04 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-09 02:35:04 status half-configured man-db 2.5.7-2 +2010-05-09 02:35:07 status installed man-db 2.5.7-2 +2010-05-09 02:35:07 trigproc hicolor-icon-theme 0.11-1 0.11-1 +2010-05-09 02:35:07 status half-configured hicolor-icon-theme 0.11-1 +2010-05-09 02:35:11 status installed hicolor-icon-theme 0.11-1 +2010-05-09 02:35:11 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-09 02:35:11 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-09 02:35:13 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-09 02:35:13 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-09 02:35:13 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-09 02:35:13 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-09 02:35:13 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-09 02:35:13 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-09 02:35:13 status half-configured python-support 1.0.4ubuntu1 +2010-05-09 02:35:18 status installed python-support 1.0.4ubuntu1 +2010-05-09 02:35:19 startup packages configure +2010-05-09 02:35:19 configure apt 0.7.25.3ubuntu8 0.7.25.3ubuntu8 +2010-05-09 02:35:19 status unpacked apt 0.7.25.3ubuntu8 +2010-05-09 02:35:19 status unpacked apt 0.7.25.3ubuntu8 +2010-05-09 02:35:19 status unpacked apt 0.7.25.3ubuntu8 +2010-05-09 02:35:19 status unpacked apt 0.7.25.3ubuntu8 +2010-05-09 02:35:19 status unpacked apt 0.7.25.3ubuntu8 +2010-05-09 02:35:19 status half-configured apt 0.7.25.3ubuntu8 +2010-05-09 02:35:19 status installed apt 0.7.25.3ubuntu8 +2010-05-09 02:35:20 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-09 02:35:20 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-09 02:35:20 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-09 02:35:21 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-09 02:35:22 startup archives unpack +2010-05-09 02:35:22 upgrade apt-utils 0.7.25.3ubuntu7 0.7.25.3ubuntu8 +2010-05-09 02:35:22 status half-configured apt-utils 0.7.25.3ubuntu7 +2010-05-09 02:35:22 status unpacked apt-utils 0.7.25.3ubuntu7 +2010-05-09 02:35:22 status half-installed apt-utils 0.7.25.3ubuntu7 +2010-05-09 02:35:23 status triggers-pending man-db 2.5.7-2 +2010-05-09 02:35:23 status half-installed apt-utils 0.7.25.3ubuntu7 +2010-05-09 02:35:24 status half-installed apt-utils 0.7.25.3ubuntu7 +2010-05-09 02:35:24 status unpacked apt-utils 0.7.25.3ubuntu8 +2010-05-09 02:35:24 status unpacked apt-utils 0.7.25.3ubuntu8 +2010-05-09 02:35:24 upgrade apt-transport-https 0.7.25.3ubuntu7 0.7.25.3ubuntu8 +2010-05-09 02:35:24 status half-configured apt-transport-https 0.7.25.3ubuntu7 +2010-05-09 02:35:24 status unpacked apt-transport-https 0.7.25.3ubuntu7 +2010-05-09 02:35:24 status half-installed apt-transport-https 0.7.25.3ubuntu7 +2010-05-09 02:35:25 status half-installed apt-transport-https 0.7.25.3ubuntu7 +2010-05-09 02:35:25 status unpacked apt-transport-https 0.7.25.3ubuntu8 +2010-05-09 02:35:25 status unpacked apt-transport-https 0.7.25.3ubuntu8 +2010-05-09 02:35:25 upgrade firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:25 status half-configured firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:25 status unpacked firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:25 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:25 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-09 02:35:25 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:25 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-09 02:35:26 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:26 status half-installed firefox-branding 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:26 status unpacked firefox-branding 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:26 status unpacked firefox-branding 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:27 upgrade firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:27 status half-configured firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:27 status unpacked firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:27 status half-installed firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:37 status half-installed firefox 3.6.5~hg20100503r34167+nobinonly-0ubuntu1~umd3 +2010-05-09 02:35:37 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:37 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:38 upgrade libcairomm-1.0-dev 1.8.0-1build2 1.8.4-0ubuntu1 +2010-05-09 02:35:38 status half-configured libcairomm-1.0-dev 1.8.0-1build2 +2010-05-09 02:35:38 status unpacked libcairomm-1.0-dev 1.8.0-1build2 +2010-05-09 02:35:38 status half-installed libcairomm-1.0-dev 1.8.0-1build2 +2010-05-09 02:35:39 status half-installed libcairomm-1.0-dev 1.8.0-1build2 +2010-05-09 02:35:39 status unpacked libcairomm-1.0-dev 1.8.4-0ubuntu1 +2010-05-09 02:35:39 status unpacked libcairomm-1.0-dev 1.8.4-0ubuntu1 +2010-05-09 02:35:40 upgrade libcairomm-1.0-1 1.8.0-1build2 1.8.4-0ubuntu1 +2010-05-09 02:35:40 status half-configured libcairomm-1.0-1 1.8.0-1build2 +2010-05-09 02:35:40 status unpacked libcairomm-1.0-1 1.8.0-1build2 +2010-05-09 02:35:40 status half-installed libcairomm-1.0-1 1.8.0-1build2 +2010-05-09 02:35:40 status half-installed libcairomm-1.0-1 1.8.0-1build2 +2010-05-09 02:35:41 status unpacked libcairomm-1.0-1 1.8.4-0ubuntu1 +2010-05-09 02:35:41 status unpacked libcairomm-1.0-1 1.8.4-0ubuntu1 +2010-05-09 02:35:41 upgrade libpangomm-1.4-dev 2.26.1-1 2.26.2-0ubuntu1 +2010-05-09 02:35:41 status half-configured libpangomm-1.4-dev 2.26.1-1 +2010-05-09 02:35:41 status unpacked libpangomm-1.4-dev 2.26.1-1 +2010-05-09 02:35:41 status half-installed libpangomm-1.4-dev 2.26.1-1 +2010-05-09 02:35:43 status half-installed libpangomm-1.4-dev 2.26.1-1 +2010-05-09 02:35:43 status unpacked libpangomm-1.4-dev 2.26.2-0ubuntu1 +2010-05-09 02:35:43 status unpacked libpangomm-1.4-dev 2.26.2-0ubuntu1 +2010-05-09 02:35:43 upgrade libpangomm-1.4-1 2.26.1-1 2.26.2-0ubuntu1 +2010-05-09 02:35:43 status half-configured libpangomm-1.4-1 2.26.1-1 +2010-05-09 02:35:44 status unpacked libpangomm-1.4-1 2.26.1-1 +2010-05-09 02:35:44 status half-installed libpangomm-1.4-1 2.26.1-1 +2010-05-09 02:35:44 status half-installed libpangomm-1.4-1 2.26.1-1 +2010-05-09 02:35:44 status unpacked libpangomm-1.4-1 2.26.2-0ubuntu1 +2010-05-09 02:35:44 status unpacked libpangomm-1.4-1 2.26.2-0ubuntu1 +2010-05-09 02:35:44 upgrade libtag1c2a 1.6.2-0ubuntu1 1.6.3-0ubuntu1 +2010-05-09 02:35:44 status half-configured libtag1c2a 1.6.2-0ubuntu1 +2010-05-09 02:35:45 status unpacked libtag1c2a 1.6.2-0ubuntu1 +2010-05-09 02:35:45 status half-installed libtag1c2a 1.6.2-0ubuntu1 +2010-05-09 02:35:47 status half-installed libtag1c2a 1.6.2-0ubuntu1 +2010-05-09 02:35:47 status unpacked libtag1c2a 1.6.3-0ubuntu1 +2010-05-09 02:35:47 status unpacked libtag1c2a 1.6.3-0ubuntu1 +2010-05-09 02:35:47 upgrade libtag1-vanilla 1.6.2-0ubuntu1 1.6.3-0ubuntu1 +2010-05-09 02:35:47 status half-configured libtag1-vanilla 1.6.2-0ubuntu1 +2010-05-09 02:35:47 status unpacked libtag1-vanilla 1.6.2-0ubuntu1 +2010-05-09 02:35:47 status half-installed libtag1-vanilla 1.6.2-0ubuntu1 +2010-05-09 02:35:48 status half-installed libtag1-vanilla 1.6.2-0ubuntu1 +2010-05-09 02:35:48 status unpacked libtag1-vanilla 1.6.3-0ubuntu1 +2010-05-09 02:35:48 status unpacked libtag1-vanilla 1.6.3-0ubuntu1 +2010-05-09 02:35:48 upgrade thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:48 status half-configured thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:48 status unpacked thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:48 status half-installed thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:49 status half-installed thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:49 status half-installed thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-09 02:35:49 status half-installed thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:04 status half-installed thunderbird 3.0.5~hg20100505r4833+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:04 status unpacked thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:05 status unpacked thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:05 upgrade xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:05 status half-configured xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-09 02:36:06 update-alternatives: run with --remove xulrunner /usr/bin/xulrunner-1.9.2 +2010-05-09 02:36:06 update-alternatives: link group xulrunner updated to point to /usr/lib/xulrunner/xulrunner +2010-05-09 02:36:06 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-09 02:36:06 status half-installed xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-09 02:36:15 status half-installed xulrunner-1.9.2 1.9.2.5~hg20100503r34167+nobinonly-0ubuntu1~umd2 +2010-05-09 02:36:15 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:15 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:15 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-09 02:36:15 status half-configured man-db 2.5.7-2 +2010-05-09 02:36:17 status installed man-db 2.5.7-2 +2010-05-09 02:36:17 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-09 02:36:17 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-09 02:36:17 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-09 02:36:17 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-09 02:36:18 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-09 02:36:18 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-09 02:36:18 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-09 02:36:18 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-09 02:36:18 status half-configured python-support 1.0.4ubuntu1 +2010-05-09 02:36:19 status installed python-support 1.0.4ubuntu1 +2010-05-09 02:36:20 startup packages configure +2010-05-09 02:36:20 configure apt-utils 0.7.25.3ubuntu8 0.7.25.3ubuntu8 +2010-05-09 02:36:20 status unpacked apt-utils 0.7.25.3ubuntu8 +2010-05-09 02:36:20 status half-configured apt-utils 0.7.25.3ubuntu8 +2010-05-09 02:36:20 status installed apt-utils 0.7.25.3ubuntu8 +2010-05-09 02:36:20 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-09 02:36:20 configure apt-transport-https 0.7.25.3ubuntu8 0.7.25.3ubuntu8 +2010-05-09 02:36:20 status unpacked apt-transport-https 0.7.25.3ubuntu8 +2010-05-09 02:36:20 status half-configured apt-transport-https 0.7.25.3ubuntu8 +2010-05-09 02:36:20 status installed apt-transport-https 0.7.25.3ubuntu8 +2010-05-09 02:36:20 configure libcairomm-1.0-1 1.8.4-0ubuntu1 1.8.4-0ubuntu1 +2010-05-09 02:36:20 status unpacked libcairomm-1.0-1 1.8.4-0ubuntu1 +2010-05-09 02:36:20 status half-configured libcairomm-1.0-1 1.8.4-0ubuntu1 +2010-05-09 02:36:20 status installed libcairomm-1.0-1 1.8.4-0ubuntu1 +2010-05-09 02:36:20 configure libcairomm-1.0-dev 1.8.4-0ubuntu1 1.8.4-0ubuntu1 +2010-05-09 02:36:20 status unpacked libcairomm-1.0-dev 1.8.4-0ubuntu1 +2010-05-09 02:36:21 status half-configured libcairomm-1.0-dev 1.8.4-0ubuntu1 +2010-05-09 02:36:21 status installed libcairomm-1.0-dev 1.8.4-0ubuntu1 +2010-05-09 02:36:21 configure libpangomm-1.4-1 2.26.2-0ubuntu1 2.26.2-0ubuntu1 +2010-05-09 02:36:21 status unpacked libpangomm-1.4-1 2.26.2-0ubuntu1 +2010-05-09 02:36:21 status half-configured libpangomm-1.4-1 2.26.2-0ubuntu1 +2010-05-09 02:36:22 status installed libpangomm-1.4-1 2.26.2-0ubuntu1 +2010-05-09 02:36:22 configure libpangomm-1.4-dev 2.26.2-0ubuntu1 2.26.2-0ubuntu1 +2010-05-09 02:36:22 status unpacked libpangomm-1.4-dev 2.26.2-0ubuntu1 +2010-05-09 02:36:22 status half-configured libpangomm-1.4-dev 2.26.2-0ubuntu1 +2010-05-09 02:36:22 status installed libpangomm-1.4-dev 2.26.2-0ubuntu1 +2010-05-09 02:36:22 configure libtag1-vanilla 1.6.3-0ubuntu1 1.6.3-0ubuntu1 +2010-05-09 02:36:22 status unpacked libtag1-vanilla 1.6.3-0ubuntu1 +2010-05-09 02:36:22 status half-configured libtag1-vanilla 1.6.3-0ubuntu1 +2010-05-09 02:36:22 status installed libtag1-vanilla 1.6.3-0ubuntu1 +2010-05-09 02:36:22 configure libtag1c2a 1.6.3-0ubuntu1 1.6.3-0ubuntu1 +2010-05-09 02:36:22 status unpacked libtag1c2a 1.6.3-0ubuntu1 +2010-05-09 02:36:22 status half-configured libtag1c2a 1.6.3-0ubuntu1 +2010-05-09 02:36:22 status installed libtag1c2a 1.6.3-0ubuntu1 +2010-05-09 02:36:22 configure thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:22 status unpacked thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:22 status unpacked thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 status half-configured thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 status installed thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 configure xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 status unpacked xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 status half-configured xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:23 update-alternatives: run with --install /usr/bin/xulrunner xulrunner /usr/bin/xulrunner-1.9.2 50 +2010-05-09 02:36:23 update-alternatives: link group xulrunner updated to point to /usr/bin/xulrunner-1.9.2 +2010-05-09 02:36:23 status installed xulrunner-1.9.2 1.9.2.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 configure firefox-branding 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox-branding 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status half-configured firefox-branding 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status installed firefox-branding 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 configure firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status unpacked firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:24 status half-configured firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:25 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/firefox 40 +2010-05-09 02:36:25 status installed firefox 3.6.5~hg20100506r34169+nobinonly-0ubuntu1~umd1 +2010-05-09 02:36:25 configure chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-09 02:36:25 status unpacked chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-09 02:36:25 status half-configured chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-09 02:36:25 status installed chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-09 02:36:25 configure chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-09 02:36:25 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-09 02:36:25 status half-configured chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-09 02:36:25 status installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-09 02:36:25 configure chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:36:25 status unpacked chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:36:25 status unpacked chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:36:26 status half-configured chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:36:26 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/chromium-browser 40 +2010-05-09 02:36:26 update-alternatives: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/chromium-browser 40 +2010-05-09 02:36:26 status installed chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-09 02:36:26 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-09 02:36:26 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-09 02:36:26 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-09 21:41:46 update-alternatives: run with --config gnome-www-browser +2010-05-09 21:59:05 update-alternatives: run with --set gnome-www-browser /usr/bin/firefox +2010-05-09 22:03:09 update-alternatives: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/firefox 40 +2010-05-09 22:03:37 update-alternatives: run with --config gnome-www-browser +2010-05-09 22:03:40 update-alternatives: status of link group gnome-www-browser set to manual +2010-05-09 22:03:40 update-alternatives: link group gnome-www-browser updated to point to /usr/bin/firefox +2010-05-09 22:19:16 startup archives unpack +2010-05-09 22:19:22 install openoffice.org-writer2latex 1.0-10ubuntu1 +2010-05-09 22:19:22 status half-installed openoffice.org-writer2latex 1.0-10ubuntu1 +2010-05-09 22:19:24 status unpacked openoffice.org-writer2latex 1.0-10ubuntu1 +2010-05-09 22:19:24 status unpacked openoffice.org-writer2latex 1.0-10ubuntu1 +2010-05-09 22:19:24 install libwriter2latex-java-doc 1.0-10ubuntu1 +2010-05-09 22:19:24 status half-installed libwriter2latex-java-doc 1.0-10ubuntu1 +2010-05-09 22:19:41 status unpacked libwriter2latex-java-doc 1.0-10ubuntu1 +2010-05-09 22:19:41 status unpacked libwriter2latex-java-doc 1.0-10ubuntu1 +2010-05-09 22:19:41 install writer2latex-manual 1.0-10ubuntu1 +2010-05-09 22:19:41 status half-installed writer2latex-manual 1.0-10ubuntu1 +2010-05-09 22:19:42 status unpacked writer2latex-manual 1.0-10ubuntu1 +2010-05-09 22:19:42 status unpacked writer2latex-manual 1.0-10ubuntu1 +2010-05-09 22:19:43 startup packages configure +2010-05-09 22:19:43 configure openoffice.org-writer2latex 1.0-10ubuntu1 1.0-10ubuntu1 +2010-05-09 22:19:43 status unpacked openoffice.org-writer2latex 1.0-10ubuntu1 +2010-05-09 22:19:43 status half-configured openoffice.org-writer2latex 1.0-10ubuntu1 +2010-05-09 22:19:49 status installed openoffice.org-writer2latex 1.0-10ubuntu1 +2010-05-09 22:19:49 configure libwriter2latex-java-doc 1.0-10ubuntu1 1.0-10ubuntu1 +2010-05-09 22:19:49 status unpacked libwriter2latex-java-doc 1.0-10ubuntu1 +2010-05-09 22:19:49 status half-configured libwriter2latex-java-doc 1.0-10ubuntu1 +2010-05-09 22:19:49 status installed libwriter2latex-java-doc 1.0-10ubuntu1 +2010-05-09 22:19:49 configure writer2latex-manual 1.0-10ubuntu1 1.0-10ubuntu1 +2010-05-09 22:19:49 status unpacked writer2latex-manual 1.0-10ubuntu1 +2010-05-09 22:19:49 status half-configured writer2latex-manual 1.0-10ubuntu1 +2010-05-09 22:19:49 status installed writer2latex-manual 1.0-10ubuntu1 +2010-05-09 22:49:29 startup archives unpack +2010-05-09 22:49:29 install libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:49:29 status half-installed libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:49:30 status triggers-pending doc-base 0.9.5 +2010-05-09 22:49:30 status half-installed libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:49:30 status triggers-pending man-db 2.5.7-2 +2010-05-09 22:49:30 status half-installed libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:49:32 status unpacked libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:49:32 status unpacked libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:49:32 install libmcs-dev 0.7.1-1 +2010-05-09 22:49:32 status half-installed libmcs-dev 0.7.1-1 +2010-05-09 22:49:33 status unpacked libmcs-dev 0.7.1-1 +2010-05-09 22:49:33 status unpacked libmcs-dev 0.7.1-1 +2010-05-09 22:49:33 install libmowgli-dev 0.6.1-1 +2010-05-09 22:49:33 status half-installed libmowgli-dev 0.6.1-1 +2010-05-09 22:49:36 status unpacked libmowgli-dev 0.6.1-1 +2010-05-09 22:49:36 status unpacked libmowgli-dev 0.6.1-1 +2010-05-09 22:49:36 install libsamplerate0-dev 0.1.7-3 +2010-05-09 22:49:36 status half-installed libsamplerate0-dev 0.1.7-3 +2010-05-09 22:49:36 status half-installed libsamplerate0-dev 0.1.7-3 +2010-05-09 22:49:37 status unpacked libsamplerate0-dev 0.1.7-3 +2010-05-09 22:49:37 status unpacked libsamplerate0-dev 0.1.7-3 +2010-05-09 22:49:38 install audacious-dev 2.3-1ubuntu4 +2010-05-09 22:49:38 status half-installed audacious-dev 2.3-1ubuntu4 +2010-05-09 22:49:41 status unpacked audacious-dev 2.3-1ubuntu4 +2010-05-09 22:49:41 status unpacked audacious-dev 2.3-1ubuntu4 +2010-05-09 22:49:41 install libgssrpc4 1.8.1+dfsg-2 +2010-05-09 22:49:41 status half-installed libgssrpc4 1.8.1+dfsg-2 +2010-05-09 22:49:41 status unpacked libgssrpc4 1.8.1+dfsg-2 +2010-05-09 22:49:41 status unpacked libgssrpc4 1.8.1+dfsg-2 +2010-05-09 22:49:42 install libkdb5-4 1.8.1+dfsg-2 +2010-05-09 22:49:42 status half-installed libkdb5-4 1.8.1+dfsg-2 +2010-05-09 22:49:42 status unpacked libkdb5-4 1.8.1+dfsg-2 +2010-05-09 22:49:42 status unpacked libkdb5-4 1.8.1+dfsg-2 +2010-05-09 22:49:42 install libkadm5srv-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:42 status half-installed libkadm5srv-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:43 status unpacked libkadm5srv-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:43 status unpacked libkadm5srv-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:43 install libkadm5clnt-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:43 status half-installed libkadm5clnt-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:43 status unpacked libkadm5clnt-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:43 status unpacked libkadm5clnt-mit7 1.8.1+dfsg-2 +2010-05-09 22:49:43 install comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:49:43 status half-installed comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:49:44 status half-installed comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:49:44 status half-installed comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:49:44 status triggers-pending install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-09 22:49:44 status half-installed comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:49:45 status unpacked comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:49:45 status unpacked comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:49:45 install krb5-multidev 1.8.1+dfsg-2 +2010-05-09 22:49:45 status half-installed krb5-multidev 1.8.1+dfsg-2 +2010-05-09 22:49:47 status unpacked krb5-multidev 1.8.1+dfsg-2 +2010-05-09 22:49:47 status unpacked krb5-multidev 1.8.1+dfsg-2 +2010-05-09 22:49:48 install libslang2-dev 2.2.2-2ubuntu1 +2010-05-09 22:49:48 status half-installed libslang2-dev 2.2.2-2ubuntu1 +2010-05-09 22:49:49 status unpacked libslang2-dev 2.2.2-2ubuntu1 +2010-05-09 22:49:49 status unpacked libslang2-dev 2.2.2-2ubuntu1 +2010-05-09 22:49:49 install libaa1-dev 1.4p5-38build1 +2010-05-09 22:49:49 status half-installed libaa1-dev 1.4p5-38build1 +2010-05-09 22:49:49 status half-installed libaa1-dev 1.4p5-38build1 +2010-05-09 22:49:49 status half-installed libaa1-dev 1.4p5-38build1 +2010-05-09 22:49:52 status unpacked libaa1-dev 1.4p5-38build1 +2010-05-09 22:49:52 status unpacked libaa1-dev 1.4p5-38build1 +2010-05-09 22:49:52 install libasound2-dev 1.0.22-0ubuntu7 +2010-05-09 22:49:52 status half-installed libasound2-dev 1.0.22-0ubuntu7 +2010-05-09 22:49:55 status unpacked libasound2-dev 1.0.22-0ubuntu7 +2010-05-09 22:49:55 status unpacked libasound2-dev 1.0.22-0ubuntu7 +2010-05-09 22:49:55 install libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:49:55 status half-installed libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:49:56 status half-installed libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:49:57 status unpacked libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:49:57 status unpacked libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:49:57 install libavutil-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:49:57 status half-installed libavutil-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:49:59 status unpacked libavutil-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:49:59 status unpacked libavutil-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:49:59 install libavcodec-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:49:59 status half-installed libavcodec-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:50:00 status unpacked libavcodec-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:50:00 status unpacked libavcodec-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:50:01 install libavformat-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:50:01 status half-installed libavformat-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:50:01 status unpacked libavformat-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:50:01 status unpacked libavformat-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:50:02 install libbinio-dev 1.4-14 +2010-05-09 22:50:02 status half-installed libbinio-dev 1.4-14 +2010-05-09 22:50:02 status unpacked libbinio-dev 1.4-14 +2010-05-09 22:50:02 status unpacked libbinio-dev 1.4-14 +2010-05-09 22:50:02 install libcaca-dev 0.99.beta16-3 +2010-05-09 22:50:02 status half-installed libcaca-dev 0.99.beta16-3 +2010-05-09 22:50:03 status half-installed libcaca-dev 0.99.beta16-3 +2010-05-09 22:50:16 status unpacked libcaca-dev 0.99.beta16-3 +2010-05-09 22:50:16 status unpacked libcaca-dev 0.99.beta16-3 +2010-05-09 22:50:17 install libcddb2-dev 1.3.2-0ubuntu1 +2010-05-09 22:50:17 status half-installed libcddb2-dev 1.3.2-0ubuntu1 +2010-05-09 22:50:18 status unpacked libcddb2-dev 1.3.2-0ubuntu1 +2010-05-09 22:50:18 status unpacked libcddb2-dev 1.3.2-0ubuntu1 +2010-05-09 22:50:19 install libcdio-dev 0.81-4 +2010-05-09 22:50:19 status half-installed libcdio-dev 0.81-4 +2010-05-09 22:50:19 status half-installed libcdio-dev 0.81-4 +2010-05-09 22:50:20 status unpacked libcdio-dev 0.81-4 +2010-05-09 22:50:21 status unpacked libcdio-dev 0.81-4 +2010-05-09 22:50:21 install libcdio-cdda-dev 0.81-4 +2010-05-09 22:50:21 status half-installed libcdio-cdda-dev 0.81-4 +2010-05-09 22:50:21 status unpacked libcdio-cdda-dev 0.81-4 +2010-05-09 22:50:21 status unpacked libcdio-cdda-dev 0.81-4 +2010-05-09 22:50:22 install libcue-dev 1.3.0-1 +2010-05-09 22:50:22 status half-installed libcue-dev 1.3.0-1 +2010-05-09 22:50:22 status unpacked libcue-dev 1.3.0-1 +2010-05-09 22:50:22 status unpacked libcue-dev 1.3.0-1 +2010-05-09 22:50:22 install libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:50:22 status half-installed libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:50:23 status half-installed libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:50:23 status unpacked libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:50:23 status unpacked libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:50:23 install libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:50:23 status half-installed libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:50:23 status half-installed libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:50:31 status unpacked libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:50:31 status unpacked libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:50:31 install libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:50:31 status half-installed libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:50:31 status half-installed libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:50:31 status half-installed libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:50:41 status unpacked libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:50:41 status unpacked libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:50:41 install libdrm-dev 2.4.18-1ubuntu3 +2010-05-09 22:50:41 status half-installed libdrm-dev 2.4.18-1ubuntu3 +2010-05-09 22:50:43 status unpacked libdrm-dev 2.4.18-1ubuntu3 +2010-05-09 22:50:43 status unpacked libdrm-dev 2.4.18-1ubuntu3 +2010-05-09 22:50:43 install libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:50:43 status half-installed libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:50:43 status half-installed libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:50:44 status unpacked libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:50:44 status unpacked libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:50:44 install libfaad-dev 2.7-4 +2010-05-09 22:50:44 status half-installed libfaad-dev 2.7-4 +2010-05-09 22:50:45 status unpacked libfaad-dev 2.7-4 +2010-05-09 22:50:45 status unpacked libfaad-dev 2.7-4 +2010-05-09 22:50:45 install libogg-dev 1.1.4~dfsg-2 +2010-05-09 22:50:45 status half-installed libogg-dev 1.1.4~dfsg-2 +2010-05-09 22:50:48 status unpacked libogg-dev 1.1.4~dfsg-2 +2010-05-09 22:50:48 status unpacked libogg-dev 1.1.4~dfsg-2 +2010-05-09 22:50:48 install libflac-dev 1.2.1-2build2 +2010-05-09 22:50:48 status half-installed libflac-dev 1.2.1-2build2 +2010-05-09 22:50:49 status unpacked libflac-dev 1.2.1-2build2 +2010-05-09 22:50:49 status unpacked libflac-dev 1.2.1-2build2 +2010-05-09 22:50:50 install uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:50:50 status half-installed uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:50:50 status half-installed uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:50:51 status unpacked uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:50:51 status unpacked uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:50:51 install liblash-dev 0.5.4-0ubuntu5 +2010-05-09 22:50:51 status half-installed liblash-dev 0.5.4-0ubuntu5 +2010-05-09 22:50:52 status unpacked liblash-dev 0.5.4-0ubuntu5 +2010-05-09 22:50:52 status unpacked liblash-dev 0.5.4-0ubuntu5 +2010-05-09 22:50:52 install libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:50:52 status half-installed libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:50:52 status half-installed libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:50:56 status unpacked libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:50:56 status unpacked libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:50:56 install libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:50:56 status half-installed libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:50:58 status unpacked libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:50:58 status unpacked libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:50:58 install libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:50:58 status half-installed libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:50:58 status half-installed libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:51:03 status unpacked libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:51:03 status unpacked libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:51:03 install libsndfile1-dev 1.0.21-2 +2010-05-09 22:51:03 status half-installed libsndfile1-dev 1.0.21-2 +2010-05-09 22:51:03 status half-installed libsndfile1-dev 1.0.21-2 +2010-05-09 22:51:05 status unpacked libsndfile1-dev 1.0.21-2 +2010-05-09 22:51:05 status unpacked libsndfile1-dev 1.0.21-2 +2010-05-09 22:51:06 install libfluidsynth-dev 1.1.1-2build1 +2010-05-09 22:51:06 status half-installed libfluidsynth-dev 1.1.1-2build1 +2010-05-09 22:51:08 status unpacked libfluidsynth-dev 1.1.1-2build1 +2010-05-09 22:51:08 status unpacked libfluidsynth-dev 1.1.1-2build1 +2010-05-09 22:51:08 install libftgl2 2.1.3~rc5-3 +2010-05-09 22:51:08 status half-installed libftgl2 2.1.3~rc5-3 +2010-05-09 22:51:08 status unpacked libftgl2 2.1.3~rc5-3 +2010-05-09 22:51:08 status unpacked libftgl2 2.1.3~rc5-3 +2010-05-09 22:51:08 install libgif-dev 4.1.6-9 +2010-05-09 22:51:08 status half-installed libgif-dev 4.1.6-9 +2010-05-09 22:51:10 status unpacked libgif-dev 4.1.6-9 +2010-05-09 22:51:10 status unpacked libgif-dev 4.1.6-9 +2010-05-09 22:51:10 install mesa-common-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:10 status half-installed mesa-common-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:14 status unpacked mesa-common-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:14 status unpacked mesa-common-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:14 install libgl1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:14 status half-installed libgl1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:14 status unpacked libgl1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:14 status unpacked libgl1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:15 install libglu1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:15 status half-installed libglu1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:15 status unpacked libglu1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:15 status unpacked libglu1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:51:15 install libimlib2 1.4.2-5build1 +2010-05-09 22:51:15 status half-installed libimlib2 1.4.2-5build1 +2010-05-09 22:51:17 status unpacked libimlib2 1.4.2-5build1 +2010-05-09 22:51:17 status unpacked libimlib2 1.4.2-5build1 +2010-05-09 22:51:17 install libtiffxx0c2 3.9.2-2 +2010-05-09 22:51:17 status half-installed libtiffxx0c2 3.9.2-2 +2010-05-09 22:51:17 status unpacked libtiffxx0c2 3.9.2-2 +2010-05-09 22:51:17 status unpacked libtiffxx0c2 3.9.2-2 +2010-05-09 22:51:17 install libtiff4-dev 3.9.2-2 +2010-05-09 22:51:17 status half-installed libtiff4-dev 3.9.2-2 +2010-05-09 22:51:17 status half-installed libtiff4-dev 3.9.2-2 +2010-05-09 22:51:20 status unpacked libtiff4-dev 3.9.2-2 +2010-05-09 22:51:20 status unpacked libtiff4-dev 3.9.2-2 +2010-05-09 22:51:20 install libimlib2-dev 1.4.2-5build1 +2010-05-09 22:51:20 status half-installed libimlib2-dev 1.4.2-5build1 +2010-05-09 22:51:20 status half-installed libimlib2-dev 1.4.2-5build1 +2010-05-09 22:51:20 status half-installed libimlib2-dev 1.4.2-5build1 +2010-05-09 22:51:23 status unpacked libimlib2-dev 1.4.2-5build1 +2010-05-09 22:51:23 status unpacked libimlib2-dev 1.4.2-5build1 +2010-05-09 22:51:23 install libmad0-dev 0.15.1b-4ubuntu1 +2010-05-09 22:51:23 status half-installed libmad0-dev 0.15.1b-4ubuntu1 +2010-05-09 22:51:24 status unpacked libmad0-dev 0.15.1b-4ubuntu1 +2010-05-09 22:51:24 status unpacked libmad0-dev 0.15.1b-4ubuntu1 +2010-05-09 22:51:24 install libmms-dev 0.4-2 +2010-05-09 22:51:24 status half-installed libmms-dev 0.4-2 +2010-05-09 22:51:25 status unpacked libmms-dev 0.4-2 +2010-05-09 22:51:25 status unpacked libmms-dev 0.4-2 +2010-05-09 22:51:25 install libusb-dev 2:0.1.12-14 +2010-05-09 22:51:25 status half-installed libusb-dev 2:0.1.12-14 +2010-05-09 22:51:26 status half-installed libusb-dev 2:0.1.12-14 +2010-05-09 22:51:26 status half-installed libusb-dev 2:0.1.12-14 +2010-05-09 22:51:28 status unpacked libusb-dev 2:0.1.12-14 +2010-05-09 22:51:28 status unpacked libusb-dev 2:0.1.12-14 +2010-05-09 22:51:28 install libmtp-dev 1.0.2-1ubuntu1 +2010-05-09 22:51:28 status half-installed libmtp-dev 1.0.2-1ubuntu1 +2010-05-09 22:51:29 status unpacked libmtp-dev 1.0.2-1ubuntu1 +2010-05-09 22:51:29 status unpacked libmtp-dev 1.0.2-1ubuntu1 +2010-05-09 22:51:29 install libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:51:29 status half-installed libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:51:29 status half-installed libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:51:35 status unpacked libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:51:35 status unpacked libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:51:35 install libprojectm-data 1.2.0-3 +2010-05-09 22:51:35 status half-installed libprojectm-data 1.2.0-3 +2010-05-09 22:51:58 status unpacked libprojectm-data 1.2.0-3 +2010-05-09 22:51:58 status unpacked libprojectm-data 1.2.0-3 +2010-05-09 22:51:58 install libprojectm2 1.2.0-3 +2010-05-09 22:51:58 status half-installed libprojectm2 1.2.0-3 +2010-05-09 22:51:58 status unpacked libprojectm2 1.2.0-3 +2010-05-09 22:51:59 status unpacked libprojectm2 1.2.0-3 +2010-05-09 22:51:59 install libprojectm-dev 1.2.0-3 +2010-05-09 22:51:59 status half-installed libprojectm-dev 1.2.0-3 +2010-05-09 22:51:59 status unpacked libprojectm-dev 1.2.0-3 +2010-05-09 22:51:59 status unpacked libprojectm-dev 1.2.0-3 +2010-05-09 22:52:00 install libresid-builder-dev 2.1.1-8 +2010-05-09 22:52:00 status half-installed libresid-builder-dev 2.1.1-8 +2010-05-09 22:52:00 status unpacked libresid-builder-dev 2.1.1-8 +2010-05-09 22:52:00 status unpacked libresid-builder-dev 2.1.1-8 +2010-05-09 22:52:00 install libaudio-dev 1.9.2-3 +2010-05-09 22:52:00 status half-installed libaudio-dev 1.9.2-3 +2010-05-09 22:52:00 status half-installed libaudio-dev 1.9.2-3 +2010-05-09 22:52:07 status unpacked libaudio-dev 1.9.2-3 +2010-05-09 22:52:07 status unpacked libaudio-dev 1.9.2-3 +2010-05-09 22:52:07 install libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:07 status half-installed libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:07 status half-installed libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:07 status half-installed libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:24 status unpacked libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:24 status unpacked libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:25 install libspeex-dev 1.2~rc1-1ubuntu1 +2010-05-09 22:52:25 status half-installed libspeex-dev 1.2~rc1-1ubuntu1 +2010-05-09 22:52:25 status unpacked libspeex-dev 1.2~rc1-1ubuntu1 +2010-05-09 22:52:25 status unpacked libspeex-dev 1.2~rc1-1ubuntu1 +2010-05-09 22:52:25 install libtheora-dev 1.1.1+dfsg.1-3 +2010-05-09 22:52:25 status half-installed libtheora-dev 1.1.1+dfsg.1-3 +2010-05-09 22:52:27 status unpacked libtheora-dev 1.1.1+dfsg.1-3 +2010-05-09 22:52:27 status unpacked libtheora-dev 1.1.1+dfsg.1-3 +2010-05-09 22:52:27 install libshout3-dev 2.2.2-5ubuntu1 +2010-05-09 22:52:27 status half-installed libshout3-dev 2.2.2-5ubuntu1 +2010-05-09 22:52:28 status unpacked libshout3-dev 2.2.2-5ubuntu1 +2010-05-09 22:52:28 status unpacked libshout3-dev 2.2.2-5ubuntu1 +2010-05-09 22:52:28 install libsidplay2-dev 2.1.1-8 +2010-05-09 22:52:28 status half-installed libsidplay2-dev 2.1.1-8 +2010-05-09 22:52:30 status unpacked libsidplay2-dev 2.1.1-8 +2010-05-09 22:52:30 status unpacked libsidplay2-dev 2.1.1-8 +2010-05-09 22:52:30 install libtag1-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:30 status half-installed libtag1-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:34 status unpacked libtag1-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:34 status unpacked libtag1-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:35 install libtagc0 1.6.3-0ubuntu1 +2010-05-09 22:52:35 status half-installed libtagc0 1.6.3-0ubuntu1 +2010-05-09 22:52:35 status unpacked libtagc0 1.6.3-0ubuntu1 +2010-05-09 22:52:35 status unpacked libtagc0 1.6.3-0ubuntu1 +2010-05-09 22:52:35 install libtagc0-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:35 status half-installed libtagc0-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:36 status unpacked libtagc0-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:36 status unpacked libtagc0-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:36 install libwavpack-dev 4.60.1-1 +2010-05-09 22:52:36 status half-installed libwavpack-dev 4.60.1-1 +2010-05-09 22:52:36 status unpacked libwavpack-dev 4.60.1-1 +2010-05-09 22:52:37 status unpacked libwavpack-dev 4.60.1-1 +2010-05-09 22:52:37 install liblircclient-dev 0.8.6-0ubuntu4 +2010-05-09 22:52:37 status half-installed liblircclient-dev 0.8.6-0ubuntu4 +2010-05-09 22:52:37 status unpacked liblircclient-dev 0.8.6-0ubuntu4 +2010-05-09 22:52:37 status unpacked liblircclient-dev 0.8.6-0ubuntu4 +2010-05-09 22:52:37 trigproc doc-base 0.9.5 0.9.5 +2010-05-09 22:52:37 status half-configured doc-base 0.9.5 +2010-05-09 22:52:39 status installed doc-base 0.9.5 +2010-05-09 22:52:39 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-09 22:52:39 status half-configured man-db 2.5.7-2 +2010-05-09 22:52:44 status installed man-db 2.5.7-2 +2010-05-09 22:52:44 trigproc install-info 4.13a.dfsg.1-5ubuntu1 4.13a.dfsg.1-5ubuntu1 +2010-05-09 22:52:44 status half-configured install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-09 22:52:45 status installed install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-09 22:52:46 startup packages configure +2010-05-09 22:52:46 configure libglade2-dev 1:2.6.4-1build1 1:2.6.4-1build1 +2010-05-09 22:52:46 status unpacked libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:52:47 status half-configured libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:52:47 status installed libglade2-dev 1:2.6.4-1build1 +2010-05-09 22:52:47 configure libmcs-dev 0.7.1-1 0.7.1-1 +2010-05-09 22:52:47 status unpacked libmcs-dev 0.7.1-1 +2010-05-09 22:52:47 status half-configured libmcs-dev 0.7.1-1 +2010-05-09 22:52:47 status installed libmcs-dev 0.7.1-1 +2010-05-09 22:52:47 configure libmowgli-dev 0.6.1-1 0.6.1-1 +2010-05-09 22:52:47 status unpacked libmowgli-dev 0.6.1-1 +2010-05-09 22:52:47 status half-configured libmowgli-dev 0.6.1-1 +2010-05-09 22:52:47 status installed libmowgli-dev 0.6.1-1 +2010-05-09 22:52:47 configure libsamplerate0-dev 0.1.7-3 0.1.7-3 +2010-05-09 22:52:47 status unpacked libsamplerate0-dev 0.1.7-3 +2010-05-09 22:52:47 status half-configured libsamplerate0-dev 0.1.7-3 +2010-05-09 22:52:47 status installed libsamplerate0-dev 0.1.7-3 +2010-05-09 22:52:47 configure audacious-dev 2.3-1ubuntu4 2.3-1ubuntu4 +2010-05-09 22:52:47 status unpacked audacious-dev 2.3-1ubuntu4 +2010-05-09 22:52:47 status half-configured audacious-dev 2.3-1ubuntu4 +2010-05-09 22:52:47 status installed audacious-dev 2.3-1ubuntu4 +2010-05-09 22:52:47 configure libgssrpc4 1.8.1+dfsg-2 1.8.1+dfsg-2 +2010-05-09 22:52:47 status unpacked libgssrpc4 1.8.1+dfsg-2 +2010-05-09 22:52:47 status half-configured libgssrpc4 1.8.1+dfsg-2 +2010-05-09 22:52:48 status installed libgssrpc4 1.8.1+dfsg-2 +2010-05-09 22:52:48 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-09 22:52:48 configure libkdb5-4 1.8.1+dfsg-2 1.8.1+dfsg-2 +2010-05-09 22:52:48 status unpacked libkdb5-4 1.8.1+dfsg-2 +2010-05-09 22:52:48 status half-configured libkdb5-4 1.8.1+dfsg-2 +2010-05-09 22:52:48 status installed libkdb5-4 1.8.1+dfsg-2 +2010-05-09 22:52:48 configure libkadm5srv-mit7 1.8.1+dfsg-2 1.8.1+dfsg-2 +2010-05-09 22:52:48 status unpacked libkadm5srv-mit7 1.8.1+dfsg-2 +2010-05-09 22:52:48 status half-configured libkadm5srv-mit7 1.8.1+dfsg-2 +2010-05-09 22:52:48 status installed libkadm5srv-mit7 1.8.1+dfsg-2 +2010-05-09 22:52:48 configure libkadm5clnt-mit7 1.8.1+dfsg-2 1.8.1+dfsg-2 +2010-05-09 22:52:48 status unpacked libkadm5clnt-mit7 1.8.1+dfsg-2 +2010-05-09 22:52:48 status half-configured libkadm5clnt-mit7 1.8.1+dfsg-2 +2010-05-09 22:52:48 status installed libkadm5clnt-mit7 1.8.1+dfsg-2 +2010-05-09 22:52:48 configure comerr-dev 2.1-1.41.11-1ubuntu2 2.1-1.41.11-1ubuntu2 +2010-05-09 22:52:48 status unpacked comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:52:48 status half-configured comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:52:49 status installed comerr-dev 2.1-1.41.11-1ubuntu2 +2010-05-09 22:52:49 configure krb5-multidev 1.8.1+dfsg-2 1.8.1+dfsg-2 +2010-05-09 22:52:49 status unpacked krb5-multidev 1.8.1+dfsg-2 +2010-05-09 22:52:49 status half-configured krb5-multidev 1.8.1+dfsg-2 +2010-05-09 22:52:49 status installed krb5-multidev 1.8.1+dfsg-2 +2010-05-09 22:52:49 configure libslang2-dev 2.2.2-2ubuntu1 2.2.2-2ubuntu1 +2010-05-09 22:52:49 status unpacked libslang2-dev 2.2.2-2ubuntu1 +2010-05-09 22:52:49 status half-configured libslang2-dev 2.2.2-2ubuntu1 +2010-05-09 22:52:49 status installed libslang2-dev 2.2.2-2ubuntu1 +2010-05-09 22:52:49 configure libaa1-dev 1.4p5-38build1 1.4p5-38build1 +2010-05-09 22:52:49 status unpacked libaa1-dev 1.4p5-38build1 +2010-05-09 22:52:49 status half-configured libaa1-dev 1.4p5-38build1 +2010-05-09 22:52:49 status installed libaa1-dev 1.4p5-38build1 +2010-05-09 22:52:49 configure libasound2-dev 1.0.22-0ubuntu7 1.0.22-0ubuntu7 +2010-05-09 22:52:49 status unpacked libasound2-dev 1.0.22-0ubuntu7 +2010-05-09 22:52:49 status half-configured libasound2-dev 1.0.22-0ubuntu7 +2010-05-09 22:52:49 status installed libasound2-dev 1.0.22-0ubuntu7 +2010-05-09 22:52:49 configure libaudiofile-dev 0.2.6-8ubuntu1 0.2.6-8ubuntu1 +2010-05-09 22:52:49 status unpacked libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:52:49 status half-configured libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:52:49 status installed libaudiofile-dev 0.2.6-8ubuntu1 +2010-05-09 22:52:49 configure libavutil-dev 4:0.5.1-1ubuntu1 4:0.5.1-1ubuntu1 +2010-05-09 22:52:49 status unpacked libavutil-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:49 status half-configured libavutil-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 status installed libavutil-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 configure libavcodec-dev 4:0.5.1-1ubuntu1 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 status unpacked libavcodec-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 status half-configured libavcodec-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 status installed libavcodec-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 configure libavformat-dev 4:0.5.1-1ubuntu1 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 status unpacked libavformat-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 status half-configured libavformat-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 status installed libavformat-dev 4:0.5.1-1ubuntu1 +2010-05-09 22:52:50 configure libbinio-dev 1.4-14 1.4-14 +2010-05-09 22:52:50 status unpacked libbinio-dev 1.4-14 +2010-05-09 22:52:50 status half-configured libbinio-dev 1.4-14 +2010-05-09 22:52:50 status installed libbinio-dev 1.4-14 +2010-05-09 22:52:50 configure libcaca-dev 0.99.beta16-3 0.99.beta16-3 +2010-05-09 22:52:50 status unpacked libcaca-dev 0.99.beta16-3 +2010-05-09 22:52:50 status half-configured libcaca-dev 0.99.beta16-3 +2010-05-09 22:52:50 status installed libcaca-dev 0.99.beta16-3 +2010-05-09 22:52:50 configure libcddb2-dev 1.3.2-0ubuntu1 1.3.2-0ubuntu1 +2010-05-09 22:52:50 status unpacked libcddb2-dev 1.3.2-0ubuntu1 +2010-05-09 22:52:50 status half-configured libcddb2-dev 1.3.2-0ubuntu1 +2010-05-09 22:52:50 status installed libcddb2-dev 1.3.2-0ubuntu1 +2010-05-09 22:52:50 configure libcdio-dev 0.81-4 0.81-4 +2010-05-09 22:52:50 status unpacked libcdio-dev 0.81-4 +2010-05-09 22:52:51 status half-configured libcdio-dev 0.81-4 +2010-05-09 22:52:51 status installed libcdio-dev 0.81-4 +2010-05-09 22:52:51 configure libcdio-cdda-dev 0.81-4 0.81-4 +2010-05-09 22:52:51 status unpacked libcdio-cdda-dev 0.81-4 +2010-05-09 22:52:51 status half-configured libcdio-cdda-dev 0.81-4 +2010-05-09 22:52:51 status installed libcdio-cdda-dev 0.81-4 +2010-05-09 22:52:51 configure libcue-dev 1.3.0-1 1.3.0-1 +2010-05-09 22:52:51 status unpacked libcue-dev 1.3.0-1 +2010-05-09 22:52:51 status half-configured libcue-dev 1.3.0-1 +2010-05-09 22:52:51 status installed libcue-dev 1.3.0-1 +2010-05-09 22:52:51 configure libkrb5-dev 1.8.1+dfsg-2 1.8.1+dfsg-2 +2010-05-09 22:52:51 status unpacked libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:52:51 status half-configured libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:52:51 status installed libkrb5-dev 1.8.1+dfsg-2 +2010-05-09 22:52:51 configure libldap2-dev 2.4.21-0ubuntu5 2.4.21-0ubuntu5 +2010-05-09 22:52:51 status unpacked libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:52:51 status half-configured libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:52:51 status installed libldap2-dev 2.4.21-0ubuntu5 +2010-05-09 22:52:51 configure libcurl4-gnutls-dev 7.19.7-1ubuntu1 7.19.7-1ubuntu1 +2010-05-09 22:52:51 status unpacked libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:52:51 status half-configured libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:52:51 status installed libcurl4-gnutls-dev 7.19.7-1ubuntu1 +2010-05-09 22:52:51 configure libdrm-dev 2.4.18-1ubuntu3 2.4.18-1ubuntu3 +2010-05-09 22:52:51 status unpacked libdrm-dev 2.4.18-1ubuntu3 +2010-05-09 22:52:52 status half-configured libdrm-dev 2.4.18-1ubuntu3 +2010-05-09 22:52:52 status installed libdrm-dev 2.4.18-1ubuntu3 +2010-05-09 22:52:52 configure libesd0-dev 0.2.41-6ubuntu1 0.2.41-6ubuntu1 +2010-05-09 22:52:52 status unpacked libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:52:52 status half-configured libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:52:52 status installed libesd0-dev 0.2.41-6ubuntu1 +2010-05-09 22:52:52 configure libfaad-dev 2.7-4 2.7-4 +2010-05-09 22:52:52 status unpacked libfaad-dev 2.7-4 +2010-05-09 22:52:52 status half-configured libfaad-dev 2.7-4 +2010-05-09 22:52:52 status installed libfaad-dev 2.7-4 +2010-05-09 22:52:52 configure libogg-dev 1.1.4~dfsg-2 1.1.4~dfsg-2 +2010-05-09 22:52:52 status unpacked libogg-dev 1.1.4~dfsg-2 +2010-05-09 22:52:52 status half-configured libogg-dev 1.1.4~dfsg-2 +2010-05-09 22:52:52 status installed libogg-dev 1.1.4~dfsg-2 +2010-05-09 22:52:52 configure libflac-dev 1.2.1-2build2 1.2.1-2build2 +2010-05-09 22:52:52 status unpacked libflac-dev 1.2.1-2build2 +2010-05-09 22:52:52 status half-configured libflac-dev 1.2.1-2build2 +2010-05-09 22:52:52 status installed libflac-dev 1.2.1-2build2 +2010-05-09 22:52:52 configure uuid-dev 2.17.2-0ubuntu1 2.17.2-0ubuntu1 +2010-05-09 22:52:52 status unpacked uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:52:52 status half-configured uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:52:53 status installed uuid-dev 2.17.2-0ubuntu1 +2010-05-09 22:52:53 configure liblash-dev 0.5.4-0ubuntu5 0.5.4-0ubuntu5 +2010-05-09 22:52:53 status unpacked liblash-dev 0.5.4-0ubuntu5 +2010-05-09 22:52:53 status half-configured liblash-dev 0.5.4-0ubuntu5 +2010-05-09 22:52:53 status installed liblash-dev 0.5.4-0ubuntu5 +2010-05-09 22:52:53 configure libjack-dev 0.118+svn3796-1ubuntu2 0.118+svn3796-1ubuntu2 +2010-05-09 22:52:53 status unpacked libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:52:53 status half-configured libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:52:53 status installed libjack-dev 0.118+svn3796-1ubuntu2 +2010-05-09 22:52:53 configure libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:52:53 status unpacked libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:52:53 status half-configured libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:52:53 status installed libpulse-dev 1:0.9.22~0.9.21+stable-queue-32-g8478-0ubuntu14 +2010-05-09 22:52:53 configure libvorbis-dev 1.2.3-3ubuntu1 1.2.3-3ubuntu1 +2010-05-09 22:52:53 status unpacked libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:52:53 status half-configured libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:52:53 status installed libvorbis-dev 1.2.3-3ubuntu1 +2010-05-09 22:52:53 configure libsndfile1-dev 1.0.21-2 1.0.21-2 +2010-05-09 22:52:53 status unpacked libsndfile1-dev 1.0.21-2 +2010-05-09 22:52:53 status half-configured libsndfile1-dev 1.0.21-2 +2010-05-09 22:52:54 status installed libsndfile1-dev 1.0.21-2 +2010-05-09 22:52:54 configure libfluidsynth-dev 1.1.1-2build1 1.1.1-2build1 +2010-05-09 22:52:54 status unpacked libfluidsynth-dev 1.1.1-2build1 +2010-05-09 22:52:54 status half-configured libfluidsynth-dev 1.1.1-2build1 +2010-05-09 22:52:54 status installed libfluidsynth-dev 1.1.1-2build1 +2010-05-09 22:52:54 configure libftgl2 2.1.3~rc5-3 2.1.3~rc5-3 +2010-05-09 22:52:54 status unpacked libftgl2 2.1.3~rc5-3 +2010-05-09 22:52:54 status half-configured libftgl2 2.1.3~rc5-3 +2010-05-09 22:52:54 status installed libftgl2 2.1.3~rc5-3 +2010-05-09 22:52:54 configure libgif-dev 4.1.6-9 4.1.6-9 +2010-05-09 22:52:54 status unpacked libgif-dev 4.1.6-9 +2010-05-09 22:52:54 status half-configured libgif-dev 4.1.6-9 +2010-05-09 22:52:55 status installed libgif-dev 4.1.6-9 +2010-05-09 22:52:55 configure mesa-common-dev 7.7.1-1ubuntu3 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status unpacked mesa-common-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status half-configured mesa-common-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status installed mesa-common-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 configure libgl1-mesa-dev 7.7.1-1ubuntu3 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status unpacked libgl1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status half-configured libgl1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status installed libgl1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 configure libglu1-mesa-dev 7.7.1-1ubuntu3 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status unpacked libglu1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status half-configured libglu1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 status installed libglu1-mesa-dev 7.7.1-1ubuntu3 +2010-05-09 22:52:55 configure libimlib2 1.4.2-5build1 1.4.2-5build1 +2010-05-09 22:52:55 status unpacked libimlib2 1.4.2-5build1 +2010-05-09 22:52:55 status half-configured libimlib2 1.4.2-5build1 +2010-05-09 22:52:55 status installed libimlib2 1.4.2-5build1 +2010-05-09 22:52:55 configure libtiffxx0c2 3.9.2-2 3.9.2-2 +2010-05-09 22:52:55 status unpacked libtiffxx0c2 3.9.2-2 +2010-05-09 22:52:55 status half-configured libtiffxx0c2 3.9.2-2 +2010-05-09 22:52:55 status installed libtiffxx0c2 3.9.2-2 +2010-05-09 22:52:56 configure libtiff4-dev 3.9.2-2 3.9.2-2 +2010-05-09 22:52:56 status unpacked libtiff4-dev 3.9.2-2 +2010-05-09 22:52:56 status half-configured libtiff4-dev 3.9.2-2 +2010-05-09 22:52:56 status installed libtiff4-dev 3.9.2-2 +2010-05-09 22:52:56 configure libimlib2-dev 1.4.2-5build1 1.4.2-5build1 +2010-05-09 22:52:56 status unpacked libimlib2-dev 1.4.2-5build1 +2010-05-09 22:52:56 status half-configured libimlib2-dev 1.4.2-5build1 +2010-05-09 22:52:56 status installed libimlib2-dev 1.4.2-5build1 +2010-05-09 22:52:56 configure libmad0-dev 0.15.1b-4ubuntu1 0.15.1b-4ubuntu1 +2010-05-09 22:52:56 status unpacked libmad0-dev 0.15.1b-4ubuntu1 +2010-05-09 22:52:56 status half-configured libmad0-dev 0.15.1b-4ubuntu1 +2010-05-09 22:52:56 status installed libmad0-dev 0.15.1b-4ubuntu1 +2010-05-09 22:52:56 configure libmms-dev 0.4-2 0.4-2 +2010-05-09 22:52:56 status unpacked libmms-dev 0.4-2 +2010-05-09 22:52:56 status half-configured libmms-dev 0.4-2 +2010-05-09 22:52:56 status installed libmms-dev 0.4-2 +2010-05-09 22:52:56 configure libusb-dev 2:0.1.12-14 2:0.1.12-14 +2010-05-09 22:52:56 status unpacked libusb-dev 2:0.1.12-14 +2010-05-09 22:52:56 status half-configured libusb-dev 2:0.1.12-14 +2010-05-09 22:52:56 status installed libusb-dev 2:0.1.12-14 +2010-05-09 22:52:56 configure libmtp-dev 1.0.2-1ubuntu1 1.0.2-1ubuntu1 +2010-05-09 22:52:56 status unpacked libmtp-dev 1.0.2-1ubuntu1 +2010-05-09 22:52:57 status half-configured libmtp-dev 1.0.2-1ubuntu1 +2010-05-09 22:52:57 status installed libmtp-dev 1.0.2-1ubuntu1 +2010-05-09 22:52:57 configure libneon27-gnutls-dev 0.29.0-1 0.29.0-1 +2010-05-09 22:52:57 status unpacked libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:52:57 status half-configured libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:52:57 status installed libneon27-gnutls-dev 0.29.0-1 +2010-05-09 22:52:57 configure libprojectm-data 1.2.0-3 1.2.0-3 +2010-05-09 22:52:57 status unpacked libprojectm-data 1.2.0-3 +2010-05-09 22:52:57 status half-configured libprojectm-data 1.2.0-3 +2010-05-09 22:52:57 status installed libprojectm-data 1.2.0-3 +2010-05-09 22:52:57 configure libprojectm2 1.2.0-3 1.2.0-3 +2010-05-09 22:52:57 status unpacked libprojectm2 1.2.0-3 +2010-05-09 22:52:57 status half-configured libprojectm2 1.2.0-3 +2010-05-09 22:52:57 status installed libprojectm2 1.2.0-3 +2010-05-09 22:52:57 configure libprojectm-dev 1.2.0-3 1.2.0-3 +2010-05-09 22:52:57 status unpacked libprojectm-dev 1.2.0-3 +2010-05-09 22:52:57 status half-configured libprojectm-dev 1.2.0-3 +2010-05-09 22:52:57 status installed libprojectm-dev 1.2.0-3 +2010-05-09 22:52:57 configure libresid-builder-dev 2.1.1-8 2.1.1-8 +2010-05-09 22:52:57 status unpacked libresid-builder-dev 2.1.1-8 +2010-05-09 22:52:58 status half-configured libresid-builder-dev 2.1.1-8 +2010-05-09 22:52:58 status installed libresid-builder-dev 2.1.1-8 +2010-05-09 22:52:58 configure libaudio-dev 1.9.2-3 1.9.2-3 +2010-05-09 22:52:58 status unpacked libaudio-dev 1.9.2-3 +2010-05-09 22:52:58 status half-configured libaudio-dev 1.9.2-3 +2010-05-09 22:52:58 status installed libaudio-dev 1.9.2-3 +2010-05-09 22:52:58 configure libsdl1.2-dev 1.2.14-4ubuntu1 1.2.14-4ubuntu1 +2010-05-09 22:52:58 status unpacked libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:58 status half-configured libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:58 status installed libsdl1.2-dev 1.2.14-4ubuntu1 +2010-05-09 22:52:58 configure libspeex-dev 1.2~rc1-1ubuntu1 1.2~rc1-1ubuntu1 +2010-05-09 22:52:58 status unpacked libspeex-dev 1.2~rc1-1ubuntu1 +2010-05-09 22:52:58 status half-configured libspeex-dev 1.2~rc1-1ubuntu1 +2010-05-09 22:52:58 status installed libspeex-dev 1.2~rc1-1ubuntu1 +2010-05-09 22:52:58 configure libtheora-dev 1.1.1+dfsg.1-3 1.1.1+dfsg.1-3 +2010-05-09 22:52:58 status unpacked libtheora-dev 1.1.1+dfsg.1-3 +2010-05-09 22:52:58 status half-configured libtheora-dev 1.1.1+dfsg.1-3 +2010-05-09 22:52:58 status installed libtheora-dev 1.1.1+dfsg.1-3 +2010-05-09 22:52:58 configure libshout3-dev 2.2.2-5ubuntu1 2.2.2-5ubuntu1 +2010-05-09 22:52:58 status unpacked libshout3-dev 2.2.2-5ubuntu1 +2010-05-09 22:52:58 status half-configured libshout3-dev 2.2.2-5ubuntu1 +2010-05-09 22:52:58 status installed libshout3-dev 2.2.2-5ubuntu1 +2010-05-09 22:52:59 configure libsidplay2-dev 2.1.1-8 2.1.1-8 +2010-05-09 22:52:59 status unpacked libsidplay2-dev 2.1.1-8 +2010-05-09 22:52:59 status half-configured libsidplay2-dev 2.1.1-8 +2010-05-09 22:52:59 status installed libsidplay2-dev 2.1.1-8 +2010-05-09 22:52:59 configure libtag1-dev 1.6.3-0ubuntu1 1.6.3-0ubuntu1 +2010-05-09 22:52:59 status unpacked libtag1-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:59 status half-configured libtag1-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:59 status installed libtag1-dev 1.6.3-0ubuntu1 +2010-05-09 22:52:59 configure libtagc0 1.6.3-0ubuntu1 1.6.3-0ubuntu1 +2010-05-09 22:52:59 status unpacked libtagc0 1.6.3-0ubuntu1 +2010-05-09 22:52:59 status half-configured libtagc0 1.6.3-0ubuntu1 +2010-05-09 22:52:59 status installed libtagc0 1.6.3-0ubuntu1 +2010-05-09 22:53:00 configure libtagc0-dev 1.6.3-0ubuntu1 1.6.3-0ubuntu1 +2010-05-09 22:53:00 status unpacked libtagc0-dev 1.6.3-0ubuntu1 +2010-05-09 22:53:00 status half-configured libtagc0-dev 1.6.3-0ubuntu1 +2010-05-09 22:53:00 status installed libtagc0-dev 1.6.3-0ubuntu1 +2010-05-09 22:53:00 configure libwavpack-dev 4.60.1-1 4.60.1-1 +2010-05-09 22:53:00 status unpacked libwavpack-dev 4.60.1-1 +2010-05-09 22:53:00 status half-configured libwavpack-dev 4.60.1-1 +2010-05-09 22:53:00 status installed libwavpack-dev 4.60.1-1 +2010-05-09 22:53:00 configure liblircclient-dev 0.8.6-0ubuntu4 0.8.6-0ubuntu4 +2010-05-09 22:53:00 status unpacked liblircclient-dev 0.8.6-0ubuntu4 +2010-05-09 22:53:00 status half-configured liblircclient-dev 0.8.6-0ubuntu4 +2010-05-09 22:53:00 status installed liblircclient-dev 0.8.6-0ubuntu4 +2010-05-09 22:53:00 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-09 22:53:00 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-09 22:53:01 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-09 22:56:44 startup archives unpack +2010-05-09 22:56:44 install libxmmsclient6 0.7DrNo-4ubuntu1 +2010-05-09 22:56:44 status half-installed libxmmsclient6 0.7DrNo-4ubuntu1 +2010-05-09 22:56:45 status unpacked libxmmsclient6 0.7DrNo-4ubuntu1 +2010-05-09 22:56:45 status unpacked libxmmsclient6 0.7DrNo-4ubuntu1 +2010-05-09 22:56:45 install libxmmsclient-glib1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:45 status half-installed libxmmsclient-glib1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:45 status unpacked libxmmsclient-glib1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:45 status unpacked libxmmsclient-glib1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:46 install xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:46 status half-installed xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:46 status triggers-pending man-db 2.5.7-2 +2010-05-09 22:56:46 status half-installed xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:46 status unpacked xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:46 status unpacked xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:47 install xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:47 status half-installed xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:47 status half-installed xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:48 status unpacked xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:48 status unpacked xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:48 install xmms2-icon 0.7DrNo-4ubuntu1 +2010-05-09 22:56:48 status half-installed xmms2-icon 0.7DrNo-4ubuntu1 +2010-05-09 22:56:49 status unpacked xmms2-icon 0.7DrNo-4ubuntu1 +2010-05-09 22:56:49 status unpacked xmms2-icon 0.7DrNo-4ubuntu1 +2010-05-09 22:56:49 install xmms2-plugin-alsa 0.7DrNo-4ubuntu1 +2010-05-09 22:56:49 status half-installed xmms2-plugin-alsa 0.7DrNo-4ubuntu1 +2010-05-09 22:56:50 status unpacked xmms2-plugin-alsa 0.7DrNo-4ubuntu1 +2010-05-09 22:56:50 status unpacked xmms2-plugin-alsa 0.7DrNo-4ubuntu1 +2010-05-09 22:56:50 install xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:50 status half-installed xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:50 status unpacked xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:50 status unpacked xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:51 install xmms2-plugin-mad 0.7DrNo-4ubuntu1 +2010-05-09 22:56:51 status half-installed xmms2-plugin-mad 0.7DrNo-4ubuntu1 +2010-05-09 22:56:51 status unpacked xmms2-plugin-mad 0.7DrNo-4ubuntu1 +2010-05-09 22:56:51 status unpacked xmms2-plugin-mad 0.7DrNo-4ubuntu1 +2010-05-09 22:56:51 install xmms2-plugin-pulse 0.7DrNo-4ubuntu1 +2010-05-09 22:56:51 status half-installed xmms2-plugin-pulse 0.7DrNo-4ubuntu1 +2010-05-09 22:56:52 status unpacked xmms2-plugin-pulse 0.7DrNo-4ubuntu1 +2010-05-09 22:56:52 status unpacked xmms2-plugin-pulse 0.7DrNo-4ubuntu1 +2010-05-09 22:56:52 install xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 +2010-05-09 22:56:52 status half-installed xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 +2010-05-09 22:56:53 status unpacked xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 +2010-05-09 22:56:53 status unpacked xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 +2010-05-09 22:56:53 install xmms2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:53 status half-installed xmms2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:53 status unpacked xmms2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:53 status unpacked xmms2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:54 install xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:54 status half-installed xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:54 status half-installed xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:54 status unpacked xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:54 status unpacked xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:54 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-09 22:56:54 status half-configured man-db 2.5.7-2 +2010-05-09 22:56:56 status installed man-db 2.5.7-2 +2010-05-09 22:56:57 startup packages configure +2010-05-09 22:56:57 configure libxmmsclient6 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status unpacked libxmmsclient6 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status half-configured libxmmsclient6 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status installed libxmmsclient6 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-09 22:56:57 configure libxmmsclient-glib1 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status unpacked libxmmsclient-glib1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status half-configured libxmmsclient-glib1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status installed libxmmsclient-glib1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 configure xmms2-client-cli 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status unpacked xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status half-configured xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:57 status installed xmms2-client-cli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 configure xmms2-core 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status unpacked xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status half-configured xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status installed xmms2-core 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 configure xmms2-icon 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status unpacked xmms2-icon 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status half-configured xmms2-icon 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status installed xmms2-icon 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 configure xmms2-plugin-alsa 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status unpacked xmms2-plugin-alsa 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status half-configured xmms2-plugin-alsa 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status installed xmms2-plugin-alsa 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 configure xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status unpacked xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status half-configured xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status installed xmms2-plugin-id3v2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 configure xmms2-plugin-mad 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status unpacked xmms2-plugin-mad 0.7DrNo-4ubuntu1 +2010-05-09 22:56:58 status half-configured xmms2-plugin-mad 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status installed xmms2-plugin-mad 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 configure xmms2-plugin-pulse 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status unpacked xmms2-plugin-pulse 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status half-configured xmms2-plugin-pulse 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status installed xmms2-plugin-pulse 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 configure xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status unpacked xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status half-configured xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status installed xmms2-plugin-vorbis 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 configure xmms2 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status unpacked xmms2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status half-configured xmms2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status installed xmms2 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 configure xmms2-client-nycli 0.7DrNo-4ubuntu1 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status unpacked xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status half-configured xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 status installed xmms2-client-nycli 0.7DrNo-4ubuntu1 +2010-05-09 22:56:59 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-09 22:56:59 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-09 22:57:00 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-09 23:02:59 startup archives unpack +2010-05-09 23:02:59 install libsdl-mixer1.2 1.2.8-6build1 +2010-05-09 23:02:59 status half-installed libsdl-mixer1.2 1.2.8-6build1 +2010-05-09 23:03:01 status unpacked libsdl-mixer1.2 1.2.8-6build1 +2010-05-09 23:03:01 status unpacked libsdl-mixer1.2 1.2.8-6build1 +2010-05-09 23:03:01 install python-sip 4.10.1-0ubuntu1 +2010-05-09 23:03:01 status half-installed python-sip 4.10.1-0ubuntu1 +2010-05-09 23:03:02 status unpacked python-sip 4.10.1-0ubuntu1 +2010-05-09 23:03:02 status unpacked python-sip 4.10.1-0ubuntu1 +2010-05-09 23:03:02 install python-qt3 3.18.1-4ubuntu1 +2010-05-09 23:03:02 status half-installed python-qt3 3.18.1-4ubuntu1 +2010-05-09 23:03:03 status unpacked python-qt3 3.18.1-4ubuntu1 +2010-05-09 23:03:03 status unpacked python-qt3 3.18.1-4ubuntu1 +2010-05-09 23:03:04 install xbmc-bin 1:9.11-lucid1 +2010-05-09 23:03:04 status half-installed xbmc-bin 1:9.11-lucid1 +2010-05-09 23:03:09 status unpacked xbmc-bin 1:9.11-lucid1 +2010-05-09 23:03:09 status unpacked xbmc-bin 1:9.11-lucid1 +2010-05-09 23:03:09 install xbmc-data 1:9.11-lucid1 +2010-05-09 23:03:09 status half-installed xbmc-data 1:9.11-lucid1 +2010-05-09 23:03:09 status triggers-pending man-db 2.5.7-2 +2010-05-09 23:03:09 status half-installed xbmc-data 1:9.11-lucid1 +2010-05-09 23:03:10 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-09 23:03:11 status half-installed xbmc-data 1:9.11-lucid1 +2010-05-09 23:03:11 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-09 23:03:11 status half-installed xbmc-data 1:9.11-lucid1 +2010-05-09 23:03:45 status unpacked xbmc-data 1:9.11-lucid1 +2010-05-09 23:03:45 status unpacked xbmc-data 1:9.11-lucid1 +2010-05-09 23:03:45 install xbmc-skin-confluence 1:9.11-lucid1 +2010-05-09 23:03:45 status half-installed xbmc-skin-confluence 1:9.11-lucid1 +2010-05-09 23:03:52 status unpacked xbmc-skin-confluence 1:9.11-lucid1 +2010-05-09 23:03:52 status unpacked xbmc-skin-confluence 1:9.11-lucid1 +2010-05-09 23:03:52 install xbmc-web-pm3 1:9.11-lucid1 +2010-05-09 23:03:52 status half-installed xbmc-web-pm3 1:9.11-lucid1 +2010-05-09 23:03:57 status unpacked xbmc-web-pm3 1:9.11-lucid1 +2010-05-09 23:03:57 status unpacked xbmc-web-pm3 1:9.11-lucid1 +2010-05-09 23:03:57 install xbmc 1:9.11-lucid1 +2010-05-09 23:03:57 status half-installed xbmc 1:9.11-lucid1 +2010-05-09 23:03:58 status unpacked xbmc 1:9.11-lucid1 +2010-05-09 23:03:58 status unpacked xbmc 1:9.11-lucid1 +2010-05-09 23:03:58 install xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:03:58 status half-installed xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:03:58 status half-installed xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:03:58 status unpacked xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:03:59 status unpacked xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:03:59 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-09 23:03:59 status half-configured man-db 2.5.7-2 +2010-05-09 23:04:00 status installed man-db 2.5.7-2 +2010-05-09 23:04:00 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-09 23:04:00 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-09 23:04:01 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-09 23:04:01 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-09 23:04:01 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-09 23:04:01 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-09 23:04:01 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-09 23:04:01 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-09 23:04:01 status half-configured python-support 1.0.4ubuntu1 +2010-05-09 23:04:06 status installed python-support 1.0.4ubuntu1 +2010-05-09 23:04:07 startup packages configure +2010-05-09 23:04:07 configure libsdl-mixer1.2 1.2.8-6build1 1.2.8-6build1 +2010-05-09 23:04:07 status unpacked libsdl-mixer1.2 1.2.8-6build1 +2010-05-09 23:04:07 status half-configured libsdl-mixer1.2 1.2.8-6build1 +2010-05-09 23:04:07 status installed libsdl-mixer1.2 1.2.8-6build1 +2010-05-09 23:04:07 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-09 23:04:07 configure python-sip 4.10.1-0ubuntu1 4.10.1-0ubuntu1 +2010-05-09 23:04:07 status unpacked python-sip 4.10.1-0ubuntu1 +2010-05-09 23:04:07 status half-configured python-sip 4.10.1-0ubuntu1 +2010-05-09 23:04:07 status installed python-sip 4.10.1-0ubuntu1 +2010-05-09 23:04:08 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-09 23:04:08 configure python-qt3 3.18.1-4ubuntu1 3.18.1-4ubuntu1 +2010-05-09 23:04:08 status unpacked python-qt3 3.18.1-4ubuntu1 +2010-05-09 23:04:08 status half-configured python-qt3 3.18.1-4ubuntu1 +2010-05-09 23:04:08 status installed python-qt3 3.18.1-4ubuntu1 +2010-05-09 23:04:08 configure xbmc-bin 1:9.11-lucid1 1:9.11-lucid1 +2010-05-09 23:04:08 status unpacked xbmc-bin 1:9.11-lucid1 +2010-05-09 23:04:08 status half-configured xbmc-bin 1:9.11-lucid1 +2010-05-09 23:04:08 status installed xbmc-bin 1:9.11-lucid1 +2010-05-09 23:04:08 configure xbmc-data 1:9.11-lucid1 1:9.11-lucid1 +2010-05-09 23:04:08 status unpacked xbmc-data 1:9.11-lucid1 +2010-05-09 23:04:08 status half-configured xbmc-data 1:9.11-lucid1 +2010-05-09 23:04:08 status installed xbmc-data 1:9.11-lucid1 +2010-05-09 23:04:08 configure xbmc-skin-confluence 1:9.11-lucid1 1:9.11-lucid1 +2010-05-09 23:04:08 status unpacked xbmc-skin-confluence 1:9.11-lucid1 +2010-05-09 23:04:08 status half-configured xbmc-skin-confluence 1:9.11-lucid1 +2010-05-09 23:04:08 status installed xbmc-skin-confluence 1:9.11-lucid1 +2010-05-09 23:04:08 configure xbmc-web-pm3 1:9.11-lucid1 1:9.11-lucid1 +2010-05-09 23:04:08 status unpacked xbmc-web-pm3 1:9.11-lucid1 +2010-05-09 23:04:08 status half-configured xbmc-web-pm3 1:9.11-lucid1 +2010-05-09 23:04:09 status installed xbmc-web-pm3 1:9.11-lucid1 +2010-05-09 23:04:09 configure xbmc 1:9.11-lucid1 1:9.11-lucid1 +2010-05-09 23:04:09 status unpacked xbmc 1:9.11-lucid1 +2010-05-09 23:04:09 status half-configured xbmc 1:9.11-lucid1 +2010-05-09 23:04:09 status installed xbmc 1:9.11-lucid1 +2010-05-09 23:04:09 configure xbmc-standalone 1:9.11-lucid1 1:9.11-lucid1 +2010-05-09 23:04:09 status unpacked xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:04:09 status half-configured xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:04:09 status installed xbmc-standalone 1:9.11-lucid1 +2010-05-09 23:04:09 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-09 23:04:09 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-09 23:04:09 status installed libc-bin 2.11.1-0ubuntu7 +2010-05-09 23:04:09 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-09 23:04:09 status half-configured python-support 1.0.4ubuntu1 +2010-05-09 23:04:10 status installed python-support 1.0.4ubuntu1 +2010-05-09 23:04:23 startup archives install +2010-05-09 23:04:23 upgrade audacious-plugins 2.3-1ubuntu4 2.3-1ubuntu4 +2010-05-09 23:04:23 status half-configured audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:24 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:24 status half-installed audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:38 status half-installed audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:38 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:38 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:38 configure audacious-plugins 2.3-1ubuntu4 2.3-1ubuntu4 +2010-05-09 23:04:38 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:38 status half-configured audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:04:38 status installed audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:23 startup archives install +2010-05-09 23:22:24 upgrade audacious-plugins 2.3-1ubuntu4 2.3-1ubuntu4 +2010-05-09 23:22:24 status half-configured audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:24 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:24 status half-installed audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:37 status half-installed audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:37 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:38 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:38 configure audacious-plugins 2.3-1ubuntu4 2.3-1ubuntu4 +2010-05-09 23:22:38 status unpacked audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:38 status half-configured audacious-plugins 2.3-1ubuntu4 +2010-05-09 23:22:38 status installed audacious-plugins 2.3-1ubuntu4 +2010-05-10 20:12:55 startup archives unpack +2010-05-10 20:13:01 install ispell 3.1.20.0-7 +2010-05-10 20:13:01 status half-installed ispell 3.1.20.0-7 +2010-05-10 20:13:01 status triggers-pending doc-base 0.9.5 +2010-05-10 20:13:02 status half-installed ispell 3.1.20.0-7 +2010-05-10 20:13:02 status triggers-pending man-db 2.5.7-2 +2010-05-10 20:13:02 status half-installed ispell 3.1.20.0-7 +2010-05-10 20:13:02 status triggers-pending install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:02 status half-installed ispell 3.1.20.0-7 +2010-05-10 20:13:03 status unpacked ispell 3.1.20.0-7 +2010-05-10 20:13:04 status unpacked ispell 3.1.20.0-7 +2010-05-10 20:13:04 install iamerican 3.1.20.0-7 +2010-05-10 20:13:04 status half-installed iamerican 3.1.20.0-7 +2010-05-10 20:13:04 status half-installed iamerican 3.1.20.0-7 +2010-05-10 20:13:04 status unpacked iamerican 3.1.20.0-7 +2010-05-10 20:13:04 status unpacked iamerican 3.1.20.0-7 +2010-05-10 20:13:05 trigproc doc-base 0.9.5 0.9.5 +2010-05-10 20:13:05 status half-configured doc-base 0.9.5 +2010-05-10 20:13:06 status installed doc-base 0.9.5 +2010-05-10 20:13:06 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-10 20:13:06 status half-configured man-db 2.5.7-2 +2010-05-10 20:13:07 status installed man-db 2.5.7-2 +2010-05-10 20:13:07 trigproc install-info 4.13a.dfsg.1-5ubuntu1 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:07 status half-configured install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:08 status installed install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:09 startup packages configure +2010-05-10 20:13:09 configure ispell 3.1.20.0-7 3.1.20.0-7 +2010-05-10 20:13:09 status unpacked ispell 3.1.20.0-7 +2010-05-10 20:13:09 status half-configured ispell 3.1.20.0-7 +2010-05-10 20:13:10 status installed ispell 3.1.20.0-7 +2010-05-10 20:13:10 configure iamerican 3.1.20.0-7 3.1.20.0-7 +2010-05-10 20:13:10 status unpacked iamerican 3.1.20.0-7 +2010-05-10 20:13:10 status half-configured iamerican 3.1.20.0-7 +2010-05-10 20:13:11 status installed iamerican 3.1.20.0-7 +2010-05-10 20:13:20 startup archives unpack +2010-05-10 20:13:21 install spell 1.0-24 +2010-05-10 20:13:21 status half-installed spell 1.0-24 +2010-05-10 20:13:21 status triggers-pending install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:21 status half-installed spell 1.0-24 +2010-05-10 20:13:21 status triggers-pending man-db 2.5.7-2 +2010-05-10 20:13:21 status half-installed spell 1.0-24 +2010-05-10 20:13:21 status unpacked spell 1.0-24 +2010-05-10 20:13:21 status unpacked spell 1.0-24 +2010-05-10 20:13:21 trigproc install-info 4.13a.dfsg.1-5ubuntu1 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:21 status half-configured install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:22 status installed install-info 4.13a.dfsg.1-5ubuntu1 +2010-05-10 20:13:22 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-10 20:13:22 status half-configured man-db 2.5.7-2 +2010-05-10 20:13:23 status installed man-db 2.5.7-2 +2010-05-10 20:13:24 startup packages configure +2010-05-10 20:13:24 configure spell 1.0-24 1.0-24 +2010-05-10 20:13:24 status unpacked spell 1.0-24 +2010-05-10 20:13:24 status half-configured spell 1.0-24 +2010-05-10 20:13:24 status installed spell 1.0-24 +2010-05-10 20:13:49 startup archives unpack +2010-05-10 20:13:49 install libtext-aspell-perl 0.04-3build1 +2010-05-10 20:13:49 status half-installed libtext-aspell-perl 0.04-3build1 +2010-05-10 20:13:49 status triggers-pending man-db 2.5.7-2 +2010-05-10 20:13:49 status half-installed libtext-aspell-perl 0.04-3build1 +2010-05-10 20:13:50 status unpacked libtext-aspell-perl 0.04-3build1 +2010-05-10 20:13:50 status unpacked libtext-aspell-perl 0.04-3build1 +2010-05-10 20:13:50 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-10 20:13:50 status half-configured man-db 2.5.7-2 +2010-05-10 20:13:51 status installed man-db 2.5.7-2 +2010-05-10 20:13:52 startup packages configure +2010-05-10 20:13:52 configure libtext-aspell-perl 0.04-3build1 0.04-3build1 +2010-05-10 20:13:52 status unpacked libtext-aspell-perl 0.04-3build1 +2010-05-10 20:13:52 status half-configured libtext-aspell-perl 0.04-3build1 +2010-05-10 20:13:52 status installed libtext-aspell-perl 0.04-3build1 +2010-05-12 00:43:53 startup archives unpack +2010-05-12 00:43:59 upgrade chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid +2010-05-12 00:43:59 status half-configured chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-12 00:43:59 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-12 00:43:59 status half-installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-12 00:44:00 status half-installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46760-0ubuntu1~ucd1 +2010-05-12 00:44:00 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid +2010-05-12 00:44:00 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid +2010-05-12 00:44:00 upgrade libglib2.0-dev 2.24.0-0ubuntu4 2.24.1-0ubuntu1 +2010-05-12 00:44:00 status half-configured libglib2.0-dev 2.24.0-0ubuntu4 +2010-05-12 00:44:00 status unpacked libglib2.0-dev 2.24.0-0ubuntu4 +2010-05-12 00:44:00 status half-installed libglib2.0-dev 2.24.0-0ubuntu4 +2010-05-12 00:44:01 status triggers-pending man-db 2.5.7-2 +2010-05-12 00:44:01 status half-installed libglib2.0-dev 2.24.0-0ubuntu4 +2010-05-12 00:44:08 status half-installed libglib2.0-dev 2.24.0-0ubuntu4 +2010-05-12 00:44:08 status unpacked libglib2.0-dev 2.24.1-0ubuntu1 +2010-05-12 00:44:08 status unpacked libglib2.0-dev 2.24.1-0ubuntu1 +2010-05-12 00:44:08 upgrade libglib2.0-0 2.24.0-0ubuntu4 2.24.1-0ubuntu1 +2010-05-12 00:44:08 status half-configured libglib2.0-0 2.24.0-0ubuntu4 +2010-05-12 00:44:08 status unpacked libglib2.0-0 2.24.0-0ubuntu4 +2010-05-12 00:44:08 status half-installed libglib2.0-0 2.24.0-0ubuntu4 +2010-05-12 00:44:09 status half-installed libglib2.0-0 2.24.0-0ubuntu4 +2010-05-12 00:44:10 status unpacked libglib2.0-0 2.24.1-0ubuntu1 +2010-05-12 00:44:10 status unpacked libglib2.0-0 2.24.1-0ubuntu1 +2010-05-12 00:44:10 upgrade chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:44:10 status half-configured chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-12 00:44:10 status unpacked chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-12 00:44:10 status half-installed chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-12 00:44:16 status half-installed chromium-browser-inspector 6.0.398.0~svn20100507r46652-0ubuntu1~ucd1 +2010-05-12 00:44:16 status unpacked chromium-browser-inspector 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:44:16 status unpacked chromium-browser-inspector 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:44:16 upgrade chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:44:16 status half-configured chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:16 status unpacked chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:16 status half-installed chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:18 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-12 00:44:18 status half-installed chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:18 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-12 00:44:18 status half-installed chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:18 status half-installed chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:18 status triggers-pending hicolor-icon-theme 0.11-1 +2010-05-12 00:44:18 status half-installed chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:23 status half-installed chromium-browser 6.0.399.0~svn20100508r46769-0ubuntu1~ucd1 +2010-05-12 00:44:23 status unpacked chromium-browser 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:44:23 status unpacked chromium-browser 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:44:23 upgrade mysql-common 5.1.41-3ubuntu12 5.1.41-3ubuntu12.1 +2010-05-12 00:44:23 status half-configured mysql-common 5.1.41-3ubuntu12 +2010-05-12 00:44:23 status unpacked mysql-common 5.1.41-3ubuntu12 +2010-05-12 00:44:23 status half-installed mysql-common 5.1.41-3ubuntu12 +2010-05-12 00:44:24 status half-installed mysql-common 5.1.41-3ubuntu12 +2010-05-12 00:44:24 status unpacked mysql-common 5.1.41-3ubuntu12.1 +2010-05-12 00:44:24 status unpacked mysql-common 5.1.41-3ubuntu12.1 +2010-05-12 00:44:24 upgrade mysql-server 5.1.41-3ubuntu12 5.1.41-3ubuntu12.1 +2010-05-12 00:44:24 status half-configured mysql-server 5.1.41-3ubuntu12 +2010-05-12 00:44:24 status unpacked mysql-server 5.1.41-3ubuntu12 +2010-05-12 00:44:24 status half-installed mysql-server 5.1.41-3ubuntu12 +2010-05-12 00:44:24 status half-installed mysql-server 5.1.41-3ubuntu12 +2010-05-12 00:44:25 status unpacked mysql-server 5.1.41-3ubuntu12.1 +2010-05-12 00:44:25 status unpacked mysql-server 5.1.41-3ubuntu12.1 +2010-05-12 00:44:25 upgrade libmysqlclient16 5.1.41-3ubuntu12 5.1.41-3ubuntu12.1 +2010-05-12 00:44:25 status half-configured libmysqlclient16 5.1.41-3ubuntu12 +2010-05-12 00:44:25 status unpacked libmysqlclient16 5.1.41-3ubuntu12 +2010-05-12 00:44:25 status half-installed libmysqlclient16 5.1.41-3ubuntu12 +2010-05-12 00:44:26 status half-installed libmysqlclient16 5.1.41-3ubuntu12 +2010-05-12 00:44:26 status unpacked libmysqlclient16 5.1.41-3ubuntu12.1 +2010-05-12 00:44:26 status unpacked libmysqlclient16 5.1.41-3ubuntu12.1 +2010-05-12 00:44:26 upgrade mysql-client-core-5.1 5.1.41-3ubuntu12 5.1.41-3ubuntu12.1 +2010-05-12 00:44:26 status half-configured mysql-client-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:26 status unpacked mysql-client-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:26 status half-installed mysql-client-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:26 status half-installed mysql-client-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:28 status half-installed mysql-client-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:28 status unpacked mysql-client-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:28 status unpacked mysql-client-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:28 upgrade mysql-client-5.1 5.1.41-3ubuntu12 5.1.41-3ubuntu12.1 +2010-05-12 00:44:28 status half-configured mysql-client-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:28 status unpacked mysql-client-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:28 status half-installed mysql-client-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:29 status half-installed mysql-client-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:31 status half-installed mysql-client-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:31 status unpacked mysql-client-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:32 status unpacked mysql-client-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:32 upgrade mysql-server-core-5.1 5.1.41-3ubuntu12 5.1.41-3ubuntu12.1 +2010-05-12 00:44:32 status half-configured mysql-server-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:32 status unpacked mysql-server-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:32 status half-installed mysql-server-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:32 status half-installed mysql-server-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:35 status half-installed mysql-server-core-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:36 status unpacked mysql-server-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:36 status unpacked mysql-server-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:36 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-12 00:44:36 status half-configured man-db 2.5.7-2 +2010-05-12 00:44:38 status installed man-db 2.5.7-2 +2010-05-12 00:44:38 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-12 00:44:38 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-12 00:44:40 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-12 00:44:40 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-12 00:44:40 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-12 00:44:40 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-12 00:44:40 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-12 00:44:40 trigproc hicolor-icon-theme 0.11-1 0.11-1 +2010-05-12 00:44:40 status half-configured hicolor-icon-theme 0.11-1 +2010-05-12 00:44:43 status installed hicolor-icon-theme 0.11-1 +2010-05-12 00:44:43 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-12 00:44:43 status half-configured python-support 1.0.4ubuntu1 +2010-05-12 00:44:48 status installed python-support 1.0.4ubuntu1 +2010-05-12 00:44:49 startup packages configure +2010-05-12 00:44:49 configure mysql-common 5.1.41-3ubuntu12.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:49 status unpacked mysql-common 5.1.41-3ubuntu12.1 +2010-05-12 00:44:49 status unpacked mysql-common 5.1.41-3ubuntu12.1 +2010-05-12 00:44:49 status half-configured mysql-common 5.1.41-3ubuntu12.1 +2010-05-12 00:44:49 status installed mysql-common 5.1.41-3ubuntu12.1 +2010-05-12 00:44:50 startup archives unpack +2010-05-12 00:44:50 upgrade mysql-server-5.1 5.1.41-3ubuntu12 5.1.41-3ubuntu12.1 +2010-05-12 00:44:50 status half-configured mysql-server-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:52 status unpacked mysql-server-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:52 status half-installed mysql-server-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:53 status triggers-pending ureadahead 0.100.0-4.1 +2010-05-12 00:44:53 status half-installed mysql-server-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:53 status triggers-pending ureadahead 0.100.0-4.1 +2010-05-12 00:44:54 status triggers-pending man-db 2.5.7-2 +2010-05-12 00:44:54 status half-installed mysql-server-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:56 status half-installed mysql-server-5.1 5.1.41-3ubuntu12 +2010-05-12 00:44:57 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:57 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:44:57 upgrade mountall 2.14 2.15 +2010-05-12 00:44:57 status half-configured mountall 2.14 +2010-05-12 00:44:57 status unpacked mountall 2.14 +2010-05-12 00:44:57 status half-installed mountall 2.14 +2010-05-12 00:44:57 status half-installed mountall 2.14 +2010-05-12 00:44:57 status half-installed mountall 2.14 +2010-05-12 00:44:58 status half-installed mountall 2.14 +2010-05-12 00:44:58 status unpacked mountall 2.15 +2010-05-12 00:44:58 status unpacked mountall 2.15 +2010-05-12 00:44:58 upgrade gdm 2.30.0-0ubuntu5 2.30.2-0ubuntu1 +2010-05-12 00:44:58 status half-configured gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:03 status unpacked gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:03 status half-installed gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:03 status triggers-pending hicolor-icon-theme 0.11-1 +2010-05-12 00:45:03 status half-installed gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:03 status triggers-pending python-gmenu 2.30.0-0ubuntu4 +2010-05-12 00:45:03 status half-installed gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:03 status triggers-pending desktop-file-utils 0.16-0ubuntu2 +2010-05-12 00:45:03 status half-installed gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:04 status half-installed gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:07 status half-installed gdm 2.30.0-0ubuntu5 +2010-05-12 00:45:07 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:45:07 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:45:07 upgrade libhal1 0.5.14-0ubuntu5 0.5.14-0ubuntu6 +2010-05-12 00:45:07 status half-configured libhal1 0.5.14-0ubuntu5 +2010-05-12 00:45:08 status unpacked libhal1 0.5.14-0ubuntu5 +2010-05-12 00:45:08 status half-installed libhal1 0.5.14-0ubuntu5 +2010-05-12 00:45:08 status half-installed libhal1 0.5.14-0ubuntu5 +2010-05-12 00:45:08 status unpacked libhal1 0.5.14-0ubuntu6 +2010-05-12 00:45:08 status unpacked libhal1 0.5.14-0ubuntu6 +2010-05-12 00:45:08 upgrade libhal-storage1 0.5.14-0ubuntu5 0.5.14-0ubuntu6 +2010-05-12 00:45:08 status half-configured libhal-storage1 0.5.14-0ubuntu5 +2010-05-12 00:45:08 status unpacked libhal-storage1 0.5.14-0ubuntu5 +2010-05-12 00:45:08 status half-installed libhal-storage1 0.5.14-0ubuntu5 +2010-05-12 00:45:09 status half-installed libhal-storage1 0.5.14-0ubuntu5 +2010-05-12 00:45:09 status unpacked libhal-storage1 0.5.14-0ubuntu6 +2010-05-12 00:45:09 status unpacked libhal-storage1 0.5.14-0ubuntu6 +2010-05-12 00:45:09 upgrade hal 0.5.14-0ubuntu5 0.5.14-0ubuntu6 +2010-05-12 00:45:09 status half-configured hal 0.5.14-0ubuntu5 +2010-05-12 00:45:09 status unpacked hal 0.5.14-0ubuntu5 +2010-05-12 00:45:09 status half-installed hal 0.5.14-0ubuntu5 +2010-05-12 00:45:09 status half-installed hal 0.5.14-0ubuntu5 +2010-05-12 00:45:13 status half-installed hal 0.5.14-0ubuntu5 +2010-05-12 00:45:14 status unpacked hal 0.5.14-0ubuntu6 +2010-05-12 00:45:14 status unpacked hal 0.5.14-0ubuntu6 +2010-05-12 00:45:14 upgrade indicator-applet-complete 0.3.6-0ubuntu2 0.3.7-0ubuntu1 +2010-05-12 00:45:14 status half-configured indicator-applet-complete 0.3.6-0ubuntu2 +2010-05-12 00:45:14 status unpacked indicator-applet-complete 0.3.6-0ubuntu2 +2010-05-12 00:45:14 status half-installed indicator-applet-complete 0.3.6-0ubuntu2 +2010-05-12 00:45:14 status half-installed indicator-applet-complete 0.3.6-0ubuntu2 +2010-05-12 00:45:14 status unpacked indicator-applet-complete 0.3.7-0ubuntu1 +2010-05-12 00:45:14 status unpacked indicator-applet-complete 0.3.7-0ubuntu1 +2010-05-12 00:45:14 upgrade indicator-applet-session 0.3.6-0ubuntu2 0.3.7-0ubuntu1 +2010-05-12 00:45:14 status half-configured indicator-applet-session 0.3.6-0ubuntu2 +2010-05-12 00:45:14 status unpacked indicator-applet-session 0.3.6-0ubuntu2 +2010-05-12 00:45:14 status half-installed indicator-applet-session 0.3.6-0ubuntu2 +2010-05-12 00:45:15 status half-installed indicator-applet-session 0.3.6-0ubuntu2 +2010-05-12 00:45:15 status unpacked indicator-applet-session 0.3.7-0ubuntu1 +2010-05-12 00:45:15 status unpacked indicator-applet-session 0.3.7-0ubuntu1 +2010-05-12 00:45:15 upgrade indicator-applet 0.3.6-0ubuntu2 0.3.7-0ubuntu1 +2010-05-12 00:45:15 status half-configured indicator-applet 0.3.6-0ubuntu2 +2010-05-12 00:45:15 status unpacked indicator-applet 0.3.6-0ubuntu2 +2010-05-12 00:45:15 status half-installed indicator-applet 0.3.6-0ubuntu2 +2010-05-12 00:45:15 status half-installed indicator-applet 0.3.6-0ubuntu2 +2010-05-12 00:45:15 status half-installed indicator-applet 0.3.6-0ubuntu2 +2010-05-12 00:45:15 status unpacked indicator-applet 0.3.7-0ubuntu1 +2010-05-12 00:45:15 status unpacked indicator-applet 0.3.7-0ubuntu1 +2010-05-12 00:45:16 upgrade libglib2.0-data 2.24.0-0ubuntu4 2.24.1-0ubuntu1 +2010-05-12 00:45:16 status half-configured libglib2.0-data 2.24.0-0ubuntu4 +2010-05-12 00:45:16 status unpacked libglib2.0-data 2.24.0-0ubuntu4 +2010-05-12 00:45:16 status half-installed libglib2.0-data 2.24.0-0ubuntu4 +2010-05-12 00:45:16 status half-installed libglib2.0-data 2.24.0-0ubuntu4 +2010-05-12 00:45:16 status unpacked libglib2.0-data 2.24.1-0ubuntu1 +2010-05-12 00:45:16 status unpacked libglib2.0-data 2.24.1-0ubuntu1 +2010-05-12 00:45:16 upgrade libglibmm-2.4-dev 2.24.1-1 2.24.2-0ubuntu1 +2010-05-12 00:45:16 status half-configured libglibmm-2.4-dev 2.24.1-1 +2010-05-12 00:45:16 status unpacked libglibmm-2.4-dev 2.24.1-1 +2010-05-12 00:45:16 status half-installed libglibmm-2.4-dev 2.24.1-1 +2010-05-12 00:45:26 status half-installed libglibmm-2.4-dev 2.24.1-1 +2010-05-12 00:45:26 status unpacked libglibmm-2.4-dev 2.24.2-0ubuntu1 +2010-05-12 00:45:26 status unpacked libglibmm-2.4-dev 2.24.2-0ubuntu1 +2010-05-12 00:45:26 upgrade libglibmm-2.4-1c2a 2.24.1-1 2.24.2-0ubuntu1 +2010-05-12 00:45:26 status half-configured libglibmm-2.4-1c2a 2.24.1-1 +2010-05-12 00:45:26 status unpacked libglibmm-2.4-1c2a 2.24.1-1 +2010-05-12 00:45:26 status half-installed libglibmm-2.4-1c2a 2.24.1-1 +2010-05-12 00:45:27 status half-installed libglibmm-2.4-1c2a 2.24.1-1 +2010-05-12 00:45:27 status unpacked libglibmm-2.4-1c2a 2.24.2-0ubuntu1 +2010-05-12 00:45:27 status unpacked libglibmm-2.4-1c2a 2.24.2-0ubuntu1 +2010-05-12 00:45:27 upgrade thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:45:27 status half-configured thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-12 00:45:27 status unpacked thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-12 00:45:27 status half-installed thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-12 00:45:28 status half-installed thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-12 00:45:28 status half-installed thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-12 00:45:28 status half-installed thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-12 00:45:43 status half-installed thunderbird 3.0.5~hg20100506r4837+nobinonly-0ubuntu1~umd1 +2010-05-12 00:45:43 status unpacked thunderbird 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:45:43 status unpacked thunderbird 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:45:44 upgrade liblircclient-dev 0.8.6-0ubuntu4 0.8.6-0ubuntu4.1 +2010-05-12 00:45:44 status half-configured liblircclient-dev 0.8.6-0ubuntu4 +2010-05-12 00:45:44 status unpacked liblircclient-dev 0.8.6-0ubuntu4 +2010-05-12 00:45:44 status half-installed liblircclient-dev 0.8.6-0ubuntu4 +2010-05-12 00:45:44 status half-installed liblircclient-dev 0.8.6-0ubuntu4 +2010-05-12 00:45:44 status unpacked liblircclient-dev 0.8.6-0ubuntu4.1 +2010-05-12 00:45:44 status unpacked liblircclient-dev 0.8.6-0ubuntu4.1 +2010-05-12 00:45:44 upgrade liblircclient0 0.8.6-0ubuntu4 0.8.6-0ubuntu4.1 +2010-05-12 00:45:44 status half-configured liblircclient0 0.8.6-0ubuntu4 +2010-05-12 00:45:44 status unpacked liblircclient0 0.8.6-0ubuntu4 +2010-05-12 00:45:45 status half-installed liblircclient0 0.8.6-0ubuntu4 +2010-05-12 00:45:45 status half-installed liblircclient0 0.8.6-0ubuntu4 +2010-05-12 00:45:45 status unpacked liblircclient0 0.8.6-0ubuntu4.1 +2010-05-12 00:45:45 status unpacked liblircclient0 0.8.6-0ubuntu4.1 +2010-05-12 00:45:45 trigproc ureadahead 0.100.0-4.1 0.100.0-4.1 +2010-05-12 00:45:45 status half-configured ureadahead 0.100.0-4.1 +2010-05-12 00:45:45 status installed ureadahead 0.100.0-4.1 +2010-05-12 00:45:45 trigproc man-db 2.5.7-2 2.5.7-2 +2010-05-12 00:45:45 status half-configured man-db 2.5.7-2 +2010-05-12 00:45:46 status installed man-db 2.5.7-2 +2010-05-12 00:45:46 trigproc hicolor-icon-theme 0.11-1 0.11-1 +2010-05-12 00:45:46 status half-configured hicolor-icon-theme 0.11-1 +2010-05-12 00:45:47 status installed hicolor-icon-theme 0.11-1 +2010-05-12 00:45:47 trigproc python-gmenu 2.30.0-0ubuntu4 2.30.0-0ubuntu4 +2010-05-12 00:45:47 status half-configured python-gmenu 2.30.0-0ubuntu4 +2010-05-12 00:45:47 status installed python-gmenu 2.30.0-0ubuntu4 +2010-05-12 00:45:47 status triggers-pending python-support 1.0.4ubuntu1 +2010-05-12 00:45:47 trigproc desktop-file-utils 0.16-0ubuntu2 0.16-0ubuntu2 +2010-05-12 00:45:47 status half-configured desktop-file-utils 0.16-0ubuntu2 +2010-05-12 00:45:47 status installed desktop-file-utils 0.16-0ubuntu2 +2010-05-12 00:45:47 trigproc python-support 1.0.4ubuntu1 1.0.4ubuntu1 +2010-05-12 00:45:47 status half-configured python-support 1.0.4ubuntu1 +2010-05-12 00:45:48 status installed python-support 1.0.4ubuntu1 +2010-05-12 00:45:49 startup packages configure +2010-05-12 00:45:49 configure libglib2.0-0 2.24.1-0ubuntu1 2.24.1-0ubuntu1 +2010-05-12 00:45:49 status unpacked libglib2.0-0 2.24.1-0ubuntu1 +2010-05-12 00:45:49 status half-configured libglib2.0-0 2.24.1-0ubuntu1 +2010-05-12 00:45:49 status installed libglib2.0-0 2.24.1-0ubuntu1 +2010-05-12 00:45:49 status triggers-pending libc-bin 2.11.1-0ubuntu7 +2010-05-12 00:45:50 configure libglib2.0-dev 2.24.1-0ubuntu1 2.24.1-0ubuntu1 +2010-05-12 00:45:50 status unpacked libglib2.0-dev 2.24.1-0ubuntu1 +2010-05-12 00:45:50 status half-configured libglib2.0-dev 2.24.1-0ubuntu1 +2010-05-12 00:45:50 status installed libglib2.0-dev 2.24.1-0ubuntu1 +2010-05-12 00:45:50 configure libmysqlclient16 5.1.41-3ubuntu12.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked libmysqlclient16 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status half-configured libmysqlclient16 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status installed libmysqlclient16 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 configure mysql-client-core-5.1 5.1.41-3ubuntu12.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-client-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status half-configured mysql-client-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status installed mysql-client-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 configure mysql-client-5.1 5.1.41-3ubuntu12.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-client-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status half-configured mysql-client-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status installed mysql-client-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 configure mysql-server-core-5.1 5.1.41-3ubuntu12.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status half-configured mysql-server-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status installed mysql-server-core-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 configure mysql-server-5.1 5.1.41-3ubuntu12.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:50 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:51 status unpacked mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:45:51 status half-configured mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:46:00 status installed mysql-server-5.1 5.1.41-3ubuntu12.1 +2010-05-12 00:46:00 configure mysql-server 5.1.41-3ubuntu12.1 5.1.41-3ubuntu12.1 +2010-05-12 00:46:00 status unpacked mysql-server 5.1.41-3ubuntu12.1 +2010-05-12 00:46:00 status half-configured mysql-server 5.1.41-3ubuntu12.1 +2010-05-12 00:46:00 status installed mysql-server 5.1.41-3ubuntu12.1 +2010-05-12 00:46:01 configure mountall 2.15 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status unpacked mountall 2.15 +2010-05-12 00:46:01 status half-configured mountall 2.15 +2010-05-12 00:46:01 status installed mountall 2.15 +2010-05-12 00:46:01 configure gdm 2.30.2-0ubuntu1 2.30.2-0ubuntu1 +2010-05-12 00:46:01 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:01 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:01 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:01 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:01 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status unpacked gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:02 status half-configured gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:03 status installed gdm 2.30.2-0ubuntu1 +2010-05-12 00:46:03 configure libhal1 0.5.14-0ubuntu6 0.5.14-0ubuntu6 +2010-05-12 00:46:03 status unpacked libhal1 0.5.14-0ubuntu6 +2010-05-12 00:46:03 status half-configured libhal1 0.5.14-0ubuntu6 +2010-05-12 00:46:03 status installed libhal1 0.5.14-0ubuntu6 +2010-05-12 00:46:03 configure libhal-storage1 0.5.14-0ubuntu6 0.5.14-0ubuntu6 +2010-05-12 00:46:03 status unpacked libhal-storage1 0.5.14-0ubuntu6 +2010-05-12 00:46:03 status half-configured libhal-storage1 0.5.14-0ubuntu6 +2010-05-12 00:46:03 status installed libhal-storage1 0.5.14-0ubuntu6 +2010-05-12 00:46:04 configure hal 0.5.14-0ubuntu6 0.5.14-0ubuntu6 +2010-05-12 00:46:04 status unpacked hal 0.5.14-0ubuntu6 +2010-05-12 00:46:04 status unpacked hal 0.5.14-0ubuntu6 +2010-05-12 00:46:04 status unpacked hal 0.5.14-0ubuntu6 +2010-05-12 00:46:04 status half-configured hal 0.5.14-0ubuntu6 +2010-05-12 00:46:04 status installed hal 0.5.14-0ubuntu6 +2010-05-12 00:46:04 configure indicator-applet 0.3.7-0ubuntu1 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status unpacked indicator-applet 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status half-configured indicator-applet 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status installed indicator-applet 0.3.7-0ubuntu1 +2010-05-12 00:46:04 configure indicator-applet-complete 0.3.7-0ubuntu1 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status unpacked indicator-applet-complete 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status half-configured indicator-applet-complete 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status installed indicator-applet-complete 0.3.7-0ubuntu1 +2010-05-12 00:46:04 configure indicator-applet-session 0.3.7-0ubuntu1 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status unpacked indicator-applet-session 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status half-configured indicator-applet-session 0.3.7-0ubuntu1 +2010-05-12 00:46:04 status installed indicator-applet-session 0.3.7-0ubuntu1 +2010-05-12 00:46:04 configure libglib2.0-data 2.24.1-0ubuntu1 2.24.1-0ubuntu1 +2010-05-12 00:46:04 status unpacked libglib2.0-data 2.24.1-0ubuntu1 +2010-05-12 00:46:04 status half-configured libglib2.0-data 2.24.1-0ubuntu1 +2010-05-12 00:46:04 status installed libglib2.0-data 2.24.1-0ubuntu1 +2010-05-12 00:46:05 configure libglibmm-2.4-1c2a 2.24.2-0ubuntu1 2.24.2-0ubuntu1 +2010-05-12 00:46:05 status unpacked libglibmm-2.4-1c2a 2.24.2-0ubuntu1 +2010-05-12 00:46:05 status half-configured libglibmm-2.4-1c2a 2.24.2-0ubuntu1 +2010-05-12 00:46:05 status installed libglibmm-2.4-1c2a 2.24.2-0ubuntu1 +2010-05-12 00:46:05 configure libglibmm-2.4-dev 2.24.2-0ubuntu1 2.24.2-0ubuntu1 +2010-05-12 00:46:05 status unpacked libglibmm-2.4-dev 2.24.2-0ubuntu1 +2010-05-12 00:46:05 status half-configured libglibmm-2.4-dev 2.24.2-0ubuntu1 +2010-05-12 00:46:05 status installed libglibmm-2.4-dev 2.24.2-0ubuntu1 +2010-05-12 00:46:05 configure thunderbird 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:46:05 status unpacked thunderbird 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:46:05 status unpacked thunderbird 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:46:05 status half-configured thunderbird 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:46:05 status installed thunderbird 3.0.5~hg20100510r4848+nobinonly-0ubuntu1~umd1~lucid +2010-05-12 00:46:05 configure liblircclient0 0.8.6-0ubuntu4.1 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 status unpacked liblircclient0 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 status half-configured liblircclient0 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 status installed liblircclient0 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 configure liblircclient-dev 0.8.6-0ubuntu4.1 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 status unpacked liblircclient-dev 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 status half-configured liblircclient-dev 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 status installed liblircclient-dev 0.8.6-0ubuntu4.1 +2010-05-12 00:46:05 configure chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid +2010-05-12 00:46:05 status unpacked chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid +2010-05-12 00:46:05 status half-configured chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid +2010-05-12 00:46:05 status installed chromium-codecs-ffmpeg 0.5+svn20100430r46138+46111+46884-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 configure chromium-browser-inspector 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 status unpacked chromium-browser-inspector 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 status half-configured chromium-browser-inspector 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 status installed chromium-browser-inspector 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 configure chromium-browser 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 status unpacked chromium-browser 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 status unpacked chromium-browser 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:06 status half-configured chromium-browser 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:07 update-alternatives: run with --install /usr/bin/x-www-browser x-www-browser /usr/bin/chromium-browser 40 +2010-05-12 00:46:08 update-alternatives: run with --install /usr/bin/gnome-www-browser gnome-www-browser /usr/bin/chromium-browser 40 +2010-05-12 00:46:08 status installed chromium-browser 6.0.401.0~svn20100511r46909-0ubuntu1~ucd1~lucid +2010-05-12 00:46:08 trigproc libc-bin 2.11.1-0ubuntu7 2.11.1-0ubuntu7 +2010-05-12 00:46:08 status half-configured libc-bin 2.11.1-0ubuntu7 +2010-05-12 00:46:09 status installed libc-bin 2.11.1-0ubuntu7 diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lz_bin_tree.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lz_bin_tree.go new file mode 100644 index 00000000..a1470d76 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lz_bin_tree.go @@ -0,0 +1,355 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import "io" + +const ( + kHash2Size = 1 << 10 + kHash3Size = 1 << 16 + kBT2HashSize = 1 << 16 + kStartMaxLen = 1 + kHash3Offset = kHash2Size + kEmptyHashValue = 0 + kMaxValForNormalize = (1 << 30) - 1 +) + +type lzBinTree struct { + iw *lzInWindow + son []uint32 + hash []uint32 + cyclicBufPos uint32 + cyclicBufSize uint32 + matchMaxLen uint32 + cutValue uint32 + hashMask uint32 + hashSizeSum uint32 + kvNumHashDirectBytes uint32 + kvMinMatchCheck uint32 + kvFixHashSize uint32 + hashArray bool +} + +func newLzBinTree(r io.Reader, historySize, keepAddBufBefore, matchMaxLen, keepAddBufAfter, numHashBytes uint32) *lzBinTree { + bt := &lzBinTree{ + son: make([]uint32, (historySize+1)*2), // history size is the dictSize from the encoder + cyclicBufPos: 0, + cyclicBufSize: historySize + 1, + matchMaxLen: matchMaxLen, + cutValue: 16 + (matchMaxLen >> 1), + } + + winSizeReserv := (historySize+keepAddBufBefore+matchMaxLen+keepAddBufAfter)/2 + 256 + bt.iw = newLzInWindow(r, historySize+keepAddBufBefore, matchMaxLen+keepAddBufAfter, winSizeReserv) + + if numHashBytes > 2 { + bt.hashArray = true + bt.kvNumHashDirectBytes = 0 + bt.kvMinMatchCheck = 4 + bt.kvFixHashSize = kHash2Size + kHash3Size + } else { + bt.hashArray = false + bt.kvNumHashDirectBytes = 2 + bt.kvMinMatchCheck = 3 + bt.kvFixHashSize = 0 + } + + hs := uint32(kBT2HashSize) + if bt.hashArray == true { + hs = historySize - 1 + hs |= hs >> 1 + hs |= hs >> 2 + hs |= hs >> 4 + hs |= hs >> 8 + hs >>= 1 + hs |= 0xFFFF + if hs > 1<<24 { + hs >>= 1 + } + bt.hashMask = hs + hs++ + hs += bt.kvFixHashSize + } + bt.hashSizeSum = hs + bt.hash = make([]uint32, bt.hashSizeSum) + for i := uint32(0); i < bt.hashSizeSum; i++ { + bt.hash[i] = kEmptyHashValue + } + + bt.iw.reduceOffsets(0xFFFFFFFF) + return bt +} + +func normalizeLinks(items []uint32, numItems, subValue uint32) { + for i := uint32(0); i < numItems; i++ { + value := items[i] + if value <= subValue { + value = kEmptyHashValue + } else { + value -= subValue + } + items[i] = value + } +} + +func (bt *lzBinTree) normalize() { + subValue := bt.iw.pos - bt.cyclicBufSize + normalizeLinks(bt.son, bt.cyclicBufSize*2, subValue) + normalizeLinks(bt.hash, bt.hashSizeSum, subValue) + bt.iw.reduceOffsets(subValue) +} + +func (bt *lzBinTree) movePos() { + bt.cyclicBufPos++ + if bt.cyclicBufPos >= bt.cyclicBufSize { + bt.cyclicBufPos = 0 + } + bt.iw.movePos() + if bt.iw.pos == kMaxValForNormalize { + bt.normalize() + } +} + +func (bt *lzBinTree) getMatches(distances []uint32) uint32 { + var lenLimit uint32 + if bt.iw.pos+bt.matchMaxLen <= bt.iw.streamPos { + lenLimit = bt.matchMaxLen + } else { + lenLimit = bt.iw.streamPos - bt.iw.pos + if lenLimit < bt.kvMinMatchCheck { + bt.movePos() + return 0 + } + } + + offset := uint32(0) + matchMinPos := uint32(0) + if bt.iw.pos > bt.cyclicBufSize { + matchMinPos = bt.iw.pos - bt.cyclicBufSize + } + cur := bt.iw.bufOffset + bt.iw.pos + maxLen := uint32(kStartMaxLen) + var hashValue uint32 + hash2Value := uint32(0) + hash3Value := uint32(0) + + if bt.hashArray == true { + tmp := crcTable[bt.iw.buf[cur]] ^ uint32(bt.iw.buf[cur+1]) + hash2Value = tmp & (kHash2Size - 1) + tmp ^= uint32(bt.iw.buf[cur+2]) << 8 + hash3Value = tmp & (kHash3Size - 1) + hashValue = (tmp ^ crcTable[bt.iw.buf[cur+3]]<<5) & bt.hashMask + } else { + hashValue = uint32(bt.iw.buf[cur]) ^ uint32(bt.iw.buf[cur+1])<<8 + } + + curMatch := bt.hash[bt.kvFixHashSize+hashValue] + if bt.hashArray == true { + curMatch2 := bt.hash[hash2Value] + curMatch3 := bt.hash[kHash3Offset+hash3Value] + bt.hash[hash2Value] = bt.iw.pos + bt.hash[kHash3Offset+hash3Value] = bt.iw.pos + if curMatch2 > matchMinPos { + if bt.iw.buf[bt.iw.bufOffset+curMatch2] == bt.iw.buf[cur] { + maxLen = 2 + distances[offset] = maxLen + offset++ + distances[offset] = bt.iw.pos - curMatch2 - 1 + offset++ + } + } + if curMatch3 > matchMinPos { + if bt.iw.buf[bt.iw.bufOffset+curMatch3] == bt.iw.buf[cur] { + if curMatch3 == curMatch2 { + offset -= 2 + } + maxLen = 3 + distances[offset] = maxLen + offset++ + distances[offset] = bt.iw.pos - curMatch3 - 1 + offset++ + curMatch2 = curMatch3 + } + } + if offset != 0 && curMatch2 == curMatch { + offset -= 2 + maxLen = kStartMaxLen + } + } + + bt.hash[bt.kvFixHashSize+hashValue] = bt.iw.pos + + if bt.kvNumHashDirectBytes != 0 { + if curMatch > matchMinPos { + if bt.iw.buf[bt.iw.bufOffset+curMatch+bt.kvNumHashDirectBytes] != bt.iw.buf[cur+bt.kvNumHashDirectBytes] { + maxLen = bt.kvNumHashDirectBytes + distances[offset] = maxLen + offset++ + distances[offset] = bt.iw.pos - curMatch - 1 + offset++ + } + } + } + + ptr0 := bt.cyclicBufPos<<1 + 1 + ptr1 := bt.cyclicBufPos << 1 + len0 := bt.kvNumHashDirectBytes + len1 := bt.kvNumHashDirectBytes + count := bt.cutValue + + for { + if curMatch <= matchMinPos || count == 0 { + bt.son[ptr1] = kEmptyHashValue + bt.son[ptr0] = kEmptyHashValue + break + } + count-- + + delta := bt.iw.pos - curMatch + var cyclicPos uint32 + if delta <= bt.cyclicBufPos { + cyclicPos = (bt.cyclicBufPos - delta) << 1 + } else { + cyclicPos = (bt.cyclicBufPos - delta + bt.cyclicBufSize) << 1 + } + pby1 := bt.iw.bufOffset + curMatch + length := minUInt32(len0, len1) + if bt.iw.buf[pby1+length] == bt.iw.buf[cur+length] { + for length++; length != lenLimit; length++ { + if bt.iw.buf[pby1+length] != bt.iw.buf[cur+length] { + break + } + } + if maxLen < length { + maxLen = length + distances[offset] = maxLen + offset++ + distances[offset] = delta - 1 + offset++ + if length == lenLimit { + bt.son[ptr1] = bt.son[cyclicPos] + bt.son[ptr0] = bt.son[cyclicPos+1] + break + } + } + } + + if bt.iw.buf[pby1+length] < bt.iw.buf[cur+length] { + bt.son[ptr1] = curMatch + ptr1 = cyclicPos + 1 + curMatch = bt.son[ptr1] + len1 = length + } else { + bt.son[ptr0] = curMatch + ptr0 = cyclicPos + curMatch = bt.son[ptr0] + len0 = length + } + } + bt.movePos() + return offset +} + +func (bt *lzBinTree) skip(num uint32) { + for i := uint32(0); i < num; i++ { + var lenLimit uint32 + if bt.iw.pos+bt.matchMaxLen <= bt.iw.streamPos { + lenLimit = bt.matchMaxLen + } else { + lenLimit = bt.iw.streamPos - bt.iw.pos + if lenLimit < bt.kvMinMatchCheck { + bt.movePos() + continue + } + } + + matchMinPos := uint32(0) + if bt.iw.pos > bt.cyclicBufSize { + matchMinPos = bt.iw.pos - bt.cyclicBufSize + } + cur := bt.iw.bufOffset + bt.iw.pos + var hashValue uint32 + if bt.hashArray == true { + tmp := crcTable[bt.iw.buf[cur]] ^ uint32(bt.iw.buf[cur+1]) + hash2Value := tmp & (kHash2Size - 1) + bt.hash[hash2Value] = bt.iw.pos + tmp ^= uint32(bt.iw.buf[cur+2]) << 8 + hash3Value := tmp & (kHash3Size - 1) + bt.hash[kHash3Offset+hash3Value] = bt.iw.pos + hashValue = (tmp ^ crcTable[bt.iw.buf[cur+3]]<<5) & bt.hashMask + } else { + hashValue = uint32(bt.iw.buf[cur]) ^ uint32(bt.iw.buf[cur+1])<<8 + } + + curMatch := bt.hash[bt.kvFixHashSize+hashValue] + bt.hash[bt.kvFixHashSize+hashValue] = bt.iw.pos + ptr0 := bt.cyclicBufPos<<1 + 1 + ptr1 := bt.cyclicBufPos << 1 + len0 := bt.kvNumHashDirectBytes + len1 := bt.kvNumHashDirectBytes + count := bt.cutValue + for { + if curMatch <= matchMinPos || count == 0 { + bt.son[ptr1] = kEmptyHashValue + bt.son[ptr0] = kEmptyHashValue + break + } + count-- + + delta := bt.iw.pos - curMatch + var cyclicPos uint32 + if delta <= bt.cyclicBufPos { + cyclicPos = (bt.cyclicBufPos - delta) << 1 + } else { + cyclicPos = (bt.cyclicBufPos - delta + bt.cyclicBufSize) << 1 + } + pby1 := bt.iw.bufOffset + curMatch + length := minUInt32(len0, len1) + if bt.iw.buf[pby1+length] == bt.iw.buf[cur+length] { + for length++; length != lenLimit; length++ { + if bt.iw.buf[pby1+length] != bt.iw.buf[cur+length] { + break + } + } + if length == lenLimit { + bt.son[ptr1] = bt.son[cyclicPos] + bt.son[ptr0] = bt.son[cyclicPos+1] + break + } + } + + if bt.iw.buf[pby1+length] < bt.iw.buf[cur+length] { + bt.son[ptr1] = curMatch + ptr1 = cyclicPos + 1 + curMatch = bt.son[ptr1] + len1 = length + } else { + bt.son[ptr0] = curMatch + ptr0 = cyclicPos + curMatch = bt.son[ptr0] + len0 = length + } + } + bt.movePos() + } +} + + +var crcTable []uint32 = make([]uint32, 256) + +// should be called in the encoder's contructor +func initCrcTable() { + for i := uint32(0); i < 256; i++ { + r := i + for j := 0; j < 8; j++ { + if r&1 != 0 { + r = r>>1 ^ 0xEDB88320 + } else { + r >>= 1 + } + } + crcTable[i] = r + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lz_window.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lz_window.go new file mode 100644 index 00000000..2be2a33e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lz_window.go @@ -0,0 +1,193 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import "io" + +type lzOutWindow struct { + w io.Writer + buf []byte + winSize uint32 + pos uint32 + streamPos uint32 + //unpacked uint32 // counter of unpacked bytes +} + +func newLzOutWindow(w io.Writer, windowSize uint32) *lzOutWindow { + return &lzOutWindow{ + w: w, + buf: make([]byte, windowSize), + winSize: windowSize, + pos: 0, + streamPos: 0, + //unpacked: 0, + } +} + +func (ow *lzOutWindow) flush() { + size := ow.pos - ow.streamPos + if size == 0 { + return + } + n, err := ow.w.Write(ow.buf[ow.streamPos : ow.streamPos+size]) + if err != nil { + throw(err) + } + if uint32(n) != size { + throw(nWriteError) + } + //unpacked += size + if ow.pos >= ow.winSize { + ow.pos = 0 + } + ow.streamPos = ow.pos +} + +func (ow *lzOutWindow) copyBlock(distance, length uint32) { + pos := ow.pos - distance - 1 + if pos >= ow.winSize { + pos += ow.winSize + } + for ; length != 0; length-- { + if pos >= ow.winSize { + pos = 0 + } + ow.buf[ow.pos] = ow.buf[pos] + ow.pos++ + pos++ + if ow.pos >= ow.winSize { + ow.flush() + } + } +} + +func (ow *lzOutWindow) putByte(b byte) { + ow.buf[ow.pos] = b + ow.pos++ + if ow.pos >= ow.winSize { + ow.flush() + } +} + +func (ow *lzOutWindow) getByte(distance uint32) byte { + pos := ow.pos - distance - 1 + if pos >= ow.winSize { + pos += ow.winSize + } + return ow.buf[pos] +} + +type lzInWindow struct { + r io.Reader + buf []byte + posLimit uint32 + lastSafePos uint32 + bufOffset uint32 + blockSize uint32 + pos uint32 + keepSizeBefore uint32 + keepSizeAfter uint32 + streamPos uint32 + streamEnd bool +} + +func newLzInWindow(r io.Reader, keepSizeBefore, keepSizeAfter, keepSizeReserv uint32) *lzInWindow { + blockSize := keepSizeBefore + keepSizeAfter + keepSizeReserv + iw := &lzInWindow{ + r: r, + buf: make([]byte, blockSize), + lastSafePos: blockSize - keepSizeAfter, + bufOffset: 0, + blockSize: blockSize, + pos: 0, + keepSizeBefore: keepSizeBefore, + keepSizeAfter: keepSizeAfter, + streamPos: 0, + streamEnd: false, + } + iw.readBlock() + return iw +} + +func (iw *lzInWindow) moveBlock() { + offset := iw.bufOffset + iw.pos - iw.keepSizeBefore + if offset > 0 { + offset-- + } + numBytes := iw.bufOffset + iw.streamPos - offset + for i := uint32(0); i < numBytes; i++ { + iw.buf[i] = iw.buf[offset+i] + } + iw.bufOffset -= offset +} + +func (iw *lzInWindow) readBlock() { + if iw.streamEnd { + return + } + for { + if iw.blockSize-iw.bufOffset-iw.streamPos == 0 { + return + } + n, err := iw.r.Read(iw.buf[iw.bufOffset+iw.streamPos : iw.blockSize]) + if err != nil && err != io.EOF { + throw(err) + } + if n == 0 && err == io.EOF { + iw.posLimit = iw.streamPos + ptr := iw.bufOffset + iw.posLimit + if ptr > iw.lastSafePos { + iw.posLimit = iw.lastSafePos - iw.bufOffset + } + iw.streamEnd = true + return + } + iw.streamPos += uint32(n) + if iw.streamPos >= iw.pos+iw.keepSizeAfter { + iw.posLimit = iw.streamPos - iw.keepSizeAfter + } + } +} + +func (iw *lzInWindow) movePos() { + iw.pos++ + if iw.pos > iw.posLimit { + ptr := iw.bufOffset + iw.pos + if ptr > iw.lastSafePos { + iw.moveBlock() + } + iw.readBlock() + } +} + +func (iw *lzInWindow) getIndexByte(index int32) byte { + return iw.buf[int32(iw.bufOffset+iw.pos)+index] +} + +func (iw *lzInWindow) getMatchLen(index int32, distance, limit uint32) (res uint32) { + uIndex := uint32(index) + if iw.streamEnd == true { + if iw.pos+uIndex+limit > iw.streamPos { + limit = iw.streamPos - (iw.pos + uIndex) + } + } + distance++ + pby := iw.bufOffset + iw.pos + uIndex + for res = uint32(0); res < limit && iw.buf[pby+res] == iw.buf[pby+res-distance]; res++ { + // empty body + } + return +} + +func (iw *lzInWindow) getNumAvailableBytes() uint32 { + return iw.streamPos - iw.pos +} + +func (iw *lzInWindow) reduceOffsets(subValue uint32) { + iw.bufOffset += subValue + iw.posLimit -= subValue + iw.pos -= subValue + iw.streamPos -= subValue +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_data_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_data_test.go new file mode 100644 index 00000000..fd953ebd --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_data_test.go @@ -0,0 +1,311 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "io/ioutil" + "log" +) + +type lzmaTest struct { + descr string + level int + size bool + raw string + lzma []byte + err error +} + +var lzmaTests = []lzmaTest{ + // fmt -w 80 -s file + // cat file | sed s/\\\\/\\\\\\\\/g | sed s/\"/\\\\\"/g | sed s/^/\"/ | sed s/$/\\\\n\"\ +/ + // hexdump -Cv file.lzma | awk '{for (i=2; i<18; i++) {printf("0x%s, ", $i); if (i==9) printf("\n");} printf("\n")}' + lzmaTest{ + "empty test", + 3, + true, + "", + []byte{ + 0x5d, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, + }, + nil, + }, + lzmaTest{ + "empty (with size == -1) test", + 3, + false, + "", + []byte{ + 0x5d, 0x00, 0x00, 0x10, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x83, 0xff, + 0xfb, 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, + }, + nil, + }, + lzmaTest{ + "hello world test", + 3, + true, + "hello world\n", + []byte{ + 0x5d, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x19, + 0x49, 0xee, 0x8d, 0xe9, 0x17, 0x89, 0x3a, 0x33, + 0x5f, 0xfc, 0xac, 0xf7, 0x20, 0x00, + }, + nil, + }, + lzmaTest{ + "hello world (with size == -1) test", + 3, + false, + "hello world\n", + []byte{ + 0x5d, 0x00, 0x00, 0x10, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x34, 0x19, + 0x49, 0xee, 0x8d, 0xe9, 0x17, 0x89, 0x3a, 0x33, + 0x5f, 0xfc, 0xb2, 0x09, 0x82, 0x2f, 0xff, 0xfd, + 0xe2, 0x80, 0x00, + }, + nil, + }, + lzmaTest{ + "text test", + 3, + true, + "Two named types are identical if their type names originate in the same type\n" + + "declaration (§Declarations and scope). A named and an unnamed type are never\n" + + "identical. Two unnamed types are identical if the corresponding type literals\n" + + "have the same literal structure and corresponding components have identical\n" + + "types. In detail:\n" + + "\n" + + " * Two array types are identical if they have identical element types and\n" + + "the same array length.\n" + + " * Two slice types are identical if they have identical element types.\n" + + " * Two struct types are identical if they have the same sequence of fields,\n" + + "and if corresponding fields have the same names and identical types. Two\n" + + "anonymous fields are considered to have the same name.\n" + + " * Two pointer types are identical if they have identical base types.\n" + + " * Two function types are identical if they have the same number of\n" + + "parameters and result values and if corresponding parameter and result types\n" + + "are identical. All \"...\" parameters without a specified type are defined to\n" + + "have identical type. All \"...\" parameters with specified identical type T are\n" + + "defined to have identical type. Parameter and result names are not required to\n" + + "match.\n" + + " * Two interface types are identical if they have the same set of methods\n" + + "with the same names and identical function types. The order of the methods is\n" + + "irrelevant.\n" + + " * Two map types are identical if they have identical key and value types.\n" + + " * Two channel types are identical if they have identical value types and\n" + + "the same direction.\n", + []byte{ + 0x5d, 0x00, 0x00, 0x10, 0x00, 0xe8, 0x05, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x1d, + 0xc9, 0xe2, 0x03, 0x0c, 0x4e, 0x75, 0xc8, 0xee, + 0x65, 0x97, 0xae, 0x0a, 0x7b, 0x0a, 0x66, 0xfa, + 0x4a, 0x94, 0xe6, 0x32, 0x2f, 0x9b, 0x44, 0x8c, + 0xaf, 0xf6, 0xf4, 0x67, 0xe2, 0x8a, 0x8b, 0x2f, + 0x26, 0x41, 0xf6, 0x64, 0xe2, 0xf6, 0x00, 0xbb, + 0x1f, 0x4a, 0xb1, 0xca, 0xa6, 0xf0, 0x54, 0x9e, + 0xa5, 0x2d, 0xe7, 0x6e, 0x6a, 0x49, 0x84, 0xac, + 0xf5, 0x52, 0xcf, 0x57, 0xcd, 0xa7, 0x84, 0xe9, + 0x27, 0xdc, 0x3d, 0xf3, 0xf4, 0x1a, 0x8d, 0x98, + 0xba, 0xcc, 0x47, 0xca, 0x1b, 0x38, 0xa6, 0x8c, + 0x96, 0x24, 0x14, 0x8d, 0x1c, 0x81, 0x6b, 0xc0, + 0x1c, 0x69, 0xa1, 0x79, 0xa2, 0x20, 0x10, 0x6c, + 0x0c, 0x56, 0x40, 0x1f, 0x3f, 0x32, 0x4a, 0x4f, + 0x1f, 0x2a, 0x29, 0xf0, 0x23, 0x99, 0xbe, 0xc7, + 0x49, 0x7e, 0xc7, 0x60, 0xa3, 0x54, 0x9c, 0x06, + 0x06, 0xb4, 0xc4, 0x4d, 0x07, 0xd5, 0xef, 0xa0, + 0xcd, 0xac, 0x8f, 0x54, 0xf9, 0x15, 0x15, 0xa0, + 0xb5, 0xf1, 0x7d, 0xde, 0xeb, 0xe0, 0x41, 0x9a, + 0x3e, 0x5a, 0x66, 0xd2, 0xfc, 0x08, 0x00, 0xe8, + 0xf2, 0xc9, 0x04, 0x94, 0x7e, 0x0b, 0x06, 0x56, + 0x9d, 0xe7, 0x1f, 0x48, 0x21, 0x4d, 0x18, 0x21, + 0xa3, 0x5f, 0x69, 0x7a, 0xed, 0x4d, 0x2d, 0xb4, + 0x3e, 0x34, 0xcf, 0x9e, 0xae, 0x11, 0x2d, 0x15, + 0xbc, 0x2c, 0xd7, 0xef, 0x1c, 0xd5, 0xd8, 0xd3, + 0xc2, 0x4f, 0xcb, 0x2c, 0xb1, 0xa3, 0x85, 0x0a, + 0xad, 0x44, 0x68, 0x42, 0xab, 0x40, 0x58, 0xa2, + 0x9b, 0xdf, 0xbd, 0xa2, 0x10, 0xc7, 0x2e, 0x5a, + 0x1d, 0x07, 0xe4, 0xb5, 0xa6, 0xa8, 0xb3, 0x12, + 0x44, 0x64, 0x18, 0xaf, 0xa7, 0x72, 0x05, 0x29, + 0x48, 0xc6, 0x78, 0xef, 0x7f, 0x54, 0xe9, 0xb3, + 0xae, 0x10, 0x51, 0x11, 0x91, 0xf6, 0x96, 0x40, + 0x6a, 0xf1, 0xc8, 0x3d, 0x46, 0x86, 0x2e, 0xd3, + 0xa1, 0xdc, 0x38, 0x97, 0x11, 0x49, 0x4b, 0x03, + 0x91, 0xa5, 0xed, 0x53, 0x3f, 0xd5, 0x87, 0x04, + 0x25, 0xf0, 0xe2, 0x19, 0x55, 0x99, 0x6b, 0xad, + 0xa2, 0x9c, 0x7a, 0xcd, 0xc9, 0x34, 0x18, 0x8f, + 0x4c, 0xaa, 0xed, 0xd3, 0x49, 0x98, 0xd9, 0x67, + 0xbe, 0x41, 0x85, 0xbf, 0x09, 0x22, 0x16, 0xa0, + 0x81, 0x71, 0x38, 0xdb, 0xb2, 0xd6, 0xfe, 0x2b, + 0xf4, 0x03, 0xf8, 0xd1, 0x00, 0x16, 0x5e, 0x77, + 0x69, 0xd4, 0x28, 0x8f, 0x94, 0x4d, 0x58, 0x4f, + 0xae, 0x6b, 0xb1, 0x09, 0x85, 0x71, 0xd7, 0x3a, + 0x4b, 0xea, 0xd2, 0x70, 0xbb, 0xa2, 0x20, 0x85, + 0x2d, 0xbd, 0x57, 0x3f, 0x81, 0x3e, 0xe4, 0xa2, + 0x43, 0x3e, 0xee, 0x04, 0xbe, 0x42, 0x51, 0xaa, + 0xad, 0xda, 0x53, 0x87, 0xeb, 0xc0, 0x9a, 0xde, + 0xa2, 0x7e, 0x19, 0x4f, 0xa7, 0xdf, 0x23, 0x96, + 0xdd, 0xe3, 0x18, 0x0f, 0xc0, 0x48, 0xfd, 0x9f, + 0x13, 0xc3, 0x3c, 0x3a, 0x7b, 0x7c, 0xa8, 0x89, + 0x6a, 0xd6, 0x68, 0xdd, 0x3b, 0xc6, 0xc6, 0x44, + 0x79, 0xc5, 0x59, 0x1c, 0x23, 0xa9, 0x8b, 0x00, + 0x62, 0xeb, 0x3a, 0x51, 0x14, 0x5e, 0x63, 0x79, + 0x97, 0x60, 0x62, 0x13, 0x49, 0x41, 0x06, 0xf4, + 0x5f, 0xe7, 0x9b, 0xd6, 0x51, 0x31, 0x6e, 0x7d, + 0x5e, 0xe8, 0x72, 0xce, 0x5e, 0xd0, 0xa7, 0x9d, + 0xa3, 0xa9, 0x92, 0xa8, 0x2f, 0x78, 0x00, 0x92, + 0x4f, 0xf0, 0x21, 0xb6, 0x74, 0xfb, 0x3c, 0xe2, + 0x60, 0xdf, 0x82, 0x09, 0x07, 0xb3, 0x68, 0x5b, + 0xe2, 0x49, 0xeb, 0x81, 0x98, 0x23, 0x19, 0xdc, + 0x2c, 0xa1, 0xad, 0x95, 0xc0, 0x9a, 0x48, 0xcd, + 0xa8, 0xe4, 0xdf, 0xbb, 0xca, 0xd4, 0x47, 0x46, + 0xe2, 0xdb, 0x5c, 0xe2, 0xdb, 0xb2, 0x32, 0x44, + 0x87, 0x0a, 0x49, 0x99, 0xc6, 0x32, 0x75, 0xc6, + 0xe7, 0x1b, 0xf1, 0x71, 0x74, 0x32, 0x4a, 0x17, + 0x2f, 0xe8, 0x00, + }, + nil, + }, + lzmaTest{ + "text test with size == -1", + 3, + false, + "Two named types are identical if their type names originate in the same type\n" + + "declaration (§Declarations and scope). A named and an unnamed type are never\n" + + "identical. Two unnamed types are identical if the corresponding type literals\n" + + "have the same literal structure and corresponding components have identical\n" + + "types. In detail:\n" + + "\n" + + " * Two array types are identical if they have identical element types and\n" + + "the same array length.\n" + + " * Two slice types are identical if they have identical element types.\n" + + " * Two struct types are identical if they have the same sequence of fields,\n" + + "and if corresponding fields have the same names and identical types. Two\n" + + "anonymous fields are considered to have the same name.\n" + + " * Two pointer types are identical if they have identical base types.\n" + + " * Two function types are identical if they have the same number of\n" + + "parameters and result values and if corresponding parameter and result types\n" + + "are identical. All \"...\" parameters without a specified type are defined to\n" + + "have identical type. All \"...\" parameters with specified identical type T are\n" + + "defined to have identical type. Parameter and result names are not required to\n" + + "match.\n" + + " * Two interface types are identical if they have the same set of methods\n" + + "with the same names and identical function types. The order of the methods is\n" + + "irrelevant.\n" + + " * Two map types are identical if they have identical key and value types.\n" + + " * Two channel types are identical if they have identical value types and\n" + + "the same direction.\n", + []byte{ + 0x5d, 0x00, 0x00, 0x10, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x2a, 0x1d, + 0xc9, 0xe2, 0x03, 0x0c, 0x4e, 0x75, 0xc8, 0xee, + 0x65, 0x97, 0xae, 0x0a, 0x7b, 0x0a, 0x66, 0xfa, + 0x4a, 0x94, 0xe6, 0x32, 0x2f, 0x9b, 0x44, 0x8c, + 0xaf, 0xf6, 0xf4, 0x67, 0xe2, 0x8a, 0x8b, 0x2f, + 0x26, 0x41, 0xf6, 0x64, 0xe2, 0xf6, 0x00, 0xbb, + 0x1f, 0x4a, 0xb1, 0xca, 0xa6, 0xf0, 0x54, 0x9e, + 0xa5, 0x2d, 0xe7, 0x6e, 0x6a, 0x49, 0x84, 0xac, + 0xf5, 0x52, 0xcf, 0x57, 0xcd, 0xa7, 0x84, 0xe9, + 0x27, 0xdc, 0x3d, 0xf3, 0xf4, 0x1a, 0x8d, 0x98, + 0xba, 0xcc, 0x47, 0xca, 0x1b, 0x38, 0xa6, 0x8c, + 0x96, 0x24, 0x14, 0x8d, 0x1c, 0x81, 0x6b, 0xc0, + 0x1c, 0x69, 0xa1, 0x79, 0xa2, 0x20, 0x10, 0x6c, + 0x0c, 0x56, 0x40, 0x1f, 0x3f, 0x32, 0x4a, 0x4f, + 0x1f, 0x2a, 0x29, 0xf0, 0x23, 0x99, 0xbe, 0xc7, + 0x49, 0x7e, 0xc7, 0x60, 0xa3, 0x54, 0x9c, 0x06, + 0x06, 0xb4, 0xc4, 0x4d, 0x07, 0xd5, 0xef, 0xa0, + 0xcd, 0xac, 0x8f, 0x54, 0xf9, 0x15, 0x15, 0xa0, + 0xb5, 0xf1, 0x7d, 0xde, 0xeb, 0xe0, 0x41, 0x9a, + 0x3e, 0x5a, 0x66, 0xd2, 0xfc, 0x08, 0x00, 0xe8, + 0xf2, 0xc9, 0x04, 0x94, 0x7e, 0x0b, 0x06, 0x56, + 0x9d, 0xe7, 0x1f, 0x48, 0x21, 0x4d, 0x18, 0x21, + 0xa3, 0x5f, 0x69, 0x7a, 0xed, 0x4d, 0x2d, 0xb4, + 0x3e, 0x34, 0xcf, 0x9e, 0xae, 0x11, 0x2d, 0x15, + 0xbc, 0x2c, 0xd7, 0xef, 0x1c, 0xd5, 0xd8, 0xd3, + 0xc2, 0x4f, 0xcb, 0x2c, 0xb1, 0xa3, 0x85, 0x0a, + 0xad, 0x44, 0x68, 0x42, 0xab, 0x40, 0x58, 0xa2, + 0x9b, 0xdf, 0xbd, 0xa2, 0x10, 0xc7, 0x2e, 0x5a, + 0x1d, 0x07, 0xe4, 0xb5, 0xa6, 0xa8, 0xb3, 0x12, + 0x44, 0x64, 0x18, 0xaf, 0xa7, 0x72, 0x05, 0x29, + 0x48, 0xc6, 0x78, 0xef, 0x7f, 0x54, 0xe9, 0xb3, + 0xae, 0x10, 0x51, 0x11, 0x91, 0xf6, 0x96, 0x40, + 0x6a, 0xf1, 0xc8, 0x3d, 0x46, 0x86, 0x2e, 0xd3, + 0xa1, 0xdc, 0x38, 0x97, 0x11, 0x49, 0x4b, 0x03, + 0x91, 0xa5, 0xed, 0x53, 0x3f, 0xd5, 0x87, 0x04, + 0x25, 0xf0, 0xe2, 0x19, 0x55, 0x99, 0x6b, 0xad, + 0xa2, 0x9c, 0x7a, 0xcd, 0xc9, 0x34, 0x18, 0x8f, + 0x4c, 0xaa, 0xed, 0xd3, 0x49, 0x98, 0xd9, 0x67, + 0xbe, 0x41, 0x85, 0xbf, 0x09, 0x22, 0x16, 0xa0, + 0x81, 0x71, 0x38, 0xdb, 0xb2, 0xd6, 0xfe, 0x2b, + 0xf4, 0x03, 0xf8, 0xd1, 0x00, 0x16, 0x5e, 0x77, + 0x69, 0xd4, 0x28, 0x8f, 0x94, 0x4d, 0x58, 0x4f, + 0xae, 0x6b, 0xb1, 0x09, 0x85, 0x71, 0xd7, 0x3a, + 0x4b, 0xea, 0xd2, 0x70, 0xbb, 0xa2, 0x20, 0x85, + 0x2d, 0xbd, 0x57, 0x3f, 0x81, 0x3e, 0xe4, 0xa2, + 0x43, 0x3e, 0xee, 0x04, 0xbe, 0x42, 0x51, 0xaa, + 0xad, 0xda, 0x53, 0x87, 0xeb, 0xc0, 0x9a, 0xde, + 0xa2, 0x7e, 0x19, 0x4f, 0xa7, 0xdf, 0x23, 0x96, + 0xdd, 0xe3, 0x18, 0x0f, 0xc0, 0x48, 0xfd, 0x9f, + 0x13, 0xc3, 0x3c, 0x3a, 0x7b, 0x7c, 0xa8, 0x89, + 0x6a, 0xd6, 0x68, 0xdd, 0x3b, 0xc6, 0xc6, 0x44, + 0x79, 0xc5, 0x59, 0x1c, 0x23, 0xa9, 0x8b, 0x00, + 0x62, 0xeb, 0x3a, 0x51, 0x14, 0x5e, 0x63, 0x79, + 0x97, 0x60, 0x62, 0x13, 0x49, 0x41, 0x06, 0xf4, + 0x5f, 0xe7, 0x9b, 0xd6, 0x51, 0x31, 0x6e, 0x7d, + 0x5e, 0xe8, 0x72, 0xce, 0x5e, 0xd0, 0xa7, 0x9d, + 0xa3, 0xa9, 0x92, 0xa8, 0x2f, 0x78, 0x00, 0x92, + 0x4f, 0xf0, 0x21, 0xb6, 0x74, 0xfb, 0x3c, 0xe2, + 0x60, 0xdf, 0x82, 0x09, 0x07, 0xb3, 0x68, 0x5b, + 0xe2, 0x49, 0xeb, 0x81, 0x98, 0x23, 0x19, 0xdc, + 0x2c, 0xa1, 0xad, 0x95, 0xc0, 0x9a, 0x48, 0xcd, + 0xa8, 0xe4, 0xdf, 0xbb, 0xca, 0xd4, 0x47, 0x46, + 0xe2, 0xdb, 0x5c, 0xe2, 0xdb, 0xb2, 0x32, 0x44, + 0x87, 0x0a, 0x49, 0x99, 0xc6, 0x32, 0x75, 0xc6, + 0xe7, 0x1b, 0xf1, 0x71, 0x74, 0x32, 0x4a, 0x8d, + 0xf2, 0x0a, 0x64, 0xff, 0xe4, 0x0d, 0xf4, 0xa2, + }, + nil, + }, + lzmaTest{ + "hello world test with corrupt lc, lp, pb in header", + 3, + true, + "hello world\n", + []byte{ + 0xfe, 0x00, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x19, + 0x49, 0xee, 0x8d, 0xe9, 0x17, 0x89, 0x3a, 0x33, + 0x5f, 0xfc, 0xac, 0xf7, 0x20, 0x00, + }, + headerError, + }, +} + +type lzmaBenchmark struct { + descr string + level int + raw []byte + lzma []byte +} + +func readFile(filename string) []byte { + file, err := ioutil.ReadFile(filename) + if err != nil { + log.Fatalf("%v", err) + } + return file +} + +var bench = lzmaBenchmark{ + descr: "text bench with size == -1", + level: 3, + raw: readFile("data/data.txt"), + lzma: readFile("data/data.eos.l3.lzma"), +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_decoder.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_decoder.go new file mode 100644 index 00000000..8edc872f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_decoder.go @@ -0,0 +1,369 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// The lzma package implements reading and writing of LZMA format compressed data. +// Reference implementation is LZMA SDK version 4.65 originaly developed by Igor +// Pavlov, available online at: +// +// http://www.7-zip.org/sdk.html +// +// +// +// Usage examples. Write compressed data to a buffer: +// +// var b bytes.Buffer +// w := lzma.NewWriter(&b) +// w.Write([]byte("hello, world\n")) +// w.Close() +// +// read that data back: +// +// r := lzma.NewReader(&b) +// io.Copy(os.Stdout, r) +// r.Close() +// +// +// +// If the data is bigger than you'd like to hold into memory, use pipes. Write +// compressed data to an io.PipeWriter: +// +// pr, pw := io.Pipe() +// go func() { +// defer pw.Close() +// w := lzma.NewWriter(pw) +// defer w.Close() +// // the bytes.Buffer would be an io.Reader used to read uncompressed data from +// io.Copy(w, bytes.NewBuffer([]byte("hello, world\n"))) +// }() +// +// and read it back: +// +// defer pr.Close() +// r := lzma.NewReader(pr) +// defer r.Close() +// // the os.Stdout would be an io.Writer used to write uncompressed data to +// io.Copy(os.Stdout, r) +// +// +// +package lzma + +import ( + "errors" + "io" +) + +const ( + inBufSize = 1 << 16 + outBufSize = 1 << 16 + lzmaPropSize = 5 + lzmaHeaderSize = lzmaPropSize + 8 + lzmaMaxReqInputSize = 20 + + kNumRepDistances = 4 + kNumStates = 12 + kNumPosSlotBits = 6 + kDicLogSizeMin = 0 + kNumLenToPosStatesBits = 2 + kNumLenToPosStates = 1 << kNumLenToPosStatesBits + kMatchMinLen = 2 + kNumAlignBits = 4 + kAlignTableSize = 1 << kNumAlignBits + kAlignMask = kAlignTableSize - 1 + kStartPosModelIndex = 4 + kEndPosModelIndex = 14 + kNumPosModels = kEndPosModelIndex - kStartPosModelIndex + kNumFullDistances = 1 << (kEndPosModelIndex / 2) + kNumLitPosStatesBitsEncodingMax = 4 + kNumLitContextBitsMax = 8 + kNumPosStatesBitsMax = 4 + kNumPosStatesMax = 1 << kNumPosStatesBitsMax + kNumLowLenBits = 3 + kNumMidLenBits = 3 + kNumHighLenBits = 8 + kNumLowLenSymbols = 1 << kNumLowLenBits + kNumMidLenSymbols = 1 << kNumMidLenBits + kNumLenSymbols = kNumLowLenSymbols + kNumMidLenSymbols + (1 << kNumHighLenBits) + kMatchMaxLen = kMatchMinLen + kNumLenSymbols - 1 +) + +// A streamError reports the presence of corrupt input stream. +var streamError = errors.New("error in lzma encoded data stream") + +// A headerError reports an error in the header of the lzma encoder file. +var headerError = errors.New("error in lzma header") + +// A nReadError reports what its message reads +var nReadError = errors.New("number of bytes returned by Reader.Read() didn't meet expectances") + +// A nWriteError reports what its message reads +var nWriteError = errors.New("number of bytes returned by Writer.Write() didn't meet expectances") + +// TODO: implement this err +// A dataIntegrityError reports an error encountered while cheching data integrity. +// -- from lzma.txt: +// You can use multiple checks to test data integrity after full decompression: +// 1) Check Result and "status" variable. +// 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. +// 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. +// You must use correct finish mode in that case. +// +//type dataIntegrityError struct { +// msg string +// // hz +//} + +func stateUpdateChar(index uint32) uint32 { + if index < 4 { + return 0 + } + if index < 10 { + return index - 3 + } + return index - 6 +} + +func stateUpdateMatch(index uint32) uint32 { + if index < 7 { + return 7 + } + return 10 +} + +func stateUpdateRep(index uint32) uint32 { + if index < 7 { + return 8 + } + return 11 +} + +func stateUpdateShortRep(index uint32) uint32 { + if index < 7 { + return 9 + } + return 11 +} + +func stateIsCharState(index uint32) bool { + if index < 7 { + return true + } + return false +} + +func getLenToPosState(length uint32) uint32 { + length -= kMatchMinLen + if length < kNumLenToPosStates { + return length + } + return kNumLenToPosStates - 1 +} + +// LZMA compressed file format +// --------------------------- +// Offset Size Description +// 0 1 Special LZMA properties (lc,lp, pb in encoded form) +// 1 4 Dictionary size (little endian) +// 5 8 Uncompressed size (little endian). Size -1 stands for unknown size + +// lzma properties +type props struct { + litContextBits, // lc + litPosStateBits, // lp + posStateBits uint8 // pb + dictSize uint32 +} + +func (p *props) decodeProps(buf []byte) { + d := buf[0] + if d > (9 * 5 * 5) { + throw(headerError) + } + p.litContextBits = d % 9 + d /= 9 + p.posStateBits = d / 5 + p.litPosStateBits = d % 5 + if p.litContextBits > kNumLitContextBitsMax || p.litPosStateBits > 4 || p.posStateBits > kNumPosStatesBitsMax { + throw(headerError) + } + for i := 0; i < 4; i++ { + p.dictSize += uint32(buf[i+1]) << uint32(i*8) + } +} + +type decoder struct { + // i/o + rd *rangeDecoder // r + outWin *lzOutWindow // w + + // lzma header + prop *props + unpackSize int64 + + // hz + matchDecoders []uint16 + repDecoders []uint16 + repG0Decoders []uint16 + repG1Decoders []uint16 + repG2Decoders []uint16 + rep0LongDecoders []uint16 + posSlotCoders []*rangeBitTreeCoder + posDecoders []uint16 + posAlignCoder *rangeBitTreeCoder + lenCoder *lenCoder + repLenCoder *lenCoder + litCoder *litCoder + dictSizeCheck uint32 + posStateMask uint32 +} + +func (z *decoder) doDecode() { + var state uint32 = 0 + var rep0 uint32 = 0 + var rep1 uint32 = 0 + var rep2 uint32 = 0 + var rep3 uint32 = 0 + var nowPos uint64 = 0 + var prevByte byte = 0 + + for z.unpackSize < 0 || int64(nowPos) < z.unpackSize { + posState := uint32(nowPos) & z.posStateMask + if z.rd.decodeBit(z.matchDecoders, state<= kStartPosModelIndex { + numDirectBits := posSlot>>1 - 1 + rep0 = (2 | posSlot&1) << numDirectBits + if posSlot < kEndPosModelIndex { + rep0 += reverseDecodeIndex(z.rd, z.posDecoders, rep0-posSlot-1, numDirectBits) + } else { + rep0 += z.rd.decodeDirectBits(numDirectBits-kNumAlignBits) << kNumAlignBits + rep0 += z.posAlignCoder.reverseDecode(z.rd) + if int32(rep0) < 0 { + if rep0 == 0xFFFFFFFF { + break + } + throw(streamError) + } + } + } else { + rep0 = posSlot + } + } + if uint64(rep0) >= nowPos || rep0 >= z.dictSizeCheck { + throw(streamError) + } + z.outWin.copyBlock(rep0, length) + nowPos += uint64(length) + prevByte = z.outWin.getByte(0) + } + } + z.outWin.flush() + //if z.unpackSize != -1 { + // if z.outWin.unpacked != z.unpackSize { + // throw(&dataIntegrityError{}) + // } + //} +} + +func (z *decoder) decoder(r io.Reader, w io.Writer) (err error) { + defer handlePanics(&err) + + // read 13 bytes (lzma header) + header := make([]byte, lzmaHeaderSize) + n, err := r.Read(header) + if err != nil { + return + } + if n != lzmaHeaderSize { + return nReadError + } + z.prop = &props{} + z.prop.decodeProps(header) + + z.unpackSize = 0 + for i := 0; i < 8; i++ { + b := header[lzmaPropSize+i] + z.unpackSize = z.unpackSize | int64(b)< 29 { + throw(&argumentValueError{"dictionary size out of range", cl.dictSize}) + } + if cl.fastBytes < 5 || cl.fastBytes > 273 { + throw(&argumentValueError{"number of fast bytes out of range", cl.fastBytes}) + } + if cl.litContextBits < 0 || cl.litContextBits > 8 { + throw(&argumentValueError{"number of literal context bits out of range", cl.litContextBits}) + } + if cl.litPosStateBits < 0 || cl.litPosStateBits > 4 { + throw(&argumentValueError{"number of literal position bits out of range", cl.litPosStateBits}) + } + if cl.posStateBits < 0 || cl.posStateBits > 4 { + throw(&argumentValueError{"number of position bits out of range", cl.posStateBits}) + } + if cl.matchFinder != "bt2" && cl.matchFinder != "bt4" { + throw(&argumentValueError{"unsuported match finder", cl.matchFinder}) + } +} + +var gFastPos []byte = make([]byte, 1<<11) + +// should be called in the encoder's contructor +func initGFastPos() { + kFastSlots := 22 + c := 2 + gFastPos[0] = 0 + gFastPos[1] = 1 + for slotFast := 2; slotFast < kFastSlots; slotFast++ { + k := 1 << uint(slotFast>>1-1) + for j := 0; j < k; j, c = j+1, c+1 { + gFastPos[c] = byte(slotFast) + } + } +} + +func getPosSlot(pos uint32) uint32 { + if pos < 1<<11 { + return uint32(gFastPos[pos]) + } + if pos < 1<<21 { + return uint32(gFastPos[pos>>10] + 20) + } + return uint32(gFastPos[pos>>20] + 40) +} + +func getPosSlot2(pos uint32) uint32 { + if pos < 1<<17 { + return uint32(gFastPos[pos>>6] + 12) + } + if pos < 1<<27 { + return uint32(gFastPos[pos>>16] + 32) + } + return uint32(gFastPos[pos>>26] + 52) +} + +type optimal struct { + state, + posPrev2, + backPrev2, + price, + posPrev, + backPrev, + backs0, + backs1, + backs2, + backs3 uint32 + + prev1IsChar, + prev2 bool +} + +func (o *optimal) makeAsChar() { + o.backPrev = 0xFFFFFFFF + o.prev1IsChar = false +} + +func (o *optimal) makeAsShortRep() { + o.backPrev = 0 + o.prev1IsChar = false +} + +func (o *optimal) isShortRep() bool { + if o.backPrev == 0 { + return true + } + return false +} + +const ( + eMatchFinderTypeBT2 = 0 + eMatchFinderTypeBT4 = 1 + kInfinityPrice = 0x0FFFFFFF + kDefaultDicLogSize = 22 + kNumFastBytesDefault = 0x20 + kNumLenSpecSymbols = kNumLowLenSymbols + kNumMidLenSymbols + kNumOpts = 1 << 12 +) + +type encoder struct { + // i/o, range encoder and match finder + re *rangeEncoder // w + mf *lzBinTree // r + + cl *compressionLevel + size int64 + writeEndMark bool // eos + + optimum []*optimal + + isMatch []uint16 + isRep []uint16 + isRepG0 []uint16 + isRepG1 []uint16 + isRepG2 []uint16 + isRep0Long []uint16 + + posSlotCoders []*rangeBitTreeCoder + + posCoders []uint16 + posAlignCoder *rangeBitTreeCoder + + lenCoder *lenPriceTableCoder + repMatchLenCoder *lenPriceTableCoder + + litCoder *litCoder + + matchDistances []uint32 + + longestMatchLen uint32 + distancePairs uint32 + + additionalOffset uint32 + + optimumEndIndex uint32 + optimumCurrentIndex uint32 + + longestMatchFound bool + + posSlotPrices []uint32 + distancesPrices []uint32 + alignPrices []uint32 + alignPriceCount uint32 + + distTableSize uint32 + + posStateMask uint32 + + nowPos int64 + finished bool + + matchFinderType uint32 + + state uint32 + prevByte byte + repDistances []uint32 + matchPriceCount uint32 + + reps []uint32 + repLens []uint32 + backRes uint32 +} + +func (z *encoder) readMatchDistances() (lenRes uint32) { + lenRes = 0 + z.distancePairs = z.mf.getMatches(z.matchDistances) + if z.distancePairs > 0 { + lenRes = z.matchDistances[z.distancePairs-2] + if lenRes == z.cl.fastBytes { + lenRes += z.mf.iw.getMatchLen(int32(lenRes)-1, z.matchDistances[z.distancePairs-1], kMatchMaxLen-lenRes) + } + } + z.additionalOffset++ + return +} + +func (z *encoder) movePos(num uint32) { + if num > 0 { + z.additionalOffset += num + z.mf.skip(num) + } +} + +func (z *encoder) getPureRepPrice(repIndex, state, posState uint32) (price uint32) { + if repIndex == 0 { + price = getPrice0(z.isRepG0[state]) + price += getPrice1(z.isRep0Long[state< 0; tmp = cur { + if z.optimum[cur].prev1IsChar == true { + z.optimum[posMem].makeAsChar() + z.optimum[posMem].posPrev = posMem - 1 + if z.optimum[cur].prev2 == true { + z.optimum[posMem-1].prev1IsChar = false + z.optimum[posMem-1].posPrev = z.optimum[cur].posPrev2 + z.optimum[posMem-1].backPrev = z.optimum[cur].backPrev2 + } + } + posPrev := posMem + backCur := backMem + backMem = z.optimum[posPrev].backPrev + posMem = z.optimum[posPrev].posPrev + z.optimum[posPrev].backPrev = backCur + z.optimum[posPrev].posPrev = cur + cur = posPrev + } + z.backRes = z.optimum[0].backPrev + z.optimumCurrentIndex = z.optimum[0].posPrev + return z.optimumCurrentIndex +} + +func (z *encoder) getOptimum(position uint32) (res uint32) { + if z.optimumEndIndex != z.optimumCurrentIndex { + lenRes := z.optimum[z.optimumCurrentIndex].posPrev - z.optimumCurrentIndex + z.backRes = z.optimum[z.optimumCurrentIndex].backPrev + z.optimumCurrentIndex = z.optimum[z.optimumCurrentIndex].posPrev + res = lenRes + return + } + + z.optimumEndIndex = 0 + z.optimumCurrentIndex = 0 + var lenMain uint32 + var distancePairs uint32 + if z.longestMatchFound == false { + lenMain = z.readMatchDistances() + } else { + lenMain = z.longestMatchLen + z.longestMatchFound = false + } + distancePairs = z.distancePairs + availableBytes := z.mf.iw.getNumAvailableBytes() + 1 + if availableBytes < 2 { + z.backRes = 0xFFFFFFFF + res = 1 + return + } + + if availableBytes > kMatchMaxLen { + availableBytes = kMatchMaxLen + } + repMaxIndex := uint32(0) + for i := uint32(0); i < kNumRepDistances; i++ { + z.reps[i] = z.repDistances[i] + z.repLens[i] = z.mf.iw.getMatchLen(0-1, z.reps[i], kMatchMaxLen) + if z.repLens[i] > z.repLens[repMaxIndex] { + repMaxIndex = i + } + } + if z.repLens[repMaxIndex] >= z.cl.fastBytes { + z.backRes = repMaxIndex + lenRes := z.repLens[repMaxIndex] + res = lenRes + z.movePos(lenRes - 1) + return + } + + if lenMain >= z.cl.fastBytes { + z.backRes = z.matchDistances[distancePairs-1] + kNumRepDistances + res = lenMain + z.movePos(lenMain - 1) + return + } + + curByte := z.mf.iw.getIndexByte(0 - 1) + matchByte := z.mf.iw.getIndexByte(0 - int32(z.repDistances[0]) - 1 - 1) + if lenMain < 2 && curByte != matchByte && z.repLens[repMaxIndex] < 2 { + z.backRes = 0xFFFFFFFF + res = 1 + return + } + + z.optimum[0].state = z.state + posState := position & z.posStateMask + z.optimum[1].price = getPrice0(z.isMatch[z.state< lenEnd { + lenEnd = lenMain + } + if lenEnd < 2 { + z.backRes = z.optimum[1].backPrev + res = 1 + return + } + + z.optimum[1].posPrev = 0 + z.optimum[0].backs0 = z.reps[0] + z.optimum[0].backs1 = z.reps[1] + z.optimum[0].backs2 = z.reps[2] + z.optimum[0].backs3 = z.reps[3] + length := lenEnd +DoWhile1: + z.optimum[length].price = kInfinityPrice + if length--; length >= 2 { + goto DoWhile1 + } + + for i := uint32(0); i < kNumRepDistances; i++ { + repLen := z.repLens[i] + if repLen < 2 { + continue + } + price := repMatchPrice + z.getPureRepPrice(i, z.state, posState) + DoWhile2: + curAndLenPrice := price + z.repMatchLenCoder.getPrice(repLen-2, posState) + optimum := z.optimum[repLen] + if curAndLenPrice < optimum.price { + optimum.price = curAndLenPrice + optimum.posPrev = 0 + optimum.backPrev = i + optimum.prev1IsChar = false + } + if repLen--; repLen >= 2 { + goto DoWhile2 + } + } + + normalMatchPrice := matchPrice + getPrice0(z.isRep[z.state]) + length = 2 + if z.repLens[0] >= 2 { + length = z.repLens[0] + 1 + } + if length <= lenMain { + offs := uint32(0) + for length > z.matchDistances[offs] { + offs += 2 + } + for ; ; length++ { + distance := z.matchDistances[offs+1] + curAndLenPrice := normalMatchPrice + z.getPosLenPrice(distance, length, posState) + optimum := z.optimum[length] + if curAndLenPrice < optimum.price { + optimum.price = curAndLenPrice + optimum.posPrev = 0 + optimum.backPrev = distance + kNumRepDistances + optimum.prev1IsChar = false + } + if length == z.matchDistances[offs] { + offs += 2 + if offs == distancePairs { + break + } + } + } + } + + cur := uint32(0) + for { + cur++ + if cur == lenEnd { + res = z.backward(cur) + return + } + + newLen := z.readMatchDistances() + distancePairs = z.distancePairs + if newLen >= z.cl.fastBytes { + z.longestMatchLen = newLen + z.longestMatchFound = true + res = z.backward(cur) + return + } + + position++ + posPrev := z.optimum[cur].posPrev + var state uint32 + if z.optimum[cur].prev1IsChar == true { + posPrev-- + if z.optimum[cur].prev2 == true { + state = z.optimum[z.optimum[cur].posPrev2].state + if z.optimum[cur].backPrev2 < kNumRepDistances { + state = stateUpdateRep(state) + } else { + state = stateUpdateMatch(state) + } + } else { + state = z.optimum[posPrev].state + } + state = stateUpdateChar(state) + } else { + state = z.optimum[posPrev].state + } + if posPrev == cur-1 { + if z.optimum[cur].isShortRep() == true { + state = stateUpdateShortRep(state) + } else { + state = stateUpdateChar(state) + } + } else { + var pos uint32 + if z.optimum[cur].prev1IsChar == true && z.optimum[cur].prev2 == true { + posPrev = z.optimum[cur].posPrev2 + pos = z.optimum[cur].backPrev2 + state = stateUpdateRep(state) + } else { + pos = z.optimum[cur].backPrev + if pos < kNumRepDistances { + state = stateUpdateRep(state) + } else { + state = stateUpdateMatch(state) + } + } + opt := z.optimum[posPrev] + if pos < kNumRepDistances { + if pos == 0 { + z.reps[0] = opt.backs0 + z.reps[1] = opt.backs1 + z.reps[2] = opt.backs2 + z.reps[3] = opt.backs3 + } else if pos == 1 { + z.reps[0] = opt.backs1 + z.reps[1] = opt.backs0 + z.reps[2] = opt.backs2 + z.reps[3] = opt.backs3 + } else if pos == 2 { + z.reps[0] = opt.backs2 + z.reps[1] = opt.backs0 + z.reps[2] = opt.backs1 + z.reps[3] = opt.backs3 + } else { + z.reps[0] = opt.backs3 + z.reps[1] = opt.backs0 + z.reps[2] = opt.backs1 + z.reps[3] = opt.backs2 + } + } else { + z.reps[0] = pos - kNumRepDistances + z.reps[1] = opt.backs0 + z.reps[2] = opt.backs1 + z.reps[3] = opt.backs2 + } + } + z.optimum[cur].state = state + z.optimum[cur].backs0 = z.reps[0] + z.optimum[cur].backs1 = z.reps[1] + z.optimum[cur].backs2 = z.reps[2] + z.optimum[cur].backs3 = z.reps[3] + curPrice := z.optimum[cur].price + curByte = z.mf.iw.getIndexByte(0 - 1) + matchByte = z.mf.iw.getIndexByte(0 - int32(z.reps[0]) - 1 - 1) + posState = position & z.posStateMask + curAnd1Price := curPrice + getPrice0(z.isMatch[state< z.cl.fastBytes { + availableBytes = z.cl.fastBytes + } + if nextIsChar == false && matchByte != curByte { + t := minUInt32(availableBytesFull-1, z.cl.fastBytes) + lenTest2 := z.mf.iw.getMatchLen(0, z.reps[0], t) + if lenTest2 >= 2 { + state2 := stateUpdateChar(state) + posStateNext := (position + 1) & z.posStateMask + nextRepMatchPrice := curAnd1Price + getPrice1(z.isMatch[state2<= 2 { + goto DoWhile3 + } + + lenTest = lenTestTemp + if repIndex == 0 { + startLen = lenTest + 1 + } + + if lenTest < availableBytesFull { + t := minUInt32(availableBytesFull-1-lenTest, z.cl.fastBytes) + lenTest2 := z.mf.iw.getMatchLen(int32(lenTest), z.reps[repIndex], t) + if lenTest2 >= 2 { + state2 := stateUpdateRep(state) + posStateNext := (position + lenTest) & z.posStateMask + curAndLenCharPrice := repMatchPrice + z.getRepPrice(repIndex, lenTest, state, posState) + + getPrice0(z.isMatch[state2< availableBytes { + newLen = availableBytes + for distancePairs = 0; newLen > z.matchDistances[distancePairs]; distancePairs += 2 { + // empty loop + } + z.matchDistances[distancePairs] = newLen + distancePairs += 2 + } + if newLen >= startLen { + normalMatchPrice = matchPrice + getPrice0(z.isRep[state]) + for lenEnd < cur+newLen { + lenEnd++ + z.optimum[lenEnd].price = kInfinityPrice + } + offs := uint32(0) + for startLen > z.matchDistances[offs] { + offs += 2 + } + + for lenTest := startLen; ; lenTest++ { + curBack := z.matchDistances[offs+1] + curAndLenPrice := normalMatchPrice + z.getPosLenPrice(curBack, lenTest, posState) + optimum := z.optimum[cur+lenTest] + if curAndLenPrice < optimum.price { + optimum.price = curAndLenPrice + optimum.posPrev = cur + optimum.backPrev = curBack + kNumRepDistances + optimum.prev1IsChar = false + } + if lenTest == z.matchDistances[offs] { + if lenTest < availableBytesFull { + t := minUInt32(availableBytesFull-1-lenTest, z.cl.fastBytes) + lenTest2 := z.mf.iw.getMatchLen(int32(lenTest), curBack, t) + if lenTest2 >= 2 { + state2 := stateUpdateMatch(state) + posStateNext := (position + lenTest) & z.posStateMask + curAndLenCharPrice := curAndLenPrice + + getPrice0(z.isMatch[state2<>1 - 1 + baseVal := (2 | posSlot&1) << footerBits + tempPrices[i] = reverseGetPriceIndex(z.posCoders, baseVal-posSlot-1, footerBits, i-baseVal) + } + for lenToPosState := uint32(0); lenToPosState < kNumLenToPosStates; lenToPosState++ { + var posSlot uint32 + st := lenToPosState << kNumPosSlotBits + for posSlot = 0; posSlot < z.distTableSize; posSlot++ { + z.posSlotPrices[st+posSlot] = z.posSlotCoders[lenToPosState].getPrice(posSlot) + } + for posSlot = kEndPosModelIndex; posSlot < z.distTableSize; posSlot++ { + z.posSlotPrices[st+posSlot] += (posSlot>>1 - 1 - kNumAlignBits) << kNumBitPriceShiftBits + } + var i uint32 + st2 := lenToPosState * kNumFullDistances + for i = 0; i < kStartPosModelIndex; i++ { + z.distancesPrices[st2+i] = z.posSlotPrices[st+i] + } + for ; i < kNumFullDistances; i++ { + z.distancesPrices[st2+i] = z.posSlotPrices[st+getPosSlot(i)] + tempPrices[i] + } + } + z.matchPriceCount = 0 +} + +func (z *encoder) fillAlignPrices() { + for i := uint32(0); i < kAlignTableSize; i++ { + z.alignPrices[i] = z.posAlignCoder.reverseGetPrice(i) + } + z.alignPriceCount = 0 +} + +func (z *encoder) writeEndMarker(posState uint32) { + if z.writeEndMark != true { + return + } + z.re.encode(z.isMatch, z.state<>kNumAlignBits, footerBits-kNumAlignBits) + z.posAlignCoder.reverseEncode(z.re, uint32(posReduced&kAlignMask)) +} + +func (z *encoder) flush(nowPos uint32) { + z.writeEndMarker(nowPos & z.posStateMask) + z.re.flush() +} + +func (z *encoder) codeOneBlock() { + z.finished = true + progressPosValuePrev := z.nowPos + if z.nowPos == 0 { + if z.mf.iw.getNumAvailableBytes() == 0 { + z.flush(uint32(z.nowPos)) + return + } + _ = z.readMatchDistances() + z.re.encode(z.isMatch, z.state<= 1; i-- { + z.repDistances[i] = z.repDistances[i-1] + } + z.repDistances[0] = distance + } + } else { + z.re.encode(z.isRep, z.state, 0) + z.state = stateUpdateMatch(z.state) + z.lenCoder.encode(z.re, length-kMatchMinLen, posState) + pos -= kNumRepDistances + posSlot := getPosSlot(pos) + lenToPosState := getLenToPosState(length) + z.posSlotCoders[lenToPosState].encode(z.re, posSlot) + if posSlot >= kStartPosModelIndex { + footerBits := posSlot>>1 - 1 + baseVal := (2 | posSlot&1) << footerBits + posReduced := pos - baseVal + if posSlot < kEndPosModelIndex { + reverseEncodeIndex(z.re, z.posCoders, baseVal-posSlot-1, footerBits, posReduced) + } else { + z.re.encodeDirectBits(posReduced>>kNumAlignBits, footerBits-kNumAlignBits) + z.posAlignCoder.reverseEncode(z.re, posReduced&kAlignMask) + z.alignPriceCount++ + } + } + for i := kNumRepDistances - 1; i >= 1; i-- { + z.repDistances[i] = z.repDistances[i-1] + } + z.repDistances[0] = pos + z.matchPriceCount++ + } + z.prevByte = z.mf.iw.getIndexByte(int32(length) - 1 - int32(z.additionalOffset)) + } + z.additionalOffset -= length + z.nowPos += int64(length) + if z.additionalOffset == 0 { + if z.matchPriceCount >= 1<<7 { + z.fillDistancesPrices() + } + if z.alignPriceCount >= kAlignTableSize { + z.fillAlignPrices() + } + if z.mf.iw.getNumAvailableBytes() == 0 { + z.flush(uint32(z.nowPos)) + return + } + if z.nowPos-progressPosValuePrev >= 1<<12 { + z.finished = false + return + } + } + } +} + +func (z *encoder) doEncode() { + for { + z.codeOneBlock() + if z.finished == true { + break + } + } +} + +func (z *encoder) encoder(r io.Reader, w io.Writer, size int64, level int) (err error) { + defer handlePanics(&err) + + // these functions are good candidates for init() but the decoder doesn't need them + initProbPrices() + initCrcTable() + initGFastPos() + + if level < 1 || level > 9 { + return &argumentValueError{"level out of range", level} + } + // do not asign &levels[level] directly to z.cl because dictSize is modified later + // and the next run of this funcion with the same compression level will fail; + // levels is intended to be const, but there is no way enforce this constraint. + cl := levels[level] + z.cl = &cl + z.cl.checkValues() + z.distTableSize = z.cl.dictSize * 2 + z.cl.dictSize = 1 << z.cl.dictSize + if size < -1 { // size can be equal to zero + return &argumentValueError{"illegal size", size} + } + z.size = size + z.writeEndMark = false + if z.size == -1 { + z.writeEndMark = true + } + + header := make([]byte, lzmaHeaderSize) + header[0] = byte((z.cl.posStateBits*5+z.cl.litPosStateBits)*9 + z.cl.litContextBits) + for i := uint32(0); i < 4; i++ { + header[i+1] = byte(z.cl.dictSize >> (8 * i)) + } + for i := uint32(0); i < 8; i++ { + header[i+lzmaPropSize] = byte(z.size >> (8 * i)) + } + n, err := w.Write(header) + if err != nil { + return + } + if n != len(header) { + return nWriteError + } + + // do not move before w.Write(header) + z.re = newRangeEncoder(w) + mft, err := strconv.ParseUint(strings.Split(z.cl.matchFinder, "")[2], 10, 64) + if err != nil { + return + } + z.matchFinderType = uint32(mft) + numHashBytes := uint32(4) + if z.matchFinderType == eMatchFinderTypeBT2 { + numHashBytes = 2 + } + z.mf = newLzBinTree(r, z.cl.dictSize, kNumOpts, z.cl.fastBytes, kMatchMaxLen+1, numHashBytes) + + z.optimum = make([]*optimal, kNumOpts) + for i := 0; i < kNumOpts; i++ { + z.optimum[i] = &optimal{} + } + + z.isMatch = initBitModels(kNumStates << kNumPosStatesBitsMax) + z.isRep = initBitModels(kNumStates) + z.isRepG0 = initBitModels(kNumStates) + z.isRepG1 = initBitModels(kNumStates) + z.isRepG2 = initBitModels(kNumStates) + z.isRep0Long = initBitModels(kNumStates << kNumPosStatesBitsMax) + + z.posSlotCoders = make([]*rangeBitTreeCoder, kNumLenToPosStates) + for i := 0; i < kNumLenToPosStates; i++ { + z.posSlotCoders[i] = newRangeBitTreeCoder(kNumPosSlotBits) + } + + z.posCoders = initBitModels(kNumFullDistances - kEndPosModelIndex) + z.posAlignCoder = newRangeBitTreeCoder(kNumAlignBits) + + z.lenCoder = newLenPriceTableCoder(z.cl.fastBytes+1-kMatchMinLen, 1< 1 { + exit("too many file, provide at most one file at a time or check order of flags") + } + //if *decompress == true && *level != 5 { + if *decompress == true && setByUser("l") == true { + exit("compression level is used for compression only") + } + if *level < 1 || *level > 9 { + exit("compression level out of range") + } + if *cores < 1 || *cores > 32 { + exit("invalid number of cores") + } + + runtime.GOMAXPROCS(*cores) + + var inFilePath string + var outFilePath string + if flag.NArg() == 0 || flag.NArg() == 1 && flag.Args()[0] == "-" { // parse args: read from stdin + if *stdout != true { + exit("reading from stdin, can write only to stdout") + } + //if *suffix != "lzma" { + if setByUser("s") == true { + exit("reading from stdin, suffix not needed") + } + stdin = true + + } else if flag.NArg() == 1 { // parse args: read from file + inFilePath = flag.Args()[0] + f, err := os.Lstat(inFilePath) + if err != nil { + log.Fatal(err.Error()) + } + if f == nil { + exit(fmt.Sprintf("file %s not found", inFilePath)) + } + if !!f.IsDir() { + exit(fmt.Sprintf("%s is not a regular file", inFilePath)) + } + + if *stdout == false { // parse args: write to file + if *suffix == "" { + exit("suffix can't be an empty string") + } + + if *decompress == true { + outFileDir, outFileName := path.Split(inFilePath) + if strings.HasSuffix(outFileName, "."+*suffix) { + if len(outFileName) > len("."+*suffix) { + nstr := strings.SplitN(outFileName, ".", len(outFileName)) + estr := strings.Join(nstr[0:len(nstr)-1], ".") + outFilePath = outFileDir + estr + } else { + log.Fatalf("error: can't strip suffix .%s from file %s", *suffix, inFilePath) + } + } else { + exit(fmt.Sprintf("file %s doesn't have suffix .%s", inFilePath, *suffix)) + } + + } else { + outFilePath = inFilePath + "." + *suffix + } + + f, err = os.Lstat(outFilePath) + if err != nil && f != nil { // should be: ||| if err != nil && err != "file not found" ||| but i can't find the error's id + log.Fatal(err.Error()) + } + if f != nil && !f.IsDir() { + if *force == true { + err = os.Remove(outFilePath) + if err != nil { + log.Fatal(err.Error()) + } + } else { + exit(fmt.Sprintf("outFile %s exists. use force to overwrite", outFilePath)) + } + } else if f != nil { + exit(fmt.Sprintf("outFile %s exists and is not a regular file", outFilePath)) + } + } + } + + pr, pw := io.Pipe() + //defer pr.Close() + //defer pw.Close() + + if *decompress { + // read from inFile into pw + go func() { + defer pw.Close() + var inFile *os.File + var err error + if stdin == true { + inFile = os.Stdin + } else { + inFile, err = os.Open(inFilePath) + } + defer inFile.Close() + if err != nil { + log.Fatal(err.Error()) + } + + _, err = io.Copy(pw, inFile) + if err != nil { + log.Fatal(err.Error()) + } + + }() + + // write into outFile from z + defer pr.Close() + z := lzma.NewReader(pr) + defer z.Close() + var outFile *os.File + var err error + if *stdout == true { + outFile = os.Stdout + } else { + outFile, err = os.Create(outFilePath) + } + defer outFile.Close() + if err != nil { + log.Fatal(err.Error()) + } + + _, err = io.Copy(outFile, z) + if err != nil { + log.Fatal(err.Error()) + } + + } else { + // read from inFile into z + go func() { + defer pw.Close() + var z io.WriteCloser + var inFile *os.File + var err error + if stdin == true { + inFile = os.Stdin + defer inFile.Close() + z = lzma.NewWriterLevel(pw, *level) + defer z.Close() + } else { + inFile, err = os.Open(inFilePath) + defer inFile.Close() + if err != nil { + log.Fatal(err.Error()) + } + f, err := os.Lstat(inFilePath) + if err != nil { + log.Fatal(err.Error()) + } + z = lzma.NewWriterSizeLevel(pw, int64(f.Size()), *level) + defer z.Close() + } + + _, err = io.Copy(z, inFile) + if err != nil { + log.Fatal(err.Error()) + } + }() + + // write into outFile from pr + defer pr.Close() + var outFile *os.File + var err error + if *stdout == true { + outFile = os.Stdout + } else { + outFile, err = os.Create(outFilePath) + } + defer outFile.Close() + if err != nil { + log.Fatal(err.Error()) + } + + _, err = io.Copy(outFile, pr) + if err != nil { + log.Fatal(err.Error()) + } + } + + if *stdout == false && *keep == false { + err := os.Remove(inFilePath) + if err != nil { + log.Fatal(err.Error()) + } + } + +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_len_coder.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_len_coder.go new file mode 100644 index 00000000..6bc8ee4c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/lzma_len_coder.go @@ -0,0 +1,126 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +type lenCoder struct { + choice []uint16 + lowCoder []*rangeBitTreeCoder + midCoder []*rangeBitTreeCoder + highCoder *rangeBitTreeCoder +} + +func newLenCoder(numPosStates /*1 << pb*/ uint32) *lenCoder { + lc := &lenCoder{ + choice: initBitModels(2), + lowCoder: make([]*rangeBitTreeCoder, kNumPosStatesMax), + midCoder: make([]*rangeBitTreeCoder, kNumPosStatesMax), + highCoder: newRangeBitTreeCoder(kNumHighLenBits), + } + for i := uint32(0); i < numPosStates; i++ { + lc.lowCoder[i] = newRangeBitTreeCoder(kNumLowLenBits) + lc.midCoder[i] = newRangeBitTreeCoder(kNumMidLenBits) + } + return lc +} + +func (lc *lenCoder) decode(rd *rangeDecoder, posState uint32) (res uint32) { + i := rd.decodeBit(lc.choice, 0) + if i == 0 { + res = lc.lowCoder[posState].decode(rd) + return + } + res = kNumLowLenSymbols + j := rd.decodeBit(lc.choice, 1) + if j == 0 { + k := lc.midCoder[posState].decode(rd) + res += k + return + } else { + l := lc.highCoder.decode(rd) + res = res + kNumMidLenSymbols + l + return + } + return +} + +func (lc *lenCoder) encode(re *rangeEncoder, symbol, posState uint32) { + if symbol < kNumLowLenSymbols { + re.encode(lc.choice, 0, 0) + lc.lowCoder[posState].encode(re, symbol) + } else { + symbol -= kNumLowLenSymbols + re.encode(lc.choice, 0, 1) + if symbol < kNumMidLenSymbols { + re.encode(lc.choice, 1, 0) + lc.midCoder[posState].encode(re, symbol) + } else { + re.encode(lc.choice, 1, 1) + lc.highCoder.encode(re, symbol-kNumMidLenSymbols) + } + } +} + +// write prices into prices []uint32 +func (lc *lenCoder) setPrices(prices []uint32, posState, numSymbols, st uint32) { + a0 := getPrice0(lc.choice[0]) + a1 := getPrice1(lc.choice[0]) + b0 := a1 + getPrice0(lc.choice[1]) + b1 := a1 + getPrice1(lc.choice[1]) + + var i uint32 + for i = 0; i < kNumLowLenSymbols; i++ { + if i >= numSymbols { + return + } + prices[st+i] = a0 + lc.lowCoder[posState].getPrice(i) + } + for ; i < kNumLowLenSymbols+kNumMidLenSymbols; i++ { + if i >= numSymbols { + return + } + prices[st+i] = b0 + lc.midCoder[posState].getPrice(i-kNumLowLenSymbols) + } + for ; i < numSymbols; i++ { + prices[st+i] = b1 + lc.highCoder.getPrice(i-kNumLowLenSymbols-kNumMidLenSymbols) + } +} + + +type lenPriceTableCoder struct { + lc *lenCoder + prices []uint32 + counters []uint32 + tableSize uint32 +} + +func newLenPriceTableCoder(tableSize, numPosStates uint32) *lenPriceTableCoder { + pc := &lenPriceTableCoder{ + lc: newLenCoder(numPosStates), + prices: make([]uint32, kNumLenSymbols<> 7) & 1 + uMatchByte <<= 1 + bit := rd.decodeBit(lsc.coders, ((1+matchBit)<<8)+symbol) + symbol = (symbol << 1) | bit + if matchBit != bit { + for symbol < 0x100 { + i := rd.decodeBit(lsc.coders, symbol) + symbol = (symbol << 1) | i + } + break + } + } + return byte(symbol) +} + + +func (lsc *litSubCoder) encode(re *rangeEncoder, symbol byte) { + uSymbol := uint32(symbol) + context := uint32(1) + for i := uint32(7); int32(i) >= 0; i-- { + bit := (uSymbol >> i) & 1 + re.encode(lsc.coders, context, bit) + context = context<<1 | bit + } +} + +func (lsc *litSubCoder) encodeMatched(re *rangeEncoder, matchByte, symbol byte) { + uMatchByte := uint32(matchByte) + uSymbol := uint32(symbol) + context := uint32(1) + same := true + for i := uint32(7); int32(i) >= 0; i-- { + bit := (uSymbol >> i) & 1 + state := context + if same == true { + matchBit := (uMatchByte >> i) & 1 + state += (1 + matchBit) << 8 + same = false + if matchBit == bit { + same = true + } + } + re.encode(lsc.coders, state, bit) + context = context<<1 | bit + } +} + +func (lsc *litSubCoder) getPrice(matchMode bool, matchByte, symbol byte) uint32 { + uMatchByte := uint32(matchByte) + uSymbol := uint32(symbol) + price := uint32(0) + context := uint32(1) + i := uint32(7) + if matchMode == true { + for ; int32(i) >= 0; i-- { + matchBit := (uMatchByte >> i) & 1 + bit := (uSymbol >> i) & 1 + price += getPrice(lsc.coders[(1+matchBit)<<8+context], bit) + context = context<<1 | bit + if matchBit != bit { + i-- + break + } + } + } + for ; int32(i) >= 0; i-- { + bit := (uSymbol >> i) & 1 + price += getPrice(lsc.coders[context], bit) + context = context<<1 | bit + } + return price +} + + +type litCoder struct { + coders []*litSubCoder + numPrevBits uint32 // literal context bits // lc + // numPosBits uint32 // literal position state bits // lp + posMask uint32 +} + +func newLitCoder(numPosBits, numPrevBits uint32) *litCoder { + numStates := uint32(1) << (numPrevBits + numPosBits) + lc := &litCoder{ + coders: make([]*litSubCoder, numStates), + numPrevBits: numPrevBits, + // numPosBits: numPosBits, + posMask: (1 << numPosBits) - 1, + } + for i := uint32(0); i < numStates; i++ { + lc.coders[i] = newLitSubCoder() + } + return lc +} + +func (lc *litCoder) getSubCoder(pos uint32, prevByte byte) *litSubCoder { + return lc.coders[((pos&lc.posMask)<>(8-lc.numPrevBits))] +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/range_bit_tree_coder.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/range_bit_tree_coder.go new file mode 100644 index 00000000..4dc39216 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/range_bit_tree_coder.go @@ -0,0 +1,117 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +type rangeBitTreeCoder struct { + models []uint16 // length(models) is at most 1<<8 + numBitLevels uint32 // min 2; max 8 +} + +func newRangeBitTreeCoder(numBitLevels uint32) *rangeBitTreeCoder { + return &rangeBitTreeCoder{ + numBitLevels: numBitLevels, + models: initBitModels(1 << numBitLevels), + } +} + +func (rc *rangeBitTreeCoder) decode(rd *rangeDecoder) (res uint32) { + res = 1 + for bitIndex := rc.numBitLevels; bitIndex != 0; bitIndex-- { + bit := rd.decodeBit(rc.models, res) + res = res<<1 + bit + } + res -= 1 << rc.numBitLevels + return +} + +func (rc *rangeBitTreeCoder) reverseDecode(rd *rangeDecoder) (res uint32) { + index := uint32(1) + res = 0 + for bitIndex := uint32(0); bitIndex < rc.numBitLevels; bitIndex++ { + bit := rd.decodeBit(rc.models, index) + index <<= 1 + index += bit + res |= bit << bitIndex + } + return +} + +func reverseDecodeIndex(rd *rangeDecoder, models []uint16, startIndex, numBitModels uint32) (res uint32) { + index := uint32(1) + res = 0 + for bitIndex := uint32(0); bitIndex < numBitModels; bitIndex++ { + bit := rd.decodeBit(models, startIndex+index) + index <<= 1 + index += bit + res |= bit << bitIndex + } + return +} + +func (rc *rangeBitTreeCoder) encode(re *rangeEncoder, symbol uint32) { + m := uint32(1) + for bitIndex := rc.numBitLevels; bitIndex != 0; { + bitIndex-- + bit := (symbol >> bitIndex) & 1 + re.encode(rc.models, m, bit) + m = m<<1 | bit + } +} + +func (rc *rangeBitTreeCoder) reverseEncode(re *rangeEncoder, symbol uint32) { + m := uint32(1) + for i := uint32(0); i < rc.numBitLevels; i++ { + bit := symbol & 1 + re.encode(rc.models, m, bit) + m = m<<1 | bit + symbol >>= 1 + } +} + +func (rc *rangeBitTreeCoder) getPrice(symbol uint32) (res uint32) { + res = 0 + m := uint32(1) + for bitIndex := rc.numBitLevels; bitIndex != 0; { + bitIndex-- + bit := (symbol >> bitIndex) & 1 + res += getPrice(rc.models[m], bit) + m = m<<1 + bit + } + return +} + +func (rc *rangeBitTreeCoder) reverseGetPrice(symbol uint32) (res uint32) { + res = 0 + m := uint32(1) + for i := rc.numBitLevels; i != 0; i-- { + bit := symbol & 1 + symbol >>= 1 + res += getPrice(rc.models[m], bit) + m = m<<1 | bit + } + return +} + +func reverseGetPriceIndex(models []uint16, startIndex, numBitLevels, symbol uint32) (res uint32) { + res = 0 + m := uint32(1) + for i := numBitLevels; i != 0; i-- { + bit := symbol & 1 + symbol >>= 1 + res += getPrice(models[startIndex+m], bit) + m = m<<1 | bit + } + return +} + +func reverseEncodeIndex(re *rangeEncoder, models []uint16, startIndex, numBitLevels, symbol uint32) { + m := uint32(1) + for i := uint32(0); i < numBitLevels; i++ { + bit := symbol & 1 + re.encode(models, startIndex+m, bit) + m = m<<1 | bit + symbol >>= 1 + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/range_coder.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/range_coder.go new file mode 100644 index 00000000..ee72b6d1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/range_coder.go @@ -0,0 +1,249 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +import ( + "bufio" + "io" +) + +const ( + kTopValue = 1 << 24 + kNumBitModelTotalBits = 11 + kBitModelTotal = 1 << kNumBitModelTotalBits + kNumMoveBits = 5 +) + +// The actual read interface needed by NewDecoder. If the passed in io.Reader +// does not also have ReadByte, the NewDecoder will introduce its own buffering. +// +type Reader interface { + io.Reader + ReadByte() (c byte, err error) +} + +type rangeDecoder struct { + r Reader + rrange uint32 + code uint32 +} + +func makeReader(r io.Reader) Reader { + if rr, ok := r.(Reader); ok { + return rr + } + return bufio.NewReader(r) +} + +func newRangeDecoder(r io.Reader) *rangeDecoder { + rd := &rangeDecoder{ + r: makeReader(r), + rrange: 0xFFFFFFFF, + code: 0, + } + buf := make([]byte, 5) + n, err := rd.r.Read(buf) + if err != nil { + throw(err) + } + if n != len(buf) { + throw(nReadError) + } + for i := 0; i < len(buf); i++ { + rd.code = rd.code<<8 | uint32(buf[i]) + } + return rd +} + +func (rd *rangeDecoder) decodeDirectBits(numTotalBits uint32) (res uint32) { + for i := numTotalBits; i != 0; i-- { + rd.rrange >>= 1 + t := (rd.code - rd.rrange) >> 31 + rd.code -= rd.rrange & (t - 1) + res = res<<1 | (1 - t) + if rd.rrange < kTopValue { + c, err := rd.r.ReadByte() + if err != nil { + throw(err) + } + rd.code = rd.code<<8 | uint32(c) + rd.rrange <<= 8 + } + } + return +} + +func (rd *rangeDecoder) decodeBit(probs []uint16, index uint32) (res uint32) { + prob := probs[index] + newBound := (rd.rrange >> kNumBitModelTotalBits) * uint32(prob) + if rd.code < newBound { + rd.rrange = newBound + probs[index] = prob + (kBitModelTotal-prob)>>kNumMoveBits + if rd.rrange < kTopValue { + b, err := rd.r.ReadByte() + if err != nil { + throw(err) + } + rd.code = rd.code<<8 | uint32(b) + rd.rrange <<= 8 + } + res = 0 + } else { + rd.rrange -= newBound + rd.code -= newBound + probs[index] = prob - prob>>kNumMoveBits + if rd.rrange < kTopValue { + b, err := rd.r.ReadByte() + if err != nil { + throw(err) + } + rd.code = rd.code<<8 | uint32(b) + rd.rrange <<= 8 + } + res = 1 + } + return +} + +func initBitModels(length uint32) (probs []uint16) { + probs = make([]uint16, length) + val := uint16(kBitModelTotal) >> 1 + for i := uint32(0); i < length; i++ { + probs[i] = val // 1 << 10 + } + return +} + +const ( + kNumMoveReducingBits = 2 + kNumBitPriceShiftBits = 6 +) + +// The actual write interface needed by NewEncoder. If the passed in io.Writer +// does not also have WriteByte and Flush, the NewEncoder will wrap it into an +// bufio.Writer. +// +type Writer interface { + io.Writer + Flush() error + WriteByte(c byte) error +} + +type rangeEncoder struct { + w Writer + low uint64 + pos uint64 + cacheSize uint32 + cache uint32 + rrange uint32 +} + +func makeWriter(w io.Writer) Writer { + if ww, ok := w.(Writer); ok { + return ww + } + return bufio.NewWriter(w) +} + +func newRangeEncoder(w io.Writer) *rangeEncoder { + return &rangeEncoder{ + w: makeWriter(w), + low: 0, + pos: 0, + cacheSize: 1, + cache: 0, + rrange: 0xFFFFFFFF, + } +} + +func (re *rangeEncoder) flush() { + for i := 0; i < 5; i++ { + re.shiftLow() + } + err := re.w.Flush() + if err != nil { + throw(err) + } +} + +func (re *rangeEncoder) shiftLow() { + lowHi := uint32(re.low >> 32) + if lowHi != 0 || re.low < uint64(0x00000000FF000000) { + re.pos += uint64(re.cacheSize) + temp := re.cache + dwtemp := uint32(1) // execute the loop at least once (do-while) + for ; dwtemp != 0; dwtemp = re.cacheSize { + err := re.w.WriteByte(byte(temp + lowHi)) + if err != nil { + throw(err) + } + temp = 0x000000FF + re.cacheSize-- + } + re.cache = uint32(re.low) >> 24 + } + re.cacheSize++ + re.low = uint64(uint32(re.low) << 8) +} + +func (re *rangeEncoder) encodeDirectBits(v, numTotalBits uint32) { + for i := numTotalBits - 1; int32(i) >= 0; i-- { + re.rrange >>= 1 + if (v>>i)&1 == 1 { + re.low += uint64(re.rrange) + } + if re.rrange < kTopValue { + re.rrange <<= 8 + re.shiftLow() + } + } +} + +func (re *rangeEncoder) processedSize() uint64 { + return uint64(re.cacheSize) + re.pos + 4 +} + +func (re *rangeEncoder) encode(probs []uint16, index, symbol uint32) { + prob := probs[index] + newBound := (re.rrange >> kNumBitModelTotalBits) * uint32(prob) + if symbol == 0 { + re.rrange = newBound + probs[index] = prob + (kBitModelTotal-prob)>>kNumMoveBits + } else { + re.low += uint64(newBound) & uint64(0xFFFFFFFFFFFFFFFF) + re.rrange -= newBound + probs[index] = prob - prob>>kNumMoveBits + } + if re.rrange < kTopValue { + re.rrange <<= 8 + re.shiftLow() + } +} + +var probPrices []uint32 = make([]uint32, kBitModelTotal>>kNumMoveReducingBits) // len(probPrices) = 512 + +// should be called in the encoder's contructor. +func initProbPrices() { + kNumBits := uint32(kNumBitModelTotalBits - kNumMoveReducingBits) + for i := kNumBits - 1; int32(i) >= 0; i-- { + start := uint32(1) << (kNumBits - i - 1) + end := uint32(1) << (kNumBits - i) + for j := start; j < end; j++ { + probPrices[j] = i<>(kNumBits-i-1) + } + } +} + +func getPrice(prob uint16, symbol uint32) uint32 { + return probPrices[(((uint32(prob)-symbol)^(-symbol))&(uint32(kBitModelTotal)-1))>>kNumMoveReducingBits] +} + +func getPrice0(prob uint16) uint32 { + return probPrices[prob>>kNumMoveReducingBits] +} + +func getPrice1(prob uint16) uint32 { + return probPrices[(kBitModelTotal-prob)>>kNumMoveReducingBits] +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/util.go b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/util.go new file mode 100644 index 00000000..6a4ec51d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/smira/lzma/util.go @@ -0,0 +1,33 @@ +// Copyright (c) 2010, Andrei Vieru. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package lzma + +func minInt32(left int32, right int32) int32 { + if left < right { + return left + } + return right +} + +func minUInt32(left uint32, right uint32) uint32 { + if left < right { + return left + } + return right +} + +func maxInt32(left int32, right int32) int32 { + if left > right { + return left + } + return right +} + +func maxUInt32(left uint32, right uint32) uint32 { + if left > right { + return left + } + return right +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/.travis.yml b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/.travis.yml index 65d13059..8288a4c0 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/.travis.yml +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/.travis.yml @@ -3,6 +3,7 @@ language: go go: - 1.2 - 1.3 + - 1.4 - tip -script: go test ./... \ No newline at end of file +script: go test -timeout 1h ./... diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/README.md b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/README.md index f8706652..d838b0cf 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/README.md +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/README.md @@ -16,88 +16,89 @@ Usage ----------- Create or open a database: - - db, err := leveldb.OpenFile("path/to/db", nil) - ... - defer db.Close() - ... - +```go +db, err := leveldb.OpenFile("path/to/db", nil) +... +defer db.Close() +... +``` Read or modify the database content: - - // Remember that the contents of the returned slice should not be modified. - data, err := db.Get([]byte("key"), nil) - ... - err = db.Put([]byte("key"), []byte("value"), nil) - ... - err = db.Delete([]byte("key"), nil) - ... +```go +// Remember that the contents of the returned slice should not be modified. +data, err := db.Get([]byte("key"), nil) +... +err = db.Put([]byte("key"), []byte("value"), nil) +... +err = db.Delete([]byte("key"), nil) +... +``` Iterate over database content: - - iter := db.NewIterator(nil, nil) - for iter.Next() { - // Remember that the contents of the returned slice should not be modified, and - // only valid until the next call to Next. - key := iter.Key() - value := iter.Value() - ... - } - iter.Release() - err = iter.Error() +```go +iter := db.NewIterator(nil, nil) +for iter.Next() { + // Remember that the contents of the returned slice should not be modified, and + // only valid until the next call to Next. + key := iter.Key() + value := iter.Value() ... - +} +iter.Release() +err = iter.Error() +... +``` Seek-then-Iterate: - - iter := db.NewIterator(nil, nil) - for ok := iter.Seek(key); ok; ok = iter.Next() { - // Use key/value. - ... - } - iter.Release() - err = iter.Error() +```go +iter := db.NewIterator(nil, nil) +for ok := iter.Seek(key); ok; ok = iter.Next() { + // Use key/value. ... - +} +iter.Release() +err = iter.Error() +... +``` Iterate over subset of database content: - - iter := db.NewIterator(&util.Range{Start: []byte("foo"), Limit: []byte("xoo")}, nil) - for iter.Next() { - // Use key/value. - ... - } - iter.Release() - err = iter.Error() +```go +iter := db.NewIterator(&util.Range{Start: []byte("foo"), Limit: []byte("xoo")}, nil) +for iter.Next() { + // Use key/value. ... - +} +iter.Release() +err = iter.Error() +... +``` Iterate over subset of database content with a particular prefix: - - iter := db.NewIterator(util.BytesPrefix([]byte("foo-")), nil) - for iter.Next() { - // Use key/value. - ... - } - iter.Release() - err = iter.Error() +```go +iter := db.NewIterator(util.BytesPrefix([]byte("foo-")), nil) +for iter.Next() { + // Use key/value. ... - +} +iter.Release() +err = iter.Error() +... +``` Batch writes: - - batch := new(leveldb.Batch) - batch.Put([]byte("foo"), []byte("value")) - batch.Put([]byte("bar"), []byte("another value")) - batch.Delete([]byte("baz")) - err = db.Write(batch, nil) - ... - +```go +batch := new(leveldb.Batch) +batch.Put([]byte("foo"), []byte("value")) +batch.Put([]byte("bar"), []byte("another value")) +batch.Delete([]byte("baz")) +err = db.Write(batch, nil) +... +``` Use bloom filter: - - o := &opt.Options{ - Filter: filter.NewBloomFilter(10), - } - db, err := leveldb.OpenFile("path/to/db", o) - ... - defer db.Close() - ... - +```go +o := &opt.Options{ + Filter: filter.NewBloomFilter(10), +} +db, err := leveldb.OpenFile("path/to/db", o) +... +defer db.Close() +... +``` Documentation ----------- diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/go13_bench_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/bench2_test.go similarity index 98% rename from src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/go13_bench_test.go rename to src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/bench2_test.go index e76657e5..0dd60fd8 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/go13_bench_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/bench2_test.go @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// +build go1.3 +// +build !go1.2 package leveldb diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/bench2_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/bench2_test.go new file mode 100644 index 00000000..175e2220 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/bench2_test.go @@ -0,0 +1,30 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// +build !go1.2 + +package cache + +import ( + "math/rand" + "testing" +) + +func BenchmarkLRUCache(b *testing.B) { + c := NewCache(NewLRU(10000)) + + b.SetParallelism(10) + b.RunParallel(func(pb *testing.PB) { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + + for pb.Next() { + key := uint64(r.Intn(1000000)) + c.Get(0, key, func() (int, Value) { + return 1, key + }).Release() + } + }) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go index baced771..c9670de5 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache.go @@ -8,152 +8,669 @@ package cache import ( + "sync" "sync/atomic" + "unsafe" + + "github.com/syndtr/goleveldb/leveldb/util" ) -// SetFunc is the function that will be called by Namespace.Get to create -// a cache object, if charge is less than one than the cache object will -// not be registered to cache tree, if value is nil then the cache object -// will not be created. -type SetFunc func() (charge int, value interface{}) - -// DelFin is the function that will be called as the result of a delete operation. -// Exist == true is indication that the object is exist, and pending == true is -// indication of deletion already happen but haven't done yet (wait for all handles -// to be released). And exist == false means the object doesn't exist. -type DelFin func(exist, pending bool) - -// PurgeFin is the function that will be called as the result of a purge operation. -type PurgeFin func(ns, key uint64) - -// Cache is a cache tree. A cache instance must be goroutine-safe. -type Cache interface { - // SetCapacity sets cache tree capacity. - SetCapacity(capacity int) - - // Capacity returns cache tree capacity. +// Cacher provides interface to implements a caching functionality. +// An implementation must be goroutine-safe. +type Cacher interface { + // Capacity returns cache capacity. Capacity() int - // Used returns used cache tree capacity. - Used() int + // SetCapacity sets cache capacity. + SetCapacity(capacity int) - // Size returns entire alive cache objects size. - Size() int + // Promote promotes the 'cache node'. + Promote(n *Node) - // NumObjects returns number of alive objects. - NumObjects() int + // Ban evicts the 'cache node' and prevent subsequent 'promote'. + Ban(n *Node) - // GetNamespace gets cache namespace with the given id. - // GetNamespace is never return nil. - GetNamespace(id uint64) Namespace + // Evict evicts the 'cache node'. + Evict(n *Node) - // PurgeNamespace purges cache namespace with the given id from this cache tree. - // Also read Namespace.Purge. - PurgeNamespace(id uint64, fin PurgeFin) + // EvictNS evicts 'cache node' with the given namespace. + EvictNS(ns uint64) - // ZapNamespace detaches cache namespace with the given id from this cache tree. - // Also read Namespace.Zap. - ZapNamespace(id uint64) + // EvictAll evicts all 'cache node'. + EvictAll() - // Purge purges all cache namespace from this cache tree. - // This is behave the same as calling Namespace.Purge method on all cache namespace. - Purge(fin PurgeFin) - - // Zap detaches all cache namespace from this cache tree. - // This is behave the same as calling Namespace.Zap method on all cache namespace. - Zap() + // Close closes the 'cache tree' + Close() error } -// Namespace is a cache namespace. A namespace instance must be goroutine-safe. -type Namespace interface { - // Get gets cache object with the given key. - // If cache object is not found and setf is not nil, Get will atomically creates - // the cache object by calling setf. Otherwise Get will returns nil. - // - // The returned cache handle should be released after use by calling Release - // method. - Get(key uint64, setf SetFunc) Handle +// Value is a 'cacheable object'. It may implements util.Releaser, if +// so the the Release method will be called once object is released. +type Value interface{} - // Delete removes cache object with the given key from cache tree. - // A deleted cache object will be released as soon as all of its handles have - // been released. - // Delete only happen once, subsequent delete will consider cache object doesn't - // exist, even if the cache object ins't released yet. - // - // If not nil, fin will be called if the cache object doesn't exist or when - // finally be released. - // - // Delete returns true if such cache object exist and never been deleted. - Delete(key uint64, fin DelFin) bool - - // Purge removes all cache objects within this namespace from cache tree. - // This is the same as doing delete on all cache objects. - // - // If not nil, fin will be called on all cache objects when its finally be - // released. - Purge(fin PurgeFin) - - // Zap detaches namespace from cache tree and release all its cache objects. - // A zapped namespace can never be filled again. - // Calling Get on zapped namespace will always return nil. - Zap() +type CacheGetter struct { + Cache *Cache + NS uint64 } -// Handle is a cache handle. -type Handle interface { - // Release releases this cache handle. This method can be safely called mutiple - // times. - Release() - - // Value returns value of this cache handle. - // Value will returns nil after this cache handle have be released. - Value() interface{} +func (g *CacheGetter) Get(key uint64, setFunc func() (size int, value Value)) *Handle { + return g.Cache.Get(g.NS, key, setFunc) } +// The hash tables implementation is based on: +// "Dynamic-Sized Nonblocking Hash Tables", by Yujie Liu, Kunlong Zhang, and Michael Spear. ACM Symposium on Principles of Distributed Computing, Jul 2014. + const ( - DelNotExist = iota - DelExist - DelPendig + mInitialSize = 1 << 4 + mOverflowThreshold = 1 << 5 + mOverflowGrowThreshold = 1 << 7 ) -// Namespace state. -type nsState int - -const ( - nsEffective nsState = iota - nsZapped -) - -// Node state. -type nodeState int - -const ( - nodeZero nodeState = iota - nodeEffective - nodeEvicted - nodeDeleted -) - -// Fake handle. -type fakeHandle struct { - value interface{} - fin func() - once uint32 +type mBucket struct { + mu sync.Mutex + node []*Node + frozen bool } -func (h *fakeHandle) Value() interface{} { - if atomic.LoadUint32(&h.once) == 0 { - return h.value +func (b *mBucket) freeze() []*Node { + b.mu.Lock() + defer b.mu.Unlock() + if !b.frozen { + b.frozen = true + } + return b.node +} + +func (b *mBucket) get(r *Cache, h *mNode, hash uint32, ns, key uint64, noset bool) (done, added bool, n *Node) { + b.mu.Lock() + + if b.frozen { + b.mu.Unlock() + return + } + + // Scan the node. + for _, n := range b.node { + if n.hash == hash && n.ns == ns && n.key == key { + atomic.AddInt32(&n.ref, 1) + b.mu.Unlock() + return true, false, n + } + } + + // Get only. + if noset { + b.mu.Unlock() + return true, false, nil + } + + // Create node. + n = &Node{ + r: r, + hash: hash, + ns: ns, + key: key, + ref: 1, + } + // Add node to bucket. + b.node = append(b.node, n) + bLen := len(b.node) + b.mu.Unlock() + + // Update counter. + grow := atomic.AddInt32(&r.nodes, 1) >= h.growThreshold + if bLen > mOverflowThreshold { + grow = grow || atomic.AddInt32(&h.overflow, 1) >= mOverflowGrowThreshold + } + + // Grow. + if grow && atomic.CompareAndSwapInt32(&h.resizeInProgess, 0, 1) { + nhLen := len(h.buckets) << 1 + nh := &mNode{ + buckets: make([]unsafe.Pointer, nhLen), + mask: uint32(nhLen) - 1, + pred: unsafe.Pointer(h), + growThreshold: int32(nhLen * mOverflowThreshold), + shrinkThreshold: int32(nhLen >> 1), + } + ok := atomic.CompareAndSwapPointer(&r.mHead, unsafe.Pointer(h), unsafe.Pointer(nh)) + if !ok { + panic("BUG: failed swapping head") + } + go nh.initBuckets() + } + + return true, true, n +} + +func (b *mBucket) delete(r *Cache, h *mNode, hash uint32, ns, key uint64) (done, deleted bool) { + b.mu.Lock() + + if b.frozen { + b.mu.Unlock() + return + } + + // Scan the node. + var ( + n *Node + bLen int + ) + for i := range b.node { + n = b.node[i] + if n.ns == ns && n.key == key { + if atomic.LoadInt32(&n.ref) == 0 { + deleted = true + + // Call releaser. + if n.value != nil { + if r, ok := n.value.(util.Releaser); ok { + r.Release() + } + n.value = nil + } + + // Remove node from bucket. + b.node = append(b.node[:i], b.node[i+1:]...) + bLen = len(b.node) + } + break + } + } + b.mu.Unlock() + + if deleted { + // Call OnDel. + for _, f := range n.onDel { + f() + } + + // Update counter. + atomic.AddInt32(&r.size, int32(n.size)*-1) + shrink := atomic.AddInt32(&r.nodes, -1) < h.shrinkThreshold + if bLen >= mOverflowThreshold { + atomic.AddInt32(&h.overflow, -1) + } + + // Shrink. + if shrink && len(h.buckets) > mInitialSize && atomic.CompareAndSwapInt32(&h.resizeInProgess, 0, 1) { + nhLen := len(h.buckets) >> 1 + nh := &mNode{ + buckets: make([]unsafe.Pointer, nhLen), + mask: uint32(nhLen) - 1, + pred: unsafe.Pointer(h), + growThreshold: int32(nhLen * mOverflowThreshold), + shrinkThreshold: int32(nhLen >> 1), + } + ok := atomic.CompareAndSwapPointer(&r.mHead, unsafe.Pointer(h), unsafe.Pointer(nh)) + if !ok { + panic("BUG: failed swapping head") + } + go nh.initBuckets() + } + } + + return true, deleted +} + +type mNode struct { + buckets []unsafe.Pointer // []*mBucket + mask uint32 + pred unsafe.Pointer // *mNode + resizeInProgess int32 + + overflow int32 + growThreshold int32 + shrinkThreshold int32 +} + +func (n *mNode) initBucket(i uint32) *mBucket { + if b := (*mBucket)(atomic.LoadPointer(&n.buckets[i])); b != nil { + return b + } + + p := (*mNode)(atomic.LoadPointer(&n.pred)) + if p != nil { + var node []*Node + if n.mask > p.mask { + // Grow. + pb := (*mBucket)(atomic.LoadPointer(&p.buckets[i&p.mask])) + if pb == nil { + pb = p.initBucket(i & p.mask) + } + m := pb.freeze() + // Split nodes. + for _, x := range m { + if x.hash&n.mask == i { + node = append(node, x) + } + } + } else { + // Shrink. + pb0 := (*mBucket)(atomic.LoadPointer(&p.buckets[i])) + if pb0 == nil { + pb0 = p.initBucket(i) + } + pb1 := (*mBucket)(atomic.LoadPointer(&p.buckets[i+uint32(len(n.buckets))])) + if pb1 == nil { + pb1 = p.initBucket(i + uint32(len(n.buckets))) + } + m0 := pb0.freeze() + m1 := pb1.freeze() + // Merge nodes. + node = make([]*Node, 0, len(m0)+len(m1)) + node = append(node, m0...) + node = append(node, m1...) + } + b := &mBucket{node: node} + if atomic.CompareAndSwapPointer(&n.buckets[i], nil, unsafe.Pointer(b)) { + if len(node) > mOverflowThreshold { + atomic.AddInt32(&n.overflow, int32(len(node)-mOverflowThreshold)) + } + return b + } + } + + return (*mBucket)(atomic.LoadPointer(&n.buckets[i])) +} + +func (n *mNode) initBuckets() { + for i := range n.buckets { + n.initBucket(uint32(i)) + } + atomic.StorePointer(&n.pred, nil) +} + +// Cache is a 'cache map'. +type Cache struct { + mu sync.RWMutex + mHead unsafe.Pointer // *mNode + nodes int32 + size int32 + cacher Cacher + closed bool +} + +// NewCache creates a new 'cache map'. The cacher is optional and +// may be nil. +func NewCache(cacher Cacher) *Cache { + h := &mNode{ + buckets: make([]unsafe.Pointer, mInitialSize), + mask: mInitialSize - 1, + growThreshold: int32(mInitialSize * mOverflowThreshold), + shrinkThreshold: 0, + } + for i := range h.buckets { + h.buckets[i] = unsafe.Pointer(&mBucket{}) + } + r := &Cache{ + mHead: unsafe.Pointer(h), + cacher: cacher, + } + return r +} + +func (r *Cache) getBucket(hash uint32) (*mNode, *mBucket) { + h := (*mNode)(atomic.LoadPointer(&r.mHead)) + i := hash & h.mask + b := (*mBucket)(atomic.LoadPointer(&h.buckets[i])) + if b == nil { + b = h.initBucket(i) + } + return h, b +} + +func (r *Cache) delete(n *Node) bool { + for { + h, b := r.getBucket(n.hash) + done, deleted := b.delete(r, h, n.hash, n.ns, n.key) + if done { + return deleted + } + } + return false +} + +// Nodes returns number of 'cache node' in the map. +func (r *Cache) Nodes() int { + return int(atomic.LoadInt32(&r.nodes)) +} + +// Size returns sums of 'cache node' size in the map. +func (r *Cache) Size() int { + return int(atomic.LoadInt32(&r.size)) +} + +// Capacity returns cache capacity. +func (r *Cache) Capacity() int { + if r.cacher == nil { + return 0 + } + return r.cacher.Capacity() +} + +// SetCapacity sets cache capacity. +func (r *Cache) SetCapacity(capacity int) { + if r.cacher != nil { + r.cacher.SetCapacity(capacity) + } +} + +// Get gets 'cache node' with the given namespace and key. +// If cache node is not found and setFunc is not nil, Get will atomically creates +// the 'cache node' by calling setFunc. Otherwise Get will returns nil. +// +// The returned 'cache handle' should be released after use by calling Release +// method. +func (r *Cache) Get(ns, key uint64, setFunc func() (size int, value Value)) *Handle { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return nil + } + + hash := murmur32(ns, key, 0xf00) + for { + h, b := r.getBucket(hash) + done, _, n := b.get(r, h, hash, ns, key, setFunc == nil) + if done { + if n != nil { + n.mu.Lock() + if n.value == nil { + if setFunc == nil { + n.mu.Unlock() + n.unref() + return nil + } + + n.size, n.value = setFunc() + if n.value == nil { + n.size = 0 + n.mu.Unlock() + n.unref() + return nil + } + atomic.AddInt32(&r.size, int32(n.size)) + } + n.mu.Unlock() + if r.cacher != nil { + r.cacher.Promote(n) + } + return &Handle{unsafe.Pointer(n)} + } + + break + } } return nil } -func (h *fakeHandle) Release() { - if !atomic.CompareAndSwapUint32(&h.once, 0, 1) { +// Delete removes and ban 'cache node' with the given namespace and key. +// A banned 'cache node' will never inserted into the 'cache tree'. Ban +// only attributed to the particular 'cache node', so when a 'cache node' +// is recreated it will not be banned. +// +// If onDel is not nil, then it will be executed if such 'cache node' +// doesn't exist or once the 'cache node' is released. +// +// Delete return true is such 'cache node' exist. +func (r *Cache) Delete(ns, key uint64, onDel func()) bool { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return false + } + + hash := murmur32(ns, key, 0xf00) + for { + h, b := r.getBucket(hash) + done, _, n := b.get(r, h, hash, ns, key, true) + if done { + if n != nil { + if onDel != nil { + n.mu.Lock() + n.onDel = append(n.onDel, onDel) + n.mu.Unlock() + } + if r.cacher != nil { + r.cacher.Ban(n) + } + n.unref() + return true + } + + break + } + } + + if onDel != nil { + onDel() + } + + return false +} + +// Evict evicts 'cache node' with the given namespace and key. This will +// simply call Cacher.Evict. +// +// Evict return true is such 'cache node' exist. +func (r *Cache) Evict(ns, key uint64) bool { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return false + } + + hash := murmur32(ns, key, 0xf00) + for { + h, b := r.getBucket(hash) + done, _, n := b.get(r, h, hash, ns, key, true) + if done { + if n != nil { + if r.cacher != nil { + r.cacher.Evict(n) + } + n.unref() + return true + } + + break + } + } + + return false +} + +// EvictNS evicts 'cache node' with the given namespace. This will +// simply call Cacher.EvictNS. +func (r *Cache) EvictNS(ns uint64) { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { return } - if h.fin != nil { - h.fin() - h.fin = nil + + if r.cacher != nil { + r.cacher.EvictNS(ns) } } + +// EvictAll evicts all 'cache node'. This will simply call Cacher.EvictAll. +func (r *Cache) EvictAll() { + r.mu.RLock() + defer r.mu.RUnlock() + if r.closed { + return + } + + if r.cacher != nil { + r.cacher.EvictAll() + } +} + +// Close closes the 'cache map' and releases all 'cache node'. +func (r *Cache) Close() error { + r.mu.Lock() + if !r.closed { + r.closed = true + + if r.cacher != nil { + if err := r.cacher.Close(); err != nil { + return err + } + } + + h := (*mNode)(r.mHead) + h.initBuckets() + + for i := range h.buckets { + b := (*mBucket)(h.buckets[i]) + for _, n := range b.node { + // Call releaser. + if n.value != nil { + if r, ok := n.value.(util.Releaser); ok { + r.Release() + } + n.value = nil + } + + // Call OnDel. + for _, f := range n.onDel { + f() + } + } + } + } + r.mu.Unlock() + return nil +} + +// Node is a 'cache node'. +type Node struct { + r *Cache + + hash uint32 + ns, key uint64 + + mu sync.Mutex + size int + value Value + + ref int32 + onDel []func() + + CacheData unsafe.Pointer +} + +// NS returns this 'cache node' namespace. +func (n *Node) NS() uint64 { + return n.ns +} + +// Key returns this 'cache node' key. +func (n *Node) Key() uint64 { + return n.key +} + +// Size returns this 'cache node' size. +func (n *Node) Size() int { + return n.size +} + +// Value returns this 'cache node' value. +func (n *Node) Value() Value { + return n.value +} + +// Ref returns this 'cache node' ref counter. +func (n *Node) Ref() int32 { + return atomic.LoadInt32(&n.ref) +} + +// GetHandle returns an handle for this 'cache node'. +func (n *Node) GetHandle() *Handle { + if atomic.AddInt32(&n.ref, 1) <= 1 { + panic("BUG: Node.GetHandle on zero ref") + } + return &Handle{unsafe.Pointer(n)} +} + +func (n *Node) unref() { + if atomic.AddInt32(&n.ref, -1) == 0 { + n.r.delete(n) + } +} + +func (n *Node) unrefLocked() { + if atomic.AddInt32(&n.ref, -1) == 0 { + n.r.mu.RLock() + if !n.r.closed { + n.r.delete(n) + } + n.r.mu.RUnlock() + } +} + +type Handle struct { + n unsafe.Pointer // *Node +} + +func (h *Handle) Value() Value { + n := (*Node)(atomic.LoadPointer(&h.n)) + if n != nil { + return n.value + } + return nil +} + +func (h *Handle) Release() { + nPtr := atomic.LoadPointer(&h.n) + if nPtr != nil && atomic.CompareAndSwapPointer(&h.n, nPtr, nil) { + n := (*Node)(nPtr) + n.unrefLocked() + } +} + +func murmur32(ns, key uint64, seed uint32) uint32 { + const ( + m = uint32(0x5bd1e995) + r = 24 + ) + + k1 := uint32(ns >> 32) + k2 := uint32(ns) + k3 := uint32(key >> 32) + k4 := uint32(key) + + k1 *= m + k1 ^= k1 >> r + k1 *= m + + k2 *= m + k2 ^= k2 >> r + k2 *= m + + k3 *= m + k3 ^= k3 >> r + k3 *= m + + k4 *= m + k4 ^= k4 >> r + k4 *= m + + h := seed + + h *= m + h ^= k1 + h *= m + h ^= k2 + h *= m + h ^= k3 + h *= m + h ^= k4 + + h ^= h >> 13 + h *= m + h ^= h >> 15 + + return h +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go index 865bc573..c2a50156 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/cache_test.go @@ -13,11 +13,26 @@ import ( "sync/atomic" "testing" "time" + "unsafe" ) +type int32o int32 + +func (o *int32o) acquire() { + if atomic.AddInt32((*int32)(o), 1) != 1 { + panic("BUG: invalid ref") + } +} + +func (o *int32o) Release() { + if atomic.AddInt32((*int32)(o), -1) != 0 { + panic("BUG: invalid ref") + } +} + type releaserFunc struct { fn func() - value interface{} + value Value } func (r releaserFunc) Release() { @@ -26,8 +41,8 @@ func (r releaserFunc) Release() { } } -func set(ns Namespace, key uint64, value interface{}, charge int, relf func()) Handle { - return ns.Get(key, func() (int, interface{}) { +func set(c *Cache, ns, key uint64, value Value, charge int, relf func()) *Handle { + return c.Get(ns, key, func() (int, Value) { if relf != nil { return charge, releaserFunc{relf, value} } else { @@ -36,7 +51,246 @@ func set(ns Namespace, key uint64, value interface{}, charge int, relf func()) H }) } -func TestCache_HitMiss(t *testing.T) { +func TestCacheMap(t *testing.T) { + runtime.GOMAXPROCS(runtime.NumCPU()) + + nsx := []struct { + nobjects, nhandles, concurrent, repeat int + }{ + {10000, 400, 50, 3}, + {100000, 1000, 100, 10}, + } + + var ( + objects [][]int32o + handles [][]unsafe.Pointer + ) + + for _, x := range nsx { + objects = append(objects, make([]int32o, x.nobjects)) + handles = append(handles, make([]unsafe.Pointer, x.nhandles)) + } + + c := NewCache(nil) + + wg := new(sync.WaitGroup) + var done int32 + + for ns, x := range nsx { + for i := 0; i < x.concurrent; i++ { + wg.Add(1) + go func(ns, i, repeat int, objects []int32o, handles []unsafe.Pointer) { + defer wg.Done() + r := rand.New(rand.NewSource(time.Now().UnixNano())) + + for j := len(objects) * repeat; j >= 0; j-- { + key := uint64(r.Intn(len(objects))) + h := c.Get(uint64(ns), key, func() (int, Value) { + o := &objects[key] + o.acquire() + return 1, o + }) + if v := h.Value().(*int32o); v != &objects[key] { + t.Fatalf("#%d invalid value: want=%p got=%p", ns, &objects[key], v) + } + if objects[key] != 1 { + t.Fatalf("#%d invalid object %d: %d", ns, key, objects[key]) + } + if !atomic.CompareAndSwapPointer(&handles[r.Intn(len(handles))], nil, unsafe.Pointer(h)) { + h.Release() + } + } + }(ns, i, x.repeat, objects[ns], handles[ns]) + } + + go func(handles []unsafe.Pointer) { + r := rand.New(rand.NewSource(time.Now().UnixNano())) + + for atomic.LoadInt32(&done) == 0 { + i := r.Intn(len(handles)) + h := (*Handle)(atomic.LoadPointer(&handles[i])) + if h != nil && atomic.CompareAndSwapPointer(&handles[i], unsafe.Pointer(h), nil) { + h.Release() + } + time.Sleep(time.Millisecond) + } + }(handles[ns]) + } + + go func() { + handles := make([]*Handle, 100000) + for atomic.LoadInt32(&done) == 0 { + for i := range handles { + handles[i] = c.Get(999999999, uint64(i), func() (int, Value) { + return 1, 1 + }) + } + for _, h := range handles { + h.Release() + } + } + }() + + wg.Wait() + + atomic.StoreInt32(&done, 1) + + for _, handles0 := range handles { + for i := range handles0 { + h := (*Handle)(atomic.LoadPointer(&handles0[i])) + if h != nil && atomic.CompareAndSwapPointer(&handles0[i], unsafe.Pointer(h), nil) { + h.Release() + } + } + } + + for ns, objects0 := range objects { + for i, o := range objects0 { + if o != 0 { + t.Fatalf("invalid object #%d.%d: ref=%d", ns, i, o) + } + } + } +} + +func TestCacheMap_NodesAndSize(t *testing.T) { + c := NewCache(nil) + if c.Nodes() != 0 { + t.Errorf("invalid nodes counter: want=%d got=%d", 0, c.Nodes()) + } + if c.Size() != 0 { + t.Errorf("invalid size counter: want=%d got=%d", 0, c.Size()) + } + set(c, 0, 1, 1, 1, nil) + set(c, 0, 2, 2, 2, nil) + set(c, 1, 1, 3, 3, nil) + set(c, 2, 1, 4, 1, nil) + if c.Nodes() != 4 { + t.Errorf("invalid nodes counter: want=%d got=%d", 4, c.Nodes()) + } + if c.Size() != 7 { + t.Errorf("invalid size counter: want=%d got=%d", 4, c.Size()) + } +} + +func TestLRUCache_Capacity(t *testing.T) { + c := NewCache(NewLRU(10)) + if c.Capacity() != 10 { + t.Errorf("invalid capacity: want=%d got=%d", 10, c.Capacity()) + } + set(c, 0, 1, 1, 1, nil).Release() + set(c, 0, 2, 2, 2, nil).Release() + set(c, 1, 1, 3, 3, nil).Release() + set(c, 2, 1, 4, 1, nil).Release() + set(c, 2, 2, 5, 1, nil).Release() + set(c, 2, 3, 6, 1, nil).Release() + set(c, 2, 4, 7, 1, nil).Release() + set(c, 2, 5, 8, 1, nil).Release() + if c.Nodes() != 7 { + t.Errorf("invalid nodes counter: want=%d got=%d", 7, c.Nodes()) + } + if c.Size() != 10 { + t.Errorf("invalid size counter: want=%d got=%d", 10, c.Size()) + } + c.SetCapacity(9) + if c.Capacity() != 9 { + t.Errorf("invalid capacity: want=%d got=%d", 9, c.Capacity()) + } + if c.Nodes() != 6 { + t.Errorf("invalid nodes counter: want=%d got=%d", 6, c.Nodes()) + } + if c.Size() != 8 { + t.Errorf("invalid size counter: want=%d got=%d", 8, c.Size()) + } +} + +func TestCacheMap_NilValue(t *testing.T) { + c := NewCache(NewLRU(10)) + h := c.Get(0, 0, func() (size int, value Value) { + return 1, nil + }) + if h != nil { + t.Error("cache handle is non-nil") + } + if c.Nodes() != 0 { + t.Errorf("invalid nodes counter: want=%d got=%d", 0, c.Nodes()) + } + if c.Size() != 0 { + t.Errorf("invalid size counter: want=%d got=%d", 0, c.Size()) + } +} + +func TestLRUCache_GetLatency(t *testing.T) { + runtime.GOMAXPROCS(runtime.NumCPU()) + + const ( + concurrentSet = 30 + concurrentGet = 3 + duration = 3 * time.Second + delay = 3 * time.Millisecond + maxkey = 100000 + ) + + var ( + set, getHit, getAll int32 + getMaxLatency, getDuration int64 + ) + + c := NewCache(NewLRU(5000)) + wg := &sync.WaitGroup{} + until := time.Now().Add(duration) + for i := 0; i < concurrentSet; i++ { + wg.Add(1) + go func(i int) { + defer wg.Done() + r := rand.New(rand.NewSource(time.Now().UnixNano())) + for time.Now().Before(until) { + c.Get(0, uint64(r.Intn(maxkey)), func() (int, Value) { + time.Sleep(delay) + atomic.AddInt32(&set, 1) + return 1, 1 + }).Release() + } + }(i) + } + for i := 0; i < concurrentGet; i++ { + wg.Add(1) + go func(i int) { + defer wg.Done() + r := rand.New(rand.NewSource(time.Now().UnixNano())) + for { + mark := time.Now() + if mark.Before(until) { + h := c.Get(0, uint64(r.Intn(maxkey)), nil) + latency := int64(time.Now().Sub(mark)) + m := atomic.LoadInt64(&getMaxLatency) + if latency > m { + atomic.CompareAndSwapInt64(&getMaxLatency, m, latency) + } + atomic.AddInt64(&getDuration, latency) + if h != nil { + atomic.AddInt32(&getHit, 1) + h.Release() + } + atomic.AddInt32(&getAll, 1) + } else { + break + } + } + }(i) + } + + wg.Wait() + getAvglatency := time.Duration(getDuration) / time.Duration(getAll) + t.Logf("set=%d getHit=%d getAll=%d getMaxLatency=%v getAvgLatency=%v", + set, getHit, getAll, time.Duration(getMaxLatency), getAvglatency) + + if getAvglatency > delay/3 { + t.Errorf("get avg latency > %v: got=%v", delay/3, getAvglatency) + } +} + +func TestLRUCache_HitMiss(t *testing.T) { cases := []struct { key uint64 value string @@ -54,14 +308,13 @@ func TestCache_HitMiss(t *testing.T) { } setfin := 0 - c := NewLRUCache(1000) - ns := c.GetNamespace(0) + c := NewCache(NewLRU(1000)) for i, x := range cases { - set(ns, x.key, x.value, len(x.value), func() { + set(c, 0, x.key, x.value, len(x.value), func() { setfin++ }).Release() for j, y := range cases { - h := ns.Get(y.key, nil) + h := c.Get(0, y.key, nil) if j <= i { // should hit if h == nil { @@ -85,7 +338,7 @@ func TestCache_HitMiss(t *testing.T) { for i, x := range cases { finalizerOk := false - ns.Delete(x.key, func(exist, pending bool) { + c.Delete(0, x.key, func() { finalizerOk = true }) @@ -94,7 +347,7 @@ func TestCache_HitMiss(t *testing.T) { } for j, y := range cases { - h := ns.Get(y.key, nil) + h := c.Get(0, y.key, nil) if j > i { // should hit if h == nil { @@ -122,20 +375,19 @@ func TestCache_HitMiss(t *testing.T) { } func TestLRUCache_Eviction(t *testing.T) { - c := NewLRUCache(12) - ns := c.GetNamespace(0) - o1 := set(ns, 1, 1, 1, nil) - set(ns, 2, 2, 1, nil).Release() - set(ns, 3, 3, 1, nil).Release() - set(ns, 4, 4, 1, nil).Release() - set(ns, 5, 5, 1, nil).Release() - if h := ns.Get(2, nil); h != nil { // 1,3,4,5,2 + c := NewCache(NewLRU(12)) + o1 := set(c, 0, 1, 1, 1, nil) + set(c, 0, 2, 2, 1, nil).Release() + set(c, 0, 3, 3, 1, nil).Release() + set(c, 0, 4, 4, 1, nil).Release() + set(c, 0, 5, 5, 1, nil).Release() + if h := c.Get(0, 2, nil); h != nil { // 1,3,4,5,2 h.Release() } - set(ns, 9, 9, 10, nil).Release() // 5,2,9 + set(c, 0, 9, 9, 10, nil).Release() // 5,2,9 for _, key := range []uint64{9, 2, 5, 1} { - h := ns.Get(key, nil) + h := c.Get(0, key, nil) if h == nil { t.Errorf("miss for key '%d'", key) } else { @@ -147,7 +399,7 @@ func TestLRUCache_Eviction(t *testing.T) { } o1.Release() for _, key := range []uint64{1, 2, 5} { - h := ns.Get(key, nil) + h := c.Get(0, key, nil) if h == nil { t.Errorf("miss for key '%d'", key) } else { @@ -158,7 +410,7 @@ func TestLRUCache_Eviction(t *testing.T) { } } for _, key := range []uint64{3, 4, 9} { - h := ns.Get(key, nil) + h := c.Get(0, key, nil) if h != nil { t.Errorf("hit for key '%d'", key) if x := h.Value().(int); x != int(key) { @@ -169,487 +421,134 @@ func TestLRUCache_Eviction(t *testing.T) { } } -func TestLRUCache_SetGet(t *testing.T) { - c := NewLRUCache(13) - ns := c.GetNamespace(0) - for i := 0; i < 200; i++ { - n := uint64(rand.Intn(99999) % 20) - set(ns, n, n, 1, nil).Release() - if h := ns.Get(n, nil); h != nil { - if h.Value() == nil { - t.Errorf("key '%d' contains nil value", n) +func TestLRUCache_Evict(t *testing.T) { + c := NewCache(NewLRU(6)) + set(c, 0, 1, 1, 1, nil).Release() + set(c, 0, 2, 2, 1, nil).Release() + set(c, 1, 1, 4, 1, nil).Release() + set(c, 1, 2, 5, 1, nil).Release() + set(c, 2, 1, 6, 1, nil).Release() + set(c, 2, 2, 7, 1, nil).Release() + + for ns := 0; ns < 3; ns++ { + for key := 1; key < 3; key++ { + if h := c.Get(uint64(ns), uint64(key), nil); h != nil { + h.Release() } else { - if x := h.Value().(uint64); x != n { - t.Errorf("invalid value for key '%d' want '%d', got '%d'", n, n, x) - } + t.Errorf("Cache.Get on #%d.%d return nil", ns, key) } + } + } + + if ok := c.Evict(0, 1); !ok { + t.Error("first Cache.Evict on #0.1 return false") + } + if ok := c.Evict(0, 1); ok { + t.Error("second Cache.Evict on #0.1 return true") + } + if h := c.Get(0, 1, nil); h != nil { + t.Errorf("Cache.Get on #0.1 return non-nil: %v", h.Value()) + } + + c.EvictNS(1) + if h := c.Get(1, 1, nil); h != nil { + t.Errorf("Cache.Get on #1.1 return non-nil: %v", h.Value()) + } + if h := c.Get(1, 2, nil); h != nil { + t.Errorf("Cache.Get on #1.2 return non-nil: %v", h.Value()) + } + + c.EvictAll() + for ns := 0; ns < 3; ns++ { + for key := 1; key < 3; key++ { + if h := c.Get(uint64(ns), uint64(key), nil); h != nil { + t.Errorf("Cache.Get on #%d.%d return non-nil: %v", ns, key, h.Value()) + } + } + } +} + +func TestLRUCache_Delete(t *testing.T) { + delFuncCalled := 0 + delFunc := func() { + delFuncCalled++ + } + + c := NewCache(NewLRU(2)) + set(c, 0, 1, 1, 1, nil).Release() + set(c, 0, 2, 2, 1, nil).Release() + + if ok := c.Delete(0, 1, delFunc); !ok { + t.Error("Cache.Delete on #1 return false") + } + if h := c.Get(0, 1, nil); h != nil { + t.Errorf("Cache.Get on #1 return non-nil: %v", h.Value()) + } + if ok := c.Delete(0, 1, delFunc); ok { + t.Error("Cache.Delete on #1 return true") + } + + h2 := c.Get(0, 2, nil) + if h2 == nil { + t.Error("Cache.Get on #2 return nil") + } + if ok := c.Delete(0, 2, delFunc); !ok { + t.Error("(1) Cache.Delete on #2 return false") + } + if ok := c.Delete(0, 2, delFunc); !ok { + t.Error("(2) Cache.Delete on #2 return false") + } + + set(c, 0, 3, 3, 1, nil).Release() + set(c, 0, 4, 4, 1, nil).Release() + c.Get(0, 2, nil).Release() + + for key := 2; key <= 4; key++ { + if h := c.Get(0, uint64(key), nil); h != nil { h.Release() } else { - t.Errorf("key '%d' doesn't exist", n) - } - } -} - -func TestLRUCache_Purge(t *testing.T) { - c := NewLRUCache(3) - ns1 := c.GetNamespace(0) - o1 := set(ns1, 1, 1, 1, nil) - o2 := set(ns1, 2, 2, 1, nil) - ns1.Purge(nil) - set(ns1, 3, 3, 1, nil).Release() - for _, key := range []uint64{1, 2, 3} { - h := ns1.Get(key, nil) - if h == nil { - t.Errorf("miss for key '%d'", key) - } else { - if x := h.Value().(int); x != int(key) { - t.Errorf("invalid value for key '%d' want '%d', got '%d'", key, key, x) - } - h.Release() - } - } - o1.Release() - o2.Release() - for _, key := range []uint64{1, 2} { - h := ns1.Get(key, nil) - if h != nil { - t.Errorf("hit for key '%d'", key) - if x := h.Value().(int); x != int(key) { - t.Errorf("invalid value for key '%d' want '%d', got '%d'", key, key, x) - } - h.Release() - } - } -} - -type testingCacheObjectCounter struct { - created uint - released uint -} - -func (c *testingCacheObjectCounter) createOne() { - c.created++ -} - -func (c *testingCacheObjectCounter) releaseOne() { - c.released++ -} - -type testingCacheObject struct { - t *testing.T - cnt *testingCacheObjectCounter - - ns, key uint64 - - releaseCalled bool -} - -func (x *testingCacheObject) Release() { - if !x.releaseCalled { - x.releaseCalled = true - x.cnt.releaseOne() - } else { - x.t.Errorf("duplicate setfin NS#%d KEY#%d", x.ns, x.key) - } -} - -func TestLRUCache_ConcurrentSetGet(t *testing.T) { - runtime.GOMAXPROCS(runtime.NumCPU()) - - seed := time.Now().UnixNano() - t.Logf("seed=%d", seed) - - const ( - N = 2000000 - M = 4000 - C = 3 - ) - - var set, get uint32 - - wg := &sync.WaitGroup{} - c := NewLRUCache(M / 4) - for ni := uint64(0); ni < C; ni++ { - r0 := rand.New(rand.NewSource(seed + int64(ni))) - r1 := rand.New(rand.NewSource(seed + int64(ni) + 1)) - ns := c.GetNamespace(ni) - - wg.Add(2) - go func(ns Namespace, r *rand.Rand) { - for i := 0; i < N; i++ { - x := uint64(r.Int63n(M)) - o := ns.Get(x, func() (int, interface{}) { - atomic.AddUint32(&set, 1) - return 1, x - }) - if v := o.Value().(uint64); v != x { - t.Errorf("#%d invalid value, got=%d", x, v) - } - o.Release() - } - wg.Done() - }(ns, r0) - go func(ns Namespace, r *rand.Rand) { - for i := 0; i < N; i++ { - x := uint64(r.Int63n(M)) - o := ns.Get(x, nil) - if o != nil { - atomic.AddUint32(&get, 1) - if v := o.Value().(uint64); v != x { - t.Errorf("#%d invalid value, got=%d", x, v) - } - o.Release() - } - } - wg.Done() - }(ns, r1) - } - - wg.Wait() - - t.Logf("set=%d get=%d", set, get) -} - -func TestLRUCache_Finalizer(t *testing.T) { - const ( - capacity = 100 - goroutines = 100 - iterations = 10000 - keymax = 8000 - ) - - cnt := &testingCacheObjectCounter{} - - c := NewLRUCache(capacity) - - type instance struct { - seed int64 - rnd *rand.Rand - nsid uint64 - ns Namespace - effective int - handles []Handle - handlesMap map[uint64]int - - delete bool - purge bool - zap bool - wantDel int - delfinCalled int - delfinCalledAll int - delfinCalledEff int - purgefinCalled int - } - - instanceGet := func(p *instance, key uint64) { - h := p.ns.Get(key, func() (charge int, value interface{}) { - to := &testingCacheObject{ - t: t, cnt: cnt, - ns: p.nsid, - key: key, - } - p.effective++ - cnt.createOne() - return 1, releaserFunc{func() { - to.Release() - p.effective-- - }, to} - }) - p.handles = append(p.handles, h) - p.handlesMap[key] = p.handlesMap[key] + 1 - } - instanceRelease := func(p *instance, i int) { - h := p.handles[i] - key := h.Value().(releaserFunc).value.(*testingCacheObject).key - if n := p.handlesMap[key]; n == 0 { - t.Fatal("key ref == 0") - } else if n > 1 { - p.handlesMap[key] = n - 1 - } else { - delete(p.handlesMap, key) - } - h.Release() - p.handles = append(p.handles[:i], p.handles[i+1:]...) - p.handles[len(p.handles) : len(p.handles)+1][0] = nil - } - - seed := time.Now().UnixNano() - t.Logf("seed=%d", seed) - - instances := make([]*instance, goroutines) - for i := range instances { - p := &instance{} - p.handlesMap = make(map[uint64]int) - p.seed = seed + int64(i) - p.rnd = rand.New(rand.NewSource(p.seed)) - p.nsid = uint64(i) - p.ns = c.GetNamespace(p.nsid) - p.delete = i%6 == 0 - p.purge = i%8 == 0 - p.zap = i%12 == 0 || i%3 == 0 - instances[i] = p - } - - runr := rand.New(rand.NewSource(seed - 1)) - run := func(rnd *rand.Rand, x []*instance, init func(p *instance) bool, fn func(p *instance, i int) bool) { - var ( - rx []*instance - rn []int - ) - if init == nil { - rx = append([]*instance{}, x...) - rn = make([]int, len(x)) - } else { - for _, p := range x { - if init(p) { - rx = append(rx, p) - rn = append(rn, 0) - } - } - } - for len(rx) > 0 { - i := rand.Intn(len(rx)) - if fn(rx[i], rn[i]) { - rn[i]++ - } else { - rx = append(rx[:i], rx[i+1:]...) - rn = append(rn[:i], rn[i+1:]...) - } + t.Errorf("Cache.Get on #%d return nil", key) } } - // Get and release. - run(runr, instances, nil, func(p *instance, i int) bool { - if i < iterations { - if len(p.handles) == 0 || p.rnd.Int()%2 == 0 { - instanceGet(p, uint64(p.rnd.Intn(keymax))) - } else { - instanceRelease(p, p.rnd.Intn(len(p.handles))) - } - return true - } else { - return false - } - }) - - if used, cap := c.Used(), c.Capacity(); used > cap { - t.Errorf("Used > capacity, used=%d cap=%d", used, cap) + h2.Release() + if h := c.Get(0, 2, nil); h != nil { + t.Errorf("Cache.Get on #2 return non-nil: %v", h.Value()) } - // Check effective objects. - for i, p := range instances { - if int(p.effective) < len(p.handlesMap) { - t.Errorf("#%d effective objects < acquired handle, eo=%d ah=%d", i, p.effective, len(p.handlesMap)) - } - } - - if want := int(cnt.created - cnt.released); c.Size() != want { - t.Errorf("Invalid cache size, want=%d got=%d", want, c.Size()) - } - - // First delete. - run(runr, instances, func(p *instance) bool { - p.wantDel = p.effective - return p.delete - }, func(p *instance, i int) bool { - key := uint64(i) - if key < keymax { - _, wantExist := p.handlesMap[key] - gotExist := p.ns.Delete(key, func(exist, pending bool) { - p.delfinCalledAll++ - if exist { - p.delfinCalledEff++ - } - }) - if !gotExist && wantExist { - t.Errorf("delete on NS#%d KEY#%d not found", p.nsid, key) - } - return true - } else { - return false - } - }) - - // Second delete. - run(runr, instances, func(p *instance) bool { - p.delfinCalled = 0 - return p.delete - }, func(p *instance, i int) bool { - key := uint64(i) - if key < keymax { - gotExist := p.ns.Delete(key, func(exist, pending bool) { - if exist && !pending { - t.Errorf("delete fin on NS#%d KEY#%d exist and not pending for deletion", p.nsid, key) - } - p.delfinCalled++ - }) - if gotExist { - t.Errorf("delete on NS#%d KEY#%d found", p.nsid, key) - } - return true - } else { - if p.delfinCalled != keymax { - t.Errorf("(2) NS#%d not all delete fin called, diff=%d", p.nsid, keymax-p.delfinCalled) - } - return false - } - }) - - // Purge. - run(runr, instances, func(p *instance) bool { - return p.purge - }, func(p *instance, i int) bool { - p.ns.Purge(func(ns, key uint64) { - p.purgefinCalled++ - }) - return false - }) - - if want := int(cnt.created - cnt.released); c.Size() != want { - t.Errorf("Invalid cache size, want=%d got=%d", want, c.Size()) - } - - // Release. - run(runr, instances, func(p *instance) bool { - return !p.zap - }, func(p *instance, i int) bool { - if len(p.handles) > 0 { - instanceRelease(p, len(p.handles)-1) - return true - } else { - return false - } - }) - - if want := int(cnt.created - cnt.released); c.Size() != want { - t.Errorf("Invalid cache size, want=%d got=%d", want, c.Size()) - } - - // Zap. - run(runr, instances, func(p *instance) bool { - return p.zap - }, func(p *instance, i int) bool { - p.ns.Zap() - p.handles = nil - p.handlesMap = nil - return false - }) - - if want := int(cnt.created - cnt.released); c.Size() != want { - t.Errorf("Invalid cache size, want=%d got=%d", want, c.Size()) - } - - if notrel, used := int(cnt.created-cnt.released), c.Used(); notrel != used { - t.Errorf("Invalid used value, want=%d got=%d", notrel, used) - } - - c.Purge(nil) - - for _, p := range instances { - if p.delete { - if p.delfinCalledAll != keymax { - t.Errorf("#%d not all delete fin called, purge=%v zap=%v diff=%d", p.nsid, p.purge, p.zap, keymax-p.delfinCalledAll) - } - if p.delfinCalledEff != p.wantDel { - t.Errorf("#%d not all effective delete fin called, diff=%d", p.nsid, p.wantDel-p.delfinCalledEff) - } - if p.purge && p.purgefinCalled > 0 { - t.Errorf("#%d some purge fin called, delete=%v zap=%v n=%d", p.nsid, p.delete, p.zap, p.purgefinCalled) - } - } else { - if p.purge { - if p.purgefinCalled != p.wantDel { - t.Errorf("#%d not all purge fin called, delete=%v zap=%v diff=%d", p.nsid, p.delete, p.zap, p.wantDel-p.purgefinCalled) - } - } - } - } - - if cnt.created != cnt.released { - t.Errorf("Some cache object weren't released, created=%d released=%d", cnt.created, cnt.released) + if delFuncCalled != 4 { + t.Errorf("delFunc isn't called 4 times: got=%d", delFuncCalled) } } -func BenchmarkLRUCache_Set(b *testing.B) { - c := NewLRUCache(0) - ns := c.GetNamespace(0) - b.ResetTimer() - for i := uint64(0); i < uint64(b.N); i++ { - set(ns, i, "", 1, nil) - } -} - -func BenchmarkLRUCache_Get(b *testing.B) { - c := NewLRUCache(0) - ns := c.GetNamespace(0) - b.ResetTimer() - for i := uint64(0); i < uint64(b.N); i++ { - set(ns, i, "", 1, nil) - } - b.ResetTimer() - for i := uint64(0); i < uint64(b.N); i++ { - ns.Get(i, nil) - } -} - -func BenchmarkLRUCache_Get2(b *testing.B) { - c := NewLRUCache(0) - ns := c.GetNamespace(0) - b.ResetTimer() - for i := uint64(0); i < uint64(b.N); i++ { - set(ns, i, "", 1, nil) - } - b.ResetTimer() - for i := uint64(0); i < uint64(b.N); i++ { - ns.Get(i, func() (charge int, value interface{}) { - return 0, nil - }) - } -} - -func BenchmarkLRUCache_Release(b *testing.B) { - c := NewLRUCache(0) - ns := c.GetNamespace(0) - handles := make([]Handle, b.N) - for i := uint64(0); i < uint64(b.N); i++ { - handles[i] = set(ns, i, "", 1, nil) - } - b.ResetTimer() - for _, h := range handles { - h.Release() - } -} - -func BenchmarkLRUCache_SetRelease(b *testing.B) { - capacity := b.N / 100 - if capacity <= 0 { - capacity = 10 - } - c := NewLRUCache(capacity) - ns := c.GetNamespace(0) - b.ResetTimer() - for i := uint64(0); i < uint64(b.N); i++ { - set(ns, i, "", 1, nil).Release() - } -} - -func BenchmarkLRUCache_SetReleaseTwice(b *testing.B) { - capacity := b.N / 100 - if capacity <= 0 { - capacity = 10 - } - c := NewLRUCache(capacity) - ns := c.GetNamespace(0) - b.ResetTimer() - - na := b.N / 2 - nb := b.N - na - - for i := uint64(0); i < uint64(na); i++ { - set(ns, i, "", 1, nil).Release() - } - - for i := uint64(0); i < uint64(nb); i++ { - set(ns, i, "", 1, nil).Release() +func TestLRUCache_Close(t *testing.T) { + relFuncCalled := 0 + relFunc := func() { + relFuncCalled++ + } + delFuncCalled := 0 + delFunc := func() { + delFuncCalled++ + } + + c := NewCache(NewLRU(2)) + set(c, 0, 1, 1, 1, relFunc).Release() + set(c, 0, 2, 2, 1, relFunc).Release() + + h3 := set(c, 0, 3, 3, 1, relFunc) + if h3 == nil { + t.Error("Cache.Get on #3 return nil") + } + if ok := c.Delete(0, 3, delFunc); !ok { + t.Error("Cache.Delete on #3 return false") + } + + c.Close() + + if relFuncCalled != 3 { + t.Errorf("relFunc isn't called 3 times: got=%d", relFuncCalled) + } + if delFuncCalled != 1 { + t.Errorf("delFunc isn't called 1 times: got=%d", delFuncCalled) } } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/lru.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/lru.go new file mode 100644 index 00000000..d9a84cde --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/lru.go @@ -0,0 +1,195 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package cache + +import ( + "sync" + "unsafe" +) + +type lruNode struct { + n *Node + h *Handle + ban bool + + next, prev *lruNode +} + +func (n *lruNode) insert(at *lruNode) { + x := at.next + at.next = n + n.prev = at + n.next = x + x.prev = n +} + +func (n *lruNode) remove() { + if n.prev != nil { + n.prev.next = n.next + n.next.prev = n.prev + n.prev = nil + n.next = nil + } else { + panic("BUG: removing removed node") + } +} + +type lru struct { + mu sync.Mutex + capacity int + used int + recent lruNode +} + +func (r *lru) reset() { + r.recent.next = &r.recent + r.recent.prev = &r.recent + r.used = 0 +} + +func (r *lru) Capacity() int { + r.mu.Lock() + defer r.mu.Unlock() + return r.capacity +} + +func (r *lru) SetCapacity(capacity int) { + var evicted []*lruNode + + r.mu.Lock() + r.capacity = capacity + for r.used > r.capacity { + rn := r.recent.prev + if rn == nil { + panic("BUG: invalid LRU used or capacity counter") + } + rn.remove() + rn.n.CacheData = nil + r.used -= rn.n.Size() + evicted = append(evicted, rn) + } + r.mu.Unlock() + + for _, rn := range evicted { + rn.h.Release() + } +} + +func (r *lru) Promote(n *Node) { + var evicted []*lruNode + + r.mu.Lock() + if n.CacheData == nil { + if n.Size() <= r.capacity { + rn := &lruNode{n: n, h: n.GetHandle()} + rn.insert(&r.recent) + n.CacheData = unsafe.Pointer(rn) + r.used += n.Size() + + for r.used > r.capacity { + rn := r.recent.prev + if rn == nil { + panic("BUG: invalid LRU used or capacity counter") + } + rn.remove() + rn.n.CacheData = nil + r.used -= rn.n.Size() + evicted = append(evicted, rn) + } + } + } else { + rn := (*lruNode)(n.CacheData) + if !rn.ban { + rn.remove() + rn.insert(&r.recent) + } + } + r.mu.Unlock() + + for _, rn := range evicted { + rn.h.Release() + } +} + +func (r *lru) Ban(n *Node) { + r.mu.Lock() + if n.CacheData == nil { + n.CacheData = unsafe.Pointer(&lruNode{n: n, ban: true}) + } else { + rn := (*lruNode)(n.CacheData) + if !rn.ban { + rn.remove() + rn.ban = true + r.used -= rn.n.Size() + r.mu.Unlock() + + rn.h.Release() + rn.h = nil + return + } + } + r.mu.Unlock() +} + +func (r *lru) Evict(n *Node) { + r.mu.Lock() + rn := (*lruNode)(n.CacheData) + if rn == nil || rn.ban { + r.mu.Unlock() + return + } + n.CacheData = nil + r.mu.Unlock() + + rn.h.Release() +} + +func (r *lru) EvictNS(ns uint64) { + var evicted []*lruNode + + r.mu.Lock() + for e := r.recent.prev; e != &r.recent; { + rn := e + e = e.prev + if rn.n.NS() == ns { + rn.remove() + rn.n.CacheData = nil + r.used -= rn.n.Size() + evicted = append(evicted, rn) + } + } + r.mu.Unlock() + + for _, rn := range evicted { + rn.h.Release() + } +} + +func (r *lru) EvictAll() { + r.mu.Lock() + back := r.recent.prev + for rn := back; rn != &r.recent; rn = rn.prev { + rn.n.CacheData = nil + } + r.reset() + r.mu.Unlock() + + for rn := back; rn != &r.recent; rn = rn.prev { + rn.h.Release() + } +} + +func (r *lru) Close() error { + return nil +} + +// NewLRU create a new LRU-cache. +func NewLRU(capacity int) Cacher { + r := &lru{capacity: capacity} + r.reset() + return r +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/lru_cache.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/lru_cache.go deleted file mode 100644 index d56c6eac..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/cache/lru_cache.go +++ /dev/null @@ -1,622 +0,0 @@ -// Copyright (c) 2012, Suryandaru Triandana -// All rights reserved. -// -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package cache - -import ( - "sync" - "sync/atomic" - - "github.com/syndtr/goleveldb/leveldb/util" -) - -// The LLRB implementation were taken from https://github.com/petar/GoLLRB. -// Which contains the following header: -// -// Copyright 2010 Petar Maymounkov. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// lruCache represent a LRU cache state. -type lruCache struct { - mu sync.Mutex - recent lruNode - table map[uint64]*lruNs - capacity int - used, size, alive int -} - -// NewLRUCache creates a new initialized LRU cache with the given capacity. -func NewLRUCache(capacity int) Cache { - c := &lruCache{ - table: make(map[uint64]*lruNs), - capacity: capacity, - } - c.recent.rNext = &c.recent - c.recent.rPrev = &c.recent - return c -} - -func (c *lruCache) Capacity() int { - c.mu.Lock() - defer c.mu.Unlock() - return c.capacity -} - -func (c *lruCache) Used() int { - c.mu.Lock() - defer c.mu.Unlock() - return c.used -} - -func (c *lruCache) Size() int { - c.mu.Lock() - defer c.mu.Unlock() - return c.size -} - -func (c *lruCache) NumObjects() int { - c.mu.Lock() - defer c.mu.Unlock() - return c.alive -} - -// SetCapacity set cache capacity. -func (c *lruCache) SetCapacity(capacity int) { - c.mu.Lock() - c.capacity = capacity - c.evict() - c.mu.Unlock() -} - -// GetNamespace return namespace object for given id. -func (c *lruCache) GetNamespace(id uint64) Namespace { - c.mu.Lock() - defer c.mu.Unlock() - - if ns, ok := c.table[id]; ok { - return ns - } - - ns := &lruNs{lru: c, id: id} - c.table[id] = ns - return ns -} - -func (c *lruCache) ZapNamespace(id uint64) { - c.mu.Lock() - if ns, exist := c.table[id]; exist { - ns.zapNB() - delete(c.table, id) - } - c.mu.Unlock() -} - -func (c *lruCache) PurgeNamespace(id uint64, fin PurgeFin) { - c.mu.Lock() - if ns, exist := c.table[id]; exist { - ns.purgeNB(fin) - } - c.mu.Unlock() -} - -// Purge purge entire cache. -func (c *lruCache) Purge(fin PurgeFin) { - c.mu.Lock() - for _, ns := range c.table { - ns.purgeNB(fin) - } - c.mu.Unlock() -} - -func (c *lruCache) Zap() { - c.mu.Lock() - for _, ns := range c.table { - ns.zapNB() - } - c.table = make(map[uint64]*lruNs) - c.mu.Unlock() -} - -func (c *lruCache) evict() { - top := &c.recent - for n := c.recent.rPrev; c.used > c.capacity && n != top; { - if n.state != nodeEffective { - panic("evicting non effective node") - } - n.state = nodeEvicted - n.rRemove() - n.derefNB() - c.used -= n.charge - n = c.recent.rPrev - } -} - -type lruNs struct { - lru *lruCache - id uint64 - rbRoot *lruNode - state nsState -} - -func (ns *lruNs) rbGetOrCreateNode(h *lruNode, key uint64) (hn, n *lruNode) { - if h == nil { - n = &lruNode{ns: ns, key: key} - return n, n - } - - if key < h.key { - hn, n = ns.rbGetOrCreateNode(h.rbLeft, key) - if hn != nil { - h.rbLeft = hn - } else { - return nil, n - } - } else if key > h.key { - hn, n = ns.rbGetOrCreateNode(h.rbRight, key) - if hn != nil { - h.rbRight = hn - } else { - return nil, n - } - } else { - return nil, h - } - - if rbIsRed(h.rbRight) && !rbIsRed(h.rbLeft) { - h = rbRotLeft(h) - } - if rbIsRed(h.rbLeft) && rbIsRed(h.rbLeft.rbLeft) { - h = rbRotRight(h) - } - if rbIsRed(h.rbLeft) && rbIsRed(h.rbRight) { - rbFlip(h) - } - return h, n -} - -func (ns *lruNs) getOrCreateNode(key uint64) *lruNode { - hn, n := ns.rbGetOrCreateNode(ns.rbRoot, key) - if hn != nil { - ns.rbRoot = hn - ns.rbRoot.rbBlack = true - } - return n -} - -func (ns *lruNs) rbGetNode(key uint64) *lruNode { - h := ns.rbRoot - for h != nil { - switch { - case key < h.key: - h = h.rbLeft - case key > h.key: - h = h.rbRight - default: - return h - } - } - return nil -} - -func (ns *lruNs) getNode(key uint64) *lruNode { - return ns.rbGetNode(key) -} - -func (ns *lruNs) rbDeleteNode(h *lruNode, key uint64) *lruNode { - if h == nil { - return nil - } - - if key < h.key { - if h.rbLeft == nil { // key not present. Nothing to delete - return h - } - if !rbIsRed(h.rbLeft) && !rbIsRed(h.rbLeft.rbLeft) { - h = rbMoveLeft(h) - } - h.rbLeft = ns.rbDeleteNode(h.rbLeft, key) - } else { - if rbIsRed(h.rbLeft) { - h = rbRotRight(h) - } - // If @key equals @h.key and no right children at @h - if h.key == key && h.rbRight == nil { - return nil - } - if h.rbRight != nil && !rbIsRed(h.rbRight) && !rbIsRed(h.rbRight.rbLeft) { - h = rbMoveRight(h) - } - // If @key equals @h.key, and (from above) 'h.Right != nil' - if h.key == key { - var x *lruNode - h.rbRight, x = rbDeleteMin(h.rbRight) - if x == nil { - panic("logic") - } - x.rbLeft, h.rbLeft = h.rbLeft, nil - x.rbRight, h.rbRight = h.rbRight, nil - x.rbBlack = h.rbBlack - h = x - } else { // Else, @key is bigger than @h.key - h.rbRight = ns.rbDeleteNode(h.rbRight, key) - } - } - - return rbFixup(h) -} - -func (ns *lruNs) deleteNode(key uint64) { - ns.rbRoot = ns.rbDeleteNode(ns.rbRoot, key) - if ns.rbRoot != nil { - ns.rbRoot.rbBlack = true - } -} - -func (ns *lruNs) rbIterateNodes(h *lruNode, pivot uint64, iter func(n *lruNode) bool) bool { - if h == nil { - return true - } - if h.key >= pivot { - if !ns.rbIterateNodes(h.rbLeft, pivot, iter) { - return false - } - if !iter(h) { - return false - } - } - return ns.rbIterateNodes(h.rbRight, pivot, iter) -} - -func (ns *lruNs) iterateNodes(iter func(n *lruNode) bool) { - ns.rbIterateNodes(ns.rbRoot, 0, iter) -} - -func (ns *lruNs) Get(key uint64, setf SetFunc) Handle { - ns.lru.mu.Lock() - defer ns.lru.mu.Unlock() - - if ns.state != nsEffective { - return nil - } - - var n *lruNode - if setf == nil { - n = ns.getNode(key) - if n == nil { - return nil - } - } else { - n = ns.getOrCreateNode(key) - } - switch n.state { - case nodeZero: - charge, value := setf() - if value == nil { - ns.deleteNode(key) - return nil - } - if charge < 0 { - charge = 0 - } - - n.value = value - n.charge = charge - n.state = nodeEvicted - - ns.lru.size += charge - ns.lru.alive++ - - fallthrough - case nodeEvicted: - if n.charge == 0 { - break - } - - // Insert to recent list. - n.state = nodeEffective - n.ref++ - ns.lru.used += n.charge - ns.lru.evict() - - fallthrough - case nodeEffective: - // Bump to front. - n.rRemove() - n.rInsert(&ns.lru.recent) - case nodeDeleted: - // Do nothing. - default: - panic("invalid state") - } - n.ref++ - - return &lruHandle{node: n} -} - -func (ns *lruNs) Delete(key uint64, fin DelFin) bool { - ns.lru.mu.Lock() - defer ns.lru.mu.Unlock() - - if ns.state != nsEffective { - if fin != nil { - fin(false, false) - } - return false - } - - n := ns.getNode(key) - if n == nil { - if fin != nil { - fin(false, false) - } - return false - - } - - switch n.state { - case nodeEffective: - ns.lru.used -= n.charge - n.state = nodeDeleted - n.delfin = fin - n.rRemove() - n.derefNB() - case nodeEvicted: - n.state = nodeDeleted - n.delfin = fin - case nodeDeleted: - if fin != nil { - fin(true, true) - } - return false - default: - panic("invalid state") - } - - return true -} - -func (ns *lruNs) purgeNB(fin PurgeFin) { - if ns.state == nsEffective { - var nodes []*lruNode - ns.iterateNodes(func(n *lruNode) bool { - nodes = append(nodes, n) - return true - }) - for _, n := range nodes { - switch n.state { - case nodeEffective: - ns.lru.used -= n.charge - n.state = nodeDeleted - n.purgefin = fin - n.rRemove() - n.derefNB() - case nodeEvicted: - n.state = nodeDeleted - n.purgefin = fin - case nodeDeleted: - default: - panic("invalid state") - } - } - } -} - -func (ns *lruNs) Purge(fin PurgeFin) { - ns.lru.mu.Lock() - ns.purgeNB(fin) - ns.lru.mu.Unlock() -} - -func (ns *lruNs) zapNB() { - if ns.state == nsEffective { - ns.state = nsZapped - - ns.iterateNodes(func(n *lruNode) bool { - if n.state == nodeEffective { - ns.lru.used -= n.charge - n.rRemove() - } - ns.lru.size -= n.charge - n.state = nodeDeleted - n.fin() - - return true - }) - ns.rbRoot = nil - } -} - -func (ns *lruNs) Zap() { - ns.lru.mu.Lock() - ns.zapNB() - delete(ns.lru.table, ns.id) - ns.lru.mu.Unlock() -} - -type lruNode struct { - ns *lruNs - - rNext, rPrev *lruNode - rbLeft, rbRight *lruNode - rbBlack bool - - key uint64 - value interface{} - charge int - ref int - state nodeState - delfin DelFin - purgefin PurgeFin -} - -func (n *lruNode) rInsert(at *lruNode) { - x := at.rNext - at.rNext = n - n.rPrev = at - n.rNext = x - x.rPrev = n -} - -func (n *lruNode) rRemove() bool { - if n.rPrev == nil { - return false - } - - n.rPrev.rNext = n.rNext - n.rNext.rPrev = n.rPrev - n.rPrev = nil - n.rNext = nil - - return true -} - -func (n *lruNode) fin() { - if r, ok := n.value.(util.Releaser); ok { - r.Release() - } - if n.purgefin != nil { - if n.delfin != nil { - panic("conflicting delete and purge fin") - } - n.purgefin(n.ns.id, n.key) - n.purgefin = nil - } else if n.delfin != nil { - n.delfin(true, false) - n.delfin = nil - } -} - -func (n *lruNode) derefNB() { - n.ref-- - if n.ref == 0 { - if n.ns.state == nsEffective { - // Remove elemement. - n.ns.deleteNode(n.key) - n.ns.lru.size -= n.charge - n.ns.lru.alive-- - n.fin() - } - n.value = nil - } else if n.ref < 0 { - panic("leveldb/cache: lruCache: negative node reference") - } -} - -func (n *lruNode) deref() { - n.ns.lru.mu.Lock() - n.derefNB() - n.ns.lru.mu.Unlock() -} - -type lruHandle struct { - node *lruNode - once uint32 -} - -func (h *lruHandle) Value() interface{} { - if atomic.LoadUint32(&h.once) == 0 { - return h.node.value - } - return nil -} - -func (h *lruHandle) Release() { - if !atomic.CompareAndSwapUint32(&h.once, 0, 1) { - return - } - h.node.deref() - h.node = nil -} - -func rbIsRed(h *lruNode) bool { - if h == nil { - return false - } - return !h.rbBlack -} - -func rbRotLeft(h *lruNode) *lruNode { - x := h.rbRight - if x.rbBlack { - panic("rotating a black link") - } - h.rbRight = x.rbLeft - x.rbLeft = h - x.rbBlack = h.rbBlack - h.rbBlack = false - return x -} - -func rbRotRight(h *lruNode) *lruNode { - x := h.rbLeft - if x.rbBlack { - panic("rotating a black link") - } - h.rbLeft = x.rbRight - x.rbRight = h - x.rbBlack = h.rbBlack - h.rbBlack = false - return x -} - -func rbFlip(h *lruNode) { - h.rbBlack = !h.rbBlack - h.rbLeft.rbBlack = !h.rbLeft.rbBlack - h.rbRight.rbBlack = !h.rbRight.rbBlack -} - -func rbMoveLeft(h *lruNode) *lruNode { - rbFlip(h) - if rbIsRed(h.rbRight.rbLeft) { - h.rbRight = rbRotRight(h.rbRight) - h = rbRotLeft(h) - rbFlip(h) - } - return h -} - -func rbMoveRight(h *lruNode) *lruNode { - rbFlip(h) - if rbIsRed(h.rbLeft.rbLeft) { - h = rbRotRight(h) - rbFlip(h) - } - return h -} - -func rbFixup(h *lruNode) *lruNode { - if rbIsRed(h.rbRight) { - h = rbRotLeft(h) - } - - if rbIsRed(h.rbLeft) && rbIsRed(h.rbLeft.rbLeft) { - h = rbRotRight(h) - } - - if rbIsRed(h.rbLeft) && rbIsRed(h.rbRight) { - rbFlip(h) - } - - return h -} - -func rbDeleteMin(h *lruNode) (hn, n *lruNode) { - if h == nil { - return nil, nil - } - if h.rbLeft == nil { - return nil, h - } - - if !rbIsRed(h.rbLeft) && !rbIsRed(h.rbLeft.rbLeft) { - h = rbMoveLeft(h) - } - - h.rbLeft, n = rbDeleteMin(h.rbLeft) - - return rbFixup(h), n -} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go index 427d7221..a351874e 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/corrupt_test.go @@ -9,14 +9,12 @@ package leveldb import ( "bytes" "fmt" - "io" - "math/rand" - "testing" - - "github.com/syndtr/goleveldb/leveldb/cache" "github.com/syndtr/goleveldb/leveldb/filter" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/storage" + "io" + "math/rand" + "testing" ) const ctValSize = 1000 @@ -33,8 +31,8 @@ func newDbCorruptHarnessWopt(t *testing.T, o *opt.Options) *dbCorruptHarness { func newDbCorruptHarness(t *testing.T) *dbCorruptHarness { return newDbCorruptHarnessWopt(t, &opt.Options{ - BlockCache: cache.NewLRUCache(100), - Strict: opt.StrictJournalChecksum, + BlockCacheCapacity: 100, + Strict: opt.StrictJournalChecksum, }) } @@ -269,9 +267,9 @@ func TestCorruptDB_TableIndex(t *testing.T) { func TestCorruptDB_MissingManifest(t *testing.T) { rnd := rand.New(rand.NewSource(0x0badda7a)) h := newDbCorruptHarnessWopt(t, &opt.Options{ - BlockCache: cache.NewLRUCache(100), - Strict: opt.StrictJournalChecksum, - WriteBuffer: 1000 * 60, + BlockCacheCapacity: 100, + Strict: opt.StrictJournalChecksum, + WriteBuffer: 1000 * 60, }) h.build(1000) diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db.go index 70c847f8..88a3e0db 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db.go @@ -63,13 +63,14 @@ type DB struct { journalAckC chan error // Compaction. - tcompCmdC chan cCmd - tcompPauseC chan chan<- struct{} - mcompCmdC chan cCmd - compErrC chan error - compPerErrC chan error - compErrSetC chan error - compStats []cStats + tcompCmdC chan cCmd + tcompPauseC chan chan<- struct{} + mcompCmdC chan cCmd + compErrC chan error + compPerErrC chan error + compErrSetC chan error + compWriteLocking bool + compStats []cStats // Close. closeW sync.WaitGroup @@ -108,28 +109,44 @@ func openDB(s *session) (*DB, error) { closeC: make(chan struct{}), } - if err := db.recoverJournal(); err != nil { - return nil, err - } + // Read-only mode. + readOnly := s.o.GetReadOnly() - // Remove any obsolete files. - if err := db.checkAndCleanFiles(); err != nil { - // Close journal. - if db.journal != nil { - db.journal.Close() - db.journalWriter.Close() + if readOnly { + // Recover journals (read-only mode). + if err := db.recoverJournalRO(); err != nil { + return nil, err } - return nil, err + } else { + // Recover journals. + if err := db.recoverJournal(); err != nil { + return nil, err + } + + // Remove any obsolete files. + if err := db.checkAndCleanFiles(); err != nil { + // Close journal. + if db.journal != nil { + db.journal.Close() + db.journalWriter.Close() + } + return nil, err + } + } // Doesn't need to be included in the wait group. go db.compactionError() go db.mpoolDrain() - db.closeW.Add(3) - go db.tCompaction() - go db.mCompaction() - go db.jWriter() + if readOnly { + db.SetReadOnly() + } else { + db.closeW.Add(3) + go db.tCompaction() + go db.mCompaction() + go db.jWriter() + } s.logf("db@open done T·%v", time.Since(start)) @@ -274,8 +291,9 @@ func recoverTable(s *session, o *opt.Options) error { // We will drop corrupted table. strict = o.GetStrict(opt.StrictRecovery) + noSync = o.GetNoSync() - rec = &sessionRecord{numLevel: o.GetNumLevel()} + rec = &sessionRecord{} bpool = util.NewBufferPool(o.GetBlockSize() + 5) ) buildTable := func(iter iterator.Iterator) (tmp storage.File, size int64, err error) { @@ -311,9 +329,11 @@ func recoverTable(s *session, o *opt.Options) error { if err != nil { return } - err = writer.Sync() - if err != nil { - return + if !noSync { + err = writer.Sync() + if err != nil { + return + } } size = int64(tw.BytesLen()) return @@ -347,12 +367,14 @@ func recoverTable(s *session, o *opt.Options) error { return err } iter := tr.NewIterator(nil, nil) - iter.(iterator.ErrorCallbackSetter).SetErrorCallback(func(err error) { - if errors.IsCorrupted(err) { - s.logf("table@recovery block corruption @%d %q", file.Num(), err) - tcorruptedBlock++ - } - }) + if itererr, ok := iter.(iterator.ErrorCallbackSetter); ok { + itererr.SetErrorCallback(func(err error) { + if errors.IsCorrupted(err) { + s.logf("table@recovery block corruption @%d %q", file.Num(), err) + tcorruptedBlock++ + } + }) + } // Scan the table. for iter.Next() { @@ -448,132 +470,136 @@ func recoverTable(s *session, o *opt.Options) error { } func (db *DB) recoverJournal() error { - // Get all tables and sort it by file number. - journalFiles_, err := db.s.getFiles(storage.TypeJournal) + // Get all journals and sort it by file number. + allJournalFiles, err := db.s.getFiles(storage.TypeJournal) if err != nil { return err } - journalFiles := files(journalFiles_) - journalFiles.sort() + files(allJournalFiles).sort() - // Discard older journal. - prev := -1 - for i, file := range journalFiles { - if file.Num() >= db.s.stJournalNum { - if prev >= 0 { - i-- - journalFiles[i] = journalFiles[prev] - } - journalFiles = journalFiles[i:] - break - } else if file.Num() == db.s.stPrevJournalNum { - prev = i + // Journals that will be recovered. + var recJournalFiles []storage.File + for _, jf := range allJournalFiles { + if jf.Num() >= db.s.stJournalNum || jf.Num() == db.s.stPrevJournalNum { + recJournalFiles = append(recJournalFiles, jf) } } - var jr *journal.Reader - var of storage.File - var mem *memdb.DB - batch := new(Batch) - cm := newCMem(db.s) - buf := new(util.Buffer) - // Options. - strict := db.s.o.GetStrict(opt.StrictJournal) - checksum := db.s.o.GetStrict(opt.StrictJournalChecksum) - writeBuffer := db.s.o.GetWriteBuffer() - recoverJournal := func(file storage.File) error { - db.logf("journal@recovery recovering @%d", file.Num()) - reader, err := file.Open() - if err != nil { - return err - } - defer reader.Close() + var ( + of storage.File // Obsolete file. + rec = &sessionRecord{} + ) - // Create/reset journal reader instance. - if jr == nil { - jr = journal.NewReader(reader, dropper{db.s, file}, strict, checksum) - } else { - jr.Reset(reader, dropper{db.s, file}, strict, checksum) - } - - // Flush memdb and remove obsolete journal file. - if of != nil { - if mem.Len() > 0 { - if err := cm.flush(mem, 0); err != nil { - return err - } - } - if err := cm.commit(file.Num(), db.seq); err != nil { - return err - } - cm.reset() - of.Remove() - of = nil - } - - // Replay journal to memdb. - mem.Reset() - for { - r, err := jr.Next() - if err != nil { - if err == io.EOF { - break - } - return errors.SetFile(err, file) - } - - buf.Reset() - if _, err := buf.ReadFrom(r); err != nil { - if err == io.ErrUnexpectedEOF { - // This is error returned due to corruption, with strict == false. - continue - } else { - return errors.SetFile(err, file) - } - } - if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mem); err != nil { - if strict || !errors.IsCorrupted(err) { - return errors.SetFile(err, file) - } else { - db.s.logf("journal error: %v (skipped)", err) - // We won't apply sequence number as it might be corrupted. - continue - } - } - - // Save sequence number. - db.seq = batch.seq + uint64(batch.Len()) - - // Flush it if large enough. - if mem.Size() >= writeBuffer { - if err := cm.flush(mem, 0); err != nil { - return err - } - mem.Reset() - } - } - - of = file - return nil - } - - // Recover all journals. - if len(journalFiles) > 0 { - db.logf("journal@recovery F·%d", len(journalFiles)) + // Recover journals. + if len(recJournalFiles) > 0 { + db.logf("journal@recovery F·%d", len(recJournalFiles)) // Mark file number as used. - db.s.markFileNum(journalFiles[len(journalFiles)-1].Num()) + db.s.markFileNum(recJournalFiles[len(recJournalFiles)-1].Num()) - mem = memdb.New(db.s.icmp, writeBuffer) - for _, file := range journalFiles { - if err := recoverJournal(file); err != nil { + var ( + // Options. + strict = db.s.o.GetStrict(opt.StrictJournal) + checksum = db.s.o.GetStrict(opt.StrictJournalChecksum) + writeBuffer = db.s.o.GetWriteBuffer() + + jr *journal.Reader + mdb = memdb.New(db.s.icmp, writeBuffer) + buf = &util.Buffer{} + batch = &Batch{} + ) + + for _, jf := range recJournalFiles { + db.logf("journal@recovery recovering @%d", jf.Num()) + + fr, err := jf.Open() + if err != nil { return err } + + // Create or reset journal reader instance. + if jr == nil { + jr = journal.NewReader(fr, dropper{db.s, jf}, strict, checksum) + } else { + jr.Reset(fr, dropper{db.s, jf}, strict, checksum) + } + + // Flush memdb and remove obsolete journal file. + if of != nil { + if mdb.Len() > 0 { + if _, err := db.s.flushMemdb(rec, mdb, -1); err != nil { + fr.Close() + return err + } + } + + rec.setJournalNum(jf.Num()) + rec.setSeqNum(db.seq) + if err := db.s.commit(rec); err != nil { + fr.Close() + return err + } + rec.resetAddedTables() + + of.Remove() + of = nil + } + + // Replay journal to memdb. + mdb.Reset() + for { + r, err := jr.Next() + if err != nil { + if err == io.EOF { + break + } + + fr.Close() + return errors.SetFile(err, jf) + } + + buf.Reset() + if _, err := buf.ReadFrom(r); err != nil { + if err == io.ErrUnexpectedEOF { + // This is error returned due to corruption, with strict == false. + continue + } + + fr.Close() + return errors.SetFile(err, jf) + } + if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mdb); err != nil { + if !strict && errors.IsCorrupted(err) { + db.s.logf("journal error: %v (skipped)", err) + // We won't apply sequence number as it might be corrupted. + continue + } + + fr.Close() + return errors.SetFile(err, jf) + } + + // Save sequence number. + db.seq = batch.seq + uint64(batch.Len()) + + // Flush it if large enough. + if mdb.Size() >= writeBuffer { + if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { + fr.Close() + return err + } + + mdb.Reset() + } + } + + fr.Close() + of = jf } - // Flush the last journal. - if mem.Len() > 0 { - if err := cm.flush(mem, 0); err != nil { + // Flush the last memdb. + if mdb.Len() > 0 { + if _, err := db.s.flushMemdb(rec, mdb, 0); err != nil { return err } } @@ -585,8 +611,10 @@ func (db *DB) recoverJournal() error { } // Commit. - if err := cm.commit(db.journalFile.Num(), db.seq); err != nil { - // Close journal. + rec.setJournalNum(db.journalFile.Num()) + rec.setSeqNum(db.seq) + if err := db.s.commit(rec); err != nil { + // Close journal on error. if db.journal != nil { db.journal.Close() db.journalWriter.Close() @@ -602,6 +630,103 @@ func (db *DB) recoverJournal() error { return nil } +func (db *DB) recoverJournalRO() error { + // Get all journals and sort it by file number. + allJournalFiles, err := db.s.getFiles(storage.TypeJournal) + if err != nil { + return err + } + files(allJournalFiles).sort() + + // Journals that will be recovered. + var recJournalFiles []storage.File + for _, jf := range allJournalFiles { + if jf.Num() >= db.s.stJournalNum || jf.Num() == db.s.stPrevJournalNum { + recJournalFiles = append(recJournalFiles, jf) + } + } + + var ( + // Options. + strict = db.s.o.GetStrict(opt.StrictJournal) + checksum = db.s.o.GetStrict(opt.StrictJournalChecksum) + writeBuffer = db.s.o.GetWriteBuffer() + + mdb = memdb.New(db.s.icmp, writeBuffer) + ) + + // Recover journals. + if len(recJournalFiles) > 0 { + db.logf("journal@recovery RO·Mode F·%d", len(recJournalFiles)) + + var ( + jr *journal.Reader + buf = &util.Buffer{} + batch = &Batch{} + ) + + for _, jf := range recJournalFiles { + db.logf("journal@recovery recovering @%d", jf.Num()) + + fr, err := jf.Open() + if err != nil { + return err + } + + // Create or reset journal reader instance. + if jr == nil { + jr = journal.NewReader(fr, dropper{db.s, jf}, strict, checksum) + } else { + jr.Reset(fr, dropper{db.s, jf}, strict, checksum) + } + + // Replay journal to memdb. + for { + r, err := jr.Next() + if err != nil { + if err == io.EOF { + break + } + + fr.Close() + return errors.SetFile(err, jf) + } + + buf.Reset() + if _, err := buf.ReadFrom(r); err != nil { + if err == io.ErrUnexpectedEOF { + // This is error returned due to corruption, with strict == false. + continue + } + + fr.Close() + return errors.SetFile(err, jf) + } + if err := batch.memDecodeAndReplay(db.seq, buf.Bytes(), mdb); err != nil { + if !strict && errors.IsCorrupted(err) { + db.s.logf("journal error: %v (skipped)", err) + // We won't apply sequence number as it might be corrupted. + continue + } + + fr.Close() + return errors.SetFile(err, jf) + } + + // Save sequence number. + db.seq = batch.seq + uint64(batch.Len()) + } + + fr.Close() + } + } + + // Set memDB. + db.mem = &memDB{db: db, DB: mdb, ref: 1} + + return nil +} + func (db *DB) get(key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, err error) { ikey := newIkey(key, seq, ktSeek) @@ -612,7 +737,7 @@ func (db *DB) get(key []byte, seq uint64, ro *opt.ReadOptions) (value []byte, er } defer m.decref() - mk, mv, me := m.mdb.Find(ikey) + mk, mv, me := m.Find(ikey) if me == nil { ukey, _, kt, kerr := parseIkey(mk) if kerr != nil { @@ -650,7 +775,7 @@ func (db *DB) has(key []byte, seq uint64, ro *opt.ReadOptions) (ret bool, err er } defer m.decref() - mk, _, me := m.mdb.Find(ikey) + mk, _, me := m.Find(ikey) if me == nil { ukey, _, kt, kerr := parseIkey(mk) if kerr != nil { @@ -782,7 +907,7 @@ func (db *DB) GetProperty(name string) (value string, err error) { const prefix = "leveldb." if !strings.HasPrefix(name, prefix) { - return "", errors.New("leveldb: GetProperty: unknown property: " + name) + return "", ErrNotFound } p := name[len(prefix):] @@ -796,7 +921,7 @@ func (db *DB) GetProperty(name string) (value string, err error) { var rest string n, _ := fmt.Sscanf(p[len(numFilesPrefix):], "%d%s", &level, &rest) if n != 1 || int(level) >= db.s.o.GetNumLevel() { - err = errors.New("leveldb: GetProperty: invalid property: " + name) + err = ErrNotFound } else { value = fmt.Sprint(v.tLen(int(level))) } @@ -823,8 +948,8 @@ func (db *DB) GetProperty(name string) (value string, err error) { case p == "blockpool": value = fmt.Sprintf("%v", db.s.tops.bpool) case p == "cachedblock": - if bc := db.s.o.GetBlockCache(); bc != nil { - value = fmt.Sprintf("%d", bc.Size()) + if db.s.tops.bcache != nil { + value = fmt.Sprintf("%d", db.s.tops.bcache.Size()) } else { value = "" } @@ -835,7 +960,7 @@ func (db *DB) GetProperty(name string) (value string, err error) { case p == "aliveiters": value = fmt.Sprintf("%d", atomic.LoadInt32(&db.aliveIters)) default: - err = errors.New("leveldb: GetProperty: unknown property: " + name) + err = ErrNotFound } return @@ -898,6 +1023,9 @@ func (db *DB) Close() error { var err error select { case err = <-db.compErrC: + if err == ErrReadOnly { + err = nil + } default: } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go index 447407ab..26003106 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_compaction.go @@ -11,7 +11,6 @@ import ( "time" "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/memdb" "github.com/syndtr/goleveldb/leveldb/opt" ) @@ -62,58 +61,8 @@ func (p *cStatsStaging) stopTimer() { } } -type cMem struct { - s *session - level int - rec *sessionRecord -} - -func newCMem(s *session) *cMem { - return &cMem{s: s, rec: &sessionRecord{numLevel: s.o.GetNumLevel()}} -} - -func (c *cMem) flush(mem *memdb.DB, level int) error { - s := c.s - - // Write memdb to table. - iter := mem.NewIterator(nil) - defer iter.Release() - t, n, err := s.tops.createFrom(iter) - if err != nil { - return err - } - - // Pick level. - if level < 0 { - v := s.version() - level = v.pickLevel(t.imin.ukey(), t.imax.ukey()) - v.release() - } - c.rec.addTableFile(level, t) - - s.logf("mem@flush created L%d@%d N·%d S·%s %q:%q", level, t.file.Num(), n, shortenb(int(t.size)), t.imin, t.imax) - - c.level = level - return nil -} - -func (c *cMem) reset() { - c.rec = &sessionRecord{numLevel: c.s.o.GetNumLevel()} -} - -func (c *cMem) commit(journal, seq uint64) error { - c.rec.setJournalNum(journal) - c.rec.setSeqNum(seq) - - // Commit changes. - return c.s.commit(c.rec) -} - func (db *DB) compactionError() { - var ( - err error - wlocked bool - ) + var err error noerr: // No error. for { @@ -121,7 +70,7 @@ noerr: case err = <-db.compErrSetC: switch { case err == nil: - case errors.IsCorrupted(err): + case err == ErrReadOnly, errors.IsCorrupted(err): goto hasperr default: goto haserr @@ -139,7 +88,7 @@ haserr: switch { case err == nil: goto noerr - case errors.IsCorrupted(err): + case err == ErrReadOnly, errors.IsCorrupted(err): goto hasperr default: } @@ -155,9 +104,9 @@ hasperr: case db.compPerErrC <- err: case db.writeLockC <- struct{}{}: // Hold write lock, so that write won't pass-through. - wlocked = true + db.compWriteLocking = true case _, _ = <-db.closeC: - if wlocked { + if db.compWriteLocking { // We should release the lock or Close will hang. <-db.writeLockC } @@ -287,21 +236,18 @@ func (db *DB) compactionExitTransact() { } func (db *DB) memCompaction() { - mem := db.getFrozenMem() - if mem == nil { + mdb := db.getFrozenMem() + if mdb == nil { return } - defer mem.decref() + defer mdb.decref() - c := newCMem(db.s) - stats := new(cStatsStaging) - - db.logf("mem@flush N·%d S·%s", mem.mdb.Len(), shortenb(mem.mdb.Size())) + db.logf("memdb@flush N·%d S·%s", mdb.Len(), shortenb(mdb.Size())) // Don't compact empty memdb. - if mem.mdb.Len() == 0 { - db.logf("mem@flush skipping") - // drop frozen mem + if mdb.Len() == 0 { + db.logf("memdb@flush skipping") + // drop frozen memdb db.dropFrozenMem() return } @@ -317,13 +263,20 @@ func (db *DB) memCompaction() { return } - db.compactionTransactFunc("mem@flush", func(cnt *compactionTransactCounter) (err error) { + var ( + rec = &sessionRecord{} + stats = &cStatsStaging{} + flushLevel int + ) + + db.compactionTransactFunc("memdb@flush", func(cnt *compactionTransactCounter) (err error) { stats.startTimer() - defer stats.stopTimer() - return c.flush(mem.mdb, -1) + flushLevel, err = db.s.flushMemdb(rec, mdb.DB, -1) + stats.stopTimer() + return }, func() error { - for _, r := range c.rec.addedTables { - db.logf("mem@flush revert @%d", r.num) + for _, r := range rec.addedTables { + db.logf("memdb@flush revert @%d", r.num) f := db.s.getTableFile(r.num) if err := f.Remove(); err != nil { return err @@ -332,20 +285,23 @@ func (db *DB) memCompaction() { return nil }) - db.compactionTransactFunc("mem@commit", func(cnt *compactionTransactCounter) (err error) { + db.compactionTransactFunc("memdb@commit", func(cnt *compactionTransactCounter) (err error) { stats.startTimer() - defer stats.stopTimer() - return c.commit(db.journalFile.Num(), db.frozenSeq) + rec.setJournalNum(db.journalFile.Num()) + rec.setSeqNum(db.frozenSeq) + err = db.s.commit(rec) + stats.stopTimer() + return }, nil) - db.logf("mem@flush committed F·%d T·%v", len(c.rec.addedTables), stats.duration) + db.logf("memdb@flush committed F·%d T·%v", len(rec.addedTables), stats.duration) - for _, r := range c.rec.addedTables { + for _, r := range rec.addedTables { stats.write += r.size } - db.compStats[c.level].add(stats) + db.compStats[flushLevel].add(stats) - // Drop frozen mem. + // Drop frozen memdb. db.dropFrozenMem() // Resume table compaction. @@ -557,7 +513,7 @@ func (b *tableCompactionBuilder) revert() error { func (db *DB) tableCompaction(c *compaction, noTrivial bool) { defer c.release() - rec := &sessionRecord{numLevel: db.s.o.GetNumLevel()} + rec := &sessionRecord{} rec.addCompPtr(c.level, c.imax) if !noTrivial && c.trivial() { diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_iter.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_iter.go index 4607e5da..656ae985 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_iter.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_iter.go @@ -8,6 +8,7 @@ package leveldb import ( "errors" + "math/rand" "runtime" "sync" "sync/atomic" @@ -39,11 +40,11 @@ func (db *DB) newRawIterator(slice *util.Range, ro *opt.ReadOptions) iterator.It ti := v.getIterators(slice, ro) n := len(ti) + 2 i := make([]iterator.Iterator, 0, n) - emi := em.mdb.NewIterator(slice) + emi := em.NewIterator(slice) emi.SetReleaser(&memdbReleaser{m: em}) i = append(i, emi) if fm != nil { - fmi := fm.mdb.NewIterator(slice) + fmi := fm.NewIterator(slice) fmi.SetReleaser(&memdbReleaser{m: fm}) i = append(i, fmi) } @@ -80,6 +81,10 @@ func (db *DB) newIterator(seq uint64, slice *util.Range, ro *opt.ReadOptions) *d return iter } +func (db *DB) iterSamplingRate() int { + return rand.Intn(2 * db.s.o.GetIteratorSamplingRate()) +} + type dir int const ( @@ -98,11 +103,21 @@ type dbIter struct { seq uint64 strict bool - dir dir - key []byte - value []byte - err error - releaser util.Releaser + smaplingGap int + dir dir + key []byte + value []byte + err error + releaser util.Releaser +} + +func (i *dbIter) sampleSeek() { + ikey := i.iter.Key() + i.smaplingGap -= len(ikey) + len(i.iter.Value()) + for i.smaplingGap < 0 { + i.smaplingGap += i.db.iterSamplingRate() + i.db.sampleSeek(ikey) + } } func (i *dbIter) setErr(err error) { @@ -175,6 +190,7 @@ func (i *dbIter) Seek(key []byte) bool { func (i *dbIter) next() bool { for { if ukey, seq, kt, kerr := parseIkey(i.iter.Key()); kerr == nil { + i.sampleSeek() if seq <= i.seq { switch kt { case ktDel: @@ -225,6 +241,7 @@ func (i *dbIter) prev() bool { if i.iter.Valid() { for { if ukey, seq, kt, kerr := parseIkey(i.iter.Key()); kerr == nil { + i.sampleSeek() if seq <= i.seq { if !del && i.icmp.uCompare(ukey, i.key) < 0 { return true @@ -266,6 +283,7 @@ func (i *dbIter) Prev() bool { case dirForward: for i.iter.Prev() { if ukey, _, _, kerr := parseIkey(i.iter.Key()); kerr == nil { + i.sampleSeek() if i.icmp.uCompare(ukey, i.key) < 0 { goto cont } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go index e41dcc65..0372848f 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_snapshot.go @@ -8,6 +8,7 @@ package leveldb import ( "container/list" + "fmt" "runtime" "sync" "sync/atomic" @@ -89,6 +90,10 @@ func (db *DB) newSnapshot() *Snapshot { return snap } +func (snap *Snapshot) String() string { + return fmt.Sprintf("leveldb.Snapshot{%d}", snap.elem.seq) +} + // Get gets the value for the given key. It returns ErrNotFound if // the DB does not contains the key. // diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_state.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_state.go index 24ecab50..24671dd3 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_state.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_state.go @@ -15,8 +15,8 @@ import ( ) type memDB struct { - db *DB - mdb *memdb.DB + db *DB + *memdb.DB ref int32 } @@ -27,12 +27,12 @@ func (m *memDB) incref() { func (m *memDB) decref() { if ref := atomic.AddInt32(&m.ref, -1); ref == 0 { // Only put back memdb with std capacity. - if m.mdb.Capacity() == m.db.s.o.GetWriteBuffer() { - m.mdb.Reset() - m.db.mpoolPut(m.mdb) + if m.Capacity() == m.db.s.o.GetWriteBuffer() { + m.Reset() + m.db.mpoolPut(m.DB) } m.db = nil - m.mdb = nil + m.DB = nil } else if ref < 0 { panic("negative memdb ref") } @@ -48,6 +48,15 @@ func (db *DB) addSeq(delta uint64) { atomic.AddUint64(&db.seq, delta) } +func (db *DB) sampleSeek(ikey iKey) { + v := db.s.version() + if v.sampleSeek(ikey) { + // Trigger table compaction. + db.compSendTrigger(db.tcompCmdC) + } + v.release() +} + func (db *DB) mpoolPut(mem *memdb.DB) { defer func() { recover() @@ -117,7 +126,7 @@ func (db *DB) newMem(n int) (mem *memDB, err error) { } mem = &memDB{ db: db, - mdb: mdb, + DB: mdb, ref: 2, } db.mem = mem diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_test.go index 0d51534b..9d91ebf1 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_test.go @@ -405,19 +405,21 @@ func (h *dbHarness) compactRange(min, max string) { t.Log("DB range compaction done") } -func (h *dbHarness) sizeAssert(start, limit string, low, hi uint64) { - t := h.t - db := h.db - - s, err := db.SizeOf([]util.Range{ +func (h *dbHarness) sizeOf(start, limit string) uint64 { + sz, err := h.db.SizeOf([]util.Range{ {[]byte(start), []byte(limit)}, }) if err != nil { - t.Error("SizeOf: got error: ", err) + h.t.Error("SizeOf: got error: ", err) } - if s.Sum() < low || s.Sum() > hi { - t.Errorf("sizeof %q to %q not in range, want %d - %d, got %d", - shorten(start), shorten(limit), low, hi, s.Sum()) + return sz.Sum() +} + +func (h *dbHarness) sizeAssert(start, limit string, low, hi uint64) { + sz := h.sizeOf(start, limit) + if sz < low || sz > hi { + h.t.Errorf("sizeOf %q to %q not in range, want %d - %d, got %d", + shorten(start), shorten(limit), low, hi, sz) } } @@ -1271,7 +1273,7 @@ func TestDB_DeletionMarkers2(t *testing.T) { } func TestDB_CompactionTableOpenError(t *testing.T) { - h := newDbHarnessWopt(t, &opt.Options{CachedOpenFiles: -1}) + h := newDbHarnessWopt(t, &opt.Options{OpenFilesCacheCapacity: -1}) defer h.close() im := 10 @@ -1629,8 +1631,8 @@ func TestDB_ManualCompaction(t *testing.T) { func TestDB_BloomFilter(t *testing.T) { h := newDbHarnessWopt(t, &opt.Options{ - BlockCache: opt.NoCache, - Filter: filter.NewBloomFilter(10), + DisableBlockCache: true, + Filter: filter.NewBloomFilter(10), }) defer h.close() @@ -2066,8 +2068,8 @@ func TestDB_GetProperties(t *testing.T) { func TestDB_GoleveldbIssue72and83(t *testing.T) { h := newDbHarnessWopt(t, &opt.Options{ - WriteBuffer: 1 * opt.MiB, - CachedOpenFiles: 3, + WriteBuffer: 1 * opt.MiB, + OpenFilesCacheCapacity: 3, }) defer h.close() @@ -2200,7 +2202,7 @@ func TestDB_GoleveldbIssue72and83(t *testing.T) { func TestDB_TransientError(t *testing.T) { h := newDbHarnessWopt(t, &opt.Options{ WriteBuffer: 128 * opt.KiB, - CachedOpenFiles: 3, + OpenFilesCacheCapacity: 3, DisableCompactionBackoff: true, }) defer h.close() @@ -2410,7 +2412,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { CompactionTableSize: 43 * opt.KiB, CompactionExpandLimitFactor: 1, CompactionGPOverlapsFactor: 1, - BlockCache: opt.NoCache, + DisableBlockCache: true, } s, err := newSession(stor, o) if err != nil { @@ -2443,7 +2445,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { if err != nil { t.Fatal(err) } - rec := &sessionRecord{numLevel: s.o.GetNumLevel()} + rec := &sessionRecord{} rec.addTableFile(i, tf) if err := s.commit(rec); err != nil { t.Fatal(err) @@ -2453,7 +2455,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { // Build grandparent. v := s.version() c := newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...)) - rec := &sessionRecord{numLevel: s.o.GetNumLevel()} + rec := &sessionRecord{} b := &tableCompactionBuilder{ s: s, c: c, @@ -2477,7 +2479,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { // Build level-1. v = s.version() c = newCompaction(s, v, 0, append(tFiles{}, v.tables[0]...)) - rec = &sessionRecord{numLevel: s.o.GetNumLevel()} + rec = &sessionRecord{} b = &tableCompactionBuilder{ s: s, c: c, @@ -2521,7 +2523,7 @@ func TestDB_TableCompactionBuilder(t *testing.T) { // Compaction with transient error. v = s.version() c = newCompaction(s, v, 1, append(tFiles{}, v.tables[1]...)) - rec = &sessionRecord{numLevel: s.o.GetNumLevel()} + rec = &sessionRecord{} b = &tableCompactionBuilder{ s: s, c: c, @@ -2577,3 +2579,123 @@ func TestDB_TableCompactionBuilder(t *testing.T) { } v.release() } + +func testDB_IterTriggeredCompaction(t *testing.T, limitDiv int) { + const ( + vSize = 200 * opt.KiB + tSize = 100 * opt.MiB + mIter = 100 + n = tSize / vSize + ) + + h := newDbHarnessWopt(t, &opt.Options{ + Compression: opt.NoCompression, + DisableBlockCache: true, + }) + defer h.close() + + key := func(x int) string { + return fmt.Sprintf("v%06d", x) + } + + // Fill. + value := strings.Repeat("x", vSize) + for i := 0; i < n; i++ { + h.put(key(i), value) + } + h.compactMem() + + // Delete all. + for i := 0; i < n; i++ { + h.delete(key(i)) + } + h.compactMem() + + var ( + limit = n / limitDiv + + startKey = key(0) + limitKey = key(limit) + maxKey = key(n) + slice = &util.Range{Limit: []byte(limitKey)} + + initialSize0 = h.sizeOf(startKey, limitKey) + initialSize1 = h.sizeOf(limitKey, maxKey) + ) + + t.Logf("inital size %s [rest %s]", shortenb(int(initialSize0)), shortenb(int(initialSize1))) + + for r := 0; true; r++ { + if r >= mIter { + t.Fatal("taking too long to compact") + } + + // Iterates. + iter := h.db.NewIterator(slice, h.ro) + for iter.Next() { + } + if err := iter.Error(); err != nil { + t.Fatalf("Iter err: %v", err) + } + iter.Release() + + // Wait compaction. + h.waitCompaction() + + // Check size. + size0 := h.sizeOf(startKey, limitKey) + size1 := h.sizeOf(limitKey, maxKey) + t.Logf("#%03d size %s [rest %s]", r, shortenb(int(size0)), shortenb(int(size1))) + if size0 < initialSize0/10 { + break + } + } + + if initialSize1 > 0 { + h.sizeAssert(limitKey, maxKey, initialSize1/4-opt.MiB, initialSize1+opt.MiB) + } +} + +func TestDB_IterTriggeredCompaction(t *testing.T) { + testDB_IterTriggeredCompaction(t, 1) +} + +func TestDB_IterTriggeredCompactionHalf(t *testing.T) { + testDB_IterTriggeredCompaction(t, 2) +} + +func TestDB_ReadOnly(t *testing.T) { + h := newDbHarness(t) + defer h.close() + + h.put("foo", "v1") + h.put("bar", "v2") + h.compactMem() + + h.put("xfoo", "v1") + h.put("xbar", "v2") + + t.Log("Trigger read-only") + if err := h.db.SetReadOnly(); err != nil { + h.close() + t.Fatalf("SetReadOnly error: %v", err) + } + + h.stor.SetEmuErr(storage.TypeAll, tsOpCreate, tsOpReplace, tsOpRemove, tsOpWrite, tsOpWrite, tsOpSync) + + ro := func(key, value, wantValue string) { + if err := h.db.Put([]byte(key), []byte(value), h.wo); err != ErrReadOnly { + t.Fatalf("unexpected error: %v", err) + } + h.getVal(key, wantValue) + } + + ro("foo", "vx", "v1") + + h.o.ReadOnly = true + h.reopenDB() + + ro("foo", "vx", "v1") + ro("bar", "vx", "v2") + h.assertNumKeys(4) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_write.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_write.go index e94b7b60..0c395653 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_write.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/db_write.go @@ -63,24 +63,24 @@ func (db *DB) rotateMem(n int) (mem *memDB, err error) { return } -func (db *DB) flush(n int) (mem *memDB, nn int, err error) { +func (db *DB) flush(n int) (mdb *memDB, mdbFree int, err error) { delayed := false flush := func() (retry bool) { v := db.s.version() defer v.release() - mem = db.getEffectiveMem() + mdb = db.getEffectiveMem() defer func() { if retry { - mem.decref() - mem = nil + mdb.decref() + mdb = nil } }() - nn = mem.mdb.Free() + mdbFree = mdb.Free() switch { case v.tLen(0) >= db.s.o.GetWriteL0SlowdownTrigger() && !delayed: delayed = true time.Sleep(time.Millisecond) - case nn >= n: + case mdbFree >= n: return false case v.tLen(0) >= db.s.o.GetWriteL0PauseTrigger(): delayed = true @@ -90,15 +90,15 @@ func (db *DB) flush(n int) (mem *memDB, nn int, err error) { } default: // Allow memdb to grow if it has no entry. - if mem.mdb.Len() == 0 { - nn = n + if mdb.Len() == 0 { + mdbFree = n } else { - mem.decref() - mem, err = db.rotateMem(n) + mdb.decref() + mdb, err = db.rotateMem(n) if err == nil { - nn = mem.mdb.Free() + mdbFree = mdb.Free() } else { - nn = 0 + mdbFree = 0 } } return false @@ -112,9 +112,9 @@ func (db *DB) flush(n int) (mem *memDB, nn int, err error) { db.writeDelay += time.Since(start) db.writeDelayN++ } else if db.writeDelayN > 0 { + db.logf("db@write was delayed N·%d T·%v", db.writeDelayN, db.writeDelay) db.writeDelay = 0 db.writeDelayN = 0 - db.logf("db@write was delayed N·%d T·%v", db.writeDelayN, db.writeDelay) } return } @@ -129,7 +129,7 @@ func (db *DB) Write(b *Batch, wo *opt.WriteOptions) (err error) { return } - b.init(wo.GetSync()) + b.init(wo.GetSync() && !db.s.o.GetNoSync()) // The write happen synchronously. select { @@ -157,18 +157,18 @@ func (db *DB) Write(b *Batch, wo *opt.WriteOptions) (err error) { } }() - mem, memFree, err := db.flush(b.size()) + mdb, mdbFree, err := db.flush(b.size()) if err != nil { return } - defer mem.decref() + defer mdb.decref() // Calculate maximum size of the batch. m := 1 << 20 if x := b.size(); x <= 128<<10 { m = x + (128 << 10) } - m = minInt(m, memFree) + m = minInt(m, mdbFree) // Merge with other batch. drain: @@ -197,7 +197,7 @@ drain: select { case db.journalC <- b: // Write into memdb - if berr := b.memReplay(mem.mdb); berr != nil { + if berr := b.memReplay(mdb.DB); berr != nil { panic(berr) } case err = <-db.compPerErrC: @@ -211,7 +211,7 @@ drain: case err = <-db.journalAckC: if err != nil { // Revert memdb if error detected - if berr := b.revertMemReplay(mem.mdb); berr != nil { + if berr := b.revertMemReplay(mdb.DB); berr != nil { panic(berr) } return @@ -225,7 +225,7 @@ drain: if err != nil { return } - if berr := b.memReplay(mem.mdb); berr != nil { + if berr := b.memReplay(mdb.DB); berr != nil { panic(berr) } } @@ -233,7 +233,7 @@ drain: // Set last seq number. db.addSeq(uint64(b.Len())) - if b.size() >= memFree { + if b.size() >= mdbFree { db.rotateMem(0) } return @@ -249,8 +249,7 @@ func (db *DB) Put(key, value []byte, wo *opt.WriteOptions) error { return db.Write(b, wo) } -// Delete deletes the value for the given key. It returns ErrNotFound if -// the DB does not contain the key. +// Delete deletes the value for the given key. // // It is safe to modify the contents of the arguments after Delete returns. func (db *DB) Delete(key []byte, wo *opt.WriteOptions) error { @@ -290,9 +289,9 @@ func (db *DB) CompactRange(r util.Range) error { } // Check for overlaps in memdb. - mem := db.getEffectiveMem() - defer mem.decref() - if isMemOverlaps(db.s.icmp, mem.mdb, r.Start, r.Limit) { + mdb := db.getEffectiveMem() + defer mdb.decref() + if isMemOverlaps(db.s.icmp, mdb.DB, r.Start, r.Limit) { // Memdb compaction. if _, err := db.rotateMem(0); err != nil { <-db.writeLockC @@ -309,3 +308,31 @@ func (db *DB) CompactRange(r util.Range) error { // Table compaction. return db.compSendRange(db.tcompCmdC, -1, r.Start, r.Limit) } + +// SetReadOnly makes DB read-only. It will stay read-only until reopened. +func (db *DB) SetReadOnly() error { + if err := db.ok(); err != nil { + return err + } + + // Lock writer. + select { + case db.writeLockC <- struct{}{}: + db.compWriteLocking = true + case err := <-db.compPerErrC: + return err + case _, _ = <-db.closeC: + return ErrClosed + } + + // Set compaction read-only. + select { + case db.compErrSetC <- ErrReadOnly: + case perr := <-db.compPerErrC: + return perr + case _, _ = <-db.closeC: + return ErrClosed + } + + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors.go index 29d0d2f2..c8bd66a5 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors.go @@ -12,6 +12,7 @@ import ( var ( ErrNotFound = errors.ErrNotFound + ErrReadOnly = errors.New("leveldb: read-only mode") ErrSnapshotReleased = errors.New("leveldb: snapshot released") ErrIterReleased = errors.New("leveldb: iterator released") ErrClosed = errors.New("leveldb: closed") diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go index 84b5d6b7..dacbf131 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/errors/errors.go @@ -52,12 +52,14 @@ func IsCorrupted(err error) bool { switch err.(type) { case *ErrCorrupted: return true + case *storage.ErrCorrupted: + return true } return false } // ErrMissingFiles is the type that indicating a corruption due to missing -// files. +// files. ErrMissingFiles always wrapped with ErrCorrupted. type ErrMissingFiles struct { Files []*storage.FileInfo } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/external_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/external_test.go index 1ae304ed..b328ece4 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/external_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/external_test.go @@ -17,14 +17,14 @@ import ( var _ = testutil.Defer(func() { Describe("Leveldb external", func() { o := &opt.Options{ - BlockCache: opt.NoCache, - BlockRestartInterval: 5, - BlockSize: 80, - Compression: opt.NoCompression, - CachedOpenFiles: -1, - Strict: opt.StrictAll, - WriteBuffer: 1000, - CompactionTableSize: 2000, + DisableBlockCache: true, + BlockRestartInterval: 5, + BlockSize: 80, + Compression: opt.NoCompression, + OpenFilesCacheCapacity: -1, + Strict: opt.StrictAll, + WriteBuffer: 1000, + CompactionTableSize: 2000, } Describe("write test", func() { diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/key.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/key.go index 98b21f44..572ae815 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/key.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/key.go @@ -106,7 +106,7 @@ func (ik iKey) assert() { panic("leveldb: nil iKey") } if len(ik) < 8 { - panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid length", ik, len(ik))) + panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid length", []byte(ik), len(ik))) } } @@ -124,7 +124,7 @@ func (ik iKey) parseNum() (seq uint64, kt kType) { num := ik.num() seq, kt = uint64(num>>8), kType(num&0xff) if kt > ktVal { - panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid type %#x", ik, len(ik), kt)) + panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid type %#x", []byte(ik), len(ik), kt)) } return } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go index e5398873..1395bd92 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/memdb/memdb.go @@ -206,6 +206,7 @@ func (p *DB) randHeight() (h int) { return } +// Must hold RW-lock if prev == true, as it use shared prevNode slice. func (p *DB) findGE(key []byte, prev bool) (int, bool) { node := 0 h := p.maxHeight - 1 @@ -302,7 +303,7 @@ func (p *DB) Put(key []byte, value []byte) error { node := len(p.nodeData) p.nodeData = append(p.nodeData, kvOffset, len(key), len(value), h) for i, n := range p.prevNode[:h] { - m := n + 4 + i + m := n + nNext + i p.nodeData = append(p.nodeData, p.nodeData[m]) p.nodeData[m] = node } @@ -434,20 +435,22 @@ func (p *DB) Len() int { // Reset resets the DB to initial empty state. Allows reuse the buffer. func (p *DB) Reset() { + p.mu.Lock() p.rnd = rand.New(rand.NewSource(0xdeadbeef)) p.maxHeight = 1 p.n = 0 p.kvSize = 0 p.kvData = p.kvData[:0] - p.nodeData = p.nodeData[:4+tMaxHeight] + p.nodeData = p.nodeData[:nNext+tMaxHeight] p.nodeData[nKV] = 0 p.nodeData[nKey] = 0 p.nodeData[nVal] = 0 p.nodeData[nHeight] = tMaxHeight for n := 0; n < tMaxHeight; n++ { - p.nodeData[4+n] = 0 + p.nodeData[nNext+n] = 0 p.prevNode[n] = 0 } + p.mu.Unlock() } // New creates a new initalized in-memory key/value DB. The capacity diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/opt/options.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/opt/options.go index 0798b879..7b5d8b9b 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/opt/options.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/opt/options.go @@ -20,8 +20,9 @@ const ( GiB = MiB * 1024 ) -const ( - DefaultBlockCacheSize = 8 * MiB +var ( + DefaultBlockCacher = LRUCacher + DefaultBlockCacheCapacity = 8 * MiB DefaultBlockRestartInterval = 16 DefaultBlockSize = 4 * KiB DefaultCompactionExpandLimitFactor = 25 @@ -33,30 +34,43 @@ const ( DefaultCompactionTotalSize = 10 * MiB DefaultCompactionTotalSizeMultiplier = 10.0 DefaultCompressionType = SnappyCompression - DefaultCachedOpenFiles = 500 + DefaultIteratorSamplingRate = 1 * MiB DefaultMaxMemCompationLevel = 2 DefaultNumLevel = 7 + DefaultOpenFilesCacher = LRUCacher + DefaultOpenFilesCacheCapacity = 500 DefaultWriteBuffer = 4 * MiB DefaultWriteL0PauseTrigger = 12 DefaultWriteL0SlowdownTrigger = 8 ) -type noCache struct{} +// Cacher is a caching algorithm. +type Cacher interface { + New(capacity int) cache.Cacher +} -func (noCache) SetCapacity(capacity int) {} -func (noCache) Capacity() int { return 0 } -func (noCache) Used() int { return 0 } -func (noCache) Size() int { return 0 } -func (noCache) NumObjects() int { return 0 } -func (noCache) GetNamespace(id uint64) cache.Namespace { return nil } -func (noCache) PurgeNamespace(id uint64, fin cache.PurgeFin) {} -func (noCache) ZapNamespace(id uint64) {} -func (noCache) Purge(fin cache.PurgeFin) {} -func (noCache) Zap() {} +type CacherFunc struct { + NewFunc func(capacity int) cache.Cacher +} -var NoCache cache.Cache = noCache{} +func (f *CacherFunc) New(capacity int) cache.Cacher { + if f.NewFunc != nil { + return f.NewFunc(capacity) + } + return nil +} -// Compression is the per-block compression algorithm to use. +func noCacher(int) cache.Cacher { return nil } + +var ( + // LRUCacher is the LRU-cache algorithm. + LRUCacher = &CacherFunc{cache.NewLRU} + + // NoCacher is the value to disable caching algorithm. + NoCacher = &CacherFunc{} +) + +// Compression is the 'sorted table' block compression algorithm to use. type Compression uint func (c Compression) String() string { @@ -133,16 +147,17 @@ type Options struct { // The default value is nil AltFilters []filter.Filter - // BlockCache provides per-block caching for LevelDB. Specify NoCache to - // disable block caching. + // BlockCacher provides cache algorithm for LevelDB 'sorted table' block caching. + // Specify NoCacher to disable caching algorithm. // - // By default LevelDB will create LRU-cache with capacity of BlockCacheSize. - BlockCache cache.Cache + // The default value is LRUCacher. + BlockCacher Cacher - // BlockCacheSize defines the capacity of the default 'block cache'. + // BlockCacheCapacity defines the capacity of the 'sorted table' block caching. + // Use -1 for zero, this has same effect as specifying NoCacher to BlockCacher. // // The default value is 8MiB. - BlockCacheSize int + BlockCacheCapacity int // BlockRestartInterval is the number of keys between restart points for // delta encoding of keys. @@ -156,13 +171,6 @@ type Options struct { // The default value is 4KiB. BlockSize int - // CachedOpenFiles defines number of open files to kept around when not - // in-use, the counting includes still in-use files. - // Set this to negative value to disable caching. - // - // The default value is 500. - CachedOpenFiles int - // CompactionExpandLimitFactor limits compaction size after expanded. // This will be multiplied by table size limit at compaction target level. // @@ -237,11 +245,22 @@ type Options struct { // The default value uses the same ordering as bytes.Compare. Comparer comparer.Comparer - // Compression defines the per-block compression to use. + // Compression defines the 'sorted table' block compression to use. // // The default value (DefaultCompression) uses snappy compression. Compression Compression + // DisableBufferPool allows disable use of util.BufferPool functionality. + // + // The default value is false. + DisableBufferPool bool + + // DisableBlockCache allows disable use of cache.Cache functionality on + // 'sorted table' block. + // + // The default value is false. + DisableBlockCache bool + // DisableCompactionBackoff allows disable compaction retry backoff. // // The default value is false. @@ -275,6 +294,13 @@ type Options struct { // The default value is nil. Filter filter.Filter + // IteratorSamplingRate defines approximate gap (in bytes) between read + // sampling of an iterator. The samples will be used to determine when + // compaction should be triggered. + // + // The default is 1MiB. + IteratorSamplingRate int + // MaxMemCompationLevel defines maximum level a newly compacted 'memdb' // will be pushed into if doesn't creates overlap. This should less than // NumLevel. Use -1 for level-0. @@ -282,12 +308,34 @@ type Options struct { // The default is 2. MaxMemCompationLevel int + // NoSync allows completely disable fsync. + // + // The default is false. + NoSync bool + // NumLevel defines number of database level. The level shouldn't changed // between opens, or the database will panic. // // The default is 7. NumLevel int + // OpenFilesCacher provides cache algorithm for open files caching. + // Specify NoCacher to disable caching algorithm. + // + // The default value is LRUCacher. + OpenFilesCacher Cacher + + // OpenFilesCacheCapacity defines the capacity of the open files caching. + // Use -1 for zero, this has same effect as specifying NoCacher to OpenFilesCacher. + // + // The default value is 500. + OpenFilesCacheCapacity int + + // If true then opens DB in read-only mode. + // + // The default value is false. + ReadOnly bool + // Strict defines the DB strict level. Strict Strict @@ -320,18 +368,22 @@ func (o *Options) GetAltFilters() []filter.Filter { return o.AltFilters } -func (o *Options) GetBlockCache() cache.Cache { - if o == nil { +func (o *Options) GetBlockCacher() Cacher { + if o == nil || o.BlockCacher == nil { + return DefaultBlockCacher + } else if o.BlockCacher == NoCacher { return nil } - return o.BlockCache + return o.BlockCacher } -func (o *Options) GetBlockCacheSize() int { - if o == nil || o.BlockCacheSize <= 0 { - return DefaultBlockCacheSize +func (o *Options) GetBlockCacheCapacity() int { + if o == nil || o.BlockCacheCapacity == 0 { + return DefaultBlockCacheCapacity + } else if o.BlockCacheCapacity < 0 { + return 0 } - return o.BlockCacheSize + return o.BlockCacheCapacity } func (o *Options) GetBlockRestartInterval() int { @@ -348,15 +400,6 @@ func (o *Options) GetBlockSize() int { return o.BlockSize } -func (o *Options) GetCachedOpenFiles() int { - if o == nil || o.CachedOpenFiles == 0 { - return DefaultCachedOpenFiles - } else if o.CachedOpenFiles < 0 { - return 0 - } - return o.CachedOpenFiles -} - func (o *Options) GetCompactionExpandLimit(level int) int { factor := DefaultCompactionExpandLimitFactor if o != nil && o.CompactionExpandLimitFactor > 0 { @@ -444,6 +487,20 @@ func (o *Options) GetCompression() Compression { return o.Compression } +func (o *Options) GetDisableBufferPool() bool { + if o == nil { + return false + } + return o.DisableBufferPool +} + +func (o *Options) GetDisableBlockCache() bool { + if o == nil { + return false + } + return o.DisableBlockCache +} + func (o *Options) GetDisableCompactionBackoff() bool { if o == nil { return false @@ -472,12 +529,19 @@ func (o *Options) GetFilter() filter.Filter { return o.Filter } +func (o *Options) GetIteratorSamplingRate() int { + if o == nil || o.IteratorSamplingRate <= 0 { + return DefaultIteratorSamplingRate + } + return o.IteratorSamplingRate +} + func (o *Options) GetMaxMemCompationLevel() int { level := DefaultMaxMemCompationLevel if o != nil { if o.MaxMemCompationLevel > 0 { level = o.MaxMemCompationLevel - } else if o.MaxMemCompationLevel == -1 { + } else if o.MaxMemCompationLevel < 0 { level = 0 } } @@ -487,6 +551,13 @@ func (o *Options) GetMaxMemCompationLevel() int { return level } +func (o *Options) GetNoSync() bool { + if o == nil { + return false + } + return o.NoSync +} + func (o *Options) GetNumLevel() int { if o == nil || o.NumLevel <= 0 { return DefaultNumLevel @@ -494,6 +565,32 @@ func (o *Options) GetNumLevel() int { return o.NumLevel } +func (o *Options) GetOpenFilesCacher() Cacher { + if o == nil || o.OpenFilesCacher == nil { + return DefaultOpenFilesCacher + } + if o.OpenFilesCacher == NoCacher { + return nil + } + return o.OpenFilesCacher +} + +func (o *Options) GetOpenFilesCacheCapacity() int { + if o == nil || o.OpenFilesCacheCapacity == 0 { + return DefaultOpenFilesCacheCapacity + } else if o.OpenFilesCacheCapacity < 0 { + return 0 + } + return o.OpenFilesCacheCapacity +} + +func (o *Options) GetReadOnly() bool { + if o == nil { + return false + } + return o.ReadOnly +} + func (o *Options) GetStrict(strict Strict) bool { if o == nil || o.Strict == 0 { return DefaultStrict&strict != 0 diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/options.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/options.go index 3928cd16..a3d84ef6 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/options.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/options.go @@ -7,7 +7,6 @@ package leveldb import ( - "github.com/syndtr/goleveldb/leveldb/cache" "github.com/syndtr/goleveldb/leveldb/filter" "github.com/syndtr/goleveldb/leveldb/opt" ) @@ -32,13 +31,6 @@ func (s *session) setOptions(o *opt.Options) { no.AltFilters[i] = &iFilter{filter} } } - // Block cache. - switch o.GetBlockCache() { - case nil: - no.BlockCache = cache.NewLRUCache(o.GetBlockCacheSize()) - case opt.NoCache: - no.BlockCache = nil - } // Comparer. s.icmp = &iComparer{o.GetComparer()} no.Comparer = s.icmp diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session.go index 5b251efb..f0bba460 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session.go @@ -11,10 +11,8 @@ import ( "io" "os" "sync" - "sync/atomic" "github.com/syndtr/goleveldb/leveldb/errors" - "github.com/syndtr/goleveldb/leveldb/iterator" "github.com/syndtr/goleveldb/leveldb/journal" "github.com/syndtr/goleveldb/leveldb/opt" "github.com/syndtr/goleveldb/leveldb/storage" @@ -73,7 +71,7 @@ func newSession(stor storage.Storage, o *opt.Options) (s *session, err error) { stCompPtrs: make([]iKey, o.GetNumLevel()), } s.setOptions(o) - s.tops = newTableOps(s, s.o.GetCachedOpenFiles()) + s.tops = newTableOps(s) s.setVersion(newVersion(s)) s.log("log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed") return @@ -82,9 +80,6 @@ func newSession(stor storage.Storage, o *opt.Options) (s *session, err error) { // Close session. func (s *session) close() { s.tops.close() - if bc := s.o.GetBlockCache(); bc != nil { - bc.Purge(nil) - } if s.manifest != nil { s.manifest.Close() } @@ -130,11 +125,16 @@ func (s *session) recover() (err error) { return } defer reader.Close() - strict := s.o.GetStrict(opt.StrictManifest) - jr := journal.NewReader(reader, dropper{s, m}, strict, true) - staging := s.stVersion.newStaging() - rec := &sessionRecord{numLevel: s.o.GetNumLevel()} + var ( + // Options. + numLevel = s.o.GetNumLevel() + strict = s.o.GetStrict(opt.StrictManifest) + + jr = journal.NewReader(reader, dropper{s, m}, strict, true) + rec = &sessionRecord{} + staging = s.stVersion.newStaging() + ) for { var r io.Reader r, err = jr.Next() @@ -146,7 +146,7 @@ func (s *session) recover() (err error) { return errors.SetFile(err, m) } - err = rec.decode(r) + err = rec.decode(r, numLevel) if err == nil { // save compact pointers for _, r := range rec.compPtrs { @@ -209,250 +209,3 @@ func (s *session) commit(r *sessionRecord) (err error) { return } - -// Pick a compaction based on current state; need external synchronization. -func (s *session) pickCompaction() *compaction { - v := s.version() - - var level int - var t0 tFiles - if v.cScore >= 1 { - level = v.cLevel - cptr := s.stCompPtrs[level] - tables := v.tables[level] - for _, t := range tables { - if cptr == nil || s.icmp.Compare(t.imax, cptr) > 0 { - t0 = append(t0, t) - break - } - } - if len(t0) == 0 { - t0 = append(t0, tables[0]) - } - } else { - if p := atomic.LoadPointer(&v.cSeek); p != nil { - ts := (*tSet)(p) - level = ts.level - t0 = append(t0, ts.table) - } else { - v.release() - return nil - } - } - - return newCompaction(s, v, level, t0) -} - -// Create compaction from given level and range; need external synchronization. -func (s *session) getCompactionRange(level int, umin, umax []byte) *compaction { - v := s.version() - - t0 := v.tables[level].getOverlaps(nil, s.icmp, umin, umax, level == 0) - if len(t0) == 0 { - v.release() - return nil - } - - // Avoid compacting too much in one shot in case the range is large. - // But we cannot do this for level-0 since level-0 files can overlap - // and we must not pick one file and drop another older file if the - // two files overlap. - if level > 0 { - limit := uint64(v.s.o.GetCompactionSourceLimit(level)) - total := uint64(0) - for i, t := range t0 { - total += t.size - if total >= limit { - s.logf("table@compaction limiting F·%d -> F·%d", len(t0), i+1) - t0 = t0[:i+1] - break - } - } - } - - return newCompaction(s, v, level, t0) -} - -func newCompaction(s *session, v *version, level int, t0 tFiles) *compaction { - c := &compaction{ - s: s, - v: v, - level: level, - tables: [2]tFiles{t0, nil}, - maxGPOverlaps: uint64(s.o.GetCompactionGPOverlaps(level)), - tPtrs: make([]int, s.o.GetNumLevel()), - } - c.expand() - c.save() - return c -} - -// compaction represent a compaction state. -type compaction struct { - s *session - v *version - - level int - tables [2]tFiles - maxGPOverlaps uint64 - - gp tFiles - gpi int - seenKey bool - gpOverlappedBytes uint64 - imin, imax iKey - tPtrs []int - released bool - - snapGPI int - snapSeenKey bool - snapGPOverlappedBytes uint64 - snapTPtrs []int -} - -func (c *compaction) save() { - c.snapGPI = c.gpi - c.snapSeenKey = c.seenKey - c.snapGPOverlappedBytes = c.gpOverlappedBytes - c.snapTPtrs = append(c.snapTPtrs[:0], c.tPtrs...) -} - -func (c *compaction) restore() { - c.gpi = c.snapGPI - c.seenKey = c.snapSeenKey - c.gpOverlappedBytes = c.snapGPOverlappedBytes - c.tPtrs = append(c.tPtrs[:0], c.snapTPtrs...) -} - -func (c *compaction) release() { - if !c.released { - c.released = true - c.v.release() - } -} - -// Expand compacted tables; need external synchronization. -func (c *compaction) expand() { - limit := uint64(c.s.o.GetCompactionExpandLimit(c.level)) - vt0, vt1 := c.v.tables[c.level], c.v.tables[c.level+1] - - t0, t1 := c.tables[0], c.tables[1] - imin, imax := t0.getRange(c.s.icmp) - // We expand t0 here just incase ukey hop across tables. - t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.level == 0) - if len(t0) != len(c.tables[0]) { - imin, imax = t0.getRange(c.s.icmp) - } - t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false) - // Get entire range covered by compaction. - amin, amax := append(t0, t1...).getRange(c.s.icmp) - - // See if we can grow the number of inputs in "level" without - // changing the number of "level+1" files we pick up. - if len(t1) > 0 { - exp0 := vt0.getOverlaps(nil, c.s.icmp, amin.ukey(), amax.ukey(), c.level == 0) - if len(exp0) > len(t0) && t1.size()+exp0.size() < limit { - xmin, xmax := exp0.getRange(c.s.icmp) - exp1 := vt1.getOverlaps(nil, c.s.icmp, xmin.ukey(), xmax.ukey(), false) - if len(exp1) == len(t1) { - c.s.logf("table@compaction expanding L%d+L%d (F·%d S·%s)+(F·%d S·%s) -> (F·%d S·%s)+(F·%d S·%s)", - c.level, c.level+1, len(t0), shortenb(int(t0.size())), len(t1), shortenb(int(t1.size())), - len(exp0), shortenb(int(exp0.size())), len(exp1), shortenb(int(exp1.size()))) - imin, imax = xmin, xmax - t0, t1 = exp0, exp1 - amin, amax = append(t0, t1...).getRange(c.s.icmp) - } - } - } - - // Compute the set of grandparent files that overlap this compaction - // (parent == level+1; grandparent == level+2) - if c.level+2 < c.s.o.GetNumLevel() { - c.gp = c.v.tables[c.level+2].getOverlaps(c.gp, c.s.icmp, amin.ukey(), amax.ukey(), false) - } - - c.tables[0], c.tables[1] = t0, t1 - c.imin, c.imax = imin, imax -} - -// Check whether compaction is trivial. -func (c *compaction) trivial() bool { - return len(c.tables[0]) == 1 && len(c.tables[1]) == 0 && c.gp.size() <= c.maxGPOverlaps -} - -func (c *compaction) baseLevelForKey(ukey []byte) bool { - for level, tables := range c.v.tables[c.level+2:] { - for c.tPtrs[level] < len(tables) { - t := tables[c.tPtrs[level]] - if c.s.icmp.uCompare(ukey, t.imax.ukey()) <= 0 { - // We've advanced far enough. - if c.s.icmp.uCompare(ukey, t.imin.ukey()) >= 0 { - // Key falls in this file's range, so definitely not base level. - return false - } - break - } - c.tPtrs[level]++ - } - } - return true -} - -func (c *compaction) shouldStopBefore(ikey iKey) bool { - for ; c.gpi < len(c.gp); c.gpi++ { - gp := c.gp[c.gpi] - if c.s.icmp.Compare(ikey, gp.imax) <= 0 { - break - } - if c.seenKey { - c.gpOverlappedBytes += gp.size - } - } - c.seenKey = true - - if c.gpOverlappedBytes > c.maxGPOverlaps { - // Too much overlap for current output; start new output. - c.gpOverlappedBytes = 0 - return true - } - return false -} - -// Creates an iterator. -func (c *compaction) newIterator() iterator.Iterator { - // Creates iterator slice. - icap := len(c.tables) - if c.level == 0 { - // Special case for level-0 - icap = len(c.tables[0]) + 1 - } - its := make([]iterator.Iterator, 0, icap) - - // Options. - ro := &opt.ReadOptions{ - DontFillCache: true, - Strict: opt.StrictOverride, - } - strict := c.s.o.GetStrict(opt.StrictCompaction) - if strict { - ro.Strict |= opt.StrictReader - } - - for i, tables := range c.tables { - if len(tables) == 0 { - continue - } - - // Level-0 is not sorted and may overlaps each other. - if c.level+i == 0 { - for _, t := range tables { - its = append(its, c.s.tops.newIterator(t, nil, ro)) - } - } else { - it := iterator.NewIndexedIterator(tables.newIndexIterator(c.s.tops, c.s.icmp, nil, ro), strict) - its = append(its, it) - } - } - - return iterator.NewMergedIterator(its, c.s.icmp, strict) -} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_compaction.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_compaction.go new file mode 100644 index 00000000..7c5a7941 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_compaction.go @@ -0,0 +1,287 @@ +// Copyright (c) 2012, Suryandaru Triandana +// All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package leveldb + +import ( + "sync/atomic" + + "github.com/syndtr/goleveldb/leveldb/iterator" + "github.com/syndtr/goleveldb/leveldb/memdb" + "github.com/syndtr/goleveldb/leveldb/opt" +) + +func (s *session) pickMemdbLevel(umin, umax []byte) int { + v := s.version() + defer v.release() + return v.pickMemdbLevel(umin, umax) +} + +func (s *session) flushMemdb(rec *sessionRecord, mdb *memdb.DB, level int) (level_ int, err error) { + // Create sorted table. + iter := mdb.NewIterator(nil) + defer iter.Release() + t, n, err := s.tops.createFrom(iter) + if err != nil { + return level, err + } + + // Pick level and add to record. + if level < 0 { + level = s.pickMemdbLevel(t.imin.ukey(), t.imax.ukey()) + } + rec.addTableFile(level, t) + + s.logf("memdb@flush created L%d@%d N·%d S·%s %q:%q", level, t.file.Num(), n, shortenb(int(t.size)), t.imin, t.imax) + return level, nil +} + +// Pick a compaction based on current state; need external synchronization. +func (s *session) pickCompaction() *compaction { + v := s.version() + + var level int + var t0 tFiles + if v.cScore >= 1 { + level = v.cLevel + cptr := s.stCompPtrs[level] + tables := v.tables[level] + for _, t := range tables { + if cptr == nil || s.icmp.Compare(t.imax, cptr) > 0 { + t0 = append(t0, t) + break + } + } + if len(t0) == 0 { + t0 = append(t0, tables[0]) + } + } else { + if p := atomic.LoadPointer(&v.cSeek); p != nil { + ts := (*tSet)(p) + level = ts.level + t0 = append(t0, ts.table) + } else { + v.release() + return nil + } + } + + return newCompaction(s, v, level, t0) +} + +// Create compaction from given level and range; need external synchronization. +func (s *session) getCompactionRange(level int, umin, umax []byte) *compaction { + v := s.version() + + t0 := v.tables[level].getOverlaps(nil, s.icmp, umin, umax, level == 0) + if len(t0) == 0 { + v.release() + return nil + } + + // Avoid compacting too much in one shot in case the range is large. + // But we cannot do this for level-0 since level-0 files can overlap + // and we must not pick one file and drop another older file if the + // two files overlap. + if level > 0 { + limit := uint64(v.s.o.GetCompactionSourceLimit(level)) + total := uint64(0) + for i, t := range t0 { + total += t.size + if total >= limit { + s.logf("table@compaction limiting F·%d -> F·%d", len(t0), i+1) + t0 = t0[:i+1] + break + } + } + } + + return newCompaction(s, v, level, t0) +} + +func newCompaction(s *session, v *version, level int, t0 tFiles) *compaction { + c := &compaction{ + s: s, + v: v, + level: level, + tables: [2]tFiles{t0, nil}, + maxGPOverlaps: uint64(s.o.GetCompactionGPOverlaps(level)), + tPtrs: make([]int, s.o.GetNumLevel()), + } + c.expand() + c.save() + return c +} + +// compaction represent a compaction state. +type compaction struct { + s *session + v *version + + level int + tables [2]tFiles + maxGPOverlaps uint64 + + gp tFiles + gpi int + seenKey bool + gpOverlappedBytes uint64 + imin, imax iKey + tPtrs []int + released bool + + snapGPI int + snapSeenKey bool + snapGPOverlappedBytes uint64 + snapTPtrs []int +} + +func (c *compaction) save() { + c.snapGPI = c.gpi + c.snapSeenKey = c.seenKey + c.snapGPOverlappedBytes = c.gpOverlappedBytes + c.snapTPtrs = append(c.snapTPtrs[:0], c.tPtrs...) +} + +func (c *compaction) restore() { + c.gpi = c.snapGPI + c.seenKey = c.snapSeenKey + c.gpOverlappedBytes = c.snapGPOverlappedBytes + c.tPtrs = append(c.tPtrs[:0], c.snapTPtrs...) +} + +func (c *compaction) release() { + if !c.released { + c.released = true + c.v.release() + } +} + +// Expand compacted tables; need external synchronization. +func (c *compaction) expand() { + limit := uint64(c.s.o.GetCompactionExpandLimit(c.level)) + vt0, vt1 := c.v.tables[c.level], c.v.tables[c.level+1] + + t0, t1 := c.tables[0], c.tables[1] + imin, imax := t0.getRange(c.s.icmp) + // We expand t0 here just incase ukey hop across tables. + t0 = vt0.getOverlaps(t0, c.s.icmp, imin.ukey(), imax.ukey(), c.level == 0) + if len(t0) != len(c.tables[0]) { + imin, imax = t0.getRange(c.s.icmp) + } + t1 = vt1.getOverlaps(t1, c.s.icmp, imin.ukey(), imax.ukey(), false) + // Get entire range covered by compaction. + amin, amax := append(t0, t1...).getRange(c.s.icmp) + + // See if we can grow the number of inputs in "level" without + // changing the number of "level+1" files we pick up. + if len(t1) > 0 { + exp0 := vt0.getOverlaps(nil, c.s.icmp, amin.ukey(), amax.ukey(), c.level == 0) + if len(exp0) > len(t0) && t1.size()+exp0.size() < limit { + xmin, xmax := exp0.getRange(c.s.icmp) + exp1 := vt1.getOverlaps(nil, c.s.icmp, xmin.ukey(), xmax.ukey(), false) + if len(exp1) == len(t1) { + c.s.logf("table@compaction expanding L%d+L%d (F·%d S·%s)+(F·%d S·%s) -> (F·%d S·%s)+(F·%d S·%s)", + c.level, c.level+1, len(t0), shortenb(int(t0.size())), len(t1), shortenb(int(t1.size())), + len(exp0), shortenb(int(exp0.size())), len(exp1), shortenb(int(exp1.size()))) + imin, imax = xmin, xmax + t0, t1 = exp0, exp1 + amin, amax = append(t0, t1...).getRange(c.s.icmp) + } + } + } + + // Compute the set of grandparent files that overlap this compaction + // (parent == level+1; grandparent == level+2) + if c.level+2 < c.s.o.GetNumLevel() { + c.gp = c.v.tables[c.level+2].getOverlaps(c.gp, c.s.icmp, amin.ukey(), amax.ukey(), false) + } + + c.tables[0], c.tables[1] = t0, t1 + c.imin, c.imax = imin, imax +} + +// Check whether compaction is trivial. +func (c *compaction) trivial() bool { + return len(c.tables[0]) == 1 && len(c.tables[1]) == 0 && c.gp.size() <= c.maxGPOverlaps +} + +func (c *compaction) baseLevelForKey(ukey []byte) bool { + for level, tables := range c.v.tables[c.level+2:] { + for c.tPtrs[level] < len(tables) { + t := tables[c.tPtrs[level]] + if c.s.icmp.uCompare(ukey, t.imax.ukey()) <= 0 { + // We've advanced far enough. + if c.s.icmp.uCompare(ukey, t.imin.ukey()) >= 0 { + // Key falls in this file's range, so definitely not base level. + return false + } + break + } + c.tPtrs[level]++ + } + } + return true +} + +func (c *compaction) shouldStopBefore(ikey iKey) bool { + for ; c.gpi < len(c.gp); c.gpi++ { + gp := c.gp[c.gpi] + if c.s.icmp.Compare(ikey, gp.imax) <= 0 { + break + } + if c.seenKey { + c.gpOverlappedBytes += gp.size + } + } + c.seenKey = true + + if c.gpOverlappedBytes > c.maxGPOverlaps { + // Too much overlap for current output; start new output. + c.gpOverlappedBytes = 0 + return true + } + return false +} + +// Creates an iterator. +func (c *compaction) newIterator() iterator.Iterator { + // Creates iterator slice. + icap := len(c.tables) + if c.level == 0 { + // Special case for level-0. + icap = len(c.tables[0]) + 1 + } + its := make([]iterator.Iterator, 0, icap) + + // Options. + ro := &opt.ReadOptions{ + DontFillCache: true, + Strict: opt.StrictOverride, + } + strict := c.s.o.GetStrict(opt.StrictCompaction) + if strict { + ro.Strict |= opt.StrictReader + } + + for i, tables := range c.tables { + if len(tables) == 0 { + continue + } + + // Level-0 is not sorted and may overlaps each other. + if c.level+i == 0 { + for _, t := range tables { + its = append(its, c.s.tops.newIterator(t, nil, ro)) + } + } else { + it := iterator.NewIndexedIterator(tables.newIndexIterator(c.s.tops, c.s.icmp, nil, ro), strict) + its = append(its, it) + } + } + + return iterator.NewMergedIterator(its, c.s.icmp, strict) +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record.go index 1bdcc68f..405e07be 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record.go @@ -52,8 +52,6 @@ type dtRecord struct { } type sessionRecord struct { - numLevel int - hasRec int comparer string journalNum uint64 @@ -230,7 +228,7 @@ func (p *sessionRecord) readBytes(field string, r byteReader) []byte { return x } -func (p *sessionRecord) readLevel(field string, r io.ByteReader) int { +func (p *sessionRecord) readLevel(field string, r io.ByteReader, numLevel int) int { if p.err != nil { return 0 } @@ -238,14 +236,14 @@ func (p *sessionRecord) readLevel(field string, r io.ByteReader) int { if p.err != nil { return 0 } - if x >= uint64(p.numLevel) { + if x >= uint64(numLevel) { p.err = errors.NewErrCorrupted(nil, &ErrManifestCorrupted{field, "invalid level number"}) return 0 } return int(x) } -func (p *sessionRecord) decode(r io.Reader) error { +func (p *sessionRecord) decode(r io.Reader, numLevel int) error { br, ok := r.(byteReader) if !ok { br = bufio.NewReader(r) @@ -286,13 +284,13 @@ func (p *sessionRecord) decode(r io.Reader) error { p.setSeqNum(x) } case recCompPtr: - level := p.readLevel("comp-ptr.level", br) + level := p.readLevel("comp-ptr.level", br, numLevel) ikey := p.readBytes("comp-ptr.ikey", br) if p.err == nil { p.addCompPtr(level, iKey(ikey)) } case recAddTable: - level := p.readLevel("add-table.level", br) + level := p.readLevel("add-table.level", br, numLevel) num := p.readUvarint("add-table.num", br) size := p.readUvarint("add-table.size", br) imin := p.readBytes("add-table.imin", br) @@ -301,7 +299,7 @@ func (p *sessionRecord) decode(r io.Reader) error { p.addTable(level, num, size, imin, imax) } case recDelTable: - level := p.readLevel("del-table.level", br) + level := p.readLevel("del-table.level", br, numLevel) num := p.readUvarint("del-table.num", br) if p.err == nil { p.delTable(level, num) diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go index c0c035ae..33c14875 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_record_test.go @@ -19,8 +19,8 @@ func decodeEncode(v *sessionRecord) (res bool, err error) { if err != nil { return } - v2 := &sessionRecord{numLevel: opt.DefaultNumLevel} - err = v.decode(b) + v2 := &sessionRecord{} + err = v.decode(b, opt.DefaultNumLevel) if err != nil { return } @@ -34,7 +34,7 @@ func decodeEncode(v *sessionRecord) (res bool, err error) { func TestSessionRecord_EncodeDecode(t *testing.T) { big := uint64(1) << 50 - v := &sessionRecord{numLevel: opt.DefaultNumLevel} + v := &sessionRecord{} i := uint64(0) test := func() { res, err := decodeEncode(v) diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_util.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_util.go index 007c02cd..7ec9f86f 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_util.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/session_util.go @@ -182,7 +182,7 @@ func (s *session) newManifest(rec *sessionRecord, v *version) (err error) { defer v.release() } if rec == nil { - rec = &sessionRecord{numLevel: s.o.GetNumLevel()} + rec = &sessionRecord{} } s.fillRecord(rec, true) v.fillRecord(rec) @@ -240,9 +240,11 @@ func (s *session) flushManifest(rec *sessionRecord) (err error) { if err != nil { return } - err = s.manifestWriter.Sync() - if err != nil { - return + if !s.o.GetNoSync() { + err = s.manifestWriter.Sync() + if err != nil { + return + } } s.recordCommited(rec) return diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go index 75439f6d..420b2773 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage.go @@ -221,7 +221,7 @@ func (fs *fileStorage) GetManifest() (f File, err error) { fs.log(fmt.Sprintf("skipping %s: invalid file name", fn)) continue } - if _, e1 := strconv.ParseUint(fn[7:], 10, 0); e1 != nil { + if _, e1 := strconv.ParseUint(fn[8:], 10, 0); e1 != nil { fs.log(fmt.Sprintf("skipping %s: invalid file num: %v", fn, e1)) continue } @@ -243,7 +243,10 @@ func (fs *fileStorage) GetManifest() (f File, err error) { rem = append(rem, fn) } if !pend1 || cerr == nil { - cerr = fmt.Errorf("leveldb/storage: corrupted or incomplete %s file", fn) + cerr = &ErrCorrupted{ + File: fsParseName(filepath.Base(fn)), + Err: errors.New("leveldb/storage: corrupted or incomplete manifest file"), + } } } else if f != nil && f1.Num() < f.Num() { fs.log(fmt.Sprintf("skipping %s: obsolete", fn)) @@ -326,8 +329,7 @@ func (fs *fileStorage) Close() error { runtime.SetFinalizer(fs, nil) if fs.open > 0 { - fs.log(fmt.Sprintf("refuse to close, %d files still open", fs.open)) - return fmt.Errorf("leveldb/storage: cannot close, %d files still open", fs.open) + fs.log(fmt.Sprintf("close: warning, %d files still open", fs.open)) } fs.open = -1 e1 := fs.logw.Close() @@ -505,30 +507,37 @@ func (f *file) path() string { return filepath.Join(f.fs.path, f.name()) } -func (f *file) parse(name string) bool { - var num uint64 +func fsParseName(name string) *FileInfo { + fi := &FileInfo{} var tail string - _, err := fmt.Sscanf(name, "%d.%s", &num, &tail) + _, err := fmt.Sscanf(name, "%d.%s", &fi.Num, &tail) if err == nil { switch tail { case "log": - f.t = TypeJournal + fi.Type = TypeJournal case "ldb", "sst": - f.t = TypeTable + fi.Type = TypeTable case "tmp": - f.t = TypeTemp + fi.Type = TypeTemp default: - return false + return nil } - f.num = num - return true + return fi } - n, _ := fmt.Sscanf(name, "MANIFEST-%d%s", &num, &tail) + n, _ := fmt.Sscanf(name, "MANIFEST-%d%s", &fi.Num, &tail) if n == 1 { - f.t = TypeManifest - f.num = num - return true + fi.Type = TypeManifest + return fi } - - return false + return nil +} + +func (f *file) parse(name string) bool { + fi := fsParseName(name) + if fi == nil { + return false + } + f.t = fi.Type + f.num = fi.Num + return true } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go index d0a604b7..6eb32742 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/file_storage_unix.go @@ -50,13 +50,23 @@ func rename(oldpath, newpath string) error { return os.Rename(oldpath, newpath) } +func isErrInvalid(err error) bool { + if err == os.ErrInvalid { + return true + } + if syserr, ok := err.(*os.SyscallError); ok && syserr.Err == syscall.EINVAL { + return true + } + return false +} + func syncDir(name string) error { f, err := os.Open(name) if err != nil { return err } defer f.Close() - if err := f.Sync(); err != nil { + if err := f.Sync(); err != nil && !isErrInvalid(err) { return err } return nil diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go index 85dd70b0..a4e037ca 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage/storage.go @@ -46,6 +46,22 @@ var ( ErrClosed = errors.New("leveldb/storage: closed") ) +// ErrCorrupted is the type that wraps errors that indicate corruption of +// a file. Package storage has its own type instead of using +// errors.ErrCorrupted to prevent circular import. +type ErrCorrupted struct { + File *FileInfo + Err error +} + +func (e *ErrCorrupted) Error() string { + if e.File != nil { + return fmt.Sprintf("%v [file=%v]", e.Err, e.File) + } else { + return e.Err.Error() + } +} + // Syncer is the interface that wraps basic Sync method. type Syncer interface { // Sync commits the current contents of the file to stable storage. diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage_test.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage_test.go index dc1f1fb5..08be0bab 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage_test.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/storage_test.go @@ -42,6 +42,8 @@ type tsOp uint const ( tsOpOpen tsOp = iota tsOpCreate + tsOpReplace + tsOpRemove tsOpRead tsOpReadAt tsOpWrite @@ -241,6 +243,10 @@ func (tf tsFile) Replace(newfile storage.File) (err error) { if err != nil { return } + if tf.shouldErr(tsOpReplace) { + err = errors.New("leveldb.testStorage: emulated create error") + return + } err = tf.File.Replace(newfile.(tsFile).File) if err != nil { ts.t.Errorf("E: cannot replace file, num=%d type=%v: %v", tf.Num(), tf.Type(), err) @@ -258,6 +264,10 @@ func (tf tsFile) Remove() (err error) { if err != nil { return } + if tf.shouldErr(tsOpRemove) { + err = errors.New("leveldb.testStorage: emulated create error") + return + } err = tf.File.Remove() if err != nil { ts.t.Errorf("E: cannot remove file, num=%d type=%v: %v", tf.Num(), tf.Type(), err) diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table.go index c3432fc9..37be47ae 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table.go @@ -286,10 +286,11 @@ func (x *tFilesSortByNum) Less(i, j int) bool { // Table operations. type tOps struct { - s *session - cache cache.Cache - cacheNS cache.Namespace - bpool *util.BufferPool + s *session + noSync bool + cache *cache.Cache + bcache *cache.Cache + bpool *util.BufferPool } // Creates an empty table and returns table writer. @@ -338,26 +339,28 @@ func (t *tOps) createFrom(src iterator.Iterator) (f *tFile, n int, err error) { // Opens table. It returns a cache handle, which should // be released after use. -func (t *tOps) open(f *tFile) (ch cache.Handle, err error) { +func (t *tOps) open(f *tFile) (ch *cache.Handle, err error) { num := f.file.Num() - ch = t.cacheNS.Get(num, func() (charge int, value interface{}) { + ch = t.cache.Get(0, num, func() (size int, value cache.Value) { var r storage.Reader r, err = f.file.Open() if err != nil { return 0, nil } - var bcacheNS cache.Namespace - if bc := t.s.o.GetBlockCache(); bc != nil { - bcacheNS = bc.GetNamespace(num) + var bcache *cache.CacheGetter + if t.bcache != nil { + bcache = &cache.CacheGetter{Cache: t.bcache, NS: num} } + var tr *table.Reader - tr, err = table.NewReader(r, int64(f.size), storage.NewFileInfo(f.file), bcacheNS, t.bpool, t.s.o.Options) + tr, err = table.NewReader(r, int64(f.size), storage.NewFileInfo(f.file), bcache, t.bpool, t.s.o.Options) if err != nil { r.Close() return 0, nil } return 1, tr + }) if ch == nil && err == nil { err = ErrClosed @@ -412,16 +415,14 @@ func (t *tOps) newIterator(f *tFile, slice *util.Range, ro *opt.ReadOptions) ite // no one use the the table. func (t *tOps) remove(f *tFile) { num := f.file.Num() - t.cacheNS.Delete(num, func(exist, pending bool) { - if !pending { - if err := f.file.Remove(); err != nil { - t.s.logf("table@remove removing @%d %q", num, err) - } else { - t.s.logf("table@remove removed @%d", num) - } - if bc := t.s.o.GetBlockCache(); bc != nil { - bc.ZapNamespace(num) - } + t.cache.Delete(0, num, func() { + if err := f.file.Remove(); err != nil { + t.s.logf("table@remove removing @%d %q", num, err) + } else { + t.s.logf("table@remove removed @%d", num) + } + if t.bcache != nil { + t.bcache.EvictNS(num) } }) } @@ -429,18 +430,39 @@ func (t *tOps) remove(f *tFile) { // Closes the table ops instance. It will close all tables, // regadless still used or not. func (t *tOps) close() { - t.cache.Zap() t.bpool.Close() + t.cache.Close() + if t.bcache != nil { + t.bcache.Close() + } } // Creates new initialized table ops instance. -func newTableOps(s *session, cacheCap int) *tOps { - c := cache.NewLRUCache(cacheCap) +func newTableOps(s *session) *tOps { + var ( + cacher cache.Cacher + bcache *cache.Cache + bpool *util.BufferPool + ) + if s.o.GetOpenFilesCacheCapacity() > 0 { + cacher = cache.NewLRU(s.o.GetOpenFilesCacheCapacity()) + } + if !s.o.GetDisableBlockCache() { + var bcacher cache.Cacher + if s.o.GetBlockCacheCapacity() > 0 { + bcacher = cache.NewLRU(s.o.GetBlockCacheCapacity()) + } + bcache = cache.NewCache(bcacher) + } + if !s.o.GetDisableBufferPool() { + bpool = util.NewBufferPool(s.o.GetBlockSize() + 5) + } return &tOps{ - s: s, - cache: c, - cacheNS: c.GetNamespace(0), - bpool: util.NewBufferPool(s.o.GetBlockSize() + 5), + s: s, + noSync: s.o.GetNoSync(), + cache: cache.NewCache(cacher), + bcache: bcache, + bpool: bpool, } } @@ -485,9 +507,11 @@ func (w *tWriter) finish() (f *tFile, err error) { if err != nil { return } - err = w.w.Sync() - if err != nil { - return + if !w.t.noSync { + err = w.w.Sync() + if err != nil { + return + } } f = newTableFile(w.file, uint64(w.tw.BytesLen()), iKey(w.first), iKey(w.last)) return diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/reader.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/reader.go index 3b574462..23c7c612 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/reader.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/reader.go @@ -14,7 +14,7 @@ import ( "strings" "sync" - "github.com/syndtr/gosnappy/snappy" + "github.com/golang/snappy" "github.com/syndtr/goleveldb/leveldb/cache" "github.com/syndtr/goleveldb/leveldb/comparer" @@ -509,7 +509,7 @@ type Reader struct { mu sync.RWMutex fi *storage.FileInfo reader io.ReaderAt - cache cache.Namespace + cache *cache.CacheGetter err error bpool *util.BufferPool // Options @@ -613,18 +613,22 @@ func (r *Reader) readBlock(bh blockHandle, verifyChecksum bool) (*block, error) func (r *Reader) readBlockCached(bh blockHandle, verifyChecksum, fillCache bool) (*block, util.Releaser, error) { if r.cache != nil { - var err error - ch := r.cache.Get(bh.offset, func() (charge int, value interface{}) { - if !fillCache { - return 0, nil - } - var b *block - b, err = r.readBlock(bh, verifyChecksum) - if err != nil { - return 0, nil - } - return cap(b.data), b - }) + var ( + err error + ch *cache.Handle + ) + if fillCache { + ch = r.cache.Get(bh.offset, func() (size int, value cache.Value) { + var b *block + b, err = r.readBlock(bh, verifyChecksum) + if err != nil { + return 0, nil + } + return cap(b.data), b + }) + } else { + ch = r.cache.Get(bh.offset, nil) + } if ch != nil { b, ok := ch.Value().(*block) if !ok { @@ -667,18 +671,22 @@ func (r *Reader) readFilterBlock(bh blockHandle) (*filterBlock, error) { func (r *Reader) readFilterBlockCached(bh blockHandle, fillCache bool) (*filterBlock, util.Releaser, error) { if r.cache != nil { - var err error - ch := r.cache.Get(bh.offset, func() (charge int, value interface{}) { - if !fillCache { - return 0, nil - } - var b *filterBlock - b, err = r.readFilterBlock(bh) - if err != nil { - return 0, nil - } - return cap(b.data), b - }) + var ( + err error + ch *cache.Handle + ) + if fillCache { + ch = r.cache.Get(bh.offset, func() (size int, value cache.Value) { + var b *filterBlock + b, err = r.readFilterBlock(bh) + if err != nil { + return 0, nil + } + return cap(b.data), b + }) + } else { + ch = r.cache.Get(bh.offset, nil) + } if ch != nil { b, ok := ch.Value().(*filterBlock) if !ok { @@ -980,7 +988,7 @@ func (r *Reader) Release() { // The fi, cache and bpool is optional and can be nil. // // The returned table reader instance is goroutine-safe. -func NewReader(f io.ReaderAt, size int64, fi *storage.FileInfo, cache cache.Namespace, bpool *util.BufferPool, o *opt.Options) (*Reader, error) { +func NewReader(f io.ReaderAt, size int64, fi *storage.FileInfo, cache *cache.CacheGetter, bpool *util.BufferPool, o *opt.Options) (*Reader, error) { if f == nil { return nil, errors.New("leveldb/table: nil file") } diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/writer.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/writer.go index 274c95fa..274dee6d 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/writer.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/table/writer.go @@ -12,7 +12,7 @@ import ( "fmt" "io" - "github.com/syndtr/gosnappy/snappy" + "github.com/golang/snappy" "github.com/syndtr/goleveldb/leveldb/comparer" "github.com/syndtr/goleveldb/leveldb/filter" @@ -167,11 +167,7 @@ func (w *Writer) writeBlock(buf *util.Buffer, compression opt.Compression) (bh b if n := snappy.MaxEncodedLen(buf.Len()) + blockTrailerLen; len(w.compressionScratch) < n { w.compressionScratch = make([]byte, n) } - var compressed []byte - compressed, err = snappy.Encode(w.compressionScratch, buf.Bytes()) - if err != nil { - return - } + compressed := snappy.Encode(w.compressionScratch, buf.Bytes()) n := len(compressed) b = compressed[:n+blockTrailerLen] b[n] = blockTypeSnappyCompression diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/util/buffer_pool.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/util/buffer_pool.go index 2b8453d7..2f3db974 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/util/buffer_pool.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/util/buffer_pool.go @@ -201,6 +201,7 @@ func (p *BufferPool) String() string { func (p *BufferPool) drain() { ticker := time.NewTicker(2 * time.Second) + defer ticker.Stop() for { select { case <-ticker.C: diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/version.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/version.go index 5ab7b53d..011d982d 100644 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/version.go +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/leveldb/version.go @@ -136,9 +136,8 @@ func (v *version) get(ikey iKey, ro *opt.ReadOptions, noValue bool) (value []byt if !tseek { if tset == nil { tset = &tSet{level, t} - } else if tset.table.consumeSeek() <= 0 { + } else { tseek = true - tcomp = atomic.CompareAndSwapPointer(&v.cSeek, nil, unsafe.Pointer(tset)) } } @@ -203,6 +202,28 @@ func (v *version) get(ikey iKey, ro *opt.ReadOptions, noValue bool) (value []byt return true }) + if tseek && tset.table.consumeSeek() <= 0 { + tcomp = atomic.CompareAndSwapPointer(&v.cSeek, nil, unsafe.Pointer(tset)) + } + + return +} + +func (v *version) sampleSeek(ikey iKey) (tcomp bool) { + var tset *tSet + + v.walkOverlapping(ikey, func(level int, t *tFile) bool { + if tset == nil { + tset = &tSet{level, t} + return true + } else { + if tset.table.consumeSeek() <= 0 { + tcomp = atomic.CompareAndSwapPointer(&v.cSeek, nil, unsafe.Pointer(tset)) + } + return false + } + }, nil) + return } @@ -279,7 +300,7 @@ func (v *version) offsetOf(ikey iKey) (n uint64, err error) { return } -func (v *version) pickLevel(umin, umax []byte) (level int) { +func (v *version) pickMemdbLevel(umin, umax []byte) (level int) { if !v.tables[0].overlaps(v.s.icmp, umin, umax, true) { var overlaps tFiles maxLevel := v.s.o.GetMaxMemCompationLevel() diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/manualtest/dbstress/key.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/manualtest/dbstress/key.go new file mode 100644 index 00000000..906d0d82 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/manualtest/dbstress/key.go @@ -0,0 +1,136 @@ +package main + +import ( + "encoding/binary" + "fmt" + + "github.com/syndtr/goleveldb/leveldb/errors" +) + +type ErrIkeyCorrupted struct { + Ikey []byte + Reason string +} + +func (e *ErrIkeyCorrupted) Error() string { + return fmt.Sprintf("leveldb: iKey %q corrupted: %s", e.Ikey, e.Reason) +} + +func newErrIkeyCorrupted(ikey []byte, reason string) error { + return errors.NewErrCorrupted(nil, &ErrIkeyCorrupted{append([]byte{}, ikey...), reason}) +} + +type kType int + +func (kt kType) String() string { + switch kt { + case ktDel: + return "d" + case ktVal: + return "v" + } + return "x" +} + +// Value types encoded as the last component of internal keys. +// Don't modify; this value are saved to disk. +const ( + ktDel kType = iota + ktVal +) + +// ktSeek defines the kType that should be passed when constructing an +// internal key for seeking to a particular sequence number (since we +// sort sequence numbers in decreasing order and the value type is +// embedded as the low 8 bits in the sequence number in internal keys, +// we need to use the highest-numbered ValueType, not the lowest). +const ktSeek = ktVal + +const ( + // Maximum value possible for sequence number; the 8-bits are + // used by value type, so its can packed together in single + // 64-bit integer. + kMaxSeq uint64 = (uint64(1) << 56) - 1 + // Maximum value possible for packed sequence number and type. + kMaxNum uint64 = (kMaxSeq << 8) | uint64(ktSeek) +) + +// Maximum number encoded in bytes. +var kMaxNumBytes = make([]byte, 8) + +func init() { + binary.LittleEndian.PutUint64(kMaxNumBytes, kMaxNum) +} + +type iKey []byte + +func newIkey(ukey []byte, seq uint64, kt kType) iKey { + if seq > kMaxSeq { + panic("leveldb: invalid sequence number") + } else if kt > ktVal { + panic("leveldb: invalid type") + } + + ik := make(iKey, len(ukey)+8) + copy(ik, ukey) + binary.LittleEndian.PutUint64(ik[len(ukey):], (seq<<8)|uint64(kt)) + return ik +} + +func parseIkey(ik []byte) (ukey []byte, seq uint64, kt kType, err error) { + if len(ik) < 8 { + return nil, 0, 0, newErrIkeyCorrupted(ik, "invalid length") + } + num := binary.LittleEndian.Uint64(ik[len(ik)-8:]) + seq, kt = uint64(num>>8), kType(num&0xff) + if kt > ktVal { + return nil, 0, 0, newErrIkeyCorrupted(ik, "invalid type") + } + ukey = ik[:len(ik)-8] + return +} + +func validIkey(ik []byte) bool { + _, _, _, err := parseIkey(ik) + return err == nil +} + +func (ik iKey) assert() { + if ik == nil { + panic("leveldb: nil iKey") + } + if len(ik) < 8 { + panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid length", ik, len(ik))) + } +} + +func (ik iKey) ukey() []byte { + ik.assert() + return ik[:len(ik)-8] +} + +func (ik iKey) num() uint64 { + ik.assert() + return binary.LittleEndian.Uint64(ik[len(ik)-8:]) +} + +func (ik iKey) parseNum() (seq uint64, kt kType) { + num := ik.num() + seq, kt = uint64(num>>8), kType(num&0xff) + if kt > ktVal { + panic(fmt.Sprintf("leveldb: iKey %q, len=%d: invalid type %#x", ik, len(ik), kt)) + } + return +} + +func (ik iKey) String() string { + if ik == nil { + return "" + } + + if ukey, seq, kt, err := parseIkey(ik); err == nil { + return fmt.Sprintf("%x,%s%d", ukey, kt, seq) + } else { + return "" + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/manualtest/dbstress/main.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/manualtest/dbstress/main.go new file mode 100644 index 00000000..c0a566b7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/goleveldb/manualtest/dbstress/main.go @@ -0,0 +1,621 @@ +package main + +import ( + "crypto/rand" + "encoding/binary" + "flag" + "fmt" + "log" + mrand "math/rand" + "net/http" + _ "net/http/pprof" + "os" + "os/signal" + "path" + "runtime" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/syndtr/goleveldb/leveldb" + "github.com/syndtr/goleveldb/leveldb/errors" + "github.com/syndtr/goleveldb/leveldb/opt" + "github.com/syndtr/goleveldb/leveldb/storage" + "github.com/syndtr/goleveldb/leveldb/table" + "github.com/syndtr/goleveldb/leveldb/util" +) + +var ( + dbPath = path.Join(os.TempDir(), "goleveldb-testdb") + openFilesCacheCapacity = 500 + dataLen = 63 + numKeys = arrayInt{100000, 1332, 531, 1234, 9553, 1024, 35743} + httpProf = "127.0.0.1:5454" + enableBlockCache = false + enableCompression = false + enableBufferPool = false + + wg = new(sync.WaitGroup) + done, fail uint32 + + bpool *util.BufferPool +) + +type arrayInt []int + +func (a arrayInt) String() string { + var str string + for i, n := range a { + if i > 0 { + str += "," + } + str += strconv.Itoa(n) + } + return str +} + +func (a *arrayInt) Set(str string) error { + var na arrayInt + for _, s := range strings.Split(str, ",") { + s = strings.TrimSpace(s) + if s != "" { + n, err := strconv.Atoi(s) + if err != nil { + return err + } + na = append(na, n) + } + } + *a = na + return nil +} + +func init() { + flag.StringVar(&dbPath, "db", dbPath, "testdb path") + flag.IntVar(&openFilesCacheCapacity, "openfilescachecap", openFilesCacheCapacity, "open files cache capacity") + flag.IntVar(&dataLen, "datalen", dataLen, "data length") + flag.Var(&numKeys, "numkeys", "num keys") + flag.StringVar(&httpProf, "httpprof", httpProf, "http pprof listen addr") + flag.BoolVar(&enableBufferPool, "enablebufferpool", enableBufferPool, "enable buffer pool") + flag.BoolVar(&enableBlockCache, "enableblockcache", enableBlockCache, "enable block cache") + flag.BoolVar(&enableCompression, "enablecompression", enableCompression, "enable block compression") +} + +func randomData(dst []byte, ns, prefix byte, i uint32) []byte { + n := 2 + dataLen + 4 + 4 + n2 := n*2 + 4 + if cap(dst) < n2 { + dst = make([]byte, n2) + } else { + dst = dst[:n2] + } + _, err := rand.Reader.Read(dst[2 : n-8]) + if err != nil { + panic(err) + } + dst[0] = ns + dst[1] = prefix + binary.LittleEndian.PutUint32(dst[n-8:], i) + binary.LittleEndian.PutUint32(dst[n-4:], util.NewCRC(dst[:n-4]).Value()) + copy(dst[n:n+n], dst[:n]) + binary.LittleEndian.PutUint32(dst[n2-4:], util.NewCRC(dst[:n2-4]).Value()) + return dst +} + +func dataSplit(data []byte) (data0, data1 []byte) { + n := (len(data) - 4) / 2 + return data[:n], data[n : n+n] +} + +func dataNS(data []byte) byte { + return data[0] +} + +func dataPrefix(data []byte) byte { + return data[1] +} + +func dataI(data []byte) uint32 { + return binary.LittleEndian.Uint32(data[len(data)-12:]) +} + +func dataChecksum(data []byte) (uint32, uint32) { + checksum0 := binary.LittleEndian.Uint32(data[len(data)-4:]) + checksum1 := util.NewCRC(data[:len(data)-4]).Value() + return checksum0, checksum1 +} + +func dataPrefixSlice(ns, prefix byte) *util.Range { + return util.BytesPrefix([]byte{ns, prefix}) +} + +func dataNsSlice(ns byte) *util.Range { + return util.BytesPrefix([]byte{ns}) +} + +type testingFile struct { + storage.File +} + +func (tf *testingFile) Remove() error { + if atomic.LoadUint32(&fail) == 1 { + return nil + } + + if tf.Type() == storage.TypeTable { + if scanTable(tf, true) { + return nil + } + } + return tf.File.Remove() +} + +type testingStorage struct { + storage.Storage +} + +func (ts *testingStorage) GetFile(num uint64, t storage.FileType) storage.File { + return &testingFile{ts.Storage.GetFile(num, t)} +} + +func (ts *testingStorage) GetFiles(t storage.FileType) ([]storage.File, error) { + files, err := ts.Storage.GetFiles(t) + if err != nil { + return nil, err + } + for i := range files { + files[i] = &testingFile{files[i]} + } + return files, nil +} + +func (ts *testingStorage) GetManifest() (storage.File, error) { + f, err := ts.Storage.GetManifest() + if err == nil { + f = &testingFile{f} + } + return f, err +} + +func (ts *testingStorage) SetManifest(f storage.File) error { + return ts.Storage.SetManifest(f.(*testingFile).File) +} + +type latencyStats struct { + mark time.Time + dur, min, max time.Duration + num int +} + +func (s *latencyStats) start() { + s.mark = time.Now() +} + +func (s *latencyStats) record(n int) { + if s.mark.IsZero() { + panic("not started") + } + dur := time.Now().Sub(s.mark) + dur1 := dur / time.Duration(n) + if dur1 < s.min || s.min == 0 { + s.min = dur1 + } + if dur1 > s.max { + s.max = dur1 + } + s.dur += dur + s.num += n + s.mark = time.Time{} +} + +func (s *latencyStats) ratePerSec() int { + durSec := s.dur / time.Second + if durSec > 0 { + return s.num / int(durSec) + } + return s.num +} + +func (s *latencyStats) avg() time.Duration { + if s.num > 0 { + return s.dur / time.Duration(s.num) + } + return 0 +} + +func (s *latencyStats) add(x *latencyStats) { + if x.min < s.min || s.min == 0 { + s.min = x.min + } + if x.max > s.max { + s.max = x.max + } + s.dur += x.dur + s.num += x.num +} + +func scanTable(f storage.File, checksum bool) (corrupted bool) { + fi := storage.NewFileInfo(f) + r, err := f.Open() + if err != nil { + log.Fatal(err) + } + defer r.Close() + + size, err := r.Seek(0, os.SEEK_END) + if err != nil { + log.Fatal(err) + } + + o := &opt.Options{Strict: opt.NoStrict} + if checksum { + o.Strict = opt.StrictBlockChecksum | opt.StrictReader + } + tr, err := table.NewReader(r, size, fi, nil, bpool, o) + if err != nil { + log.Fatal(err) + } + defer tr.Release() + + checkData := func(i int, t string, data []byte) bool { + if len(data) == 0 { + panic(fmt.Sprintf("[%v] nil data: i=%d t=%s", fi, i, t)) + } + + checksum0, checksum1 := dataChecksum(data) + if checksum0 != checksum1 { + atomic.StoreUint32(&fail, 1) + atomic.StoreUint32(&done, 1) + corrupted = true + + data0, data1 := dataSplit(data) + data0c0, data0c1 := dataChecksum(data0) + data1c0, data1c1 := dataChecksum(data1) + log.Printf("FATAL: [%v] Corrupted data i=%d t=%s (%#x != %#x): %x(%v) vs %x(%v)", + fi, i, t, checksum0, checksum1, data0, data0c0 == data0c1, data1, data1c0 == data1c1) + return true + } + return false + } + + iter := tr.NewIterator(nil, nil) + defer iter.Release() + for i := 0; iter.Next(); i++ { + ukey, _, kt, kerr := parseIkey(iter.Key()) + if kerr != nil { + atomic.StoreUint32(&fail, 1) + atomic.StoreUint32(&done, 1) + corrupted = true + + log.Printf("FATAL: [%v] Corrupted ikey i=%d: %v", fi, i, kerr) + return + } + if checkData(i, "key", ukey) { + return + } + if kt == ktVal && checkData(i, "value", iter.Value()) { + return + } + } + if err := iter.Error(); err != nil { + if errors.IsCorrupted(err) { + atomic.StoreUint32(&fail, 1) + atomic.StoreUint32(&done, 1) + corrupted = true + + log.Printf("FATAL: [%v] Corruption detected: %v", fi, err) + } else { + log.Fatal(err) + } + } + + return +} + +func main() { + flag.Parse() + + if enableBufferPool { + bpool = util.NewBufferPool(opt.DefaultBlockSize + 128) + } + + log.Printf("Test DB stored at %q", dbPath) + if httpProf != "" { + log.Printf("HTTP pprof listening at %q", httpProf) + runtime.SetBlockProfileRate(1) + go func() { + if err := http.ListenAndServe(httpProf, nil); err != nil { + log.Fatalf("HTTPPROF: %v", err) + } + }() + } + + runtime.GOMAXPROCS(runtime.NumCPU()) + + os.RemoveAll(dbPath) + stor, err := storage.OpenFile(dbPath) + if err != nil { + log.Fatal(err) + } + stor = &testingStorage{stor} + defer stor.Close() + + fatalf := func(err error, format string, v ...interface{}) { + atomic.StoreUint32(&fail, 1) + atomic.StoreUint32(&done, 1) + log.Printf("FATAL: "+format, v...) + if err != nil && errors.IsCorrupted(err) { + cerr := err.(*errors.ErrCorrupted) + if cerr.File != nil && cerr.File.Type == storage.TypeTable { + log.Print("FATAL: corruption detected, scanning...") + if !scanTable(stor.GetFile(cerr.File.Num, cerr.File.Type), false) { + log.Printf("FATAL: unable to find corrupted key/value pair in table %v", cerr.File) + } + } + } + runtime.Goexit() + } + + if openFilesCacheCapacity == 0 { + openFilesCacheCapacity = -1 + } + o := &opt.Options{ + OpenFilesCacheCapacity: openFilesCacheCapacity, + DisableBufferPool: !enableBufferPool, + DisableBlockCache: !enableBlockCache, + ErrorIfExist: true, + Compression: opt.NoCompression, + } + if enableCompression { + o.Compression = opt.DefaultCompression + } + + db, err := leveldb.Open(stor, o) + if err != nil { + log.Fatal(err) + } + defer db.Close() + + var ( + mu = &sync.Mutex{} + gGetStat = &latencyStats{} + gIterStat = &latencyStats{} + gWriteStat = &latencyStats{} + startTime = time.Now() + + writeReq = make(chan *leveldb.Batch) + writeAck = make(chan error) + writeAckAck = make(chan struct{}) + ) + + go func() { + for b := range writeReq { + gWriteStat.start() + err := db.Write(b, nil) + if err == nil { + gWriteStat.record(b.Len()) + } + writeAck <- err + <-writeAckAck + } + }() + + go func() { + for { + time.Sleep(3 * time.Second) + + log.Print("------------------------") + + log.Printf("> Elapsed=%v", time.Now().Sub(startTime)) + mu.Lock() + log.Printf("> GetLatencyMin=%v GetLatencyMax=%v GetLatencyAvg=%v GetRatePerSec=%d", + gGetStat.min, gGetStat.max, gGetStat.avg(), gGetStat.ratePerSec()) + log.Printf("> IterLatencyMin=%v IterLatencyMax=%v IterLatencyAvg=%v IterRatePerSec=%d", + gIterStat.min, gIterStat.max, gIterStat.avg(), gIterStat.ratePerSec()) + log.Printf("> WriteLatencyMin=%v WriteLatencyMax=%v WriteLatencyAvg=%v WriteRatePerSec=%d", + gWriteStat.min, gWriteStat.max, gWriteStat.avg(), gWriteStat.ratePerSec()) + mu.Unlock() + + cachedblock, _ := db.GetProperty("leveldb.cachedblock") + openedtables, _ := db.GetProperty("leveldb.openedtables") + alivesnaps, _ := db.GetProperty("leveldb.alivesnaps") + aliveiters, _ := db.GetProperty("leveldb.aliveiters") + blockpool, _ := db.GetProperty("leveldb.blockpool") + log.Printf("> BlockCache=%s OpenedTables=%s AliveSnaps=%s AliveIter=%s BlockPool=%q", + cachedblock, openedtables, alivesnaps, aliveiters, blockpool) + + log.Print("------------------------") + } + }() + + for ns, numKey := range numKeys { + func(ns, numKey int) { + log.Printf("[%02d] STARTING: numKey=%d", ns, numKey) + + keys := make([][]byte, numKey) + for i := range keys { + keys[i] = randomData(nil, byte(ns), 1, uint32(i)) + } + + wg.Add(1) + go func() { + var wi uint32 + defer func() { + log.Printf("[%02d] WRITER DONE #%d", ns, wi) + wg.Done() + }() + + var ( + b = new(leveldb.Batch) + k2, v2 []byte + nReader int32 + ) + for atomic.LoadUint32(&done) == 0 { + log.Printf("[%02d] WRITER #%d", ns, wi) + + b.Reset() + for _, k1 := range keys { + k2 = randomData(k2, byte(ns), 2, wi) + v2 = randomData(v2, byte(ns), 3, wi) + b.Put(k2, v2) + b.Put(k1, k2) + } + writeReq <- b + if err := <-writeAck; err != nil { + writeAckAck <- struct{}{} + fatalf(err, "[%02d] WRITER #%d db.Write: %v", ns, wi, err) + } + + snap, err := db.GetSnapshot() + if err != nil { + writeAckAck <- struct{}{} + fatalf(err, "[%02d] WRITER #%d db.GetSnapshot: %v", ns, wi, err) + } + + writeAckAck <- struct{}{} + + wg.Add(1) + atomic.AddInt32(&nReader, 1) + go func(snapwi uint32, snap *leveldb.Snapshot) { + var ( + ri int + iterStat = &latencyStats{} + getStat = &latencyStats{} + ) + defer func() { + mu.Lock() + gGetStat.add(getStat) + gIterStat.add(iterStat) + mu.Unlock() + + atomic.AddInt32(&nReader, -1) + log.Printf("[%02d] READER #%d.%d DONE Snap=%v Alive=%d IterLatency=%v GetLatency=%v", ns, snapwi, ri, snap, atomic.LoadInt32(&nReader), iterStat.avg(), getStat.avg()) + snap.Release() + wg.Done() + }() + + stopi := snapwi + 3 + for (ri < 3 || atomic.LoadUint32(&wi) < stopi) && atomic.LoadUint32(&done) == 0 { + var n int + iter := snap.NewIterator(dataPrefixSlice(byte(ns), 1), nil) + iterStat.start() + for iter.Next() { + k1 := iter.Key() + k2 := iter.Value() + iterStat.record(1) + + if dataNS(k2) != byte(ns) { + fatalf(nil, "[%02d] READER #%d.%d K%d invalid in-key NS: want=%d got=%d", ns, snapwi, ri, n, ns, dataNS(k2)) + } + + kwritei := dataI(k2) + if kwritei != snapwi { + fatalf(nil, "[%02d] READER #%d.%d K%d invalid in-key iter num: %d", ns, snapwi, ri, n, kwritei) + } + + getStat.start() + _, err := snap.Get(k2, nil) + if err != nil { + fatalf(err, "[%02d] READER #%d.%d K%d snap.Get: %v\nk1: %x\n -> k2: %x", ns, snapwi, ri, n, err, k1, k2) + } + getStat.record(1) + + n++ + iterStat.start() + } + iter.Release() + if err := iter.Error(); err != nil { + fatalf(err, "[%02d] READER #%d.%d K%d iter.Error: %v", ns, snapwi, ri, numKey, err) + } + if n != numKey { + fatalf(nil, "[%02d] READER #%d.%d missing keys: want=%d got=%d", ns, snapwi, ri, numKey, n) + } + + ri++ + } + }(wi, snap) + + atomic.AddUint32(&wi, 1) + } + }() + + delB := new(leveldb.Batch) + wg.Add(1) + go func() { + var ( + i int + iterStat = &latencyStats{} + ) + defer func() { + log.Printf("[%02d] SCANNER DONE #%d", ns, i) + wg.Done() + }() + + time.Sleep(2 * time.Second) + + for atomic.LoadUint32(&done) == 0 { + var n int + delB.Reset() + iter := db.NewIterator(dataNsSlice(byte(ns)), nil) + iterStat.start() + for iter.Next() && atomic.LoadUint32(&done) == 0 { + k := iter.Key() + v := iter.Value() + iterStat.record(1) + + for ci, x := range [...][]byte{k, v} { + checksum0, checksum1 := dataChecksum(x) + if checksum0 != checksum1 { + if ci == 0 { + fatalf(nil, "[%02d] SCANNER %d.%d invalid key checksum: want %d, got %d\n%x -> %x", ns, i, n, checksum0, checksum1, k, v) + } else { + fatalf(nil, "[%02d] SCANNER %d.%d invalid value checksum: want %d, got %d\n%x -> %x", ns, i, n, checksum0, checksum1, k, v) + } + } + } + + if dataPrefix(k) == 2 || mrand.Int()%999 == 0 { + delB.Delete(k) + } + + n++ + iterStat.start() + } + iter.Release() + if err := iter.Error(); err != nil { + fatalf(err, "[%02d] SCANNER #%d.%d iter.Error: %v", ns, i, n, err) + } + + if n > 0 { + log.Printf("[%02d] SCANNER #%d IterLatency=%v", ns, i, iterStat.avg()) + } + + if delB.Len() > 0 && atomic.LoadUint32(&done) == 0 { + t := time.Now() + writeReq <- delB + if err := <-writeAck; err != nil { + writeAckAck <- struct{}{} + fatalf(err, "[%02d] SCANNER #%d db.Write: %v", ns, i, err) + } else { + writeAckAck <- struct{}{} + } + log.Printf("[%02d] SCANNER #%d Deleted=%d Time=%v", ns, i, delB.Len(), time.Now().Sub(t)) + } + + i++ + } + }() + }(ns, numKey) + } + + go func() { + sig := make(chan os.Signal) + signal.Notify(sig, os.Interrupt, os.Kill) + log.Printf("Got signal: %v, exiting...", <-sig) + atomic.StoreUint32(&done, 1) + }() + + wg.Wait() +} diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/.hgignore b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/.hgignore deleted file mode 100644 index d804706f..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/.hgignore +++ /dev/null @@ -1,30 +0,0 @@ -syntax:glob -.DS_Store -.git -.gitignore -*.[568ao] -*.ao -*.so -*.pyc -._* -.nfs.* -[568a].out -*~ -*.orig -*.rej -*.exe -.*.swp -core -*.cgo*.go -*.cgo*.c -_cgo_* -_obj -_test -_testmain.go -build.out -snappy/testdata -test.out -y.tab.[ch] - -syntax:regexp -^.*/core.[0-9]*$ diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/README b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/README deleted file mode 100644 index 3cf8be1f..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/README +++ /dev/null @@ -1,11 +0,0 @@ -This is a Snappy library for the Go programming language. - -To download and install from source: -$ go get code.google.com/p/snappy-go/snappy - -Unless otherwise noted, the Snappy-Go source files are distributed -under the BSD-style license found in the LICENSE file. - -Contributions should follow the same procedure as for the Go project: -http://golang.org/doc/contribute.html - diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/lib/codereview/codereview.cfg b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/lib/codereview/codereview.cfg deleted file mode 100644 index 93b55c0a..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/lib/codereview/codereview.cfg +++ /dev/null @@ -1 +0,0 @@ -defaultcc: golang-dev@googlegroups.com diff --git a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/decode.go b/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/decode.go deleted file mode 100644 index d93c1b9d..00000000 --- a/src/github.com/smira/aptly/_vendor/src/github.com/syndtr/gosnappy/snappy/decode.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2011 The Snappy-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 snappy - -import ( - "encoding/binary" - "errors" -) - -// ErrCorrupt reports that the input is invalid. -var ErrCorrupt = errors.New("snappy: corrupt input") - -// DecodedLen returns the length of the decoded block. -func DecodedLen(src []byte) (int, error) { - v, _, err := decodedLen(src) - return v, err -} - -// decodedLen returns the length of the decoded block and the number of bytes -// that the length header occupied. -func decodedLen(src []byte) (blockLen, headerLen int, err error) { - v, n := binary.Uvarint(src) - if n == 0 { - return 0, 0, ErrCorrupt - } - if uint64(int(v)) != v { - return 0, 0, errors.New("snappy: decoded block is too large") - } - return int(v), n, nil -} - -// Decode returns the decoded form of src. The returned slice may be a sub- -// slice of dst if dst was large enough to hold the entire decoded block. -// Otherwise, a newly allocated slice will be returned. -// It is valid to pass a nil dst. -func Decode(dst, src []byte) ([]byte, error) { - dLen, s, err := decodedLen(src) - if err != nil { - return nil, err - } - if len(dst) < dLen { - dst = make([]byte, dLen) - } - - var d, offset, length int - for s < len(src) { - switch src[s] & 0x03 { - case tagLiteral: - x := uint(src[s] >> 2) - switch { - case x < 60: - s += 1 - case x == 60: - s += 2 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-1]) - case x == 61: - s += 3 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-2]) | uint(src[s-1])<<8 - case x == 62: - s += 4 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-3]) | uint(src[s-2])<<8 | uint(src[s-1])<<16 - case x == 63: - s += 5 - if s > len(src) { - return nil, ErrCorrupt - } - x = uint(src[s-4]) | uint(src[s-3])<<8 | uint(src[s-2])<<16 | uint(src[s-1])<<24 - } - length = int(x + 1) - if length <= 0 { - return nil, errors.New("snappy: unsupported literal length") - } - if length > len(dst)-d || length > len(src)-s { - return nil, ErrCorrupt - } - copy(dst[d:], src[s:s+length]) - d += length - s += length - continue - - case tagCopy1: - s += 2 - if s > len(src) { - return nil, ErrCorrupt - } - length = 4 + int(src[s-2])>>2&0x7 - offset = int(src[s-2])&0xe0<<3 | int(src[s-1]) - - case tagCopy2: - s += 3 - if s > len(src) { - return nil, ErrCorrupt - } - length = 1 + int(src[s-3])>>2 - offset = int(src[s-2]) | int(src[s-1])<<8 - - case tagCopy4: - return nil, errors.New("snappy: unsupported COPY_4 tag") - } - - end := d + length - if offset > d || end > len(dst) { - return nil, ErrCorrupt - } - for ; d < end; d++ { - dst[d] = dst[d-offset] - } - } - if d != dLen { - return nil, ErrCorrupt - } - return dst[:d], nil -} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/.gitattributes b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/.gitattributes new file mode 100644 index 00000000..d2f212e5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/.gitattributes @@ -0,0 +1,10 @@ +# Treat all files in this repo as binary, with no git magic updating +# line endings. Windows users contributing to Go will need to use a +# modern version of git and editors capable of LF line endings. +# +# We'll prevent accidental CRLF line endings from entering the repo +# via the git-review gofmt checks. +# +# See golang.org/issue/9281 + +* -text diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/.gitignore b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/.gitignore new file mode 100644 index 00000000..8339fd61 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/.gitignore @@ -0,0 +1,2 @@ +# Add no patterns to .hgignore except for files generated by the build. +last-change diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/AUTHORS b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/AUTHORS new file mode 100644 index 00000000..15167cd7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/AUTHORS @@ -0,0 +1,3 @@ +# This source code refers to The Go Authors for copyright purposes. +# The master list of authors is in the main Go distribution, +# visible at http://tip.golang.org/AUTHORS. diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/CONTRIBUTING.md b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/CONTRIBUTING.md new file mode 100644 index 00000000..88dff59b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/CONTRIBUTING.md @@ -0,0 +1,31 @@ +# Contributing to Go + +Go is an open source project. + +It is the work of hundreds of contributors. We appreciate your help! + + +## Filing issues + +When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions: + +1. What version of Go are you using (`go version`)? +2. What operating system and processor architecture are you using? +3. What did you do? +4. What did you expect to see? +5. What did you see instead? + +General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker. +The gophers there will answer or ask you to file an issue if you've tripped over a bug. + +## Contributing code + +Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html) +before sending patches. + +**We do not accept GitHub pull requests** +(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review). + +Unless otherwise noted, the Go source files are distributed under +the BSD-style license found in the LICENSE file. + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/CONTRIBUTORS b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/CONTRIBUTORS new file mode 100644 index 00000000..1c4577e9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/CONTRIBUTORS @@ -0,0 +1,3 @@ +# This source code was written by the Go contributors. +# The master list of contributors is in the main Go distribution, +# visible at http://tip.golang.org/CONTRIBUTORS. diff --git a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/LICENSE b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/LICENSE similarity index 96% rename from src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/LICENSE rename to src/github.com/smira/aptly/_vendor/src/golang.org/x/net/LICENSE index ab6b011a..6a66aea5 100644 --- a/src/github.com/smira/aptly/_vendor/src/code.google.com/p/go-uuid/uuid/LICENSE +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 Google Inc. All rights reserved. +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 diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/PATENTS b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/PATENTS new file mode 100644 index 00000000..73309904 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/PATENTS @@ -0,0 +1,22 @@ +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/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/README b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/README new file mode 100644 index 00000000..6b13d8e5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/README @@ -0,0 +1,3 @@ +This repository holds supplementary Go networking libraries. + +To submit changes to this repository, see http://golang.org/doc/contribute.html. diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/codereview.cfg b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/codereview.cfg new file mode 100644 index 00000000..3f8b14b6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/codereview.cfg @@ -0,0 +1 @@ +issuerepo: golang/go diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/context.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/context.go new file mode 100644 index 00000000..77b64d0c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/context.go @@ -0,0 +1,447 @@ +// 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. + +// Package context defines the Context type, which carries deadlines, +// cancelation signals, and other request-scoped values across API boundaries +// and between processes. +// +// Incoming requests to a server should create a Context, and outgoing calls to +// servers should accept a Context. The chain of function calls between must +// propagate the Context, optionally replacing it with a modified copy created +// using WithDeadline, WithTimeout, WithCancel, or WithValue. +// +// Programs that use Contexts should follow these rules to keep interfaces +// consistent across packages and enable static analysis tools to check context +// propagation: +// +// Do not store Contexts inside a struct type; instead, pass a Context +// explicitly to each function that needs it. The Context should be the first +// parameter, typically named ctx: +// +// func DoSomething(ctx context.Context, arg Arg) error { +// // ... use ctx ... +// } +// +// Do not pass a nil Context, even if a function permits it. Pass context.TODO +// if you are unsure about which Context to use. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +// +// The same Context may be passed to functions running in different goroutines; +// Contexts are safe for simultaneous use by multiple goroutines. +// +// See http://blog.golang.org/context for example code for a server that uses +// Contexts. +package context // import "golang.org/x/net/context" + +import ( + "errors" + "fmt" + "sync" + "time" +) + +// A Context carries a deadline, a cancelation signal, and other values across +// API boundaries. +// +// Context's methods may be called by multiple goroutines simultaneously. +type Context interface { + // Deadline returns the time when work done on behalf of this context + // should be canceled. Deadline returns ok==false when no deadline is + // set. Successive calls to Deadline return the same results. + Deadline() (deadline time.Time, ok bool) + + // Done returns a channel that's closed when work done on behalf of this + // context should be canceled. Done may return nil if this context can + // never be canceled. Successive calls to Done return the same value. + // + // WithCancel arranges for Done to be closed when cancel is called; + // WithDeadline arranges for Done to be closed when the deadline + // expires; WithTimeout arranges for Done to be closed when the timeout + // elapses. + // + // Done is provided for use in select statements: + // + // // Stream generates values with DoSomething and sends them to out + // // until DoSomething returns an error or ctx.Done is closed. + // func Stream(ctx context.Context, out <-chan Value) error { + // for { + // v, err := DoSomething(ctx) + // if err != nil { + // return err + // } + // select { + // case <-ctx.Done(): + // return ctx.Err() + // case out <- v: + // } + // } + // } + // + // See http://blog.golang.org/pipelines for more examples of how to use + // a Done channel for cancelation. + Done() <-chan struct{} + + // Err returns a non-nil error value after Done is closed. Err returns + // Canceled if the context was canceled or DeadlineExceeded if the + // context's deadline passed. No other values for Err are defined. + // After Done is closed, successive calls to Err return the same value. + Err() error + + // Value returns the value associated with this context for key, or nil + // if no value is associated with key. Successive calls to Value with + // the same key returns the same result. + // + // Use context values only for request-scoped data that transits + // processes and API boundaries, not for passing optional parameters to + // functions. + // + // A key identifies a specific value in a Context. Functions that wish + // to store values in Context typically allocate a key in a global + // variable then use that key as the argument to context.WithValue and + // Context.Value. A key can be any type that supports equality; + // packages should define keys as an unexported type to avoid + // collisions. + // + // Packages that define a Context key should provide type-safe accessors + // for the values stores using that key: + // + // // Package user defines a User type that's stored in Contexts. + // package user + // + // import "golang.org/x/net/context" + // + // // User is the type of value stored in the Contexts. + // type User struct {...} + // + // // key is an unexported type for keys defined in this package. + // // This prevents collisions with keys defined in other packages. + // type key int + // + // // userKey is the key for user.User values in Contexts. It is + // // unexported; clients use user.NewContext and user.FromContext + // // instead of using this key directly. + // var userKey key = 0 + // + // // NewContext returns a new Context that carries value u. + // func NewContext(ctx context.Context, u *User) context.Context { + // return context.WithValue(ctx, userKey, u) + // } + // + // // FromContext returns the User value stored in ctx, if any. + // func FromContext(ctx context.Context) (*User, bool) { + // u, ok := ctx.Value(userKey).(*User) + // return u, ok + // } + Value(key interface{}) interface{} +} + +// Canceled is the error returned by Context.Err when the context is canceled. +var Canceled = errors.New("context canceled") + +// DeadlineExceeded is the error returned by Context.Err when the context's +// deadline passes. +var DeadlineExceeded = errors.New("context deadline exceeded") + +// An emptyCtx is never canceled, has no values, and has no deadline. It is not +// struct{}, since vars of this type must have distinct addresses. +type emptyCtx int + +func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { + return +} + +func (*emptyCtx) Done() <-chan struct{} { + return nil +} + +func (*emptyCtx) Err() error { + return nil +} + +func (*emptyCtx) Value(key interface{}) interface{} { + return nil +} + +func (e *emptyCtx) String() string { + switch e { + case background: + return "context.Background" + case todo: + return "context.TODO" + } + return "unknown empty Context" +} + +var ( + background = new(emptyCtx) + todo = new(emptyCtx) +) + +// Background returns a non-nil, empty Context. It is never canceled, has no +// values, and has no deadline. It is typically used by the main function, +// initialization, and tests, and as the top-level Context for incoming +// requests. +func Background() Context { + return background +} + +// TODO returns a non-nil, empty Context. Code should use context.TODO when +// it's unclear which Context to use or it is not yet available (because the +// surrounding function has not yet been extended to accept a Context +// parameter). TODO is recognized by static analysis tools that determine +// whether Contexts are propagated correctly in a program. +func TODO() Context { + return todo +} + +// A CancelFunc tells an operation to abandon its work. +// A CancelFunc does not wait for the work to stop. +// After the first call, subsequent calls to a CancelFunc do nothing. +type CancelFunc func() + +// WithCancel returns a copy of parent with a new Done channel. The returned +// context's Done channel is closed when the returned cancel function is called +// or when the parent context's Done channel is closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { + c := newCancelCtx(parent) + propagateCancel(parent, &c) + return &c, func() { c.cancel(true, Canceled) } +} + +// newCancelCtx returns an initialized cancelCtx. +func newCancelCtx(parent Context) cancelCtx { + return cancelCtx{ + Context: parent, + done: make(chan struct{}), + } +} + +// propagateCancel arranges for child to be canceled when parent is. +func propagateCancel(parent Context, child canceler) { + if parent.Done() == nil { + return // parent is never canceled + } + if p, ok := parentCancelCtx(parent); ok { + p.mu.Lock() + if p.err != nil { + // parent has already been canceled + child.cancel(false, p.err) + } else { + if p.children == nil { + p.children = make(map[canceler]bool) + } + p.children[child] = true + } + p.mu.Unlock() + } else { + go func() { + select { + case <-parent.Done(): + child.cancel(false, parent.Err()) + case <-child.Done(): + } + }() + } +} + +// parentCancelCtx follows a chain of parent references until it finds a +// *cancelCtx. This function understands how each of the concrete types in this +// package represents its parent. +func parentCancelCtx(parent Context) (*cancelCtx, bool) { + for { + switch c := parent.(type) { + case *cancelCtx: + return c, true + case *timerCtx: + return &c.cancelCtx, true + case *valueCtx: + parent = c.Context + default: + return nil, false + } + } +} + +// removeChild removes a context from its parent. +func removeChild(parent Context, child canceler) { + p, ok := parentCancelCtx(parent) + if !ok { + return + } + p.mu.Lock() + if p.children != nil { + delete(p.children, child) + } + p.mu.Unlock() +} + +// A canceler is a context type that can be canceled directly. The +// implementations are *cancelCtx and *timerCtx. +type canceler interface { + cancel(removeFromParent bool, err error) + Done() <-chan struct{} +} + +// A cancelCtx can be canceled. When canceled, it also cancels any children +// that implement canceler. +type cancelCtx struct { + Context + + done chan struct{} // closed by the first cancel call. + + mu sync.Mutex + children map[canceler]bool // set to nil by the first cancel call + err error // set to non-nil by the first cancel call +} + +func (c *cancelCtx) Done() <-chan struct{} { + return c.done +} + +func (c *cancelCtx) Err() error { + c.mu.Lock() + defer c.mu.Unlock() + return c.err +} + +func (c *cancelCtx) String() string { + return fmt.Sprintf("%v.WithCancel", c.Context) +} + +// cancel closes c.done, cancels each of c's children, and, if +// removeFromParent is true, removes c from its parent's children. +func (c *cancelCtx) cancel(removeFromParent bool, err error) { + if err == nil { + panic("context: internal error: missing cancel error") + } + c.mu.Lock() + if c.err != nil { + c.mu.Unlock() + return // already canceled + } + c.err = err + close(c.done) + for child := range c.children { + // NOTE: acquiring the child's lock while holding parent's lock. + child.cancel(false, err) + } + c.children = nil + c.mu.Unlock() + + if removeFromParent { + removeChild(c.Context, c) + } +} + +// WithDeadline returns a copy of the parent context with the deadline adjusted +// to be no later than d. If the parent's deadline is already earlier than d, +// WithDeadline(parent, d) is semantically equivalent to parent. The returned +// context's Done channel is closed when the deadline expires, when the returned +// cancel function is called, or when the parent context's Done channel is +// closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. +func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { + if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { + // The current deadline is already sooner than the new one. + return WithCancel(parent) + } + c := &timerCtx{ + cancelCtx: newCancelCtx(parent), + deadline: deadline, + } + propagateCancel(parent, c) + d := deadline.Sub(time.Now()) + if d <= 0 { + c.cancel(true, DeadlineExceeded) // deadline has already passed + return c, func() { c.cancel(true, Canceled) } + } + c.mu.Lock() + defer c.mu.Unlock() + if c.err == nil { + c.timer = time.AfterFunc(d, func() { + c.cancel(true, DeadlineExceeded) + }) + } + return c, func() { c.cancel(true, Canceled) } +} + +// A timerCtx carries a timer and a deadline. It embeds a cancelCtx to +// implement Done and Err. It implements cancel by stopping its timer then +// delegating to cancelCtx.cancel. +type timerCtx struct { + cancelCtx + timer *time.Timer // Under cancelCtx.mu. + + deadline time.Time +} + +func (c *timerCtx) Deadline() (deadline time.Time, ok bool) { + return c.deadline, true +} + +func (c *timerCtx) String() string { + return fmt.Sprintf("%v.WithDeadline(%s [%s])", c.cancelCtx.Context, c.deadline, c.deadline.Sub(time.Now())) +} + +func (c *timerCtx) cancel(removeFromParent bool, err error) { + c.cancelCtx.cancel(false, err) + if removeFromParent { + // Remove this timerCtx from its parent cancelCtx's children. + removeChild(c.cancelCtx.Context, c) + } + c.mu.Lock() + if c.timer != nil { + c.timer.Stop() + c.timer = nil + } + c.mu.Unlock() +} + +// WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete: +// +// func slowOperationWithTimeout(ctx context.Context) (Result, error) { +// ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) +// defer cancel() // releases resources if slowOperation completes before timeout elapses +// return slowOperation(ctx) +// } +func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { + return WithDeadline(parent, time.Now().Add(timeout)) +} + +// WithValue returns a copy of parent in which the value associated with key is +// val. +// +// Use context Values only for request-scoped data that transits processes and +// APIs, not for passing optional parameters to functions. +func WithValue(parent Context, key interface{}, val interface{}) Context { + return &valueCtx{parent, key, val} +} + +// A valueCtx carries a key-value pair. It implements Value for that key and +// delegates all other calls to the embedded Context. +type valueCtx struct { + Context + key, val interface{} +} + +func (c *valueCtx) String() string { + return fmt.Sprintf("%v.WithValue(%#v, %#v)", c.Context, c.key, c.val) +} + +func (c *valueCtx) Value(key interface{}) interface{} { + if c.key == key { + return c.val + } + return c.Context.Value(key) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/context_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/context_test.go new file mode 100644 index 00000000..05345fc5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/context_test.go @@ -0,0 +1,575 @@ +// 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. + +package context + +import ( + "fmt" + "math/rand" + "runtime" + "strings" + "sync" + "testing" + "time" +) + +// otherContext is a Context that's not one of the types defined in context.go. +// This lets us test code paths that differ based on the underlying type of the +// Context. +type otherContext struct { + Context +} + +func TestBackground(t *testing.T) { + c := Background() + if c == nil { + t.Fatalf("Background returned nil") + } + select { + case x := <-c.Done(): + t.Errorf("<-c.Done() == %v want nothing (it should block)", x) + default: + } + if got, want := fmt.Sprint(c), "context.Background"; got != want { + t.Errorf("Background().String() = %q want %q", got, want) + } +} + +func TestTODO(t *testing.T) { + c := TODO() + if c == nil { + t.Fatalf("TODO returned nil") + } + select { + case x := <-c.Done(): + t.Errorf("<-c.Done() == %v want nothing (it should block)", x) + default: + } + if got, want := fmt.Sprint(c), "context.TODO"; got != want { + t.Errorf("TODO().String() = %q want %q", got, want) + } +} + +func TestWithCancel(t *testing.T) { + c1, cancel := WithCancel(Background()) + + if got, want := fmt.Sprint(c1), "context.Background.WithCancel"; got != want { + t.Errorf("c1.String() = %q want %q", got, want) + } + + o := otherContext{c1} + c2, _ := WithCancel(o) + contexts := []Context{c1, o, c2} + + for i, c := range contexts { + if d := c.Done(); d == nil { + t.Errorf("c[%d].Done() == %v want non-nil", i, d) + } + if e := c.Err(); e != nil { + t.Errorf("c[%d].Err() == %v want nil", i, e) + } + + select { + case x := <-c.Done(): + t.Errorf("<-c.Done() == %v want nothing (it should block)", x) + default: + } + } + + cancel() + time.Sleep(100 * time.Millisecond) // let cancelation propagate + + for i, c := range contexts { + select { + case <-c.Done(): + default: + t.Errorf("<-c[%d].Done() blocked, but shouldn't have", i) + } + if e := c.Err(); e != Canceled { + t.Errorf("c[%d].Err() == %v want %v", i, e, Canceled) + } + } +} + +func TestParentFinishesChild(t *testing.T) { + // Context tree: + // parent -> cancelChild + // parent -> valueChild -> timerChild + parent, cancel := WithCancel(Background()) + cancelChild, stop := WithCancel(parent) + defer stop() + valueChild := WithValue(parent, "key", "value") + timerChild, stop := WithTimeout(valueChild, 10000*time.Hour) + defer stop() + + select { + case x := <-parent.Done(): + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x) + case x := <-cancelChild.Done(): + t.Errorf("<-cancelChild.Done() == %v want nothing (it should block)", x) + case x := <-timerChild.Done(): + t.Errorf("<-timerChild.Done() == %v want nothing (it should block)", x) + case x := <-valueChild.Done(): + t.Errorf("<-valueChild.Done() == %v want nothing (it should block)", x) + default: + } + + // The parent's children should contain the two cancelable children. + pc := parent.(*cancelCtx) + cc := cancelChild.(*cancelCtx) + tc := timerChild.(*timerCtx) + pc.mu.Lock() + if len(pc.children) != 2 || !pc.children[cc] || !pc.children[tc] { + t.Errorf("bad linkage: pc.children = %v, want %v and %v", + pc.children, cc, tc) + } + pc.mu.Unlock() + + if p, ok := parentCancelCtx(cc.Context); !ok || p != pc { + t.Errorf("bad linkage: parentCancelCtx(cancelChild.Context) = %v, %v want %v, true", p, ok, pc) + } + if p, ok := parentCancelCtx(tc.Context); !ok || p != pc { + t.Errorf("bad linkage: parentCancelCtx(timerChild.Context) = %v, %v want %v, true", p, ok, pc) + } + + cancel() + + pc.mu.Lock() + if len(pc.children) != 0 { + t.Errorf("pc.cancel didn't clear pc.children = %v", pc.children) + } + pc.mu.Unlock() + + // parent and children should all be finished. + check := func(ctx Context, name string) { + select { + case <-ctx.Done(): + default: + t.Errorf("<-%s.Done() blocked, but shouldn't have", name) + } + if e := ctx.Err(); e != Canceled { + t.Errorf("%s.Err() == %v want %v", name, e, Canceled) + } + } + check(parent, "parent") + check(cancelChild, "cancelChild") + check(valueChild, "valueChild") + check(timerChild, "timerChild") + + // WithCancel should return a canceled context on a canceled parent. + precanceledChild := WithValue(parent, "key", "value") + select { + case <-precanceledChild.Done(): + default: + t.Errorf("<-precanceledChild.Done() blocked, but shouldn't have") + } + if e := precanceledChild.Err(); e != Canceled { + t.Errorf("precanceledChild.Err() == %v want %v", e, Canceled) + } +} + +func TestChildFinishesFirst(t *testing.T) { + cancelable, stop := WithCancel(Background()) + defer stop() + for _, parent := range []Context{Background(), cancelable} { + child, cancel := WithCancel(parent) + + select { + case x := <-parent.Done(): + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x) + case x := <-child.Done(): + t.Errorf("<-child.Done() == %v want nothing (it should block)", x) + default: + } + + cc := child.(*cancelCtx) + pc, pcok := parent.(*cancelCtx) // pcok == false when parent == Background() + if p, ok := parentCancelCtx(cc.Context); ok != pcok || (ok && pc != p) { + t.Errorf("bad linkage: parentCancelCtx(cc.Context) = %v, %v want %v, %v", p, ok, pc, pcok) + } + + if pcok { + pc.mu.Lock() + if len(pc.children) != 1 || !pc.children[cc] { + t.Errorf("bad linkage: pc.children = %v, cc = %v", pc.children, cc) + } + pc.mu.Unlock() + } + + cancel() + + if pcok { + pc.mu.Lock() + if len(pc.children) != 0 { + t.Errorf("child's cancel didn't remove self from pc.children = %v", pc.children) + } + pc.mu.Unlock() + } + + // child should be finished. + select { + case <-child.Done(): + default: + t.Errorf("<-child.Done() blocked, but shouldn't have") + } + if e := child.Err(); e != Canceled { + t.Errorf("child.Err() == %v want %v", e, Canceled) + } + + // parent should not be finished. + select { + case x := <-parent.Done(): + t.Errorf("<-parent.Done() == %v want nothing (it should block)", x) + default: + } + if e := parent.Err(); e != nil { + t.Errorf("parent.Err() == %v want nil", e) + } + } +} + +func testDeadline(c Context, wait time.Duration, t *testing.T) { + select { + case <-time.After(wait): + t.Fatalf("context should have timed out") + case <-c.Done(): + } + if e := c.Err(); e != DeadlineExceeded { + t.Errorf("c.Err() == %v want %v", e, DeadlineExceeded) + } +} + +func TestDeadline(t *testing.T) { + c, _ := WithDeadline(Background(), time.Now().Add(100*time.Millisecond)) + if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { + t.Errorf("c.String() = %q want prefix %q", got, prefix) + } + testDeadline(c, 200*time.Millisecond, t) + + c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond)) + o := otherContext{c} + testDeadline(o, 200*time.Millisecond, t) + + c, _ = WithDeadline(Background(), time.Now().Add(100*time.Millisecond)) + o = otherContext{c} + c, _ = WithDeadline(o, time.Now().Add(300*time.Millisecond)) + testDeadline(c, 200*time.Millisecond, t) +} + +func TestTimeout(t *testing.T) { + c, _ := WithTimeout(Background(), 100*time.Millisecond) + if got, prefix := fmt.Sprint(c), "context.Background.WithDeadline("; !strings.HasPrefix(got, prefix) { + t.Errorf("c.String() = %q want prefix %q", got, prefix) + } + testDeadline(c, 200*time.Millisecond, t) + + c, _ = WithTimeout(Background(), 100*time.Millisecond) + o := otherContext{c} + testDeadline(o, 200*time.Millisecond, t) + + c, _ = WithTimeout(Background(), 100*time.Millisecond) + o = otherContext{c} + c, _ = WithTimeout(o, 300*time.Millisecond) + testDeadline(c, 200*time.Millisecond, t) +} + +func TestCanceledTimeout(t *testing.T) { + c, _ := WithTimeout(Background(), 200*time.Millisecond) + o := otherContext{c} + c, cancel := WithTimeout(o, 400*time.Millisecond) + cancel() + time.Sleep(100 * time.Millisecond) // let cancelation propagate + select { + case <-c.Done(): + default: + t.Errorf("<-c.Done() blocked, but shouldn't have") + } + if e := c.Err(); e != Canceled { + t.Errorf("c.Err() == %v want %v", e, Canceled) + } +} + +type key1 int +type key2 int + +var k1 = key1(1) +var k2 = key2(1) // same int as k1, different type +var k3 = key2(3) // same type as k2, different int + +func TestValues(t *testing.T) { + check := func(c Context, nm, v1, v2, v3 string) { + if v, ok := c.Value(k1).(string); ok == (len(v1) == 0) || v != v1 { + t.Errorf(`%s.Value(k1).(string) = %q, %t want %q, %t`, nm, v, ok, v1, len(v1) != 0) + } + if v, ok := c.Value(k2).(string); ok == (len(v2) == 0) || v != v2 { + t.Errorf(`%s.Value(k2).(string) = %q, %t want %q, %t`, nm, v, ok, v2, len(v2) != 0) + } + if v, ok := c.Value(k3).(string); ok == (len(v3) == 0) || v != v3 { + t.Errorf(`%s.Value(k3).(string) = %q, %t want %q, %t`, nm, v, ok, v3, len(v3) != 0) + } + } + + c0 := Background() + check(c0, "c0", "", "", "") + + c1 := WithValue(Background(), k1, "c1k1") + check(c1, "c1", "c1k1", "", "") + + if got, want := fmt.Sprint(c1), `context.Background.WithValue(1, "c1k1")`; got != want { + t.Errorf("c.String() = %q want %q", got, want) + } + + c2 := WithValue(c1, k2, "c2k2") + check(c2, "c2", "c1k1", "c2k2", "") + + c3 := WithValue(c2, k3, "c3k3") + check(c3, "c2", "c1k1", "c2k2", "c3k3") + + c4 := WithValue(c3, k1, nil) + check(c4, "c4", "", "c2k2", "c3k3") + + o0 := otherContext{Background()} + check(o0, "o0", "", "", "") + + o1 := otherContext{WithValue(Background(), k1, "c1k1")} + check(o1, "o1", "c1k1", "", "") + + o2 := WithValue(o1, k2, "o2k2") + check(o2, "o2", "c1k1", "o2k2", "") + + o3 := otherContext{c4} + check(o3, "o3", "", "c2k2", "c3k3") + + o4 := WithValue(o3, k3, nil) + check(o4, "o4", "", "c2k2", "") +} + +func TestAllocs(t *testing.T) { + bg := Background() + for _, test := range []struct { + desc string + f func() + limit float64 + gccgoLimit float64 + }{ + { + desc: "Background()", + f: func() { Background() }, + limit: 0, + gccgoLimit: 0, + }, + { + desc: fmt.Sprintf("WithValue(bg, %v, nil)", k1), + f: func() { + c := WithValue(bg, k1, nil) + c.Value(k1) + }, + limit: 3, + gccgoLimit: 3, + }, + { + desc: "WithTimeout(bg, 15*time.Millisecond)", + f: func() { + c, _ := WithTimeout(bg, 15*time.Millisecond) + <-c.Done() + }, + limit: 8, + gccgoLimit: 15, + }, + { + desc: "WithCancel(bg)", + f: func() { + c, cancel := WithCancel(bg) + cancel() + <-c.Done() + }, + limit: 5, + gccgoLimit: 8, + }, + { + desc: "WithTimeout(bg, 100*time.Millisecond)", + f: func() { + c, cancel := WithTimeout(bg, 100*time.Millisecond) + cancel() + <-c.Done() + }, + limit: 8, + gccgoLimit: 25, + }, + } { + limit := test.limit + if runtime.Compiler == "gccgo" { + // gccgo does not yet do escape analysis. + // TOOD(iant): Remove this when gccgo does do escape analysis. + limit = test.gccgoLimit + } + if n := testing.AllocsPerRun(100, test.f); n > limit { + t.Errorf("%s allocs = %f want %d", test.desc, n, int(limit)) + } + } +} + +func TestSimultaneousCancels(t *testing.T) { + root, cancel := WithCancel(Background()) + m := map[Context]CancelFunc{root: cancel} + q := []Context{root} + // Create a tree of contexts. + for len(q) != 0 && len(m) < 100 { + parent := q[0] + q = q[1:] + for i := 0; i < 4; i++ { + ctx, cancel := WithCancel(parent) + m[ctx] = cancel + q = append(q, ctx) + } + } + // Start all the cancels in a random order. + var wg sync.WaitGroup + wg.Add(len(m)) + for _, cancel := range m { + go func(cancel CancelFunc) { + cancel() + wg.Done() + }(cancel) + } + // Wait on all the contexts in a random order. + for ctx := range m { + select { + case <-ctx.Done(): + case <-time.After(1 * time.Second): + buf := make([]byte, 10<<10) + n := runtime.Stack(buf, true) + t.Fatalf("timed out waiting for <-ctx.Done(); stacks:\n%s", buf[:n]) + } + } + // Wait for all the cancel functions to return. + done := make(chan struct{}) + go func() { + wg.Wait() + close(done) + }() + select { + case <-done: + case <-time.After(1 * time.Second): + buf := make([]byte, 10<<10) + n := runtime.Stack(buf, true) + t.Fatalf("timed out waiting for cancel functions; stacks:\n%s", buf[:n]) + } +} + +func TestInterlockedCancels(t *testing.T) { + parent, cancelParent := WithCancel(Background()) + child, cancelChild := WithCancel(parent) + go func() { + parent.Done() + cancelChild() + }() + cancelParent() + select { + case <-child.Done(): + case <-time.After(1 * time.Second): + buf := make([]byte, 10<<10) + n := runtime.Stack(buf, true) + t.Fatalf("timed out waiting for child.Done(); stacks:\n%s", buf[:n]) + } +} + +func TestLayersCancel(t *testing.T) { + testLayers(t, time.Now().UnixNano(), false) +} + +func TestLayersTimeout(t *testing.T) { + testLayers(t, time.Now().UnixNano(), true) +} + +func testLayers(t *testing.T, seed int64, testTimeout bool) { + rand.Seed(seed) + errorf := func(format string, a ...interface{}) { + t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...) + } + const ( + timeout = 200 * time.Millisecond + minLayers = 30 + ) + type value int + var ( + vals []*value + cancels []CancelFunc + numTimers int + ctx = Background() + ) + for i := 0; i < minLayers || numTimers == 0 || len(cancels) == 0 || len(vals) == 0; i++ { + switch rand.Intn(3) { + case 0: + v := new(value) + ctx = WithValue(ctx, v, v) + vals = append(vals, v) + case 1: + var cancel CancelFunc + ctx, cancel = WithCancel(ctx) + cancels = append(cancels, cancel) + case 2: + var cancel CancelFunc + ctx, cancel = WithTimeout(ctx, timeout) + cancels = append(cancels, cancel) + numTimers++ + } + } + checkValues := func(when string) { + for _, key := range vals { + if val := ctx.Value(key).(*value); key != val { + errorf("%s: ctx.Value(%p) = %p want %p", when, key, val, key) + } + } + } + select { + case <-ctx.Done(): + errorf("ctx should not be canceled yet") + default: + } + if s, prefix := fmt.Sprint(ctx), "context.Background."; !strings.HasPrefix(s, prefix) { + t.Errorf("ctx.String() = %q want prefix %q", s, prefix) + } + t.Log(ctx) + checkValues("before cancel") + if testTimeout { + select { + case <-ctx.Done(): + case <-time.After(timeout + 100*time.Millisecond): + errorf("ctx should have timed out") + } + checkValues("after timeout") + } else { + cancel := cancels[rand.Intn(len(cancels))] + cancel() + select { + case <-ctx.Done(): + default: + errorf("ctx should be canceled") + } + checkValues("after cancel") + } +} + +func TestCancelRemoves(t *testing.T) { + checkChildren := func(when string, ctx Context, want int) { + if got := len(ctx.(*cancelCtx).children); got != want { + t.Errorf("%s: context has %d children, want %d", when, got, want) + } + } + + ctx, _ := WithCancel(Background()) + checkChildren("after creation", ctx, 0) + _, cancel := WithCancel(ctx) + checkChildren("with WithCancel child ", ctx, 1) + cancel() + checkChildren("after cancelling WithCancel child", ctx, 0) + + ctx, _ = WithCancel(Background()) + checkChildren("after creation", ctx, 0) + _, cancel = WithTimeout(ctx, 60*time.Minute) + checkChildren("with WithTimeout child ", ctx, 1) + cancel() + checkChildren("after cancelling WithTimeout child", ctx, 0) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/cancelreq.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/cancelreq.go new file mode 100644 index 00000000..e3170e33 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/cancelreq.go @@ -0,0 +1,19 @@ +// 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 go1.5 + +package ctxhttp + +import "net/http" + +func canceler(client *http.Client, req *http.Request) func() { + // TODO(djd): Respect any existing value of req.Cancel. + ch := make(chan struct{}) + req.Cancel = ch + + return func() { + close(ch) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go new file mode 100644 index 00000000..56bcbadb --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go @@ -0,0 +1,23 @@ +// 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 !go1.5 + +package ctxhttp + +import "net/http" + +type requestCanceler interface { + CancelRequest(*http.Request) +} + +func canceler(client *http.Client, req *http.Request) func() { + rc, ok := client.Transport.(requestCanceler) + if !ok { + return func() {} + } + return func() { + rc.CancelRequest(req) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/ctxhttp.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/ctxhttp.go new file mode 100644 index 00000000..62620d4e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/ctxhttp.go @@ -0,0 +1,140 @@ +// 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 ctxhttp provides helper functions for performing context-aware HTTP requests. +package ctxhttp // import "golang.org/x/net/context/ctxhttp" + +import ( + "io" + "net/http" + "net/url" + "strings" + + "golang.org/x/net/context" +) + +func nop() {} + +var ( + testHookContextDoneBeforeHeaders = nop + testHookDoReturned = nop + testHookDidBodyClose = nop +) + +// Do sends an HTTP request with the provided http.Client and returns an HTTP response. +// If the client is nil, http.DefaultClient is used. +// If the context is canceled or times out, ctx.Err() will be returned. +func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + if client == nil { + client = http.DefaultClient + } + + // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. + cancel := canceler(client, req) + + type responseAndError struct { + resp *http.Response + err error + } + result := make(chan responseAndError, 1) + + go func() { + resp, err := client.Do(req) + testHookDoReturned() + result <- responseAndError{resp, err} + }() + + var resp *http.Response + + select { + case <-ctx.Done(): + testHookContextDoneBeforeHeaders() + cancel() + // Clean up after the goroutine calling client.Do: + go func() { + if r := <-result; r.resp != nil { + testHookDidBodyClose() + r.resp.Body.Close() + } + }() + return nil, ctx.Err() + case r := <-result: + var err error + resp, err = r.resp, r.err + if err != nil { + return resp, err + } + } + + c := make(chan struct{}) + go func() { + select { + case <-ctx.Done(): + cancel() + case <-c: + // The response's Body is closed. + } + }() + resp.Body = ¬ifyingReader{resp.Body, c} + + return resp, nil +} + +// Get issues a GET request via the Do function. +func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Head issues a HEAD request via the Do function. +func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("HEAD", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Post issues a POST request via the Do function. +func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { + req, err := http.NewRequest("POST", url, body) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", bodyType) + return Do(ctx, client, req) +} + +// PostForm issues a POST request via the Do function. +func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { + return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) +} + +// notifyingReader is an io.ReadCloser that closes the notify channel after +// Close is called or a Read fails on the underlying ReadCloser. +type notifyingReader struct { + io.ReadCloser + notify chan<- struct{} +} + +func (r *notifyingReader) Read(p []byte) (int, error) { + n, err := r.ReadCloser.Read(p) + if err != nil && r.notify != nil { + close(r.notify) + r.notify = nil + } + return n, err +} + +func (r *notifyingReader) Close() error { + err := r.ReadCloser.Close() + if r.notify != nil { + close(r.notify) + r.notify = nil + } + return err +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go new file mode 100644 index 00000000..77c25ba7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go @@ -0,0 +1,176 @@ +// 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 !plan9 + +package ctxhttp + +import ( + "io/ioutil" + "net" + "net/http" + "net/http/httptest" + "sync" + "testing" + "time" + + "golang.org/x/net/context" +) + +const ( + requestDuration = 100 * time.Millisecond + requestBody = "ok" +) + +func TestNoTimeout(t *testing.T) { + ctx := context.Background() + resp, err := doRequest(ctx) + + if resp == nil || err != nil { + t.Fatalf("error received from client: %v %v", err, resp) + } +} + +func TestCancel(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + go func() { + time.Sleep(requestDuration / 2) + cancel() + }() + + resp, err := doRequest(ctx) + + if resp != nil || err == nil { + t.Fatalf("expected error, didn't get one. resp: %v", resp) + } + if err != ctx.Err() { + t.Fatalf("expected error from context but got: %v", err) + } +} + +func TestCancelAfterRequest(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + + resp, err := doRequest(ctx) + + // Cancel before reading the body. + // Request.Body should still be readable after the context is canceled. + cancel() + + b, err := ioutil.ReadAll(resp.Body) + if err != nil || string(b) != requestBody { + t.Fatalf("could not read body: %q %v", b, err) + } +} + +func TestCancelAfterHangingRequest(t *testing.T) { + handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.(http.Flusher).Flush() + <-w.(http.CloseNotifier).CloseNotify() + }) + + serv := httptest.NewServer(handler) + defer serv.Close() + + ctx, cancel := context.WithCancel(context.Background()) + resp, err := Get(ctx, nil, serv.URL) + if err != nil { + t.Fatalf("unexpected error in Get: %v", err) + } + + // Cancel befer reading the body. + // Reading Request.Body should fail, since the request was + // canceled before anything was written. + cancel() + + done := make(chan struct{}) + + go func() { + b, err := ioutil.ReadAll(resp.Body) + if len(b) != 0 || err == nil { + t.Errorf(`Read got (%q, %v); want ("", error)`, b, err) + } + close(done) + }() + + select { + case <-time.After(1 * time.Second): + t.Errorf("Test timed out") + case <-done: + } +} + +func doRequest(ctx context.Context) (*http.Response, error) { + var okHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + time.Sleep(requestDuration) + w.Write([]byte(requestBody)) + }) + + serv := httptest.NewServer(okHandler) + defer serv.Close() + + return Get(ctx, nil, serv.URL) +} + +// golang.org/issue/14065 +func TestClosesResponseBodyOnCancel(t *testing.T) { + defer func() { testHookContextDoneBeforeHeaders = nop }() + defer func() { testHookDoReturned = nop }() + defer func() { testHookDidBodyClose = nop }() + + ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) + defer ts.Close() + + ctx, cancel := context.WithCancel(context.Background()) + + // closed when Do enters select case <-ctx.Done() + enteredDonePath := make(chan struct{}) + + testHookContextDoneBeforeHeaders = func() { + close(enteredDonePath) + } + + testHookDoReturned = func() { + // We now have the result (the Flush'd headers) at least, + // so we can cancel the request. + cancel() + + // But block the client.Do goroutine from sending + // until Do enters into the <-ctx.Done() path, since + // otherwise if both channels are readable, select + // picks a random one. + <-enteredDonePath + } + + sawBodyClose := make(chan struct{}) + testHookDidBodyClose = func() { close(sawBodyClose) } + + tr := &http.Transport{} + defer tr.CloseIdleConnections() + c := &http.Client{Transport: tr} + req, _ := http.NewRequest("GET", ts.URL, nil) + _, doErr := Do(ctx, c, req) + + select { + case <-sawBodyClose: + case <-time.After(5 * time.Second): + t.Fatal("timeout waiting for body to close") + } + + if doErr != ctx.Err() { + t.Errorf("Do error = %v; want %v", doErr, ctx.Err()) + } +} + +type noteCloseConn struct { + net.Conn + onceClose sync.Once + closefn func() +} + +func (c *noteCloseConn) Close() error { + c.onceClose.Do(c.closefn) + return c.Conn.Close() +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/withtimeout_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/withtimeout_test.go new file mode 100644 index 00000000..a6754dc3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/context/withtimeout_test.go @@ -0,0 +1,26 @@ +// 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. + +package context_test + +import ( + "fmt" + "time" + + "golang.org/x/net/context" +) + +func ExampleWithTimeout() { + // Pass a context with a timeout to tell a blocking function that it + // should abandon its work after the timeout elapses. + ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) + select { + case <-time.After(200 * time.Millisecond): + fmt.Println("overslept") + case <-ctx.Done(): + fmt.Println(ctx.Err()) // prints "context deadline exceeded" + } + // Output: + // context deadline exceeded +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/dict/dict.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/dict/dict.go new file mode 100644 index 00000000..58fef89e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/dict/dict.go @@ -0,0 +1,210 @@ +// 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 dict implements the Dictionary Server Protocol +// as defined in RFC 2229. +package dict // import "golang.org/x/net/dict" + +import ( + "net/textproto" + "strconv" + "strings" +) + +// A Client represents a client connection to a dictionary server. +type Client struct { + text *textproto.Conn +} + +// Dial returns a new client connected to a dictionary server at +// addr on the given network. +func Dial(network, addr string) (*Client, error) { + text, err := textproto.Dial(network, addr) + if err != nil { + return nil, err + } + _, _, err = text.ReadCodeLine(220) + if err != nil { + text.Close() + return nil, err + } + return &Client{text: text}, nil +} + +// Close closes the connection to the dictionary server. +func (c *Client) Close() error { + return c.text.Close() +} + +// A Dict represents a dictionary available on the server. +type Dict struct { + Name string // short name of dictionary + Desc string // long description +} + +// Dicts returns a list of the dictionaries available on the server. +func (c *Client) Dicts() ([]Dict, error) { + id, err := c.text.Cmd("SHOW DB") + if err != nil { + return nil, err + } + + c.text.StartResponse(id) + defer c.text.EndResponse(id) + + _, _, err = c.text.ReadCodeLine(110) + if err != nil { + return nil, err + } + lines, err := c.text.ReadDotLines() + if err != nil { + return nil, err + } + _, _, err = c.text.ReadCodeLine(250) + + dicts := make([]Dict, len(lines)) + for i := range dicts { + d := &dicts[i] + a, _ := fields(lines[i]) + if len(a) < 2 { + return nil, textproto.ProtocolError("invalid dictionary: " + lines[i]) + } + d.Name = a[0] + d.Desc = a[1] + } + return dicts, err +} + +// A Defn represents a definition. +type Defn struct { + Dict Dict // Dict where definition was found + Word string // Word being defined + Text []byte // Definition text, typically multiple lines +} + +// Define requests the definition of the given word. +// The argument dict names the dictionary to use, +// the Name field of a Dict returned by Dicts. +// +// The special dictionary name "*" means to look in all the +// server's dictionaries. +// The special dictionary name "!" means to look in all the +// server's dictionaries in turn, stopping after finding the word +// in one of them. +func (c *Client) Define(dict, word string) ([]*Defn, error) { + id, err := c.text.Cmd("DEFINE %s %q", dict, word) + if err != nil { + return nil, err + } + + c.text.StartResponse(id) + defer c.text.EndResponse(id) + + _, line, err := c.text.ReadCodeLine(150) + if err != nil { + return nil, err + } + a, _ := fields(line) + if len(a) < 1 { + return nil, textproto.ProtocolError("malformed response: " + line) + } + n, err := strconv.Atoi(a[0]) + if err != nil { + return nil, textproto.ProtocolError("invalid definition count: " + a[0]) + } + def := make([]*Defn, n) + for i := 0; i < n; i++ { + _, line, err = c.text.ReadCodeLine(151) + if err != nil { + return nil, err + } + a, _ := fields(line) + if len(a) < 3 { + // skip it, to keep protocol in sync + i-- + n-- + def = def[0:n] + continue + } + d := &Defn{Word: a[0], Dict: Dict{a[1], a[2]}} + d.Text, err = c.text.ReadDotBytes() + if err != nil { + return nil, err + } + def[i] = d + } + _, _, err = c.text.ReadCodeLine(250) + return def, err +} + +// Fields returns the fields in s. +// Fields are space separated unquoted words +// or quoted with single or double quote. +func fields(s string) ([]string, error) { + var v []string + i := 0 + for { + for i < len(s) && (s[i] == ' ' || s[i] == '\t') { + i++ + } + if i >= len(s) { + break + } + if s[i] == '"' || s[i] == '\'' { + q := s[i] + // quoted string + var j int + for j = i + 1; ; j++ { + if j >= len(s) { + return nil, textproto.ProtocolError("malformed quoted string") + } + if s[j] == '\\' { + j++ + continue + } + if s[j] == q { + j++ + break + } + } + v = append(v, unquote(s[i+1:j-1])) + i = j + } else { + // atom + var j int + for j = i; j < len(s); j++ { + if s[j] == ' ' || s[j] == '\t' || s[j] == '\\' || s[j] == '"' || s[j] == '\'' { + break + } + } + v = append(v, s[i:j]) + i = j + } + if i < len(s) { + c := s[i] + if c != ' ' && c != '\t' { + return nil, textproto.ProtocolError("quotes not on word boundaries") + } + } + } + return v, nil +} + +func unquote(s string) string { + if strings.Index(s, "\\") < 0 { + return s + } + b := []byte(s) + w := 0 + for r := 0; r < len(b); r++ { + c := b[r] + if c == '\\' { + r++ + c = b[r] + } + b[w] = c + w++ + } + return string(b[0:w]) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/atom.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/atom.go new file mode 100644 index 00000000..cd0a8ac1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/atom.go @@ -0,0 +1,78 @@ +// 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 atom provides integer codes (also known as atoms) for a fixed set of +// frequently occurring HTML strings: tag names and attribute keys such as "p" +// and "id". +// +// Sharing an atom's name between all elements with the same tag can result in +// fewer string allocations when tokenizing and parsing HTML. Integer +// comparisons are also generally faster than string comparisons. +// +// The value of an atom's particular code is not guaranteed to stay the same +// between versions of this package. Neither is any ordering guaranteed: +// whether atom.H1 < atom.H2 may also change. The codes are not guaranteed to +// be dense. The only guarantees are that e.g. looking up "div" will yield +// atom.Div, calling atom.Div.String will return "div", and atom.Div != 0. +package atom // import "golang.org/x/net/html/atom" + +// Atom is an integer code for a string. The zero value maps to "". +type Atom uint32 + +// String returns the atom's name. +func (a Atom) String() string { + start := uint32(a >> 8) + n := uint32(a & 0xff) + if start+n > uint32(len(atomText)) { + return "" + } + return atomText[start : start+n] +} + +func (a Atom) string() string { + return atomText[a>>8 : a>>8+a&0xff] +} + +// fnv computes the FNV hash with an arbitrary starting value h. +func fnv(h uint32, s []byte) uint32 { + for i := range s { + h ^= uint32(s[i]) + h *= 16777619 + } + return h +} + +func match(s string, t []byte) bool { + for i, c := range t { + if s[i] != c { + return false + } + } + return true +} + +// Lookup returns the atom whose name is s. It returns zero if there is no +// such atom. The lookup is case sensitive. +func Lookup(s []byte) Atom { + if len(s) == 0 || len(s) > maxAtomLen { + return 0 + } + h := fnv(hash0, s) + if a := table[h&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { + return a + } + if a := table[(h>>16)&uint32(len(table)-1)]; int(a&0xff) == len(s) && match(a.string(), s) { + return a + } + return 0 +} + +// String returns a string whose contents are equal to s. In that sense, it is +// equivalent to string(s) but may be more efficient. +func String(s []byte) string { + if a := Lookup(s); a != 0 { + return a.String() + } + return string(s) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/atom_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/atom_test.go new file mode 100644 index 00000000..6e33704d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/atom_test.go @@ -0,0 +1,109 @@ +// 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 atom + +import ( + "sort" + "testing" +) + +func TestKnown(t *testing.T) { + for _, s := range testAtomList { + if atom := Lookup([]byte(s)); atom.String() != s { + t.Errorf("Lookup(%q) = %#x (%q)", s, uint32(atom), atom.String()) + } + } +} + +func TestHits(t *testing.T) { + for _, a := range table { + if a == 0 { + continue + } + got := Lookup([]byte(a.String())) + if got != a { + t.Errorf("Lookup(%q) = %#x, want %#x", a.String(), uint32(got), uint32(a)) + } + } +} + +func TestMisses(t *testing.T) { + testCases := []string{ + "", + "\x00", + "\xff", + "A", + "DIV", + "Div", + "dIV", + "aa", + "a\x00", + "ab", + "abb", + "abbr0", + "abbr ", + " abbr", + " a", + "acceptcharset", + "acceptCharset", + "accept_charset", + "h0", + "h1h2", + "h7", + "onClick", + "λ", + // The following string has the same hash (0xa1d7fab7) as "onmouseover". + "\x00\x00\x00\x00\x00\x50\x18\xae\x38\xd0\xb7", + } + for _, tc := range testCases { + got := Lookup([]byte(tc)) + if got != 0 { + t.Errorf("Lookup(%q): got %d, want 0", tc, got) + } + } +} + +func TestForeignObject(t *testing.T) { + const ( + afo = Foreignobject + afO = ForeignObject + sfo = "foreignobject" + sfO = "foreignObject" + ) + if got := Lookup([]byte(sfo)); got != afo { + t.Errorf("Lookup(%q): got %#v, want %#v", sfo, got, afo) + } + if got := Lookup([]byte(sfO)); got != afO { + t.Errorf("Lookup(%q): got %#v, want %#v", sfO, got, afO) + } + if got := afo.String(); got != sfo { + t.Errorf("Atom(%#v).String(): got %q, want %q", afo, got, sfo) + } + if got := afO.String(); got != sfO { + t.Errorf("Atom(%#v).String(): got %q, want %q", afO, got, sfO) + } +} + +func BenchmarkLookup(b *testing.B) { + sortedTable := make([]string, 0, len(table)) + for _, a := range table { + if a != 0 { + sortedTable = append(sortedTable, a.String()) + } + } + sort.Strings(sortedTable) + + x := make([][]byte, 1000) + for i := range x { + x[i] = []byte(sortedTable[i%len(sortedTable)]) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, s := range x { + Lookup(s) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/gen.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/gen.go new file mode 100644 index 00000000..6bfa8660 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/gen.go @@ -0,0 +1,648 @@ +// 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 ignore + +package main + +// This program generates table.go and table_test.go. +// Invoke as +// +// go run gen.go |gofmt >table.go +// go run gen.go -test |gofmt >table_test.go + +import ( + "flag" + "fmt" + "math/rand" + "os" + "sort" + "strings" +) + +// identifier converts s to a Go exported identifier. +// It converts "div" to "Div" and "accept-charset" to "AcceptCharset". +func identifier(s string) string { + b := make([]byte, 0, len(s)) + cap := true + for _, c := range s { + if c == '-' { + cap = true + continue + } + if cap && 'a' <= c && c <= 'z' { + c -= 'a' - 'A' + } + cap = false + b = append(b, byte(c)) + } + return string(b) +} + +var test = flag.Bool("test", false, "generate table_test.go") + +func main() { + flag.Parse() + + var all []string + all = append(all, elements...) + all = append(all, attributes...) + all = append(all, eventHandlers...) + all = append(all, extra...) + sort.Strings(all) + + if *test { + fmt.Printf("// generated by go run gen.go -test; DO NOT EDIT\n\n") + fmt.Printf("package atom\n\n") + fmt.Printf("var testAtomList = []string{\n") + for _, s := range all { + fmt.Printf("\t%q,\n", s) + } + fmt.Printf("}\n") + return + } + + // uniq - lists have dups + // compute max len too + maxLen := 0 + w := 0 + for _, s := range all { + if w == 0 || all[w-1] != s { + if maxLen < len(s) { + maxLen = len(s) + } + all[w] = s + w++ + } + } + all = all[:w] + + // Find hash that minimizes table size. + var best *table + for i := 0; i < 1000000; i++ { + if best != nil && 1<<(best.k-1) < len(all) { + break + } + h := rand.Uint32() + for k := uint(0); k <= 16; k++ { + if best != nil && k >= best.k { + break + } + var t table + if t.init(h, k, all) { + best = &t + break + } + } + } + if best == nil { + fmt.Fprintf(os.Stderr, "failed to construct string table\n") + os.Exit(1) + } + + // Lay out strings, using overlaps when possible. + layout := append([]string{}, all...) + + // Remove strings that are substrings of other strings + for changed := true; changed; { + changed = false + for i, s := range layout { + if s == "" { + continue + } + for j, t := range layout { + if i != j && t != "" && strings.Contains(s, t) { + changed = true + layout[j] = "" + } + } + } + } + + // Join strings where one suffix matches another prefix. + for { + // Find best i, j, k such that layout[i][len-k:] == layout[j][:k], + // maximizing overlap length k. + besti := -1 + bestj := -1 + bestk := 0 + for i, s := range layout { + if s == "" { + continue + } + for j, t := range layout { + if i == j { + continue + } + for k := bestk + 1; k <= len(s) && k <= len(t); k++ { + if s[len(s)-k:] == t[:k] { + besti = i + bestj = j + bestk = k + } + } + } + } + if bestk > 0 { + layout[besti] += layout[bestj][bestk:] + layout[bestj] = "" + continue + } + break + } + + text := strings.Join(layout, "") + + atom := map[string]uint32{} + for _, s := range all { + off := strings.Index(text, s) + if off < 0 { + panic("lost string " + s) + } + atom[s] = uint32(off<<8 | len(s)) + } + + // Generate the Go code. + fmt.Printf("// generated by go run gen.go; DO NOT EDIT\n\n") + fmt.Printf("package atom\n\nconst (\n") + for _, s := range all { + fmt.Printf("\t%s Atom = %#x\n", identifier(s), atom[s]) + } + fmt.Printf(")\n\n") + + fmt.Printf("const hash0 = %#x\n\n", best.h0) + fmt.Printf("const maxAtomLen = %d\n\n", maxLen) + + fmt.Printf("var table = [1<<%d]Atom{\n", best.k) + for i, s := range best.tab { + if s == "" { + continue + } + fmt.Printf("\t%#x: %#x, // %s\n", i, atom[s], s) + } + fmt.Printf("}\n") + datasize := (1 << best.k) * 4 + + fmt.Printf("const atomText =\n") + textsize := len(text) + for len(text) > 60 { + fmt.Printf("\t%q +\n", text[:60]) + text = text[60:] + } + fmt.Printf("\t%q\n\n", text) + + fmt.Fprintf(os.Stderr, "%d atoms; %d string bytes + %d tables = %d total data\n", len(all), textsize, datasize, textsize+datasize) +} + +type byLen []string + +func (x byLen) Less(i, j int) bool { return len(x[i]) > len(x[j]) } +func (x byLen) Swap(i, j int) { x[i], x[j] = x[j], x[i] } +func (x byLen) Len() int { return len(x) } + +// fnv computes the FNV hash with an arbitrary starting value h. +func fnv(h uint32, s string) uint32 { + for i := 0; i < len(s); i++ { + h ^= uint32(s[i]) + h *= 16777619 + } + return h +} + +// A table represents an attempt at constructing the lookup table. +// The lookup table uses cuckoo hashing, meaning that each string +// can be found in one of two positions. +type table struct { + h0 uint32 + k uint + mask uint32 + tab []string +} + +// hash returns the two hashes for s. +func (t *table) hash(s string) (h1, h2 uint32) { + h := fnv(t.h0, s) + h1 = h & t.mask + h2 = (h >> 16) & t.mask + return +} + +// init initializes the table with the given parameters. +// h0 is the initial hash value, +// k is the number of bits of hash value to use, and +// x is the list of strings to store in the table. +// init returns false if the table cannot be constructed. +func (t *table) init(h0 uint32, k uint, x []string) bool { + t.h0 = h0 + t.k = k + t.tab = make([]string, 1< len(t.tab) { + return false + } + s := t.tab[i] + h1, h2 := t.hash(s) + j := h1 + h2 - i + if t.tab[j] != "" && !t.push(j, depth+1) { + return false + } + t.tab[j] = s + return true +} + +// The lists of element names and attribute keys were taken from +// https://html.spec.whatwg.org/multipage/indices.html#index +// as of the "HTML Living Standard - Last Updated 21 February 2015" version. + +var elements = []string{ + "a", + "abbr", + "address", + "area", + "article", + "aside", + "audio", + "b", + "base", + "bdi", + "bdo", + "blockquote", + "body", + "br", + "button", + "canvas", + "caption", + "cite", + "code", + "col", + "colgroup", + "command", + "data", + "datalist", + "dd", + "del", + "details", + "dfn", + "dialog", + "div", + "dl", + "dt", + "em", + "embed", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "hr", + "html", + "i", + "iframe", + "img", + "input", + "ins", + "kbd", + "keygen", + "label", + "legend", + "li", + "link", + "map", + "mark", + "menu", + "menuitem", + "meta", + "meter", + "nav", + "noscript", + "object", + "ol", + "optgroup", + "option", + "output", + "p", + "param", + "pre", + "progress", + "q", + "rp", + "rt", + "ruby", + "s", + "samp", + "script", + "section", + "select", + "small", + "source", + "span", + "strong", + "style", + "sub", + "summary", + "sup", + "table", + "tbody", + "td", + "template", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "track", + "u", + "ul", + "var", + "video", + "wbr", +} + +// https://html.spec.whatwg.org/multipage/indices.html#attributes-3 + +var attributes = []string{ + "abbr", + "accept", + "accept-charset", + "accesskey", + "action", + "alt", + "async", + "autocomplete", + "autofocus", + "autoplay", + "challenge", + "charset", + "checked", + "cite", + "class", + "cols", + "colspan", + "command", + "content", + "contenteditable", + "contextmenu", + "controls", + "coords", + "crossorigin", + "data", + "datetime", + "default", + "defer", + "dir", + "dirname", + "disabled", + "download", + "draggable", + "dropzone", + "enctype", + "for", + "form", + "formaction", + "formenctype", + "formmethod", + "formnovalidate", + "formtarget", + "headers", + "height", + "hidden", + "high", + "href", + "hreflang", + "http-equiv", + "icon", + "id", + "inputmode", + "ismap", + "itemid", + "itemprop", + "itemref", + "itemscope", + "itemtype", + "keytype", + "kind", + "label", + "lang", + "list", + "loop", + "low", + "manifest", + "max", + "maxlength", + "media", + "mediagroup", + "method", + "min", + "minlength", + "multiple", + "muted", + "name", + "novalidate", + "open", + "optimum", + "pattern", + "ping", + "placeholder", + "poster", + "preload", + "radiogroup", + "readonly", + "rel", + "required", + "reversed", + "rows", + "rowspan", + "sandbox", + "spellcheck", + "scope", + "scoped", + "seamless", + "selected", + "shape", + "size", + "sizes", + "sortable", + "sorted", + "span", + "src", + "srcdoc", + "srclang", + "start", + "step", + "style", + "tabindex", + "target", + "title", + "translate", + "type", + "typemustmatch", + "usemap", + "value", + "width", + "wrap", +} + +var eventHandlers = []string{ + "onabort", + "onautocomplete", + "onautocompleteerror", + "onafterprint", + "onbeforeprint", + "onbeforeunload", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "onhashchange", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onlanguagechange", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmessage", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onoffline", + "ononline", + "onpagehide", + "onpageshow", + "onpause", + "onplay", + "onplaying", + "onpopstate", + "onprogress", + "onratechange", + "onreset", + "onresize", + "onscroll", + "onseeked", + "onseeking", + "onselect", + "onshow", + "onsort", + "onstalled", + "onstorage", + "onsubmit", + "onsuspend", + "ontimeupdate", + "ontoggle", + "onunload", + "onvolumechange", + "onwaiting", +} + +// extra are ad-hoc values not covered by any of the lists above. +var extra = []string{ + "align", + "annotation", + "annotation-xml", + "applet", + "basefont", + "bgsound", + "big", + "blink", + "center", + "color", + "desc", + "face", + "font", + "foreignObject", // HTML is case-insensitive, but SVG-embedded-in-HTML is case-sensitive. + "foreignobject", + "frame", + "frameset", + "image", + "isindex", + "listing", + "malignmark", + "marquee", + "math", + "mglyph", + "mi", + "mn", + "mo", + "ms", + "mtext", + "nobr", + "noembed", + "noframes", + "plaintext", + "prompt", + "public", + "spacer", + "strike", + "svg", + "system", + "tt", + "xmp", +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/table.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/table.go new file mode 100644 index 00000000..2605ba31 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/table.go @@ -0,0 +1,713 @@ +// generated by go run gen.go; DO NOT EDIT + +package atom + +const ( + A Atom = 0x1 + Abbr Atom = 0x4 + Accept Atom = 0x2106 + AcceptCharset Atom = 0x210e + Accesskey Atom = 0x3309 + Action Atom = 0x1f606 + Address Atom = 0x4f307 + Align Atom = 0x1105 + Alt Atom = 0x4503 + Annotation Atom = 0x1670a + AnnotationXml Atom = 0x1670e + Applet Atom = 0x2b306 + Area Atom = 0x2fa04 + Article Atom = 0x38807 + Aside Atom = 0x8305 + Async Atom = 0x7b05 + Audio Atom = 0xa605 + Autocomplete Atom = 0x1fc0c + Autofocus Atom = 0xb309 + Autoplay Atom = 0xce08 + B Atom = 0x101 + Base Atom = 0xd604 + Basefont Atom = 0xd608 + Bdi Atom = 0x1a03 + Bdo Atom = 0xe703 + Bgsound Atom = 0x11807 + Big Atom = 0x12403 + Blink Atom = 0x12705 + Blockquote Atom = 0x12c0a + Body Atom = 0x2f04 + Br Atom = 0x202 + Button Atom = 0x13606 + Canvas Atom = 0x7f06 + Caption Atom = 0x1bb07 + Center Atom = 0x5b506 + Challenge Atom = 0x21f09 + Charset Atom = 0x2807 + Checked Atom = 0x32807 + Cite Atom = 0x3c804 + Class Atom = 0x4de05 + Code Atom = 0x14904 + Col Atom = 0x15003 + Colgroup Atom = 0x15008 + Color Atom = 0x15d05 + Cols Atom = 0x16204 + Colspan Atom = 0x16207 + Command Atom = 0x17507 + Content Atom = 0x42307 + Contenteditable Atom = 0x4230f + Contextmenu Atom = 0x3310b + Controls Atom = 0x18808 + Coords Atom = 0x19406 + Crossorigin Atom = 0x19f0b + Data Atom = 0x44a04 + Datalist Atom = 0x44a08 + Datetime Atom = 0x23c08 + Dd Atom = 0x26702 + Default Atom = 0x8607 + Defer Atom = 0x14b05 + Del Atom = 0x3ef03 + Desc Atom = 0x4db04 + Details Atom = 0x4807 + Dfn Atom = 0x6103 + Dialog Atom = 0x1b06 + Dir Atom = 0x6903 + Dirname Atom = 0x6907 + Disabled Atom = 0x10c08 + Div Atom = 0x11303 + Dl Atom = 0x11e02 + Download Atom = 0x40008 + Draggable Atom = 0x17b09 + Dropzone Atom = 0x39108 + Dt Atom = 0x50902 + Em Atom = 0x6502 + Embed Atom = 0x6505 + Enctype Atom = 0x21107 + Face Atom = 0x5b304 + Fieldset Atom = 0x1b008 + Figcaption Atom = 0x1b80a + Figure Atom = 0x1cc06 + Font Atom = 0xda04 + Footer Atom = 0x8d06 + For Atom = 0x1d803 + ForeignObject Atom = 0x1d80d + Foreignobject Atom = 0x1e50d + Form Atom = 0x1f204 + Formaction Atom = 0x1f20a + Formenctype Atom = 0x20d0b + Formmethod Atom = 0x2280a + Formnovalidate Atom = 0x2320e + Formtarget Atom = 0x2470a + Frame Atom = 0x9a05 + Frameset Atom = 0x9a08 + H1 Atom = 0x26e02 + H2 Atom = 0x29402 + H3 Atom = 0x2a702 + H4 Atom = 0x2e902 + H5 Atom = 0x2f302 + H6 Atom = 0x50b02 + Head Atom = 0x2d504 + Header Atom = 0x2d506 + Headers Atom = 0x2d507 + Height Atom = 0x25106 + Hgroup Atom = 0x25906 + Hidden Atom = 0x26506 + High Atom = 0x26b04 + Hr Atom = 0x27002 + Href Atom = 0x27004 + Hreflang Atom = 0x27008 + Html Atom = 0x25504 + HttpEquiv Atom = 0x2780a + I Atom = 0x601 + Icon Atom = 0x42204 + Id Atom = 0x8502 + Iframe Atom = 0x29606 + Image Atom = 0x29c05 + Img Atom = 0x2a103 + Input Atom = 0x3e805 + Inputmode Atom = 0x3e809 + Ins Atom = 0x1a803 + Isindex Atom = 0x2a907 + Ismap Atom = 0x2b005 + Itemid Atom = 0x33c06 + Itemprop Atom = 0x3c908 + Itemref Atom = 0x5ad07 + Itemscope Atom = 0x2b909 + Itemtype Atom = 0x2c308 + Kbd Atom = 0x1903 + Keygen Atom = 0x3906 + Keytype Atom = 0x53707 + Kind Atom = 0x10904 + Label Atom = 0xf005 + Lang Atom = 0x27404 + Legend Atom = 0x18206 + Li Atom = 0x1202 + Link Atom = 0x12804 + List Atom = 0x44e04 + Listing Atom = 0x44e07 + Loop Atom = 0xf404 + Low Atom = 0x11f03 + Malignmark Atom = 0x100a + Manifest Atom = 0x5f108 + Map Atom = 0x2b203 + Mark Atom = 0x1604 + Marquee Atom = 0x2cb07 + Math Atom = 0x2d204 + Max Atom = 0x2e103 + Maxlength Atom = 0x2e109 + Media Atom = 0x6e05 + Mediagroup Atom = 0x6e0a + Menu Atom = 0x33804 + Menuitem Atom = 0x33808 + Meta Atom = 0x45d04 + Meter Atom = 0x24205 + Method Atom = 0x22c06 + Mglyph Atom = 0x2a206 + Mi Atom = 0x2eb02 + Min Atom = 0x2eb03 + Minlength Atom = 0x2eb09 + Mn Atom = 0x23502 + Mo Atom = 0x3ed02 + Ms Atom = 0x2bc02 + Mtext Atom = 0x2f505 + Multiple Atom = 0x30308 + Muted Atom = 0x30b05 + Name Atom = 0x6c04 + Nav Atom = 0x3e03 + Nobr Atom = 0x5704 + Noembed Atom = 0x6307 + Noframes Atom = 0x9808 + Noscript Atom = 0x3d208 + Novalidate Atom = 0x2360a + Object Atom = 0x1ec06 + Ol Atom = 0xc902 + Onabort Atom = 0x13a07 + Onafterprint Atom = 0x1c00c + Onautocomplete Atom = 0x1fa0e + Onautocompleteerror Atom = 0x1fa13 + Onbeforeprint Atom = 0x6040d + Onbeforeunload Atom = 0x4e70e + Onblur Atom = 0xaa06 + Oncancel Atom = 0xe908 + Oncanplay Atom = 0x28509 + Oncanplaythrough Atom = 0x28510 + Onchange Atom = 0x3a708 + Onclick Atom = 0x31007 + Onclose Atom = 0x31707 + Oncontextmenu Atom = 0x32f0d + Oncuechange Atom = 0x3420b + Ondblclick Atom = 0x34d0a + Ondrag Atom = 0x35706 + Ondragend Atom = 0x35709 + Ondragenter Atom = 0x3600b + Ondragleave Atom = 0x36b0b + Ondragover Atom = 0x3760a + Ondragstart Atom = 0x3800b + Ondrop Atom = 0x38f06 + Ondurationchange Atom = 0x39f10 + Onemptied Atom = 0x39609 + Onended Atom = 0x3af07 + Onerror Atom = 0x3b607 + Onfocus Atom = 0x3bd07 + Onhashchange Atom = 0x3da0c + Oninput Atom = 0x3e607 + Oninvalid Atom = 0x3f209 + Onkeydown Atom = 0x3fb09 + Onkeypress Atom = 0x4080a + Onkeyup Atom = 0x41807 + Onlanguagechange Atom = 0x43210 + Onload Atom = 0x44206 + Onloadeddata Atom = 0x4420c + Onloadedmetadata Atom = 0x45510 + Onloadstart Atom = 0x46b0b + Onmessage Atom = 0x47609 + Onmousedown Atom = 0x47f0b + Onmousemove Atom = 0x48a0b + Onmouseout Atom = 0x4950a + Onmouseover Atom = 0x4a20b + Onmouseup Atom = 0x4ad09 + Onmousewheel Atom = 0x4b60c + Onoffline Atom = 0x4c209 + Ononline Atom = 0x4cb08 + Onpagehide Atom = 0x4d30a + Onpageshow Atom = 0x4fe0a + Onpause Atom = 0x50d07 + Onplay Atom = 0x51706 + Onplaying Atom = 0x51709 + Onpopstate Atom = 0x5200a + Onprogress Atom = 0x52a0a + Onratechange Atom = 0x53e0c + Onreset Atom = 0x54a07 + Onresize Atom = 0x55108 + Onscroll Atom = 0x55f08 + Onseeked Atom = 0x56708 + Onseeking Atom = 0x56f09 + Onselect Atom = 0x57808 + Onshow Atom = 0x58206 + Onsort Atom = 0x58b06 + Onstalled Atom = 0x59509 + Onstorage Atom = 0x59e09 + Onsubmit Atom = 0x5a708 + Onsuspend Atom = 0x5bb09 + Ontimeupdate Atom = 0xdb0c + Ontoggle Atom = 0x5c408 + Onunload Atom = 0x5cc08 + Onvolumechange Atom = 0x5d40e + Onwaiting Atom = 0x5e209 + Open Atom = 0x3cf04 + Optgroup Atom = 0xf608 + Optimum Atom = 0x5eb07 + Option Atom = 0x60006 + Output Atom = 0x49c06 + P Atom = 0xc01 + Param Atom = 0xc05 + Pattern Atom = 0x5107 + Ping Atom = 0x7704 + Placeholder Atom = 0xc30b + Plaintext Atom = 0xfd09 + Poster Atom = 0x15706 + Pre Atom = 0x25e03 + Preload Atom = 0x25e07 + Progress Atom = 0x52c08 + Prompt Atom = 0x5fa06 + Public Atom = 0x41e06 + Q Atom = 0x13101 + Radiogroup Atom = 0x30a + Readonly Atom = 0x2fb08 + Rel Atom = 0x25f03 + Required Atom = 0x1d008 + Reversed Atom = 0x5a08 + Rows Atom = 0x9204 + Rowspan Atom = 0x9207 + Rp Atom = 0x1c602 + Rt Atom = 0x13f02 + Ruby Atom = 0xaf04 + S Atom = 0x2c01 + Samp Atom = 0x4e04 + Sandbox Atom = 0xbb07 + Scope Atom = 0x2bd05 + Scoped Atom = 0x2bd06 + Script Atom = 0x3d406 + Seamless Atom = 0x31c08 + Section Atom = 0x4e207 + Select Atom = 0x57a06 + Selected Atom = 0x57a08 + Shape Atom = 0x4f905 + Size Atom = 0x55504 + Sizes Atom = 0x55505 + Small Atom = 0x18f05 + Sortable Atom = 0x58d08 + Sorted Atom = 0x19906 + Source Atom = 0x1aa06 + Spacer Atom = 0x2db06 + Span Atom = 0x9504 + Spellcheck Atom = 0x3230a + Src Atom = 0x3c303 + Srcdoc Atom = 0x3c306 + Srclang Atom = 0x41107 + Start Atom = 0x38605 + Step Atom = 0x5f704 + Strike Atom = 0x53306 + Strong Atom = 0x55906 + Style Atom = 0x61105 + Sub Atom = 0x5a903 + Summary Atom = 0x61607 + Sup Atom = 0x61d03 + Svg Atom = 0x62003 + System Atom = 0x62306 + Tabindex Atom = 0x46308 + Table Atom = 0x42d05 + Target Atom = 0x24b06 + Tbody Atom = 0x2e05 + Td Atom = 0x4702 + Template Atom = 0x62608 + Textarea Atom = 0x2f608 + Tfoot Atom = 0x8c05 + Th Atom = 0x22e02 + Thead Atom = 0x2d405 + Time Atom = 0xdd04 + Title Atom = 0xa105 + Tr Atom = 0x10502 + Track Atom = 0x10505 + Translate Atom = 0x14009 + Tt Atom = 0x5302 + Type Atom = 0x21404 + Typemustmatch Atom = 0x2140d + U Atom = 0xb01 + Ul Atom = 0x8a02 + Usemap Atom = 0x51106 + Value Atom = 0x4005 + Var Atom = 0x11503 + Video Atom = 0x28105 + Wbr Atom = 0x12103 + Width Atom = 0x50705 + Wrap Atom = 0x58704 + Xmp Atom = 0xc103 +) + +const hash0 = 0xc17da63e + +const maxAtomLen = 19 + +var table = [1 << 9]Atom{ + 0x1: 0x48a0b, // onmousemove + 0x2: 0x5e209, // onwaiting + 0x3: 0x1fa13, // onautocompleteerror + 0x4: 0x5fa06, // prompt + 0x7: 0x5eb07, // optimum + 0x8: 0x1604, // mark + 0xa: 0x5ad07, // itemref + 0xb: 0x4fe0a, // onpageshow + 0xc: 0x57a06, // select + 0xd: 0x17b09, // draggable + 0xe: 0x3e03, // nav + 0xf: 0x17507, // command + 0x11: 0xb01, // u + 0x14: 0x2d507, // headers + 0x15: 0x44a08, // datalist + 0x17: 0x4e04, // samp + 0x1a: 0x3fb09, // onkeydown + 0x1b: 0x55f08, // onscroll + 0x1c: 0x15003, // col + 0x20: 0x3c908, // itemprop + 0x21: 0x2780a, // http-equiv + 0x22: 0x61d03, // sup + 0x24: 0x1d008, // required + 0x2b: 0x25e07, // preload + 0x2c: 0x6040d, // onbeforeprint + 0x2d: 0x3600b, // ondragenter + 0x2e: 0x50902, // dt + 0x2f: 0x5a708, // onsubmit + 0x30: 0x27002, // hr + 0x31: 0x32f0d, // oncontextmenu + 0x33: 0x29c05, // image + 0x34: 0x50d07, // onpause + 0x35: 0x25906, // hgroup + 0x36: 0x7704, // ping + 0x37: 0x57808, // onselect + 0x3a: 0x11303, // div + 0x3b: 0x1fa0e, // onautocomplete + 0x40: 0x2eb02, // mi + 0x41: 0x31c08, // seamless + 0x42: 0x2807, // charset + 0x43: 0x8502, // id + 0x44: 0x5200a, // onpopstate + 0x45: 0x3ef03, // del + 0x46: 0x2cb07, // marquee + 0x47: 0x3309, // accesskey + 0x49: 0x8d06, // footer + 0x4a: 0x44e04, // list + 0x4b: 0x2b005, // ismap + 0x51: 0x33804, // menu + 0x52: 0x2f04, // body + 0x55: 0x9a08, // frameset + 0x56: 0x54a07, // onreset + 0x57: 0x12705, // blink + 0x58: 0xa105, // title + 0x59: 0x38807, // article + 0x5b: 0x22e02, // th + 0x5d: 0x13101, // q + 0x5e: 0x3cf04, // open + 0x5f: 0x2fa04, // area + 0x61: 0x44206, // onload + 0x62: 0xda04, // font + 0x63: 0xd604, // base + 0x64: 0x16207, // colspan + 0x65: 0x53707, // keytype + 0x66: 0x11e02, // dl + 0x68: 0x1b008, // fieldset + 0x6a: 0x2eb03, // min + 0x6b: 0x11503, // var + 0x6f: 0x2d506, // header + 0x70: 0x13f02, // rt + 0x71: 0x15008, // colgroup + 0x72: 0x23502, // mn + 0x74: 0x13a07, // onabort + 0x75: 0x3906, // keygen + 0x76: 0x4c209, // onoffline + 0x77: 0x21f09, // challenge + 0x78: 0x2b203, // map + 0x7a: 0x2e902, // h4 + 0x7b: 0x3b607, // onerror + 0x7c: 0x2e109, // maxlength + 0x7d: 0x2f505, // mtext + 0x7e: 0xbb07, // sandbox + 0x7f: 0x58b06, // onsort + 0x80: 0x100a, // malignmark + 0x81: 0x45d04, // meta + 0x82: 0x7b05, // async + 0x83: 0x2a702, // h3 + 0x84: 0x26702, // dd + 0x85: 0x27004, // href + 0x86: 0x6e0a, // mediagroup + 0x87: 0x19406, // coords + 0x88: 0x41107, // srclang + 0x89: 0x34d0a, // ondblclick + 0x8a: 0x4005, // value + 0x8c: 0xe908, // oncancel + 0x8e: 0x3230a, // spellcheck + 0x8f: 0x9a05, // frame + 0x91: 0x12403, // big + 0x94: 0x1f606, // action + 0x95: 0x6903, // dir + 0x97: 0x2fb08, // readonly + 0x99: 0x42d05, // table + 0x9a: 0x61607, // summary + 0x9b: 0x12103, // wbr + 0x9c: 0x30a, // radiogroup + 0x9d: 0x6c04, // name + 0x9f: 0x62306, // system + 0xa1: 0x15d05, // color + 0xa2: 0x7f06, // canvas + 0xa3: 0x25504, // html + 0xa5: 0x56f09, // onseeking + 0xac: 0x4f905, // shape + 0xad: 0x25f03, // rel + 0xae: 0x28510, // oncanplaythrough + 0xaf: 0x3760a, // ondragover + 0xb0: 0x62608, // template + 0xb1: 0x1d80d, // foreignObject + 0xb3: 0x9204, // rows + 0xb6: 0x44e07, // listing + 0xb7: 0x49c06, // output + 0xb9: 0x3310b, // contextmenu + 0xbb: 0x11f03, // low + 0xbc: 0x1c602, // rp + 0xbd: 0x5bb09, // onsuspend + 0xbe: 0x13606, // button + 0xbf: 0x4db04, // desc + 0xc1: 0x4e207, // section + 0xc2: 0x52a0a, // onprogress + 0xc3: 0x59e09, // onstorage + 0xc4: 0x2d204, // math + 0xc5: 0x4503, // alt + 0xc7: 0x8a02, // ul + 0xc8: 0x5107, // pattern + 0xc9: 0x4b60c, // onmousewheel + 0xca: 0x35709, // ondragend + 0xcb: 0xaf04, // ruby + 0xcc: 0xc01, // p + 0xcd: 0x31707, // onclose + 0xce: 0x24205, // meter + 0xcf: 0x11807, // bgsound + 0xd2: 0x25106, // height + 0xd4: 0x101, // b + 0xd5: 0x2c308, // itemtype + 0xd8: 0x1bb07, // caption + 0xd9: 0x10c08, // disabled + 0xdb: 0x33808, // menuitem + 0xdc: 0x62003, // svg + 0xdd: 0x18f05, // small + 0xde: 0x44a04, // data + 0xe0: 0x4cb08, // ononline + 0xe1: 0x2a206, // mglyph + 0xe3: 0x6505, // embed + 0xe4: 0x10502, // tr + 0xe5: 0x46b0b, // onloadstart + 0xe7: 0x3c306, // srcdoc + 0xeb: 0x5c408, // ontoggle + 0xed: 0xe703, // bdo + 0xee: 0x4702, // td + 0xef: 0x8305, // aside + 0xf0: 0x29402, // h2 + 0xf1: 0x52c08, // progress + 0xf2: 0x12c0a, // blockquote + 0xf4: 0xf005, // label + 0xf5: 0x601, // i + 0xf7: 0x9207, // rowspan + 0xfb: 0x51709, // onplaying + 0xfd: 0x2a103, // img + 0xfe: 0xf608, // optgroup + 0xff: 0x42307, // content + 0x101: 0x53e0c, // onratechange + 0x103: 0x3da0c, // onhashchange + 0x104: 0x4807, // details + 0x106: 0x40008, // download + 0x109: 0x14009, // translate + 0x10b: 0x4230f, // contenteditable + 0x10d: 0x36b0b, // ondragleave + 0x10e: 0x2106, // accept + 0x10f: 0x57a08, // selected + 0x112: 0x1f20a, // formaction + 0x113: 0x5b506, // center + 0x115: 0x45510, // onloadedmetadata + 0x116: 0x12804, // link + 0x117: 0xdd04, // time + 0x118: 0x19f0b, // crossorigin + 0x119: 0x3bd07, // onfocus + 0x11a: 0x58704, // wrap + 0x11b: 0x42204, // icon + 0x11d: 0x28105, // video + 0x11e: 0x4de05, // class + 0x121: 0x5d40e, // onvolumechange + 0x122: 0xaa06, // onblur + 0x123: 0x2b909, // itemscope + 0x124: 0x61105, // style + 0x127: 0x41e06, // public + 0x129: 0x2320e, // formnovalidate + 0x12a: 0x58206, // onshow + 0x12c: 0x51706, // onplay + 0x12d: 0x3c804, // cite + 0x12e: 0x2bc02, // ms + 0x12f: 0xdb0c, // ontimeupdate + 0x130: 0x10904, // kind + 0x131: 0x2470a, // formtarget + 0x135: 0x3af07, // onended + 0x136: 0x26506, // hidden + 0x137: 0x2c01, // s + 0x139: 0x2280a, // formmethod + 0x13a: 0x3e805, // input + 0x13c: 0x50b02, // h6 + 0x13d: 0xc902, // ol + 0x13e: 0x3420b, // oncuechange + 0x13f: 0x1e50d, // foreignobject + 0x143: 0x4e70e, // onbeforeunload + 0x144: 0x2bd05, // scope + 0x145: 0x39609, // onemptied + 0x146: 0x14b05, // defer + 0x147: 0xc103, // xmp + 0x148: 0x39f10, // ondurationchange + 0x149: 0x1903, // kbd + 0x14c: 0x47609, // onmessage + 0x14d: 0x60006, // option + 0x14e: 0x2eb09, // minlength + 0x14f: 0x32807, // checked + 0x150: 0xce08, // autoplay + 0x152: 0x202, // br + 0x153: 0x2360a, // novalidate + 0x156: 0x6307, // noembed + 0x159: 0x31007, // onclick + 0x15a: 0x47f0b, // onmousedown + 0x15b: 0x3a708, // onchange + 0x15e: 0x3f209, // oninvalid + 0x15f: 0x2bd06, // scoped + 0x160: 0x18808, // controls + 0x161: 0x30b05, // muted + 0x162: 0x58d08, // sortable + 0x163: 0x51106, // usemap + 0x164: 0x1b80a, // figcaption + 0x165: 0x35706, // ondrag + 0x166: 0x26b04, // high + 0x168: 0x3c303, // src + 0x169: 0x15706, // poster + 0x16b: 0x1670e, // annotation-xml + 0x16c: 0x5f704, // step + 0x16d: 0x4, // abbr + 0x16e: 0x1b06, // dialog + 0x170: 0x1202, // li + 0x172: 0x3ed02, // mo + 0x175: 0x1d803, // for + 0x176: 0x1a803, // ins + 0x178: 0x55504, // size + 0x179: 0x43210, // onlanguagechange + 0x17a: 0x8607, // default + 0x17b: 0x1a03, // bdi + 0x17c: 0x4d30a, // onpagehide + 0x17d: 0x6907, // dirname + 0x17e: 0x21404, // type + 0x17f: 0x1f204, // form + 0x181: 0x28509, // oncanplay + 0x182: 0x6103, // dfn + 0x183: 0x46308, // tabindex + 0x186: 0x6502, // em + 0x187: 0x27404, // lang + 0x189: 0x39108, // dropzone + 0x18a: 0x4080a, // onkeypress + 0x18b: 0x23c08, // datetime + 0x18c: 0x16204, // cols + 0x18d: 0x1, // a + 0x18e: 0x4420c, // onloadeddata + 0x190: 0xa605, // audio + 0x192: 0x2e05, // tbody + 0x193: 0x22c06, // method + 0x195: 0xf404, // loop + 0x196: 0x29606, // iframe + 0x198: 0x2d504, // head + 0x19e: 0x5f108, // manifest + 0x19f: 0xb309, // autofocus + 0x1a0: 0x14904, // code + 0x1a1: 0x55906, // strong + 0x1a2: 0x30308, // multiple + 0x1a3: 0xc05, // param + 0x1a6: 0x21107, // enctype + 0x1a7: 0x5b304, // face + 0x1a8: 0xfd09, // plaintext + 0x1a9: 0x26e02, // h1 + 0x1aa: 0x59509, // onstalled + 0x1ad: 0x3d406, // script + 0x1ae: 0x2db06, // spacer + 0x1af: 0x55108, // onresize + 0x1b0: 0x4a20b, // onmouseover + 0x1b1: 0x5cc08, // onunload + 0x1b2: 0x56708, // onseeked + 0x1b4: 0x2140d, // typemustmatch + 0x1b5: 0x1cc06, // figure + 0x1b6: 0x4950a, // onmouseout + 0x1b7: 0x25e03, // pre + 0x1b8: 0x50705, // width + 0x1b9: 0x19906, // sorted + 0x1bb: 0x5704, // nobr + 0x1be: 0x5302, // tt + 0x1bf: 0x1105, // align + 0x1c0: 0x3e607, // oninput + 0x1c3: 0x41807, // onkeyup + 0x1c6: 0x1c00c, // onafterprint + 0x1c7: 0x210e, // accept-charset + 0x1c8: 0x33c06, // itemid + 0x1c9: 0x3e809, // inputmode + 0x1cb: 0x53306, // strike + 0x1cc: 0x5a903, // sub + 0x1cd: 0x10505, // track + 0x1ce: 0x38605, // start + 0x1d0: 0xd608, // basefont + 0x1d6: 0x1aa06, // source + 0x1d7: 0x18206, // legend + 0x1d8: 0x2d405, // thead + 0x1da: 0x8c05, // tfoot + 0x1dd: 0x1ec06, // object + 0x1de: 0x6e05, // media + 0x1df: 0x1670a, // annotation + 0x1e0: 0x20d0b, // formenctype + 0x1e2: 0x3d208, // noscript + 0x1e4: 0x55505, // sizes + 0x1e5: 0x1fc0c, // autocomplete + 0x1e6: 0x9504, // span + 0x1e7: 0x9808, // noframes + 0x1e8: 0x24b06, // target + 0x1e9: 0x38f06, // ondrop + 0x1ea: 0x2b306, // applet + 0x1ec: 0x5a08, // reversed + 0x1f0: 0x2a907, // isindex + 0x1f3: 0x27008, // hreflang + 0x1f5: 0x2f302, // h5 + 0x1f6: 0x4f307, // address + 0x1fa: 0x2e103, // max + 0x1fb: 0xc30b, // placeholder + 0x1fc: 0x2f608, // textarea + 0x1fe: 0x4ad09, // onmouseup + 0x1ff: 0x3800b, // ondragstart +} + +const atomText = "abbradiogrouparamalignmarkbdialogaccept-charsetbodyaccesskey" + + "genavaluealtdetailsampatternobreversedfnoembedirnamediagroup" + + "ingasyncanvasidefaultfooterowspanoframesetitleaudionblurubya" + + "utofocusandboxmplaceholderautoplaybasefontimeupdatebdoncance" + + "labelooptgrouplaintextrackindisabledivarbgsoundlowbrbigblink" + + "blockquotebuttonabortranslatecodefercolgroupostercolorcolspa" + + "nnotation-xmlcommandraggablegendcontrolsmallcoordsortedcross" + + "originsourcefieldsetfigcaptionafterprintfigurequiredforeignO" + + "bjectforeignobjectformactionautocompleteerrorformenctypemust" + + "matchallengeformmethodformnovalidatetimeterformtargetheightm" + + "lhgroupreloadhiddenhigh1hreflanghttp-equivideoncanplaythroug" + + "h2iframeimageimglyph3isindexismappletitemscopeditemtypemarqu" + + "eematheaderspacermaxlength4minlength5mtextareadonlymultiplem" + + "utedonclickoncloseamlesspellcheckedoncontextmenuitemidoncuec" + + "hangeondblclickondragendondragenterondragleaveondragoverondr" + + "agstarticleondropzonemptiedondurationchangeonendedonerroronf" + + "ocusrcdocitempropenoscriptonhashchangeoninputmodeloninvalido" + + "nkeydownloadonkeypressrclangonkeyupublicontenteditableonlang" + + "uagechangeonloadeddatalistingonloadedmetadatabindexonloadsta" + + "rtonmessageonmousedownonmousemoveonmouseoutputonmouseoveronm" + + "ouseuponmousewheelonofflineononlineonpagehidesclassectionbef" + + "oreunloaddresshapeonpageshowidth6onpausemaponplayingonpopsta" + + "teonprogresstrikeytypeonratechangeonresetonresizestrongonscr" + + "ollonseekedonseekingonselectedonshowraponsortableonstalledon" + + "storageonsubmitemrefacenteronsuspendontoggleonunloadonvolume" + + "changeonwaitingoptimumanifestepromptoptionbeforeprintstylesu" + + "mmarysupsvgsystemplate" diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/table_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/table_test.go new file mode 100644 index 00000000..0f2ecce4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/atom/table_test.go @@ -0,0 +1,351 @@ +// generated by go run gen.go -test; DO NOT EDIT + +package atom + +var testAtomList = []string{ + "a", + "abbr", + "abbr", + "accept", + "accept-charset", + "accesskey", + "action", + "address", + "align", + "alt", + "annotation", + "annotation-xml", + "applet", + "area", + "article", + "aside", + "async", + "audio", + "autocomplete", + "autofocus", + "autoplay", + "b", + "base", + "basefont", + "bdi", + "bdo", + "bgsound", + "big", + "blink", + "blockquote", + "body", + "br", + "button", + "canvas", + "caption", + "center", + "challenge", + "charset", + "checked", + "cite", + "cite", + "class", + "code", + "col", + "colgroup", + "color", + "cols", + "colspan", + "command", + "command", + "content", + "contenteditable", + "contextmenu", + "controls", + "coords", + "crossorigin", + "data", + "data", + "datalist", + "datetime", + "dd", + "default", + "defer", + "del", + "desc", + "details", + "dfn", + "dialog", + "dir", + "dirname", + "disabled", + "div", + "dl", + "download", + "draggable", + "dropzone", + "dt", + "em", + "embed", + "enctype", + "face", + "fieldset", + "figcaption", + "figure", + "font", + "footer", + "for", + "foreignObject", + "foreignobject", + "form", + "form", + "formaction", + "formenctype", + "formmethod", + "formnovalidate", + "formtarget", + "frame", + "frameset", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "headers", + "height", + "hgroup", + "hidden", + "high", + "hr", + "href", + "hreflang", + "html", + "http-equiv", + "i", + "icon", + "id", + "iframe", + "image", + "img", + "input", + "inputmode", + "ins", + "isindex", + "ismap", + "itemid", + "itemprop", + "itemref", + "itemscope", + "itemtype", + "kbd", + "keygen", + "keytype", + "kind", + "label", + "label", + "lang", + "legend", + "li", + "link", + "list", + "listing", + "loop", + "low", + "malignmark", + "manifest", + "map", + "mark", + "marquee", + "math", + "max", + "maxlength", + "media", + "mediagroup", + "menu", + "menuitem", + "meta", + "meter", + "method", + "mglyph", + "mi", + "min", + "minlength", + "mn", + "mo", + "ms", + "mtext", + "multiple", + "muted", + "name", + "nav", + "nobr", + "noembed", + "noframes", + "noscript", + "novalidate", + "object", + "ol", + "onabort", + "onafterprint", + "onautocomplete", + "onautocompleteerror", + "onbeforeprint", + "onbeforeunload", + "onblur", + "oncancel", + "oncanplay", + "oncanplaythrough", + "onchange", + "onclick", + "onclose", + "oncontextmenu", + "oncuechange", + "ondblclick", + "ondrag", + "ondragend", + "ondragenter", + "ondragleave", + "ondragover", + "ondragstart", + "ondrop", + "ondurationchange", + "onemptied", + "onended", + "onerror", + "onfocus", + "onhashchange", + "oninput", + "oninvalid", + "onkeydown", + "onkeypress", + "onkeyup", + "onlanguagechange", + "onload", + "onloadeddata", + "onloadedmetadata", + "onloadstart", + "onmessage", + "onmousedown", + "onmousemove", + "onmouseout", + "onmouseover", + "onmouseup", + "onmousewheel", + "onoffline", + "ononline", + "onpagehide", + "onpageshow", + "onpause", + "onplay", + "onplaying", + "onpopstate", + "onprogress", + "onratechange", + "onreset", + "onresize", + "onscroll", + "onseeked", + "onseeking", + "onselect", + "onshow", + "onsort", + "onstalled", + "onstorage", + "onsubmit", + "onsuspend", + "ontimeupdate", + "ontoggle", + "onunload", + "onvolumechange", + "onwaiting", + "open", + "optgroup", + "optimum", + "option", + "output", + "p", + "param", + "pattern", + "ping", + "placeholder", + "plaintext", + "poster", + "pre", + "preload", + "progress", + "prompt", + "public", + "q", + "radiogroup", + "readonly", + "rel", + "required", + "reversed", + "rows", + "rowspan", + "rp", + "rt", + "ruby", + "s", + "samp", + "sandbox", + "scope", + "scoped", + "script", + "seamless", + "section", + "select", + "selected", + "shape", + "size", + "sizes", + "small", + "sortable", + "sorted", + "source", + "spacer", + "span", + "span", + "spellcheck", + "src", + "srcdoc", + "srclang", + "start", + "step", + "strike", + "strong", + "style", + "style", + "sub", + "summary", + "sup", + "svg", + "system", + "tabindex", + "table", + "target", + "tbody", + "td", + "template", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "title", + "tr", + "track", + "translate", + "tt", + "type", + "typemustmatch", + "u", + "ul", + "usemap", + "value", + "var", + "video", + "wbr", + "width", + "wrap", + "xmp", +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/charset.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/charset.go new file mode 100644 index 00000000..13bed159 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/charset.go @@ -0,0 +1,257 @@ +// 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 charset provides common text encodings for HTML documents. +// +// The mapping from encoding labels to encodings is defined at +// https://encoding.spec.whatwg.org/. +package charset // import "golang.org/x/net/html/charset" + +import ( + "bytes" + "fmt" + "io" + "mime" + "strings" + "unicode/utf8" + + "golang.org/x/net/html" + "golang.org/x/text/encoding" + "golang.org/x/text/encoding/charmap" + "golang.org/x/text/encoding/htmlindex" + "golang.org/x/text/transform" +) + +// Lookup returns the encoding with the specified label, and its canonical +// name. It returns nil and the empty string if label is not one of the +// standard encodings for HTML. Matching is case-insensitive and ignores +// leading and trailing whitespace. Encoders will use HTML escape sequences for +// runes that are not supported by the character set. +func Lookup(label string) (e encoding.Encoding, name string) { + e, err := htmlindex.Get(label) + if err != nil { + return nil, "" + } + name, _ = htmlindex.Name(e) + return &htmlEncoding{e}, name +} + +type htmlEncoding struct{ encoding.Encoding } + +func (h *htmlEncoding) NewEncoder() *encoding.Encoder { + // HTML requires a non-terminating legacy encoder. We use HTML escapes to + // substitute unsupported code points. + return encoding.HTMLEscapeUnsupported(h.Encoding.NewEncoder()) +} + +// DetermineEncoding determines the encoding of an HTML document by examining +// up to the first 1024 bytes of content and the declared Content-Type. +// +// See http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#determining-the-character-encoding +func DetermineEncoding(content []byte, contentType string) (e encoding.Encoding, name string, certain bool) { + if len(content) > 1024 { + content = content[:1024] + } + + for _, b := range boms { + if bytes.HasPrefix(content, b.bom) { + e, name = Lookup(b.enc) + return e, name, true + } + } + + if _, params, err := mime.ParseMediaType(contentType); err == nil { + if cs, ok := params["charset"]; ok { + if e, name = Lookup(cs); e != nil { + return e, name, true + } + } + } + + if len(content) > 0 { + e, name = prescan(content) + if e != nil { + return e, name, false + } + } + + // Try to detect UTF-8. + // First eliminate any partial rune at the end. + for i := len(content) - 1; i >= 0 && i > len(content)-4; i-- { + b := content[i] + if b < 0x80 { + break + } + if utf8.RuneStart(b) { + content = content[:i] + break + } + } + hasHighBit := false + for _, c := range content { + if c >= 0x80 { + hasHighBit = true + break + } + } + if hasHighBit && utf8.Valid(content) { + return encoding.Nop, "utf-8", false + } + + // TODO: change default depending on user's locale? + return charmap.Windows1252, "windows-1252", false +} + +// NewReader returns an io.Reader that converts the content of r to UTF-8. +// It calls DetermineEncoding to find out what r's encoding is. +func NewReader(r io.Reader, contentType string) (io.Reader, error) { + preview := make([]byte, 1024) + n, err := io.ReadFull(r, preview) + switch { + case err == io.ErrUnexpectedEOF: + preview = preview[:n] + r = bytes.NewReader(preview) + case err != nil: + return nil, err + default: + r = io.MultiReader(bytes.NewReader(preview), r) + } + + if e, _, _ := DetermineEncoding(preview, contentType); e != encoding.Nop { + r = transform.NewReader(r, e.NewDecoder()) + } + return r, nil +} + +// NewReaderLabel returns a reader that converts from the specified charset to +// UTF-8. It uses Lookup to find the encoding that corresponds to label, and +// returns an error if Lookup returns nil. It is suitable for use as +// encoding/xml.Decoder's CharsetReader function. +func NewReaderLabel(label string, input io.Reader) (io.Reader, error) { + e, _ := Lookup(label) + if e == nil { + return nil, fmt.Errorf("unsupported charset: %q", label) + } + return transform.NewReader(input, e.NewDecoder()), nil +} + +func prescan(content []byte) (e encoding.Encoding, name string) { + z := html.NewTokenizer(bytes.NewReader(content)) + for { + switch z.Next() { + case html.ErrorToken: + return nil, "" + + case html.StartTagToken, html.SelfClosingTagToken: + tagName, hasAttr := z.TagName() + if !bytes.Equal(tagName, []byte("meta")) { + continue + } + attrList := make(map[string]bool) + gotPragma := false + + const ( + dontKnow = iota + doNeedPragma + doNotNeedPragma + ) + needPragma := dontKnow + + name = "" + e = nil + for hasAttr { + var key, val []byte + key, val, hasAttr = z.TagAttr() + ks := string(key) + if attrList[ks] { + continue + } + attrList[ks] = true + for i, c := range val { + if 'A' <= c && c <= 'Z' { + val[i] = c + 0x20 + } + } + + switch ks { + case "http-equiv": + if bytes.Equal(val, []byte("content-type")) { + gotPragma = true + } + + case "content": + if e == nil { + name = fromMetaElement(string(val)) + if name != "" { + e, name = Lookup(name) + if e != nil { + needPragma = doNeedPragma + } + } + } + + case "charset": + e, name = Lookup(string(val)) + needPragma = doNotNeedPragma + } + } + + if needPragma == dontKnow || needPragma == doNeedPragma && !gotPragma { + continue + } + + if strings.HasPrefix(name, "utf-16") { + name = "utf-8" + e = encoding.Nop + } + + if e != nil { + return e, name + } + } + } +} + +func fromMetaElement(s string) string { + for s != "" { + csLoc := strings.Index(s, "charset") + if csLoc == -1 { + return "" + } + s = s[csLoc+len("charset"):] + s = strings.TrimLeft(s, " \t\n\f\r") + if !strings.HasPrefix(s, "=") { + continue + } + s = s[1:] + s = strings.TrimLeft(s, " \t\n\f\r") + if s == "" { + return "" + } + if q := s[0]; q == '"' || q == '\'' { + s = s[1:] + closeQuote := strings.IndexRune(s, rune(q)) + if closeQuote == -1 { + return "" + } + return s[:closeQuote] + } + + end := strings.IndexAny(s, "; \t\n\f\r") + if end == -1 { + end = len(s) + } + return s[:end] + } + return "" +} + +var boms = []struct { + bom []byte + enc string +}{ + {[]byte{0xfe, 0xff}, "utf-16be"}, + {[]byte{0xff, 0xfe}, "utf-16le"}, + {[]byte{0xef, 0xbb, 0xbf}, "utf-8"}, +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/charset_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/charset_test.go new file mode 100644 index 00000000..e4e7d86b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/charset_test.go @@ -0,0 +1,237 @@ +// 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 charset + +import ( + "bytes" + "encoding/xml" + "io/ioutil" + "runtime" + "strings" + "testing" + + "golang.org/x/text/transform" +) + +func transformString(t transform.Transformer, s string) (string, error) { + r := transform.NewReader(strings.NewReader(s), t) + b, err := ioutil.ReadAll(r) + return string(b), err +} + +type testCase struct { + utf8, other, otherEncoding string +} + +// testCases for encoding and decoding. +var testCases = []testCase{ + {"Résumé", "Résumé", "utf8"}, + {"Résumé", "R\xe9sum\xe9", "latin1"}, + {"これは漢字です。", "S0\x8c0o0\"oW[g0Y0\x020", "UTF-16LE"}, + {"これは漢字です。", "0S0\x8c0oo\"[W0g0Y0\x02", "UTF-16BE"}, + {"Hello, world", "Hello, world", "ASCII"}, + {"Gdańsk", "Gda\xf1sk", "ISO-8859-2"}, + {"Ââ Čč Đđ Ŋŋ Õõ Šš Žž Åå Ää", "\xc2\xe2 \xc8\xe8 \xa9\xb9 \xaf\xbf \xd5\xf5 \xaa\xba \xac\xbc \xc5\xe5 \xc4\xe4", "ISO-8859-10"}, + {"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "ISO-8859-11"}, + {"latviešu", "latvie\xf0u", "ISO-8859-13"}, + {"Seònaid", "Se\xf2naid", "ISO-8859-14"}, + {"€1 is cheap", "\xa41 is cheap", "ISO-8859-15"}, + {"românește", "rom\xe2ne\xbate", "ISO-8859-16"}, + {"nutraĵo", "nutra\xbco", "ISO-8859-3"}, + {"Kalâdlit", "Kal\xe2dlit", "ISO-8859-4"}, + {"русский", "\xe0\xe3\xe1\xe1\xda\xd8\xd9", "ISO-8859-5"}, + {"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "ISO-8859-7"}, + {"Kağan", "Ka\xf0an", "ISO-8859-9"}, + {"Résumé", "R\x8esum\x8e", "macintosh"}, + {"Gdańsk", "Gda\xf1sk", "windows-1250"}, + {"русский", "\xf0\xf3\xf1\xf1\xea\xe8\xe9", "windows-1251"}, + {"Résumé", "R\xe9sum\xe9", "windows-1252"}, + {"ελληνικά", "\xe5\xeb\xeb\xe7\xed\xe9\xea\xdc", "windows-1253"}, + {"Kağan", "Ka\xf0an", "windows-1254"}, + {"עִבְרִית", "\xf2\xc4\xe1\xc0\xf8\xc4\xe9\xfa", "windows-1255"}, + {"العربية", "\xc7\xe1\xda\xd1\xc8\xed\xc9", "windows-1256"}, + {"latviešu", "latvie\xf0u", "windows-1257"}, + {"Việt", "Vi\xea\xf2t", "windows-1258"}, + {"สำหรับ", "\xca\xd3\xcb\xc3\u047a", "windows-874"}, + {"русский", "\xd2\xd5\xd3\xd3\xcb\xc9\xca", "KOI8-R"}, + {"українська", "\xd5\xcb\xd2\xc1\xa7\xce\xd3\xd8\xcb\xc1", "KOI8-U"}, + {"Hello 常用國字標準字體表", "Hello \xb1`\xa5\u03b0\xea\xa6r\xbc\u0437\u01e6r\xc5\xe9\xaa\xed", "big5"}, + {"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gbk"}, + {"Hello 常用國字標準字體表", "Hello \xb3\xa3\xd3\xc3\x87\xf8\xd7\xd6\x98\xcb\x9c\xca\xd7\xd6\xf3\x77\xb1\xed", "gb18030"}, + {"עִבְרִית", "\x81\x30\xfb\x30\x81\x30\xf6\x34\x81\x30\xf9\x33\x81\x30\xf6\x30\x81\x30\xfb\x36\x81\x30\xf6\x34\x81\x30\xfa\x31\x81\x30\xfb\x38", "gb18030"}, + {"㧯", "\x82\x31\x89\x38", "gb18030"}, + {"これは漢字です。", "\x82\xb1\x82\xea\x82\xcd\x8a\xbf\x8e\x9a\x82\xc5\x82\xb7\x81B", "SJIS"}, + {"Hello, 世界!", "Hello, \x90\xa2\x8aE!", "SJIS"}, + {"イウエオカ", "\xb2\xb3\xb4\xb5\xb6", "SJIS"}, + {"これは漢字です。", "\xa4\xb3\xa4\xec\xa4\u03f4\xc1\xbb\xfa\xa4\u01e4\xb9\xa1\xa3", "EUC-JP"}, + {"Hello, 世界!", "Hello, \x1b$B@$3&\x1b(B!", "ISO-2022-JP"}, + {"다음과 같은 조건을 따라야 합니다: 저작자표시", "\xb4\xd9\xc0\xbd\xb0\xfa \xb0\xb0\xc0\xba \xc1\xb6\xb0\xc7\xc0\xbb \xb5\xfb\xb6\xf3\xbe\xdf \xc7մϴ\xd9: \xc0\xfa\xc0\xdb\xc0\xdaǥ\xbd\xc3", "EUC-KR"}, +} + +func TestDecode(t *testing.T) { + testCases := append(testCases, []testCase{ + // Replace multi-byte maximum subpart of ill-formed subsequence with + // single replacement character (WhatWG requirement). + {"Rés\ufffdumé", "Rés\xe1\x80umé", "utf8"}, + }...) + for _, tc := range testCases { + e, _ := Lookup(tc.otherEncoding) + if e == nil { + t.Errorf("%s: not found", tc.otherEncoding) + continue + } + s, err := transformString(e.NewDecoder(), tc.other) + if err != nil { + t.Errorf("%s: decode %q: %v", tc.otherEncoding, tc.other, err) + continue + } + if s != tc.utf8 { + t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.utf8) + } + } +} + +func TestEncode(t *testing.T) { + testCases := append(testCases, []testCase{ + // Use Go-style replacement. + {"Rés\xe1\x80umé", "Rés\ufffd\ufffdumé", "utf8"}, + // U+0144 LATIN SMALL LETTER N WITH ACUTE not supported by encoding. + {"Gdańsk", "Gdańsk", "ISO-8859-11"}, + {"\ufffd", "�", "ISO-8859-11"}, + {"a\xe1\x80b", "a��b", "ISO-8859-11"}, + }...) + for _, tc := range testCases { + e, _ := Lookup(tc.otherEncoding) + if e == nil { + t.Errorf("%s: not found", tc.otherEncoding) + continue + } + s, err := transformString(e.NewEncoder(), tc.utf8) + if err != nil { + t.Errorf("%s: encode %q: %s", tc.otherEncoding, tc.utf8, err) + continue + } + if s != tc.other { + t.Errorf("%s: got %q, want %q", tc.otherEncoding, s, tc.other) + } + } +} + +var sniffTestCases = []struct { + filename, declared, want string +}{ + {"HTTP-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"}, + {"UTF-16LE-BOM.html", "", "utf-16le"}, + {"UTF-16BE-BOM.html", "", "utf-16be"}, + {"meta-content-attribute.html", "text/html", "iso-8859-15"}, + {"meta-charset-attribute.html", "text/html", "iso-8859-15"}, + {"No-encoding-declaration.html", "text/html", "utf-8"}, + {"HTTP-vs-UTF-8-BOM.html", "text/html; charset=iso-8859-15", "utf-8"}, + {"HTTP-vs-meta-content.html", "text/html; charset=iso-8859-15", "iso-8859-15"}, + {"HTTP-vs-meta-charset.html", "text/html; charset=iso-8859-15", "iso-8859-15"}, + {"UTF-8-BOM-vs-meta-content.html", "text/html", "utf-8"}, + {"UTF-8-BOM-vs-meta-charset.html", "text/html", "utf-8"}, +} + +func TestSniff(t *testing.T) { + switch runtime.GOOS { + case "nacl": // platforms that don't permit direct file system access + t.Skipf("not supported on %q", runtime.GOOS) + } + + for _, tc := range sniffTestCases { + content, err := ioutil.ReadFile("testdata/" + tc.filename) + if err != nil { + t.Errorf("%s: error reading file: %v", tc.filename, err) + continue + } + + _, name, _ := DetermineEncoding(content, tc.declared) + if name != tc.want { + t.Errorf("%s: got %q, want %q", tc.filename, name, tc.want) + continue + } + } +} + +func TestReader(t *testing.T) { + switch runtime.GOOS { + case "nacl": // platforms that don't permit direct file system access + t.Skipf("not supported on %q", runtime.GOOS) + } + + for _, tc := range sniffTestCases { + content, err := ioutil.ReadFile("testdata/" + tc.filename) + if err != nil { + t.Errorf("%s: error reading file: %v", tc.filename, err) + continue + } + + r, err := NewReader(bytes.NewReader(content), tc.declared) + if err != nil { + t.Errorf("%s: error creating reader: %v", tc.filename, err) + continue + } + + got, err := ioutil.ReadAll(r) + if err != nil { + t.Errorf("%s: error reading from charset.NewReader: %v", tc.filename, err) + continue + } + + e, _ := Lookup(tc.want) + want, err := ioutil.ReadAll(transform.NewReader(bytes.NewReader(content), e.NewDecoder())) + if err != nil { + t.Errorf("%s: error decoding with hard-coded charset name: %v", tc.filename, err) + continue + } + + if !bytes.Equal(got, want) { + t.Errorf("%s: got %q, want %q", tc.filename, got, want) + continue + } + } +} + +var metaTestCases = []struct { + meta, want string +}{ + {"", ""}, + {"text/html", ""}, + {"text/html; charset utf-8", ""}, + {"text/html; charset=latin-2", "latin-2"}, + {"text/html; charset; charset = utf-8", "utf-8"}, + {`charset="big5"`, "big5"}, + {"charset='shift_jis'", "shift_jis"}, +} + +func TestFromMeta(t *testing.T) { + for _, tc := range metaTestCases { + got := fromMetaElement(tc.meta) + if got != tc.want { + t.Errorf("%q: got %q, want %q", tc.meta, got, tc.want) + } + } +} + +func TestXML(t *testing.T) { + const s = "r\xe9sum\xe9" + + d := xml.NewDecoder(strings.NewReader(s)) + d.CharsetReader = NewReaderLabel + + var a struct { + Word string + } + err := d.Decode(&a) + if err != nil { + t.Fatalf("Decode: %v", err) + } + + want := "résumé" + if a.Word != want { + t.Errorf("got %q, want %q", a.Word, want) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-charset.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-charset.html new file mode 100644 index 00000000..9915fa0e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-charset.html @@ -0,0 +1,48 @@ + + + + HTTP charset + + + + + + + + + + + +

HTTP charset

+ + +
+ + +
 
+ + + + + +
+

The character encoding of a page can be set using the HTTP header charset declaration.

+

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

The only character encoding declaration for this HTML file is in the HTTP header, which sets the encoding to ISO 8859-15.

+
+
+
HTML5
+

the-input-byte-stream-001
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html new file mode 100644 index 00000000..26e5d8b4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-UTF-8-BOM.html @@ -0,0 +1,48 @@ + + + + HTTP vs UTF-8 BOM + + + + + + + + + + + +

HTTP vs UTF-8 BOM

+ + +
+ + +
 
+ + + + + +
+

A character encoding set in the HTTP header has lower precedence than the UTF-8 signature.

+

The HTTP header attempts to set the character encoding to ISO 8859-15. The page starts with a UTF-8 signature.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

If the test is unsuccessful, the characters  should appear at the top of the page. These represent the bytes that make up the UTF-8 signature when encountered in the ISO 8859-15 encoding.

+
+
+
HTML5
+

the-input-byte-stream-034
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-charset.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-charset.html new file mode 100644 index 00000000..2f07e951 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-charset.html @@ -0,0 +1,49 @@ + + + + HTTP vs meta charset + + + + + + + + + + + +

HTTP vs meta charset

+ + +
+ + +
 
+ + + + + +
+

The HTTP header has a higher precedence than an encoding declaration in a meta charset attribute.

+

The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-1.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-018
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-content.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-content.html new file mode 100644 index 00000000..6853cdde --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/HTTP-vs-meta-content.html @@ -0,0 +1,49 @@ + + + + HTTP vs meta content + + + + + + + + + + + +

HTTP vs meta content

+ + +
+ + +
 
+ + + + + +
+

The HTTP header has a higher precedence than an encoding declaration in a meta content attribute.

+

The HTTP header attempts to set the character encoding to ISO 8859-15. The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-1.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-016
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/No-encoding-declaration.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/No-encoding-declaration.html new file mode 100644 index 00000000..612e26c6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/No-encoding-declaration.html @@ -0,0 +1,47 @@ + + + + No encoding declaration + + + + + + + + + + + +

No encoding declaration

+ + +
+ + +
 
+ + + + + +
+

A page with no encoding information in HTTP, BOM, XML declaration or meta element will be treated as UTF-8.

+

The test on this page contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-015
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/README b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/README new file mode 100644 index 00000000..38ef0f9f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/README @@ -0,0 +1,9 @@ +These test cases come from +http://www.w3.org/International/tests/repository/html5/the-input-byte-stream/results-basics + +Distributed under both the W3C Test Suite License +(http://www.w3.org/Consortium/Legal/2008/04-testsuite-license) +and the W3C 3-clause BSD License +(http://www.w3.org/Consortium/Legal/2008/03-bsd-license). +To contribute to a W3C Test Suite, see the policies and contribution +forms (http://www.w3.org/2004/10/27-testcases). diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-16BE-BOM.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-16BE-BOM.html new file mode 100644 index 00000000..3abf7a93 Binary files /dev/null and b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-16BE-BOM.html differ diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-16LE-BOM.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-16LE-BOM.html new file mode 100644 index 00000000..76254c98 Binary files /dev/null and b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-16LE-BOM.html differ diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html new file mode 100644 index 00000000..83de4333 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-charset.html @@ -0,0 +1,49 @@ + + + + UTF-8 BOM vs meta charset + + + + + + + + + + + +

UTF-8 BOM vs meta charset

+ + +
+ + +
 
+ + + + + +
+

A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta charset attribute declares a different encoding.

+

The page contains an encoding declaration in a meta charset attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-038
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html new file mode 100644 index 00000000..501aac2d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/UTF-8-BOM-vs-meta-content.html @@ -0,0 +1,48 @@ + + + + UTF-8 BOM vs meta content + + + + + + + + + + + +

UTF-8 BOM vs meta content

+ + +
+ + +
 
+ + + + + +
+

A page with a UTF-8 BOM will be recognized as UTF-8 even if the meta content attribute declares a different encoding.

+

The page contains an encoding declaration in a meta content attribute that attempts to set the character encoding to ISO 8859-15, but the file starts with a UTF-8 signature.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ýäè. This matches the sequence of bytes above when they are interpreted as UTF-8. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-037
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/meta-charset-attribute.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/meta-charset-attribute.html new file mode 100644 index 00000000..2d7d25ab --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/meta-charset-attribute.html @@ -0,0 +1,48 @@ + + + + meta charset attribute + + + + + + + + + + + +

meta charset attribute

+ + +
+ + +
 
+ + + + + +
+

The character encoding of the page can be set by a meta element with charset attribute.

+

The only character encoding declaration for this HTML file is in the charset attribute of the meta element, which declares the encoding to be ISO 8859-15.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-009
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/meta-content-attribute.html b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/meta-content-attribute.html new file mode 100644 index 00000000..1c3f228e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/charset/testdata/meta-content-attribute.html @@ -0,0 +1,48 @@ + + + + meta content attribute + + + + + + + + + + + +

meta content attribute

+ + +
+ + +
 
+ + + + + +
+

The character encoding of the page can be set by a meta element with http-equiv and content attributes.

+

The only character encoding declaration for this HTML file is in the content attribute of the meta element, which declares the encoding to be ISO 8859-15.

The test contains a div with a class name that contains the following sequence of bytes: 0xC3 0xBD 0xC3 0xA4 0xC3 0xA8. These represent different sequences of characters in ISO 8859-15, ISO 8859-1 and UTF-8. The external, UTF-8-encoded stylesheet contains a selector .test div.ÜÀÚ. This matches the sequence of bytes above when they are interpreted as ISO 8859-15. If the class name matches the selector then the test will pass.

+
+
+
HTML5
+

the-input-byte-stream-007
Result summary & related tests
Detailed results for this test
Link to spec

+
Assumptions:
  • The default encoding for the browser you are testing is not set to ISO 8859-15.
  • +
  • The test is read from a server that supports HTTP.
+
+ + + + + + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/const.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/const.go new file mode 100644 index 00000000..52f651ff --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/const.go @@ -0,0 +1,102 @@ +// 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 html + +// Section 12.2.3.2 of the HTML5 specification says "The following elements +// have varying levels of special parsing rules". +// https://html.spec.whatwg.org/multipage/syntax.html#the-stack-of-open-elements +var isSpecialElementMap = map[string]bool{ + "address": true, + "applet": true, + "area": true, + "article": true, + "aside": true, + "base": true, + "basefont": true, + "bgsound": true, + "blockquote": true, + "body": true, + "br": true, + "button": true, + "caption": true, + "center": true, + "col": true, + "colgroup": true, + "dd": true, + "details": true, + "dir": true, + "div": true, + "dl": true, + "dt": true, + "embed": true, + "fieldset": true, + "figcaption": true, + "figure": true, + "footer": true, + "form": true, + "frame": true, + "frameset": true, + "h1": true, + "h2": true, + "h3": true, + "h4": true, + "h5": true, + "h6": true, + "head": true, + "header": true, + "hgroup": true, + "hr": true, + "html": true, + "iframe": true, + "img": true, + "input": true, + "isindex": true, + "li": true, + "link": true, + "listing": true, + "marquee": true, + "menu": true, + "meta": true, + "nav": true, + "noembed": true, + "noframes": true, + "noscript": true, + "object": true, + "ol": true, + "p": true, + "param": true, + "plaintext": true, + "pre": true, + "script": true, + "section": true, + "select": true, + "source": true, + "style": true, + "summary": true, + "table": true, + "tbody": true, + "td": true, + "template": true, + "textarea": true, + "tfoot": true, + "th": true, + "thead": true, + "title": true, + "tr": true, + "track": true, + "ul": true, + "wbr": true, + "xmp": true, +} + +func isSpecialElement(element *Node) bool { + switch element.Namespace { + case "", "html": + return isSpecialElementMap[element.Data] + case "svg": + return element.Data == "foreignObject" + } + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/doc.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/doc.go new file mode 100644 index 00000000..94f49687 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/doc.go @@ -0,0 +1,106 @@ +// 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 html implements an HTML5-compliant tokenizer and parser. + +Tokenization is done by creating a Tokenizer for an io.Reader r. It is the +caller's responsibility to ensure that r provides UTF-8 encoded HTML. + + z := html.NewTokenizer(r) + +Given a Tokenizer z, the HTML is tokenized by repeatedly calling z.Next(), +which parses the next token and returns its type, or an error: + + for { + tt := z.Next() + if tt == html.ErrorToken { + // ... + return ... + } + // Process the current token. + } + +There are two APIs for retrieving the current token. The high-level API is to +call Token; the low-level API is to call Text or TagName / TagAttr. Both APIs +allow optionally calling Raw after Next but before Token, Text, TagName, or +TagAttr. In EBNF notation, the valid call sequence per token is: + + Next {Raw} [ Token | Text | TagName {TagAttr} ] + +Token returns an independent data structure that completely describes a token. +Entities (such as "<") are unescaped, tag names and attribute keys are +lower-cased, and attributes are collected into a []Attribute. For example: + + for { + if z.Next() == html.ErrorToken { + // Returning io.EOF indicates success. + return z.Err() + } + emitToken(z.Token()) + } + +The low-level API performs fewer allocations and copies, but the contents of +the []byte values returned by Text, TagName and TagAttr may change on the next +call to Next. For example, to extract an HTML page's anchor text: + + depth := 0 + for { + tt := z.Next() + switch tt { + case ErrorToken: + return z.Err() + case TextToken: + if depth > 0 { + // emitBytes should copy the []byte it receives, + // if it doesn't process it immediately. + emitBytes(z.Text()) + } + case StartTagToken, EndTagToken: + tn, _ := z.TagName() + if len(tn) == 1 && tn[0] == 'a' { + if tt == StartTagToken { + depth++ + } else { + depth-- + } + } + } + } + +Parsing is done by calling Parse with an io.Reader, which returns the root of +the parse tree (the document element) as a *Node. It is the caller's +responsibility to ensure that the Reader provides UTF-8 encoded HTML. For +example, to process each anchor node in depth-first order: + + doc, err := html.Parse(r) + if err != nil { + // ... + } + var f func(*html.Node) + f = func(n *html.Node) { + if n.Type == html.ElementNode && n.Data == "a" { + // Do something with n... + } + for c := n.FirstChild; c != nil; c = c.NextSibling { + f(c) + } + } + f(doc) + +The relevant specifications include: +https://html.spec.whatwg.org/multipage/syntax.html and +https://html.spec.whatwg.org/multipage/syntax.html#tokenization +*/ +package html // import "golang.org/x/net/html" + +// The tokenization algorithm implemented by this package is not a line-by-line +// transliteration of the relatively verbose state-machine in the WHATWG +// specification. A more direct approach is used instead, where the program +// counter implies the state, such as whether it is tokenizing a tag or a text +// node. Specification compliance is verified by checking expected and actual +// outputs over a test suite rather than aiming for algorithmic fidelity. + +// TODO(nigeltao): Does a DOM API belong in this package or a separate one? +// TODO(nigeltao): How does parsing interact with a JavaScript engine? diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/doctype.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/doctype.go new file mode 100644 index 00000000..c484e5a9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/doctype.go @@ -0,0 +1,156 @@ +// 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 html + +import ( + "strings" +) + +// parseDoctype parses the data from a DoctypeToken into a name, +// public identifier, and system identifier. It returns a Node whose Type +// is DoctypeNode, whose Data is the name, and which has attributes +// named "system" and "public" for the two identifiers if they were present. +// quirks is whether the document should be parsed in "quirks mode". +func parseDoctype(s string) (n *Node, quirks bool) { + n = &Node{Type: DoctypeNode} + + // Find the name. + space := strings.IndexAny(s, whitespace) + if space == -1 { + space = len(s) + } + n.Data = s[:space] + // The comparison to "html" is case-sensitive. + if n.Data != "html" { + quirks = true + } + n.Data = strings.ToLower(n.Data) + s = strings.TrimLeft(s[space:], whitespace) + + if len(s) < 6 { + // It can't start with "PUBLIC" or "SYSTEM". + // Ignore the rest of the string. + return n, quirks || s != "" + } + + key := strings.ToLower(s[:6]) + s = s[6:] + for key == "public" || key == "system" { + s = strings.TrimLeft(s, whitespace) + if s == "" { + break + } + quote := s[0] + if quote != '"' && quote != '\'' { + break + } + s = s[1:] + q := strings.IndexRune(s, rune(quote)) + var id string + if q == -1 { + id = s + s = "" + } else { + id = s[:q] + s = s[q+1:] + } + n.Attr = append(n.Attr, Attribute{Key: key, Val: id}) + if key == "public" { + key = "system" + } else { + key = "" + } + } + + if key != "" || s != "" { + quirks = true + } else if len(n.Attr) > 0 { + if n.Attr[0].Key == "public" { + public := strings.ToLower(n.Attr[0].Val) + switch public { + case "-//w3o//dtd w3 html strict 3.0//en//", "-/w3d/dtd html 4.0 transitional/en", "html": + quirks = true + default: + for _, q := range quirkyIDs { + if strings.HasPrefix(public, q) { + quirks = true + break + } + } + } + // The following two public IDs only cause quirks mode if there is no system ID. + if len(n.Attr) == 1 && (strings.HasPrefix(public, "-//w3c//dtd html 4.01 frameset//") || + strings.HasPrefix(public, "-//w3c//dtd html 4.01 transitional//")) { + quirks = true + } + } + if lastAttr := n.Attr[len(n.Attr)-1]; lastAttr.Key == "system" && + strings.ToLower(lastAttr.Val) == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd" { + quirks = true + } + } + + return n, quirks +} + +// quirkyIDs is a list of public doctype identifiers that cause a document +// to be interpreted in quirks mode. The identifiers should be in lower case. +var quirkyIDs = []string{ + "+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//", +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/entity.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/entity.go new file mode 100644 index 00000000..a50c04c6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/entity.go @@ -0,0 +1,2253 @@ +// 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 html + +// All entities that do not end with ';' are 6 or fewer bytes long. +const longestEntityWithoutSemicolon = 6 + +// entity is a map from HTML entity names to their values. The semicolon matters: +// https://html.spec.whatwg.org/multipage/syntax.html#named-character-references +// lists both "amp" and "amp;" as two separate entries. +// +// Note that the HTML5 list is larger than the HTML4 list at +// http://www.w3.org/TR/html4/sgml/entities.html +var entity = map[string]rune{ + "AElig;": '\U000000C6', + "AMP;": '\U00000026', + "Aacute;": '\U000000C1', + "Abreve;": '\U00000102', + "Acirc;": '\U000000C2', + "Acy;": '\U00000410', + "Afr;": '\U0001D504', + "Agrave;": '\U000000C0', + "Alpha;": '\U00000391', + "Amacr;": '\U00000100', + "And;": '\U00002A53', + "Aogon;": '\U00000104', + "Aopf;": '\U0001D538', + "ApplyFunction;": '\U00002061', + "Aring;": '\U000000C5', + "Ascr;": '\U0001D49C', + "Assign;": '\U00002254', + "Atilde;": '\U000000C3', + "Auml;": '\U000000C4', + "Backslash;": '\U00002216', + "Barv;": '\U00002AE7', + "Barwed;": '\U00002306', + "Bcy;": '\U00000411', + "Because;": '\U00002235', + "Bernoullis;": '\U0000212C', + "Beta;": '\U00000392', + "Bfr;": '\U0001D505', + "Bopf;": '\U0001D539', + "Breve;": '\U000002D8', + "Bscr;": '\U0000212C', + "Bumpeq;": '\U0000224E', + "CHcy;": '\U00000427', + "COPY;": '\U000000A9', + "Cacute;": '\U00000106', + "Cap;": '\U000022D2', + "CapitalDifferentialD;": '\U00002145', + "Cayleys;": '\U0000212D', + "Ccaron;": '\U0000010C', + "Ccedil;": '\U000000C7', + "Ccirc;": '\U00000108', + "Cconint;": '\U00002230', + "Cdot;": '\U0000010A', + "Cedilla;": '\U000000B8', + "CenterDot;": '\U000000B7', + "Cfr;": '\U0000212D', + "Chi;": '\U000003A7', + "CircleDot;": '\U00002299', + "CircleMinus;": '\U00002296', + "CirclePlus;": '\U00002295', + "CircleTimes;": '\U00002297', + "ClockwiseContourIntegral;": '\U00002232', + "CloseCurlyDoubleQuote;": '\U0000201D', + "CloseCurlyQuote;": '\U00002019', + "Colon;": '\U00002237', + "Colone;": '\U00002A74', + "Congruent;": '\U00002261', + "Conint;": '\U0000222F', + "ContourIntegral;": '\U0000222E', + "Copf;": '\U00002102', + "Coproduct;": '\U00002210', + "CounterClockwiseContourIntegral;": '\U00002233', + "Cross;": '\U00002A2F', + "Cscr;": '\U0001D49E', + "Cup;": '\U000022D3', + "CupCap;": '\U0000224D', + "DD;": '\U00002145', + "DDotrahd;": '\U00002911', + "DJcy;": '\U00000402', + "DScy;": '\U00000405', + "DZcy;": '\U0000040F', + "Dagger;": '\U00002021', + "Darr;": '\U000021A1', + "Dashv;": '\U00002AE4', + "Dcaron;": '\U0000010E', + "Dcy;": '\U00000414', + "Del;": '\U00002207', + "Delta;": '\U00000394', + "Dfr;": '\U0001D507', + "DiacriticalAcute;": '\U000000B4', + "DiacriticalDot;": '\U000002D9', + "DiacriticalDoubleAcute;": '\U000002DD', + "DiacriticalGrave;": '\U00000060', + "DiacriticalTilde;": '\U000002DC', + "Diamond;": '\U000022C4', + "DifferentialD;": '\U00002146', + "Dopf;": '\U0001D53B', + "Dot;": '\U000000A8', + "DotDot;": '\U000020DC', + "DotEqual;": '\U00002250', + "DoubleContourIntegral;": '\U0000222F', + "DoubleDot;": '\U000000A8', + "DoubleDownArrow;": '\U000021D3', + "DoubleLeftArrow;": '\U000021D0', + "DoubleLeftRightArrow;": '\U000021D4', + "DoubleLeftTee;": '\U00002AE4', + "DoubleLongLeftArrow;": '\U000027F8', + "DoubleLongLeftRightArrow;": '\U000027FA', + "DoubleLongRightArrow;": '\U000027F9', + "DoubleRightArrow;": '\U000021D2', + "DoubleRightTee;": '\U000022A8', + "DoubleUpArrow;": '\U000021D1', + "DoubleUpDownArrow;": '\U000021D5', + "DoubleVerticalBar;": '\U00002225', + "DownArrow;": '\U00002193', + "DownArrowBar;": '\U00002913', + "DownArrowUpArrow;": '\U000021F5', + "DownBreve;": '\U00000311', + "DownLeftRightVector;": '\U00002950', + "DownLeftTeeVector;": '\U0000295E', + "DownLeftVector;": '\U000021BD', + "DownLeftVectorBar;": '\U00002956', + "DownRightTeeVector;": '\U0000295F', + "DownRightVector;": '\U000021C1', + "DownRightVectorBar;": '\U00002957', + "DownTee;": '\U000022A4', + "DownTeeArrow;": '\U000021A7', + "Downarrow;": '\U000021D3', + "Dscr;": '\U0001D49F', + "Dstrok;": '\U00000110', + "ENG;": '\U0000014A', + "ETH;": '\U000000D0', + "Eacute;": '\U000000C9', + "Ecaron;": '\U0000011A', + "Ecirc;": '\U000000CA', + "Ecy;": '\U0000042D', + "Edot;": '\U00000116', + "Efr;": '\U0001D508', + "Egrave;": '\U000000C8', + "Element;": '\U00002208', + "Emacr;": '\U00000112', + "EmptySmallSquare;": '\U000025FB', + "EmptyVerySmallSquare;": '\U000025AB', + "Eogon;": '\U00000118', + "Eopf;": '\U0001D53C', + "Epsilon;": '\U00000395', + "Equal;": '\U00002A75', + "EqualTilde;": '\U00002242', + "Equilibrium;": '\U000021CC', + "Escr;": '\U00002130', + "Esim;": '\U00002A73', + "Eta;": '\U00000397', + "Euml;": '\U000000CB', + "Exists;": '\U00002203', + "ExponentialE;": '\U00002147', + "Fcy;": '\U00000424', + "Ffr;": '\U0001D509', + "FilledSmallSquare;": '\U000025FC', + "FilledVerySmallSquare;": '\U000025AA', + "Fopf;": '\U0001D53D', + "ForAll;": '\U00002200', + "Fouriertrf;": '\U00002131', + "Fscr;": '\U00002131', + "GJcy;": '\U00000403', + "GT;": '\U0000003E', + "Gamma;": '\U00000393', + "Gammad;": '\U000003DC', + "Gbreve;": '\U0000011E', + "Gcedil;": '\U00000122', + "Gcirc;": '\U0000011C', + "Gcy;": '\U00000413', + "Gdot;": '\U00000120', + "Gfr;": '\U0001D50A', + "Gg;": '\U000022D9', + "Gopf;": '\U0001D53E', + "GreaterEqual;": '\U00002265', + "GreaterEqualLess;": '\U000022DB', + "GreaterFullEqual;": '\U00002267', + "GreaterGreater;": '\U00002AA2', + "GreaterLess;": '\U00002277', + "GreaterSlantEqual;": '\U00002A7E', + "GreaterTilde;": '\U00002273', + "Gscr;": '\U0001D4A2', + "Gt;": '\U0000226B', + "HARDcy;": '\U0000042A', + "Hacek;": '\U000002C7', + "Hat;": '\U0000005E', + "Hcirc;": '\U00000124', + "Hfr;": '\U0000210C', + "HilbertSpace;": '\U0000210B', + "Hopf;": '\U0000210D', + "HorizontalLine;": '\U00002500', + "Hscr;": '\U0000210B', + "Hstrok;": '\U00000126', + "HumpDownHump;": '\U0000224E', + "HumpEqual;": '\U0000224F', + "IEcy;": '\U00000415', + "IJlig;": '\U00000132', + "IOcy;": '\U00000401', + "Iacute;": '\U000000CD', + "Icirc;": '\U000000CE', + "Icy;": '\U00000418', + "Idot;": '\U00000130', + "Ifr;": '\U00002111', + "Igrave;": '\U000000CC', + "Im;": '\U00002111', + "Imacr;": '\U0000012A', + "ImaginaryI;": '\U00002148', + "Implies;": '\U000021D2', + "Int;": '\U0000222C', + "Integral;": '\U0000222B', + "Intersection;": '\U000022C2', + "InvisibleComma;": '\U00002063', + "InvisibleTimes;": '\U00002062', + "Iogon;": '\U0000012E', + "Iopf;": '\U0001D540', + "Iota;": '\U00000399', + "Iscr;": '\U00002110', + "Itilde;": '\U00000128', + "Iukcy;": '\U00000406', + "Iuml;": '\U000000CF', + "Jcirc;": '\U00000134', + "Jcy;": '\U00000419', + "Jfr;": '\U0001D50D', + "Jopf;": '\U0001D541', + "Jscr;": '\U0001D4A5', + "Jsercy;": '\U00000408', + "Jukcy;": '\U00000404', + "KHcy;": '\U00000425', + "KJcy;": '\U0000040C', + "Kappa;": '\U0000039A', + "Kcedil;": '\U00000136', + "Kcy;": '\U0000041A', + "Kfr;": '\U0001D50E', + "Kopf;": '\U0001D542', + "Kscr;": '\U0001D4A6', + "LJcy;": '\U00000409', + "LT;": '\U0000003C', + "Lacute;": '\U00000139', + "Lambda;": '\U0000039B', + "Lang;": '\U000027EA', + "Laplacetrf;": '\U00002112', + "Larr;": '\U0000219E', + "Lcaron;": '\U0000013D', + "Lcedil;": '\U0000013B', + "Lcy;": '\U0000041B', + "LeftAngleBracket;": '\U000027E8', + "LeftArrow;": '\U00002190', + "LeftArrowBar;": '\U000021E4', + "LeftArrowRightArrow;": '\U000021C6', + "LeftCeiling;": '\U00002308', + "LeftDoubleBracket;": '\U000027E6', + "LeftDownTeeVector;": '\U00002961', + "LeftDownVector;": '\U000021C3', + "LeftDownVectorBar;": '\U00002959', + "LeftFloor;": '\U0000230A', + "LeftRightArrow;": '\U00002194', + "LeftRightVector;": '\U0000294E', + "LeftTee;": '\U000022A3', + "LeftTeeArrow;": '\U000021A4', + "LeftTeeVector;": '\U0000295A', + "LeftTriangle;": '\U000022B2', + "LeftTriangleBar;": '\U000029CF', + "LeftTriangleEqual;": '\U000022B4', + "LeftUpDownVector;": '\U00002951', + "LeftUpTeeVector;": '\U00002960', + "LeftUpVector;": '\U000021BF', + "LeftUpVectorBar;": '\U00002958', + "LeftVector;": '\U000021BC', + "LeftVectorBar;": '\U00002952', + "Leftarrow;": '\U000021D0', + "Leftrightarrow;": '\U000021D4', + "LessEqualGreater;": '\U000022DA', + "LessFullEqual;": '\U00002266', + "LessGreater;": '\U00002276', + "LessLess;": '\U00002AA1', + "LessSlantEqual;": '\U00002A7D', + "LessTilde;": '\U00002272', + "Lfr;": '\U0001D50F', + "Ll;": '\U000022D8', + "Lleftarrow;": '\U000021DA', + "Lmidot;": '\U0000013F', + "LongLeftArrow;": '\U000027F5', + "LongLeftRightArrow;": '\U000027F7', + "LongRightArrow;": '\U000027F6', + "Longleftarrow;": '\U000027F8', + "Longleftrightarrow;": '\U000027FA', + "Longrightarrow;": '\U000027F9', + "Lopf;": '\U0001D543', + "LowerLeftArrow;": '\U00002199', + "LowerRightArrow;": '\U00002198', + "Lscr;": '\U00002112', + "Lsh;": '\U000021B0', + "Lstrok;": '\U00000141', + "Lt;": '\U0000226A', + "Map;": '\U00002905', + "Mcy;": '\U0000041C', + "MediumSpace;": '\U0000205F', + "Mellintrf;": '\U00002133', + "Mfr;": '\U0001D510', + "MinusPlus;": '\U00002213', + "Mopf;": '\U0001D544', + "Mscr;": '\U00002133', + "Mu;": '\U0000039C', + "NJcy;": '\U0000040A', + "Nacute;": '\U00000143', + "Ncaron;": '\U00000147', + "Ncedil;": '\U00000145', + "Ncy;": '\U0000041D', + "NegativeMediumSpace;": '\U0000200B', + "NegativeThickSpace;": '\U0000200B', + "NegativeThinSpace;": '\U0000200B', + "NegativeVeryThinSpace;": '\U0000200B', + "NestedGreaterGreater;": '\U0000226B', + "NestedLessLess;": '\U0000226A', + "NewLine;": '\U0000000A', + "Nfr;": '\U0001D511', + "NoBreak;": '\U00002060', + "NonBreakingSpace;": '\U000000A0', + "Nopf;": '\U00002115', + "Not;": '\U00002AEC', + "NotCongruent;": '\U00002262', + "NotCupCap;": '\U0000226D', + "NotDoubleVerticalBar;": '\U00002226', + "NotElement;": '\U00002209', + "NotEqual;": '\U00002260', + "NotExists;": '\U00002204', + "NotGreater;": '\U0000226F', + "NotGreaterEqual;": '\U00002271', + "NotGreaterLess;": '\U00002279', + "NotGreaterTilde;": '\U00002275', + "NotLeftTriangle;": '\U000022EA', + "NotLeftTriangleEqual;": '\U000022EC', + "NotLess;": '\U0000226E', + "NotLessEqual;": '\U00002270', + "NotLessGreater;": '\U00002278', + "NotLessTilde;": '\U00002274', + "NotPrecedes;": '\U00002280', + "NotPrecedesSlantEqual;": '\U000022E0', + "NotReverseElement;": '\U0000220C', + "NotRightTriangle;": '\U000022EB', + "NotRightTriangleEqual;": '\U000022ED', + "NotSquareSubsetEqual;": '\U000022E2', + "NotSquareSupersetEqual;": '\U000022E3', + "NotSubsetEqual;": '\U00002288', + "NotSucceeds;": '\U00002281', + "NotSucceedsSlantEqual;": '\U000022E1', + "NotSupersetEqual;": '\U00002289', + "NotTilde;": '\U00002241', + "NotTildeEqual;": '\U00002244', + "NotTildeFullEqual;": '\U00002247', + "NotTildeTilde;": '\U00002249', + "NotVerticalBar;": '\U00002224', + "Nscr;": '\U0001D4A9', + "Ntilde;": '\U000000D1', + "Nu;": '\U0000039D', + "OElig;": '\U00000152', + "Oacute;": '\U000000D3', + "Ocirc;": '\U000000D4', + "Ocy;": '\U0000041E', + "Odblac;": '\U00000150', + "Ofr;": '\U0001D512', + "Ograve;": '\U000000D2', + "Omacr;": '\U0000014C', + "Omega;": '\U000003A9', + "Omicron;": '\U0000039F', + "Oopf;": '\U0001D546', + "OpenCurlyDoubleQuote;": '\U0000201C', + "OpenCurlyQuote;": '\U00002018', + "Or;": '\U00002A54', + "Oscr;": '\U0001D4AA', + "Oslash;": '\U000000D8', + "Otilde;": '\U000000D5', + "Otimes;": '\U00002A37', + "Ouml;": '\U000000D6', + "OverBar;": '\U0000203E', + "OverBrace;": '\U000023DE', + "OverBracket;": '\U000023B4', + "OverParenthesis;": '\U000023DC', + "PartialD;": '\U00002202', + "Pcy;": '\U0000041F', + "Pfr;": '\U0001D513', + "Phi;": '\U000003A6', + "Pi;": '\U000003A0', + "PlusMinus;": '\U000000B1', + "Poincareplane;": '\U0000210C', + "Popf;": '\U00002119', + "Pr;": '\U00002ABB', + "Precedes;": '\U0000227A', + "PrecedesEqual;": '\U00002AAF', + "PrecedesSlantEqual;": '\U0000227C', + "PrecedesTilde;": '\U0000227E', + "Prime;": '\U00002033', + "Product;": '\U0000220F', + "Proportion;": '\U00002237', + "Proportional;": '\U0000221D', + "Pscr;": '\U0001D4AB', + "Psi;": '\U000003A8', + "QUOT;": '\U00000022', + "Qfr;": '\U0001D514', + "Qopf;": '\U0000211A', + "Qscr;": '\U0001D4AC', + "RBarr;": '\U00002910', + "REG;": '\U000000AE', + "Racute;": '\U00000154', + "Rang;": '\U000027EB', + "Rarr;": '\U000021A0', + "Rarrtl;": '\U00002916', + "Rcaron;": '\U00000158', + "Rcedil;": '\U00000156', + "Rcy;": '\U00000420', + "Re;": '\U0000211C', + "ReverseElement;": '\U0000220B', + "ReverseEquilibrium;": '\U000021CB', + "ReverseUpEquilibrium;": '\U0000296F', + "Rfr;": '\U0000211C', + "Rho;": '\U000003A1', + "RightAngleBracket;": '\U000027E9', + "RightArrow;": '\U00002192', + "RightArrowBar;": '\U000021E5', + "RightArrowLeftArrow;": '\U000021C4', + "RightCeiling;": '\U00002309', + "RightDoubleBracket;": '\U000027E7', + "RightDownTeeVector;": '\U0000295D', + "RightDownVector;": '\U000021C2', + "RightDownVectorBar;": '\U00002955', + "RightFloor;": '\U0000230B', + "RightTee;": '\U000022A2', + "RightTeeArrow;": '\U000021A6', + "RightTeeVector;": '\U0000295B', + "RightTriangle;": '\U000022B3', + "RightTriangleBar;": '\U000029D0', + "RightTriangleEqual;": '\U000022B5', + "RightUpDownVector;": '\U0000294F', + "RightUpTeeVector;": '\U0000295C', + "RightUpVector;": '\U000021BE', + "RightUpVectorBar;": '\U00002954', + "RightVector;": '\U000021C0', + "RightVectorBar;": '\U00002953', + "Rightarrow;": '\U000021D2', + "Ropf;": '\U0000211D', + "RoundImplies;": '\U00002970', + "Rrightarrow;": '\U000021DB', + "Rscr;": '\U0000211B', + "Rsh;": '\U000021B1', + "RuleDelayed;": '\U000029F4', + "SHCHcy;": '\U00000429', + "SHcy;": '\U00000428', + "SOFTcy;": '\U0000042C', + "Sacute;": '\U0000015A', + "Sc;": '\U00002ABC', + "Scaron;": '\U00000160', + "Scedil;": '\U0000015E', + "Scirc;": '\U0000015C', + "Scy;": '\U00000421', + "Sfr;": '\U0001D516', + "ShortDownArrow;": '\U00002193', + "ShortLeftArrow;": '\U00002190', + "ShortRightArrow;": '\U00002192', + "ShortUpArrow;": '\U00002191', + "Sigma;": '\U000003A3', + "SmallCircle;": '\U00002218', + "Sopf;": '\U0001D54A', + "Sqrt;": '\U0000221A', + "Square;": '\U000025A1', + "SquareIntersection;": '\U00002293', + "SquareSubset;": '\U0000228F', + "SquareSubsetEqual;": '\U00002291', + "SquareSuperset;": '\U00002290', + "SquareSupersetEqual;": '\U00002292', + "SquareUnion;": '\U00002294', + "Sscr;": '\U0001D4AE', + "Star;": '\U000022C6', + "Sub;": '\U000022D0', + "Subset;": '\U000022D0', + "SubsetEqual;": '\U00002286', + "Succeeds;": '\U0000227B', + "SucceedsEqual;": '\U00002AB0', + "SucceedsSlantEqual;": '\U0000227D', + "SucceedsTilde;": '\U0000227F', + "SuchThat;": '\U0000220B', + "Sum;": '\U00002211', + "Sup;": '\U000022D1', + "Superset;": '\U00002283', + "SupersetEqual;": '\U00002287', + "Supset;": '\U000022D1', + "THORN;": '\U000000DE', + "TRADE;": '\U00002122', + "TSHcy;": '\U0000040B', + "TScy;": '\U00000426', + "Tab;": '\U00000009', + "Tau;": '\U000003A4', + "Tcaron;": '\U00000164', + "Tcedil;": '\U00000162', + "Tcy;": '\U00000422', + "Tfr;": '\U0001D517', + "Therefore;": '\U00002234', + "Theta;": '\U00000398', + "ThinSpace;": '\U00002009', + "Tilde;": '\U0000223C', + "TildeEqual;": '\U00002243', + "TildeFullEqual;": '\U00002245', + "TildeTilde;": '\U00002248', + "Topf;": '\U0001D54B', + "TripleDot;": '\U000020DB', + "Tscr;": '\U0001D4AF', + "Tstrok;": '\U00000166', + "Uacute;": '\U000000DA', + "Uarr;": '\U0000219F', + "Uarrocir;": '\U00002949', + "Ubrcy;": '\U0000040E', + "Ubreve;": '\U0000016C', + "Ucirc;": '\U000000DB', + "Ucy;": '\U00000423', + "Udblac;": '\U00000170', + "Ufr;": '\U0001D518', + "Ugrave;": '\U000000D9', + "Umacr;": '\U0000016A', + "UnderBar;": '\U0000005F', + "UnderBrace;": '\U000023DF', + "UnderBracket;": '\U000023B5', + "UnderParenthesis;": '\U000023DD', + "Union;": '\U000022C3', + "UnionPlus;": '\U0000228E', + "Uogon;": '\U00000172', + "Uopf;": '\U0001D54C', + "UpArrow;": '\U00002191', + "UpArrowBar;": '\U00002912', + "UpArrowDownArrow;": '\U000021C5', + "UpDownArrow;": '\U00002195', + "UpEquilibrium;": '\U0000296E', + "UpTee;": '\U000022A5', + "UpTeeArrow;": '\U000021A5', + "Uparrow;": '\U000021D1', + "Updownarrow;": '\U000021D5', + "UpperLeftArrow;": '\U00002196', + "UpperRightArrow;": '\U00002197', + "Upsi;": '\U000003D2', + "Upsilon;": '\U000003A5', + "Uring;": '\U0000016E', + "Uscr;": '\U0001D4B0', + "Utilde;": '\U00000168', + "Uuml;": '\U000000DC', + "VDash;": '\U000022AB', + "Vbar;": '\U00002AEB', + "Vcy;": '\U00000412', + "Vdash;": '\U000022A9', + "Vdashl;": '\U00002AE6', + "Vee;": '\U000022C1', + "Verbar;": '\U00002016', + "Vert;": '\U00002016', + "VerticalBar;": '\U00002223', + "VerticalLine;": '\U0000007C', + "VerticalSeparator;": '\U00002758', + "VerticalTilde;": '\U00002240', + "VeryThinSpace;": '\U0000200A', + "Vfr;": '\U0001D519', + "Vopf;": '\U0001D54D', + "Vscr;": '\U0001D4B1', + "Vvdash;": '\U000022AA', + "Wcirc;": '\U00000174', + "Wedge;": '\U000022C0', + "Wfr;": '\U0001D51A', + "Wopf;": '\U0001D54E', + "Wscr;": '\U0001D4B2', + "Xfr;": '\U0001D51B', + "Xi;": '\U0000039E', + "Xopf;": '\U0001D54F', + "Xscr;": '\U0001D4B3', + "YAcy;": '\U0000042F', + "YIcy;": '\U00000407', + "YUcy;": '\U0000042E', + "Yacute;": '\U000000DD', + "Ycirc;": '\U00000176', + "Ycy;": '\U0000042B', + "Yfr;": '\U0001D51C', + "Yopf;": '\U0001D550', + "Yscr;": '\U0001D4B4', + "Yuml;": '\U00000178', + "ZHcy;": '\U00000416', + "Zacute;": '\U00000179', + "Zcaron;": '\U0000017D', + "Zcy;": '\U00000417', + "Zdot;": '\U0000017B', + "ZeroWidthSpace;": '\U0000200B', + "Zeta;": '\U00000396', + "Zfr;": '\U00002128', + "Zopf;": '\U00002124', + "Zscr;": '\U0001D4B5', + "aacute;": '\U000000E1', + "abreve;": '\U00000103', + "ac;": '\U0000223E', + "acd;": '\U0000223F', + "acirc;": '\U000000E2', + "acute;": '\U000000B4', + "acy;": '\U00000430', + "aelig;": '\U000000E6', + "af;": '\U00002061', + "afr;": '\U0001D51E', + "agrave;": '\U000000E0', + "alefsym;": '\U00002135', + "aleph;": '\U00002135', + "alpha;": '\U000003B1', + "amacr;": '\U00000101', + "amalg;": '\U00002A3F', + "amp;": '\U00000026', + "and;": '\U00002227', + "andand;": '\U00002A55', + "andd;": '\U00002A5C', + "andslope;": '\U00002A58', + "andv;": '\U00002A5A', + "ang;": '\U00002220', + "ange;": '\U000029A4', + "angle;": '\U00002220', + "angmsd;": '\U00002221', + "angmsdaa;": '\U000029A8', + "angmsdab;": '\U000029A9', + "angmsdac;": '\U000029AA', + "angmsdad;": '\U000029AB', + "angmsdae;": '\U000029AC', + "angmsdaf;": '\U000029AD', + "angmsdag;": '\U000029AE', + "angmsdah;": '\U000029AF', + "angrt;": '\U0000221F', + "angrtvb;": '\U000022BE', + "angrtvbd;": '\U0000299D', + "angsph;": '\U00002222', + "angst;": '\U000000C5', + "angzarr;": '\U0000237C', + "aogon;": '\U00000105', + "aopf;": '\U0001D552', + "ap;": '\U00002248', + "apE;": '\U00002A70', + "apacir;": '\U00002A6F', + "ape;": '\U0000224A', + "apid;": '\U0000224B', + "apos;": '\U00000027', + "approx;": '\U00002248', + "approxeq;": '\U0000224A', + "aring;": '\U000000E5', + "ascr;": '\U0001D4B6', + "ast;": '\U0000002A', + "asymp;": '\U00002248', + "asympeq;": '\U0000224D', + "atilde;": '\U000000E3', + "auml;": '\U000000E4', + "awconint;": '\U00002233', + "awint;": '\U00002A11', + "bNot;": '\U00002AED', + "backcong;": '\U0000224C', + "backepsilon;": '\U000003F6', + "backprime;": '\U00002035', + "backsim;": '\U0000223D', + "backsimeq;": '\U000022CD', + "barvee;": '\U000022BD', + "barwed;": '\U00002305', + "barwedge;": '\U00002305', + "bbrk;": '\U000023B5', + "bbrktbrk;": '\U000023B6', + "bcong;": '\U0000224C', + "bcy;": '\U00000431', + "bdquo;": '\U0000201E', + "becaus;": '\U00002235', + "because;": '\U00002235', + "bemptyv;": '\U000029B0', + "bepsi;": '\U000003F6', + "bernou;": '\U0000212C', + "beta;": '\U000003B2', + "beth;": '\U00002136', + "between;": '\U0000226C', + "bfr;": '\U0001D51F', + "bigcap;": '\U000022C2', + "bigcirc;": '\U000025EF', + "bigcup;": '\U000022C3', + "bigodot;": '\U00002A00', + "bigoplus;": '\U00002A01', + "bigotimes;": '\U00002A02', + "bigsqcup;": '\U00002A06', + "bigstar;": '\U00002605', + "bigtriangledown;": '\U000025BD', + "bigtriangleup;": '\U000025B3', + "biguplus;": '\U00002A04', + "bigvee;": '\U000022C1', + "bigwedge;": '\U000022C0', + "bkarow;": '\U0000290D', + "blacklozenge;": '\U000029EB', + "blacksquare;": '\U000025AA', + "blacktriangle;": '\U000025B4', + "blacktriangledown;": '\U000025BE', + "blacktriangleleft;": '\U000025C2', + "blacktriangleright;": '\U000025B8', + "blank;": '\U00002423', + "blk12;": '\U00002592', + "blk14;": '\U00002591', + "blk34;": '\U00002593', + "block;": '\U00002588', + "bnot;": '\U00002310', + "bopf;": '\U0001D553', + "bot;": '\U000022A5', + "bottom;": '\U000022A5', + "bowtie;": '\U000022C8', + "boxDL;": '\U00002557', + "boxDR;": '\U00002554', + "boxDl;": '\U00002556', + "boxDr;": '\U00002553', + "boxH;": '\U00002550', + "boxHD;": '\U00002566', + "boxHU;": '\U00002569', + "boxHd;": '\U00002564', + "boxHu;": '\U00002567', + "boxUL;": '\U0000255D', + "boxUR;": '\U0000255A', + "boxUl;": '\U0000255C', + "boxUr;": '\U00002559', + "boxV;": '\U00002551', + "boxVH;": '\U0000256C', + "boxVL;": '\U00002563', + "boxVR;": '\U00002560', + "boxVh;": '\U0000256B', + "boxVl;": '\U00002562', + "boxVr;": '\U0000255F', + "boxbox;": '\U000029C9', + "boxdL;": '\U00002555', + "boxdR;": '\U00002552', + "boxdl;": '\U00002510', + "boxdr;": '\U0000250C', + "boxh;": '\U00002500', + "boxhD;": '\U00002565', + "boxhU;": '\U00002568', + "boxhd;": '\U0000252C', + "boxhu;": '\U00002534', + "boxminus;": '\U0000229F', + "boxplus;": '\U0000229E', + "boxtimes;": '\U000022A0', + "boxuL;": '\U0000255B', + "boxuR;": '\U00002558', + "boxul;": '\U00002518', + "boxur;": '\U00002514', + "boxv;": '\U00002502', + "boxvH;": '\U0000256A', + "boxvL;": '\U00002561', + "boxvR;": '\U0000255E', + "boxvh;": '\U0000253C', + "boxvl;": '\U00002524', + "boxvr;": '\U0000251C', + "bprime;": '\U00002035', + "breve;": '\U000002D8', + "brvbar;": '\U000000A6', + "bscr;": '\U0001D4B7', + "bsemi;": '\U0000204F', + "bsim;": '\U0000223D', + "bsime;": '\U000022CD', + "bsol;": '\U0000005C', + "bsolb;": '\U000029C5', + "bsolhsub;": '\U000027C8', + "bull;": '\U00002022', + "bullet;": '\U00002022', + "bump;": '\U0000224E', + "bumpE;": '\U00002AAE', + "bumpe;": '\U0000224F', + "bumpeq;": '\U0000224F', + "cacute;": '\U00000107', + "cap;": '\U00002229', + "capand;": '\U00002A44', + "capbrcup;": '\U00002A49', + "capcap;": '\U00002A4B', + "capcup;": '\U00002A47', + "capdot;": '\U00002A40', + "caret;": '\U00002041', + "caron;": '\U000002C7', + "ccaps;": '\U00002A4D', + "ccaron;": '\U0000010D', + "ccedil;": '\U000000E7', + "ccirc;": '\U00000109', + "ccups;": '\U00002A4C', + "ccupssm;": '\U00002A50', + "cdot;": '\U0000010B', + "cedil;": '\U000000B8', + "cemptyv;": '\U000029B2', + "cent;": '\U000000A2', + "centerdot;": '\U000000B7', + "cfr;": '\U0001D520', + "chcy;": '\U00000447', + "check;": '\U00002713', + "checkmark;": '\U00002713', + "chi;": '\U000003C7', + "cir;": '\U000025CB', + "cirE;": '\U000029C3', + "circ;": '\U000002C6', + "circeq;": '\U00002257', + "circlearrowleft;": '\U000021BA', + "circlearrowright;": '\U000021BB', + "circledR;": '\U000000AE', + "circledS;": '\U000024C8', + "circledast;": '\U0000229B', + "circledcirc;": '\U0000229A', + "circleddash;": '\U0000229D', + "cire;": '\U00002257', + "cirfnint;": '\U00002A10', + "cirmid;": '\U00002AEF', + "cirscir;": '\U000029C2', + "clubs;": '\U00002663', + "clubsuit;": '\U00002663', + "colon;": '\U0000003A', + "colone;": '\U00002254', + "coloneq;": '\U00002254', + "comma;": '\U0000002C', + "commat;": '\U00000040', + "comp;": '\U00002201', + "compfn;": '\U00002218', + "complement;": '\U00002201', + "complexes;": '\U00002102', + "cong;": '\U00002245', + "congdot;": '\U00002A6D', + "conint;": '\U0000222E', + "copf;": '\U0001D554', + "coprod;": '\U00002210', + "copy;": '\U000000A9', + "copysr;": '\U00002117', + "crarr;": '\U000021B5', + "cross;": '\U00002717', + "cscr;": '\U0001D4B8', + "csub;": '\U00002ACF', + "csube;": '\U00002AD1', + "csup;": '\U00002AD0', + "csupe;": '\U00002AD2', + "ctdot;": '\U000022EF', + "cudarrl;": '\U00002938', + "cudarrr;": '\U00002935', + "cuepr;": '\U000022DE', + "cuesc;": '\U000022DF', + "cularr;": '\U000021B6', + "cularrp;": '\U0000293D', + "cup;": '\U0000222A', + "cupbrcap;": '\U00002A48', + "cupcap;": '\U00002A46', + "cupcup;": '\U00002A4A', + "cupdot;": '\U0000228D', + "cupor;": '\U00002A45', + "curarr;": '\U000021B7', + "curarrm;": '\U0000293C', + "curlyeqprec;": '\U000022DE', + "curlyeqsucc;": '\U000022DF', + "curlyvee;": '\U000022CE', + "curlywedge;": '\U000022CF', + "curren;": '\U000000A4', + "curvearrowleft;": '\U000021B6', + "curvearrowright;": '\U000021B7', + "cuvee;": '\U000022CE', + "cuwed;": '\U000022CF', + "cwconint;": '\U00002232', + "cwint;": '\U00002231', + "cylcty;": '\U0000232D', + "dArr;": '\U000021D3', + "dHar;": '\U00002965', + "dagger;": '\U00002020', + "daleth;": '\U00002138', + "darr;": '\U00002193', + "dash;": '\U00002010', + "dashv;": '\U000022A3', + "dbkarow;": '\U0000290F', + "dblac;": '\U000002DD', + "dcaron;": '\U0000010F', + "dcy;": '\U00000434', + "dd;": '\U00002146', + "ddagger;": '\U00002021', + "ddarr;": '\U000021CA', + "ddotseq;": '\U00002A77', + "deg;": '\U000000B0', + "delta;": '\U000003B4', + "demptyv;": '\U000029B1', + "dfisht;": '\U0000297F', + "dfr;": '\U0001D521', + "dharl;": '\U000021C3', + "dharr;": '\U000021C2', + "diam;": '\U000022C4', + "diamond;": '\U000022C4', + "diamondsuit;": '\U00002666', + "diams;": '\U00002666', + "die;": '\U000000A8', + "digamma;": '\U000003DD', + "disin;": '\U000022F2', + "div;": '\U000000F7', + "divide;": '\U000000F7', + "divideontimes;": '\U000022C7', + "divonx;": '\U000022C7', + "djcy;": '\U00000452', + "dlcorn;": '\U0000231E', + "dlcrop;": '\U0000230D', + "dollar;": '\U00000024', + "dopf;": '\U0001D555', + "dot;": '\U000002D9', + "doteq;": '\U00002250', + "doteqdot;": '\U00002251', + "dotminus;": '\U00002238', + "dotplus;": '\U00002214', + "dotsquare;": '\U000022A1', + "doublebarwedge;": '\U00002306', + "downarrow;": '\U00002193', + "downdownarrows;": '\U000021CA', + "downharpoonleft;": '\U000021C3', + "downharpoonright;": '\U000021C2', + "drbkarow;": '\U00002910', + "drcorn;": '\U0000231F', + "drcrop;": '\U0000230C', + "dscr;": '\U0001D4B9', + "dscy;": '\U00000455', + "dsol;": '\U000029F6', + "dstrok;": '\U00000111', + "dtdot;": '\U000022F1', + "dtri;": '\U000025BF', + "dtrif;": '\U000025BE', + "duarr;": '\U000021F5', + "duhar;": '\U0000296F', + "dwangle;": '\U000029A6', + "dzcy;": '\U0000045F', + "dzigrarr;": '\U000027FF', + "eDDot;": '\U00002A77', + "eDot;": '\U00002251', + "eacute;": '\U000000E9', + "easter;": '\U00002A6E', + "ecaron;": '\U0000011B', + "ecir;": '\U00002256', + "ecirc;": '\U000000EA', + "ecolon;": '\U00002255', + "ecy;": '\U0000044D', + "edot;": '\U00000117', + "ee;": '\U00002147', + "efDot;": '\U00002252', + "efr;": '\U0001D522', + "eg;": '\U00002A9A', + "egrave;": '\U000000E8', + "egs;": '\U00002A96', + "egsdot;": '\U00002A98', + "el;": '\U00002A99', + "elinters;": '\U000023E7', + "ell;": '\U00002113', + "els;": '\U00002A95', + "elsdot;": '\U00002A97', + "emacr;": '\U00000113', + "empty;": '\U00002205', + "emptyset;": '\U00002205', + "emptyv;": '\U00002205', + "emsp;": '\U00002003', + "emsp13;": '\U00002004', + "emsp14;": '\U00002005', + "eng;": '\U0000014B', + "ensp;": '\U00002002', + "eogon;": '\U00000119', + "eopf;": '\U0001D556', + "epar;": '\U000022D5', + "eparsl;": '\U000029E3', + "eplus;": '\U00002A71', + "epsi;": '\U000003B5', + "epsilon;": '\U000003B5', + "epsiv;": '\U000003F5', + "eqcirc;": '\U00002256', + "eqcolon;": '\U00002255', + "eqsim;": '\U00002242', + "eqslantgtr;": '\U00002A96', + "eqslantless;": '\U00002A95', + "equals;": '\U0000003D', + "equest;": '\U0000225F', + "equiv;": '\U00002261', + "equivDD;": '\U00002A78', + "eqvparsl;": '\U000029E5', + "erDot;": '\U00002253', + "erarr;": '\U00002971', + "escr;": '\U0000212F', + "esdot;": '\U00002250', + "esim;": '\U00002242', + "eta;": '\U000003B7', + "eth;": '\U000000F0', + "euml;": '\U000000EB', + "euro;": '\U000020AC', + "excl;": '\U00000021', + "exist;": '\U00002203', + "expectation;": '\U00002130', + "exponentiale;": '\U00002147', + "fallingdotseq;": '\U00002252', + "fcy;": '\U00000444', + "female;": '\U00002640', + "ffilig;": '\U0000FB03', + "fflig;": '\U0000FB00', + "ffllig;": '\U0000FB04', + "ffr;": '\U0001D523', + "filig;": '\U0000FB01', + "flat;": '\U0000266D', + "fllig;": '\U0000FB02', + "fltns;": '\U000025B1', + "fnof;": '\U00000192', + "fopf;": '\U0001D557', + "forall;": '\U00002200', + "fork;": '\U000022D4', + "forkv;": '\U00002AD9', + "fpartint;": '\U00002A0D', + "frac12;": '\U000000BD', + "frac13;": '\U00002153', + "frac14;": '\U000000BC', + "frac15;": '\U00002155', + "frac16;": '\U00002159', + "frac18;": '\U0000215B', + "frac23;": '\U00002154', + "frac25;": '\U00002156', + "frac34;": '\U000000BE', + "frac35;": '\U00002157', + "frac38;": '\U0000215C', + "frac45;": '\U00002158', + "frac56;": '\U0000215A', + "frac58;": '\U0000215D', + "frac78;": '\U0000215E', + "frasl;": '\U00002044', + "frown;": '\U00002322', + "fscr;": '\U0001D4BB', + "gE;": '\U00002267', + "gEl;": '\U00002A8C', + "gacute;": '\U000001F5', + "gamma;": '\U000003B3', + "gammad;": '\U000003DD', + "gap;": '\U00002A86', + "gbreve;": '\U0000011F', + "gcirc;": '\U0000011D', + "gcy;": '\U00000433', + "gdot;": '\U00000121', + "ge;": '\U00002265', + "gel;": '\U000022DB', + "geq;": '\U00002265', + "geqq;": '\U00002267', + "geqslant;": '\U00002A7E', + "ges;": '\U00002A7E', + "gescc;": '\U00002AA9', + "gesdot;": '\U00002A80', + "gesdoto;": '\U00002A82', + "gesdotol;": '\U00002A84', + "gesles;": '\U00002A94', + "gfr;": '\U0001D524', + "gg;": '\U0000226B', + "ggg;": '\U000022D9', + "gimel;": '\U00002137', + "gjcy;": '\U00000453', + "gl;": '\U00002277', + "glE;": '\U00002A92', + "gla;": '\U00002AA5', + "glj;": '\U00002AA4', + "gnE;": '\U00002269', + "gnap;": '\U00002A8A', + "gnapprox;": '\U00002A8A', + "gne;": '\U00002A88', + "gneq;": '\U00002A88', + "gneqq;": '\U00002269', + "gnsim;": '\U000022E7', + "gopf;": '\U0001D558', + "grave;": '\U00000060', + "gscr;": '\U0000210A', + "gsim;": '\U00002273', + "gsime;": '\U00002A8E', + "gsiml;": '\U00002A90', + "gt;": '\U0000003E', + "gtcc;": '\U00002AA7', + "gtcir;": '\U00002A7A', + "gtdot;": '\U000022D7', + "gtlPar;": '\U00002995', + "gtquest;": '\U00002A7C', + "gtrapprox;": '\U00002A86', + "gtrarr;": '\U00002978', + "gtrdot;": '\U000022D7', + "gtreqless;": '\U000022DB', + "gtreqqless;": '\U00002A8C', + "gtrless;": '\U00002277', + "gtrsim;": '\U00002273', + "hArr;": '\U000021D4', + "hairsp;": '\U0000200A', + "half;": '\U000000BD', + "hamilt;": '\U0000210B', + "hardcy;": '\U0000044A', + "harr;": '\U00002194', + "harrcir;": '\U00002948', + "harrw;": '\U000021AD', + "hbar;": '\U0000210F', + "hcirc;": '\U00000125', + "hearts;": '\U00002665', + "heartsuit;": '\U00002665', + "hellip;": '\U00002026', + "hercon;": '\U000022B9', + "hfr;": '\U0001D525', + "hksearow;": '\U00002925', + "hkswarow;": '\U00002926', + "hoarr;": '\U000021FF', + "homtht;": '\U0000223B', + "hookleftarrow;": '\U000021A9', + "hookrightarrow;": '\U000021AA', + "hopf;": '\U0001D559', + "horbar;": '\U00002015', + "hscr;": '\U0001D4BD', + "hslash;": '\U0000210F', + "hstrok;": '\U00000127', + "hybull;": '\U00002043', + "hyphen;": '\U00002010', + "iacute;": '\U000000ED', + "ic;": '\U00002063', + "icirc;": '\U000000EE', + "icy;": '\U00000438', + "iecy;": '\U00000435', + "iexcl;": '\U000000A1', + "iff;": '\U000021D4', + "ifr;": '\U0001D526', + "igrave;": '\U000000EC', + "ii;": '\U00002148', + "iiiint;": '\U00002A0C', + "iiint;": '\U0000222D', + "iinfin;": '\U000029DC', + "iiota;": '\U00002129', + "ijlig;": '\U00000133', + "imacr;": '\U0000012B', + "image;": '\U00002111', + "imagline;": '\U00002110', + "imagpart;": '\U00002111', + "imath;": '\U00000131', + "imof;": '\U000022B7', + "imped;": '\U000001B5', + "in;": '\U00002208', + "incare;": '\U00002105', + "infin;": '\U0000221E', + "infintie;": '\U000029DD', + "inodot;": '\U00000131', + "int;": '\U0000222B', + "intcal;": '\U000022BA', + "integers;": '\U00002124', + "intercal;": '\U000022BA', + "intlarhk;": '\U00002A17', + "intprod;": '\U00002A3C', + "iocy;": '\U00000451', + "iogon;": '\U0000012F', + "iopf;": '\U0001D55A', + "iota;": '\U000003B9', + "iprod;": '\U00002A3C', + "iquest;": '\U000000BF', + "iscr;": '\U0001D4BE', + "isin;": '\U00002208', + "isinE;": '\U000022F9', + "isindot;": '\U000022F5', + "isins;": '\U000022F4', + "isinsv;": '\U000022F3', + "isinv;": '\U00002208', + "it;": '\U00002062', + "itilde;": '\U00000129', + "iukcy;": '\U00000456', + "iuml;": '\U000000EF', + "jcirc;": '\U00000135', + "jcy;": '\U00000439', + "jfr;": '\U0001D527', + "jmath;": '\U00000237', + "jopf;": '\U0001D55B', + "jscr;": '\U0001D4BF', + "jsercy;": '\U00000458', + "jukcy;": '\U00000454', + "kappa;": '\U000003BA', + "kappav;": '\U000003F0', + "kcedil;": '\U00000137', + "kcy;": '\U0000043A', + "kfr;": '\U0001D528', + "kgreen;": '\U00000138', + "khcy;": '\U00000445', + "kjcy;": '\U0000045C', + "kopf;": '\U0001D55C', + "kscr;": '\U0001D4C0', + "lAarr;": '\U000021DA', + "lArr;": '\U000021D0', + "lAtail;": '\U0000291B', + "lBarr;": '\U0000290E', + "lE;": '\U00002266', + "lEg;": '\U00002A8B', + "lHar;": '\U00002962', + "lacute;": '\U0000013A', + "laemptyv;": '\U000029B4', + "lagran;": '\U00002112', + "lambda;": '\U000003BB', + "lang;": '\U000027E8', + "langd;": '\U00002991', + "langle;": '\U000027E8', + "lap;": '\U00002A85', + "laquo;": '\U000000AB', + "larr;": '\U00002190', + "larrb;": '\U000021E4', + "larrbfs;": '\U0000291F', + "larrfs;": '\U0000291D', + "larrhk;": '\U000021A9', + "larrlp;": '\U000021AB', + "larrpl;": '\U00002939', + "larrsim;": '\U00002973', + "larrtl;": '\U000021A2', + "lat;": '\U00002AAB', + "latail;": '\U00002919', + "late;": '\U00002AAD', + "lbarr;": '\U0000290C', + "lbbrk;": '\U00002772', + "lbrace;": '\U0000007B', + "lbrack;": '\U0000005B', + "lbrke;": '\U0000298B', + "lbrksld;": '\U0000298F', + "lbrkslu;": '\U0000298D', + "lcaron;": '\U0000013E', + "lcedil;": '\U0000013C', + "lceil;": '\U00002308', + "lcub;": '\U0000007B', + "lcy;": '\U0000043B', + "ldca;": '\U00002936', + "ldquo;": '\U0000201C', + "ldquor;": '\U0000201E', + "ldrdhar;": '\U00002967', + "ldrushar;": '\U0000294B', + "ldsh;": '\U000021B2', + "le;": '\U00002264', + "leftarrow;": '\U00002190', + "leftarrowtail;": '\U000021A2', + "leftharpoondown;": '\U000021BD', + "leftharpoonup;": '\U000021BC', + "leftleftarrows;": '\U000021C7', + "leftrightarrow;": '\U00002194', + "leftrightarrows;": '\U000021C6', + "leftrightharpoons;": '\U000021CB', + "leftrightsquigarrow;": '\U000021AD', + "leftthreetimes;": '\U000022CB', + "leg;": '\U000022DA', + "leq;": '\U00002264', + "leqq;": '\U00002266', + "leqslant;": '\U00002A7D', + "les;": '\U00002A7D', + "lescc;": '\U00002AA8', + "lesdot;": '\U00002A7F', + "lesdoto;": '\U00002A81', + "lesdotor;": '\U00002A83', + "lesges;": '\U00002A93', + "lessapprox;": '\U00002A85', + "lessdot;": '\U000022D6', + "lesseqgtr;": '\U000022DA', + "lesseqqgtr;": '\U00002A8B', + "lessgtr;": '\U00002276', + "lesssim;": '\U00002272', + "lfisht;": '\U0000297C', + "lfloor;": '\U0000230A', + "lfr;": '\U0001D529', + "lg;": '\U00002276', + "lgE;": '\U00002A91', + "lhard;": '\U000021BD', + "lharu;": '\U000021BC', + "lharul;": '\U0000296A', + "lhblk;": '\U00002584', + "ljcy;": '\U00000459', + "ll;": '\U0000226A', + "llarr;": '\U000021C7', + "llcorner;": '\U0000231E', + "llhard;": '\U0000296B', + "lltri;": '\U000025FA', + "lmidot;": '\U00000140', + "lmoust;": '\U000023B0', + "lmoustache;": '\U000023B0', + "lnE;": '\U00002268', + "lnap;": '\U00002A89', + "lnapprox;": '\U00002A89', + "lne;": '\U00002A87', + "lneq;": '\U00002A87', + "lneqq;": '\U00002268', + "lnsim;": '\U000022E6', + "loang;": '\U000027EC', + "loarr;": '\U000021FD', + "lobrk;": '\U000027E6', + "longleftarrow;": '\U000027F5', + "longleftrightarrow;": '\U000027F7', + "longmapsto;": '\U000027FC', + "longrightarrow;": '\U000027F6', + "looparrowleft;": '\U000021AB', + "looparrowright;": '\U000021AC', + "lopar;": '\U00002985', + "lopf;": '\U0001D55D', + "loplus;": '\U00002A2D', + "lotimes;": '\U00002A34', + "lowast;": '\U00002217', + "lowbar;": '\U0000005F', + "loz;": '\U000025CA', + "lozenge;": '\U000025CA', + "lozf;": '\U000029EB', + "lpar;": '\U00000028', + "lparlt;": '\U00002993', + "lrarr;": '\U000021C6', + "lrcorner;": '\U0000231F', + "lrhar;": '\U000021CB', + "lrhard;": '\U0000296D', + "lrm;": '\U0000200E', + "lrtri;": '\U000022BF', + "lsaquo;": '\U00002039', + "lscr;": '\U0001D4C1', + "lsh;": '\U000021B0', + "lsim;": '\U00002272', + "lsime;": '\U00002A8D', + "lsimg;": '\U00002A8F', + "lsqb;": '\U0000005B', + "lsquo;": '\U00002018', + "lsquor;": '\U0000201A', + "lstrok;": '\U00000142', + "lt;": '\U0000003C', + "ltcc;": '\U00002AA6', + "ltcir;": '\U00002A79', + "ltdot;": '\U000022D6', + "lthree;": '\U000022CB', + "ltimes;": '\U000022C9', + "ltlarr;": '\U00002976', + "ltquest;": '\U00002A7B', + "ltrPar;": '\U00002996', + "ltri;": '\U000025C3', + "ltrie;": '\U000022B4', + "ltrif;": '\U000025C2', + "lurdshar;": '\U0000294A', + "luruhar;": '\U00002966', + "mDDot;": '\U0000223A', + "macr;": '\U000000AF', + "male;": '\U00002642', + "malt;": '\U00002720', + "maltese;": '\U00002720', + "map;": '\U000021A6', + "mapsto;": '\U000021A6', + "mapstodown;": '\U000021A7', + "mapstoleft;": '\U000021A4', + "mapstoup;": '\U000021A5', + "marker;": '\U000025AE', + "mcomma;": '\U00002A29', + "mcy;": '\U0000043C', + "mdash;": '\U00002014', + "measuredangle;": '\U00002221', + "mfr;": '\U0001D52A', + "mho;": '\U00002127', + "micro;": '\U000000B5', + "mid;": '\U00002223', + "midast;": '\U0000002A', + "midcir;": '\U00002AF0', + "middot;": '\U000000B7', + "minus;": '\U00002212', + "minusb;": '\U0000229F', + "minusd;": '\U00002238', + "minusdu;": '\U00002A2A', + "mlcp;": '\U00002ADB', + "mldr;": '\U00002026', + "mnplus;": '\U00002213', + "models;": '\U000022A7', + "mopf;": '\U0001D55E', + "mp;": '\U00002213', + "mscr;": '\U0001D4C2', + "mstpos;": '\U0000223E', + "mu;": '\U000003BC', + "multimap;": '\U000022B8', + "mumap;": '\U000022B8', + "nLeftarrow;": '\U000021CD', + "nLeftrightarrow;": '\U000021CE', + "nRightarrow;": '\U000021CF', + "nVDash;": '\U000022AF', + "nVdash;": '\U000022AE', + "nabla;": '\U00002207', + "nacute;": '\U00000144', + "nap;": '\U00002249', + "napos;": '\U00000149', + "napprox;": '\U00002249', + "natur;": '\U0000266E', + "natural;": '\U0000266E', + "naturals;": '\U00002115', + "nbsp;": '\U000000A0', + "ncap;": '\U00002A43', + "ncaron;": '\U00000148', + "ncedil;": '\U00000146', + "ncong;": '\U00002247', + "ncup;": '\U00002A42', + "ncy;": '\U0000043D', + "ndash;": '\U00002013', + "ne;": '\U00002260', + "neArr;": '\U000021D7', + "nearhk;": '\U00002924', + "nearr;": '\U00002197', + "nearrow;": '\U00002197', + "nequiv;": '\U00002262', + "nesear;": '\U00002928', + "nexist;": '\U00002204', + "nexists;": '\U00002204', + "nfr;": '\U0001D52B', + "nge;": '\U00002271', + "ngeq;": '\U00002271', + "ngsim;": '\U00002275', + "ngt;": '\U0000226F', + "ngtr;": '\U0000226F', + "nhArr;": '\U000021CE', + "nharr;": '\U000021AE', + "nhpar;": '\U00002AF2', + "ni;": '\U0000220B', + "nis;": '\U000022FC', + "nisd;": '\U000022FA', + "niv;": '\U0000220B', + "njcy;": '\U0000045A', + "nlArr;": '\U000021CD', + "nlarr;": '\U0000219A', + "nldr;": '\U00002025', + "nle;": '\U00002270', + "nleftarrow;": '\U0000219A', + "nleftrightarrow;": '\U000021AE', + "nleq;": '\U00002270', + "nless;": '\U0000226E', + "nlsim;": '\U00002274', + "nlt;": '\U0000226E', + "nltri;": '\U000022EA', + "nltrie;": '\U000022EC', + "nmid;": '\U00002224', + "nopf;": '\U0001D55F', + "not;": '\U000000AC', + "notin;": '\U00002209', + "notinva;": '\U00002209', + "notinvb;": '\U000022F7', + "notinvc;": '\U000022F6', + "notni;": '\U0000220C', + "notniva;": '\U0000220C', + "notnivb;": '\U000022FE', + "notnivc;": '\U000022FD', + "npar;": '\U00002226', + "nparallel;": '\U00002226', + "npolint;": '\U00002A14', + "npr;": '\U00002280', + "nprcue;": '\U000022E0', + "nprec;": '\U00002280', + "nrArr;": '\U000021CF', + "nrarr;": '\U0000219B', + "nrightarrow;": '\U0000219B', + "nrtri;": '\U000022EB', + "nrtrie;": '\U000022ED', + "nsc;": '\U00002281', + "nsccue;": '\U000022E1', + "nscr;": '\U0001D4C3', + "nshortmid;": '\U00002224', + "nshortparallel;": '\U00002226', + "nsim;": '\U00002241', + "nsime;": '\U00002244', + "nsimeq;": '\U00002244', + "nsmid;": '\U00002224', + "nspar;": '\U00002226', + "nsqsube;": '\U000022E2', + "nsqsupe;": '\U000022E3', + "nsub;": '\U00002284', + "nsube;": '\U00002288', + "nsubseteq;": '\U00002288', + "nsucc;": '\U00002281', + "nsup;": '\U00002285', + "nsupe;": '\U00002289', + "nsupseteq;": '\U00002289', + "ntgl;": '\U00002279', + "ntilde;": '\U000000F1', + "ntlg;": '\U00002278', + "ntriangleleft;": '\U000022EA', + "ntrianglelefteq;": '\U000022EC', + "ntriangleright;": '\U000022EB', + "ntrianglerighteq;": '\U000022ED', + "nu;": '\U000003BD', + "num;": '\U00000023', + "numero;": '\U00002116', + "numsp;": '\U00002007', + "nvDash;": '\U000022AD', + "nvHarr;": '\U00002904', + "nvdash;": '\U000022AC', + "nvinfin;": '\U000029DE', + "nvlArr;": '\U00002902', + "nvrArr;": '\U00002903', + "nwArr;": '\U000021D6', + "nwarhk;": '\U00002923', + "nwarr;": '\U00002196', + "nwarrow;": '\U00002196', + "nwnear;": '\U00002927', + "oS;": '\U000024C8', + "oacute;": '\U000000F3', + "oast;": '\U0000229B', + "ocir;": '\U0000229A', + "ocirc;": '\U000000F4', + "ocy;": '\U0000043E', + "odash;": '\U0000229D', + "odblac;": '\U00000151', + "odiv;": '\U00002A38', + "odot;": '\U00002299', + "odsold;": '\U000029BC', + "oelig;": '\U00000153', + "ofcir;": '\U000029BF', + "ofr;": '\U0001D52C', + "ogon;": '\U000002DB', + "ograve;": '\U000000F2', + "ogt;": '\U000029C1', + "ohbar;": '\U000029B5', + "ohm;": '\U000003A9', + "oint;": '\U0000222E', + "olarr;": '\U000021BA', + "olcir;": '\U000029BE', + "olcross;": '\U000029BB', + "oline;": '\U0000203E', + "olt;": '\U000029C0', + "omacr;": '\U0000014D', + "omega;": '\U000003C9', + "omicron;": '\U000003BF', + "omid;": '\U000029B6', + "ominus;": '\U00002296', + "oopf;": '\U0001D560', + "opar;": '\U000029B7', + "operp;": '\U000029B9', + "oplus;": '\U00002295', + "or;": '\U00002228', + "orarr;": '\U000021BB', + "ord;": '\U00002A5D', + "order;": '\U00002134', + "orderof;": '\U00002134', + "ordf;": '\U000000AA', + "ordm;": '\U000000BA', + "origof;": '\U000022B6', + "oror;": '\U00002A56', + "orslope;": '\U00002A57', + "orv;": '\U00002A5B', + "oscr;": '\U00002134', + "oslash;": '\U000000F8', + "osol;": '\U00002298', + "otilde;": '\U000000F5', + "otimes;": '\U00002297', + "otimesas;": '\U00002A36', + "ouml;": '\U000000F6', + "ovbar;": '\U0000233D', + "par;": '\U00002225', + "para;": '\U000000B6', + "parallel;": '\U00002225', + "parsim;": '\U00002AF3', + "parsl;": '\U00002AFD', + "part;": '\U00002202', + "pcy;": '\U0000043F', + "percnt;": '\U00000025', + "period;": '\U0000002E', + "permil;": '\U00002030', + "perp;": '\U000022A5', + "pertenk;": '\U00002031', + "pfr;": '\U0001D52D', + "phi;": '\U000003C6', + "phiv;": '\U000003D5', + "phmmat;": '\U00002133', + "phone;": '\U0000260E', + "pi;": '\U000003C0', + "pitchfork;": '\U000022D4', + "piv;": '\U000003D6', + "planck;": '\U0000210F', + "planckh;": '\U0000210E', + "plankv;": '\U0000210F', + "plus;": '\U0000002B', + "plusacir;": '\U00002A23', + "plusb;": '\U0000229E', + "pluscir;": '\U00002A22', + "plusdo;": '\U00002214', + "plusdu;": '\U00002A25', + "pluse;": '\U00002A72', + "plusmn;": '\U000000B1', + "plussim;": '\U00002A26', + "plustwo;": '\U00002A27', + "pm;": '\U000000B1', + "pointint;": '\U00002A15', + "popf;": '\U0001D561', + "pound;": '\U000000A3', + "pr;": '\U0000227A', + "prE;": '\U00002AB3', + "prap;": '\U00002AB7', + "prcue;": '\U0000227C', + "pre;": '\U00002AAF', + "prec;": '\U0000227A', + "precapprox;": '\U00002AB7', + "preccurlyeq;": '\U0000227C', + "preceq;": '\U00002AAF', + "precnapprox;": '\U00002AB9', + "precneqq;": '\U00002AB5', + "precnsim;": '\U000022E8', + "precsim;": '\U0000227E', + "prime;": '\U00002032', + "primes;": '\U00002119', + "prnE;": '\U00002AB5', + "prnap;": '\U00002AB9', + "prnsim;": '\U000022E8', + "prod;": '\U0000220F', + "profalar;": '\U0000232E', + "profline;": '\U00002312', + "profsurf;": '\U00002313', + "prop;": '\U0000221D', + "propto;": '\U0000221D', + "prsim;": '\U0000227E', + "prurel;": '\U000022B0', + "pscr;": '\U0001D4C5', + "psi;": '\U000003C8', + "puncsp;": '\U00002008', + "qfr;": '\U0001D52E', + "qint;": '\U00002A0C', + "qopf;": '\U0001D562', + "qprime;": '\U00002057', + "qscr;": '\U0001D4C6', + "quaternions;": '\U0000210D', + "quatint;": '\U00002A16', + "quest;": '\U0000003F', + "questeq;": '\U0000225F', + "quot;": '\U00000022', + "rAarr;": '\U000021DB', + "rArr;": '\U000021D2', + "rAtail;": '\U0000291C', + "rBarr;": '\U0000290F', + "rHar;": '\U00002964', + "racute;": '\U00000155', + "radic;": '\U0000221A', + "raemptyv;": '\U000029B3', + "rang;": '\U000027E9', + "rangd;": '\U00002992', + "range;": '\U000029A5', + "rangle;": '\U000027E9', + "raquo;": '\U000000BB', + "rarr;": '\U00002192', + "rarrap;": '\U00002975', + "rarrb;": '\U000021E5', + "rarrbfs;": '\U00002920', + "rarrc;": '\U00002933', + "rarrfs;": '\U0000291E', + "rarrhk;": '\U000021AA', + "rarrlp;": '\U000021AC', + "rarrpl;": '\U00002945', + "rarrsim;": '\U00002974', + "rarrtl;": '\U000021A3', + "rarrw;": '\U0000219D', + "ratail;": '\U0000291A', + "ratio;": '\U00002236', + "rationals;": '\U0000211A', + "rbarr;": '\U0000290D', + "rbbrk;": '\U00002773', + "rbrace;": '\U0000007D', + "rbrack;": '\U0000005D', + "rbrke;": '\U0000298C', + "rbrksld;": '\U0000298E', + "rbrkslu;": '\U00002990', + "rcaron;": '\U00000159', + "rcedil;": '\U00000157', + "rceil;": '\U00002309', + "rcub;": '\U0000007D', + "rcy;": '\U00000440', + "rdca;": '\U00002937', + "rdldhar;": '\U00002969', + "rdquo;": '\U0000201D', + "rdquor;": '\U0000201D', + "rdsh;": '\U000021B3', + "real;": '\U0000211C', + "realine;": '\U0000211B', + "realpart;": '\U0000211C', + "reals;": '\U0000211D', + "rect;": '\U000025AD', + "reg;": '\U000000AE', + "rfisht;": '\U0000297D', + "rfloor;": '\U0000230B', + "rfr;": '\U0001D52F', + "rhard;": '\U000021C1', + "rharu;": '\U000021C0', + "rharul;": '\U0000296C', + "rho;": '\U000003C1', + "rhov;": '\U000003F1', + "rightarrow;": '\U00002192', + "rightarrowtail;": '\U000021A3', + "rightharpoondown;": '\U000021C1', + "rightharpoonup;": '\U000021C0', + "rightleftarrows;": '\U000021C4', + "rightleftharpoons;": '\U000021CC', + "rightrightarrows;": '\U000021C9', + "rightsquigarrow;": '\U0000219D', + "rightthreetimes;": '\U000022CC', + "ring;": '\U000002DA', + "risingdotseq;": '\U00002253', + "rlarr;": '\U000021C4', + "rlhar;": '\U000021CC', + "rlm;": '\U0000200F', + "rmoust;": '\U000023B1', + "rmoustache;": '\U000023B1', + "rnmid;": '\U00002AEE', + "roang;": '\U000027ED', + "roarr;": '\U000021FE', + "robrk;": '\U000027E7', + "ropar;": '\U00002986', + "ropf;": '\U0001D563', + "roplus;": '\U00002A2E', + "rotimes;": '\U00002A35', + "rpar;": '\U00000029', + "rpargt;": '\U00002994', + "rppolint;": '\U00002A12', + "rrarr;": '\U000021C9', + "rsaquo;": '\U0000203A', + "rscr;": '\U0001D4C7', + "rsh;": '\U000021B1', + "rsqb;": '\U0000005D', + "rsquo;": '\U00002019', + "rsquor;": '\U00002019', + "rthree;": '\U000022CC', + "rtimes;": '\U000022CA', + "rtri;": '\U000025B9', + "rtrie;": '\U000022B5', + "rtrif;": '\U000025B8', + "rtriltri;": '\U000029CE', + "ruluhar;": '\U00002968', + "rx;": '\U0000211E', + "sacute;": '\U0000015B', + "sbquo;": '\U0000201A', + "sc;": '\U0000227B', + "scE;": '\U00002AB4', + "scap;": '\U00002AB8', + "scaron;": '\U00000161', + "sccue;": '\U0000227D', + "sce;": '\U00002AB0', + "scedil;": '\U0000015F', + "scirc;": '\U0000015D', + "scnE;": '\U00002AB6', + "scnap;": '\U00002ABA', + "scnsim;": '\U000022E9', + "scpolint;": '\U00002A13', + "scsim;": '\U0000227F', + "scy;": '\U00000441', + "sdot;": '\U000022C5', + "sdotb;": '\U000022A1', + "sdote;": '\U00002A66', + "seArr;": '\U000021D8', + "searhk;": '\U00002925', + "searr;": '\U00002198', + "searrow;": '\U00002198', + "sect;": '\U000000A7', + "semi;": '\U0000003B', + "seswar;": '\U00002929', + "setminus;": '\U00002216', + "setmn;": '\U00002216', + "sext;": '\U00002736', + "sfr;": '\U0001D530', + "sfrown;": '\U00002322', + "sharp;": '\U0000266F', + "shchcy;": '\U00000449', + "shcy;": '\U00000448', + "shortmid;": '\U00002223', + "shortparallel;": '\U00002225', + "shy;": '\U000000AD', + "sigma;": '\U000003C3', + "sigmaf;": '\U000003C2', + "sigmav;": '\U000003C2', + "sim;": '\U0000223C', + "simdot;": '\U00002A6A', + "sime;": '\U00002243', + "simeq;": '\U00002243', + "simg;": '\U00002A9E', + "simgE;": '\U00002AA0', + "siml;": '\U00002A9D', + "simlE;": '\U00002A9F', + "simne;": '\U00002246', + "simplus;": '\U00002A24', + "simrarr;": '\U00002972', + "slarr;": '\U00002190', + "smallsetminus;": '\U00002216', + "smashp;": '\U00002A33', + "smeparsl;": '\U000029E4', + "smid;": '\U00002223', + "smile;": '\U00002323', + "smt;": '\U00002AAA', + "smte;": '\U00002AAC', + "softcy;": '\U0000044C', + "sol;": '\U0000002F', + "solb;": '\U000029C4', + "solbar;": '\U0000233F', + "sopf;": '\U0001D564', + "spades;": '\U00002660', + "spadesuit;": '\U00002660', + "spar;": '\U00002225', + "sqcap;": '\U00002293', + "sqcup;": '\U00002294', + "sqsub;": '\U0000228F', + "sqsube;": '\U00002291', + "sqsubset;": '\U0000228F', + "sqsubseteq;": '\U00002291', + "sqsup;": '\U00002290', + "sqsupe;": '\U00002292', + "sqsupset;": '\U00002290', + "sqsupseteq;": '\U00002292', + "squ;": '\U000025A1', + "square;": '\U000025A1', + "squarf;": '\U000025AA', + "squf;": '\U000025AA', + "srarr;": '\U00002192', + "sscr;": '\U0001D4C8', + "ssetmn;": '\U00002216', + "ssmile;": '\U00002323', + "sstarf;": '\U000022C6', + "star;": '\U00002606', + "starf;": '\U00002605', + "straightepsilon;": '\U000003F5', + "straightphi;": '\U000003D5', + "strns;": '\U000000AF', + "sub;": '\U00002282', + "subE;": '\U00002AC5', + "subdot;": '\U00002ABD', + "sube;": '\U00002286', + "subedot;": '\U00002AC3', + "submult;": '\U00002AC1', + "subnE;": '\U00002ACB', + "subne;": '\U0000228A', + "subplus;": '\U00002ABF', + "subrarr;": '\U00002979', + "subset;": '\U00002282', + "subseteq;": '\U00002286', + "subseteqq;": '\U00002AC5', + "subsetneq;": '\U0000228A', + "subsetneqq;": '\U00002ACB', + "subsim;": '\U00002AC7', + "subsub;": '\U00002AD5', + "subsup;": '\U00002AD3', + "succ;": '\U0000227B', + "succapprox;": '\U00002AB8', + "succcurlyeq;": '\U0000227D', + "succeq;": '\U00002AB0', + "succnapprox;": '\U00002ABA', + "succneqq;": '\U00002AB6', + "succnsim;": '\U000022E9', + "succsim;": '\U0000227F', + "sum;": '\U00002211', + "sung;": '\U0000266A', + "sup;": '\U00002283', + "sup1;": '\U000000B9', + "sup2;": '\U000000B2', + "sup3;": '\U000000B3', + "supE;": '\U00002AC6', + "supdot;": '\U00002ABE', + "supdsub;": '\U00002AD8', + "supe;": '\U00002287', + "supedot;": '\U00002AC4', + "suphsol;": '\U000027C9', + "suphsub;": '\U00002AD7', + "suplarr;": '\U0000297B', + "supmult;": '\U00002AC2', + "supnE;": '\U00002ACC', + "supne;": '\U0000228B', + "supplus;": '\U00002AC0', + "supset;": '\U00002283', + "supseteq;": '\U00002287', + "supseteqq;": '\U00002AC6', + "supsetneq;": '\U0000228B', + "supsetneqq;": '\U00002ACC', + "supsim;": '\U00002AC8', + "supsub;": '\U00002AD4', + "supsup;": '\U00002AD6', + "swArr;": '\U000021D9', + "swarhk;": '\U00002926', + "swarr;": '\U00002199', + "swarrow;": '\U00002199', + "swnwar;": '\U0000292A', + "szlig;": '\U000000DF', + "target;": '\U00002316', + "tau;": '\U000003C4', + "tbrk;": '\U000023B4', + "tcaron;": '\U00000165', + "tcedil;": '\U00000163', + "tcy;": '\U00000442', + "tdot;": '\U000020DB', + "telrec;": '\U00002315', + "tfr;": '\U0001D531', + "there4;": '\U00002234', + "therefore;": '\U00002234', + "theta;": '\U000003B8', + "thetasym;": '\U000003D1', + "thetav;": '\U000003D1', + "thickapprox;": '\U00002248', + "thicksim;": '\U0000223C', + "thinsp;": '\U00002009', + "thkap;": '\U00002248', + "thksim;": '\U0000223C', + "thorn;": '\U000000FE', + "tilde;": '\U000002DC', + "times;": '\U000000D7', + "timesb;": '\U000022A0', + "timesbar;": '\U00002A31', + "timesd;": '\U00002A30', + "tint;": '\U0000222D', + "toea;": '\U00002928', + "top;": '\U000022A4', + "topbot;": '\U00002336', + "topcir;": '\U00002AF1', + "topf;": '\U0001D565', + "topfork;": '\U00002ADA', + "tosa;": '\U00002929', + "tprime;": '\U00002034', + "trade;": '\U00002122', + "triangle;": '\U000025B5', + "triangledown;": '\U000025BF', + "triangleleft;": '\U000025C3', + "trianglelefteq;": '\U000022B4', + "triangleq;": '\U0000225C', + "triangleright;": '\U000025B9', + "trianglerighteq;": '\U000022B5', + "tridot;": '\U000025EC', + "trie;": '\U0000225C', + "triminus;": '\U00002A3A', + "triplus;": '\U00002A39', + "trisb;": '\U000029CD', + "tritime;": '\U00002A3B', + "trpezium;": '\U000023E2', + "tscr;": '\U0001D4C9', + "tscy;": '\U00000446', + "tshcy;": '\U0000045B', + "tstrok;": '\U00000167', + "twixt;": '\U0000226C', + "twoheadleftarrow;": '\U0000219E', + "twoheadrightarrow;": '\U000021A0', + "uArr;": '\U000021D1', + "uHar;": '\U00002963', + "uacute;": '\U000000FA', + "uarr;": '\U00002191', + "ubrcy;": '\U0000045E', + "ubreve;": '\U0000016D', + "ucirc;": '\U000000FB', + "ucy;": '\U00000443', + "udarr;": '\U000021C5', + "udblac;": '\U00000171', + "udhar;": '\U0000296E', + "ufisht;": '\U0000297E', + "ufr;": '\U0001D532', + "ugrave;": '\U000000F9', + "uharl;": '\U000021BF', + "uharr;": '\U000021BE', + "uhblk;": '\U00002580', + "ulcorn;": '\U0000231C', + "ulcorner;": '\U0000231C', + "ulcrop;": '\U0000230F', + "ultri;": '\U000025F8', + "umacr;": '\U0000016B', + "uml;": '\U000000A8', + "uogon;": '\U00000173', + "uopf;": '\U0001D566', + "uparrow;": '\U00002191', + "updownarrow;": '\U00002195', + "upharpoonleft;": '\U000021BF', + "upharpoonright;": '\U000021BE', + "uplus;": '\U0000228E', + "upsi;": '\U000003C5', + "upsih;": '\U000003D2', + "upsilon;": '\U000003C5', + "upuparrows;": '\U000021C8', + "urcorn;": '\U0000231D', + "urcorner;": '\U0000231D', + "urcrop;": '\U0000230E', + "uring;": '\U0000016F', + "urtri;": '\U000025F9', + "uscr;": '\U0001D4CA', + "utdot;": '\U000022F0', + "utilde;": '\U00000169', + "utri;": '\U000025B5', + "utrif;": '\U000025B4', + "uuarr;": '\U000021C8', + "uuml;": '\U000000FC', + "uwangle;": '\U000029A7', + "vArr;": '\U000021D5', + "vBar;": '\U00002AE8', + "vBarv;": '\U00002AE9', + "vDash;": '\U000022A8', + "vangrt;": '\U0000299C', + "varepsilon;": '\U000003F5', + "varkappa;": '\U000003F0', + "varnothing;": '\U00002205', + "varphi;": '\U000003D5', + "varpi;": '\U000003D6', + "varpropto;": '\U0000221D', + "varr;": '\U00002195', + "varrho;": '\U000003F1', + "varsigma;": '\U000003C2', + "vartheta;": '\U000003D1', + "vartriangleleft;": '\U000022B2', + "vartriangleright;": '\U000022B3', + "vcy;": '\U00000432', + "vdash;": '\U000022A2', + "vee;": '\U00002228', + "veebar;": '\U000022BB', + "veeeq;": '\U0000225A', + "vellip;": '\U000022EE', + "verbar;": '\U0000007C', + "vert;": '\U0000007C', + "vfr;": '\U0001D533', + "vltri;": '\U000022B2', + "vopf;": '\U0001D567', + "vprop;": '\U0000221D', + "vrtri;": '\U000022B3', + "vscr;": '\U0001D4CB', + "vzigzag;": '\U0000299A', + "wcirc;": '\U00000175', + "wedbar;": '\U00002A5F', + "wedge;": '\U00002227', + "wedgeq;": '\U00002259', + "weierp;": '\U00002118', + "wfr;": '\U0001D534', + "wopf;": '\U0001D568', + "wp;": '\U00002118', + "wr;": '\U00002240', + "wreath;": '\U00002240', + "wscr;": '\U0001D4CC', + "xcap;": '\U000022C2', + "xcirc;": '\U000025EF', + "xcup;": '\U000022C3', + "xdtri;": '\U000025BD', + "xfr;": '\U0001D535', + "xhArr;": '\U000027FA', + "xharr;": '\U000027F7', + "xi;": '\U000003BE', + "xlArr;": '\U000027F8', + "xlarr;": '\U000027F5', + "xmap;": '\U000027FC', + "xnis;": '\U000022FB', + "xodot;": '\U00002A00', + "xopf;": '\U0001D569', + "xoplus;": '\U00002A01', + "xotime;": '\U00002A02', + "xrArr;": '\U000027F9', + "xrarr;": '\U000027F6', + "xscr;": '\U0001D4CD', + "xsqcup;": '\U00002A06', + "xuplus;": '\U00002A04', + "xutri;": '\U000025B3', + "xvee;": '\U000022C1', + "xwedge;": '\U000022C0', + "yacute;": '\U000000FD', + "yacy;": '\U0000044F', + "ycirc;": '\U00000177', + "ycy;": '\U0000044B', + "yen;": '\U000000A5', + "yfr;": '\U0001D536', + "yicy;": '\U00000457', + "yopf;": '\U0001D56A', + "yscr;": '\U0001D4CE', + "yucy;": '\U0000044E', + "yuml;": '\U000000FF', + "zacute;": '\U0000017A', + "zcaron;": '\U0000017E', + "zcy;": '\U00000437', + "zdot;": '\U0000017C', + "zeetrf;": '\U00002128', + "zeta;": '\U000003B6', + "zfr;": '\U0001D537', + "zhcy;": '\U00000436', + "zigrarr;": '\U000021DD', + "zopf;": '\U0001D56B', + "zscr;": '\U0001D4CF', + "zwj;": '\U0000200D', + "zwnj;": '\U0000200C', + "AElig": '\U000000C6', + "AMP": '\U00000026', + "Aacute": '\U000000C1', + "Acirc": '\U000000C2', + "Agrave": '\U000000C0', + "Aring": '\U000000C5', + "Atilde": '\U000000C3', + "Auml": '\U000000C4', + "COPY": '\U000000A9', + "Ccedil": '\U000000C7', + "ETH": '\U000000D0', + "Eacute": '\U000000C9', + "Ecirc": '\U000000CA', + "Egrave": '\U000000C8', + "Euml": '\U000000CB', + "GT": '\U0000003E', + "Iacute": '\U000000CD', + "Icirc": '\U000000CE', + "Igrave": '\U000000CC', + "Iuml": '\U000000CF', + "LT": '\U0000003C', + "Ntilde": '\U000000D1', + "Oacute": '\U000000D3', + "Ocirc": '\U000000D4', + "Ograve": '\U000000D2', + "Oslash": '\U000000D8', + "Otilde": '\U000000D5', + "Ouml": '\U000000D6', + "QUOT": '\U00000022', + "REG": '\U000000AE', + "THORN": '\U000000DE', + "Uacute": '\U000000DA', + "Ucirc": '\U000000DB', + "Ugrave": '\U000000D9', + "Uuml": '\U000000DC', + "Yacute": '\U000000DD', + "aacute": '\U000000E1', + "acirc": '\U000000E2', + "acute": '\U000000B4', + "aelig": '\U000000E6', + "agrave": '\U000000E0', + "amp": '\U00000026', + "aring": '\U000000E5', + "atilde": '\U000000E3', + "auml": '\U000000E4', + "brvbar": '\U000000A6', + "ccedil": '\U000000E7', + "cedil": '\U000000B8', + "cent": '\U000000A2', + "copy": '\U000000A9', + "curren": '\U000000A4', + "deg": '\U000000B0', + "divide": '\U000000F7', + "eacute": '\U000000E9', + "ecirc": '\U000000EA', + "egrave": '\U000000E8', + "eth": '\U000000F0', + "euml": '\U000000EB', + "frac12": '\U000000BD', + "frac14": '\U000000BC', + "frac34": '\U000000BE', + "gt": '\U0000003E', + "iacute": '\U000000ED', + "icirc": '\U000000EE', + "iexcl": '\U000000A1', + "igrave": '\U000000EC', + "iquest": '\U000000BF', + "iuml": '\U000000EF', + "laquo": '\U000000AB', + "lt": '\U0000003C', + "macr": '\U000000AF', + "micro": '\U000000B5', + "middot": '\U000000B7', + "nbsp": '\U000000A0', + "not": '\U000000AC', + "ntilde": '\U000000F1', + "oacute": '\U000000F3', + "ocirc": '\U000000F4', + "ograve": '\U000000F2', + "ordf": '\U000000AA', + "ordm": '\U000000BA', + "oslash": '\U000000F8', + "otilde": '\U000000F5', + "ouml": '\U000000F6', + "para": '\U000000B6', + "plusmn": '\U000000B1', + "pound": '\U000000A3', + "quot": '\U00000022', + "raquo": '\U000000BB', + "reg": '\U000000AE', + "sect": '\U000000A7', + "shy": '\U000000AD', + "sup1": '\U000000B9', + "sup2": '\U000000B2', + "sup3": '\U000000B3', + "szlig": '\U000000DF', + "thorn": '\U000000FE', + "times": '\U000000D7', + "uacute": '\U000000FA', + "ucirc": '\U000000FB', + "ugrave": '\U000000F9', + "uml": '\U000000A8', + "uuml": '\U000000FC', + "yacute": '\U000000FD', + "yen": '\U000000A5', + "yuml": '\U000000FF', +} + +// HTML entities that are two unicode codepoints. +var entity2 = map[string][2]rune{ + // TODO(nigeltao): Handle replacements that are wider than their names. + // "nLt;": {'\u226A', '\u20D2'}, + // "nGt;": {'\u226B', '\u20D2'}, + "NotEqualTilde;": {'\u2242', '\u0338'}, + "NotGreaterFullEqual;": {'\u2267', '\u0338'}, + "NotGreaterGreater;": {'\u226B', '\u0338'}, + "NotGreaterSlantEqual;": {'\u2A7E', '\u0338'}, + "NotHumpDownHump;": {'\u224E', '\u0338'}, + "NotHumpEqual;": {'\u224F', '\u0338'}, + "NotLeftTriangleBar;": {'\u29CF', '\u0338'}, + "NotLessLess;": {'\u226A', '\u0338'}, + "NotLessSlantEqual;": {'\u2A7D', '\u0338'}, + "NotNestedGreaterGreater;": {'\u2AA2', '\u0338'}, + "NotNestedLessLess;": {'\u2AA1', '\u0338'}, + "NotPrecedesEqual;": {'\u2AAF', '\u0338'}, + "NotRightTriangleBar;": {'\u29D0', '\u0338'}, + "NotSquareSubset;": {'\u228F', '\u0338'}, + "NotSquareSuperset;": {'\u2290', '\u0338'}, + "NotSubset;": {'\u2282', '\u20D2'}, + "NotSucceedsEqual;": {'\u2AB0', '\u0338'}, + "NotSucceedsTilde;": {'\u227F', '\u0338'}, + "NotSuperset;": {'\u2283', '\u20D2'}, + "ThickSpace;": {'\u205F', '\u200A'}, + "acE;": {'\u223E', '\u0333'}, + "bne;": {'\u003D', '\u20E5'}, + "bnequiv;": {'\u2261', '\u20E5'}, + "caps;": {'\u2229', '\uFE00'}, + "cups;": {'\u222A', '\uFE00'}, + "fjlig;": {'\u0066', '\u006A'}, + "gesl;": {'\u22DB', '\uFE00'}, + "gvertneqq;": {'\u2269', '\uFE00'}, + "gvnE;": {'\u2269', '\uFE00'}, + "lates;": {'\u2AAD', '\uFE00'}, + "lesg;": {'\u22DA', '\uFE00'}, + "lvertneqq;": {'\u2268', '\uFE00'}, + "lvnE;": {'\u2268', '\uFE00'}, + "nGg;": {'\u22D9', '\u0338'}, + "nGtv;": {'\u226B', '\u0338'}, + "nLl;": {'\u22D8', '\u0338'}, + "nLtv;": {'\u226A', '\u0338'}, + "nang;": {'\u2220', '\u20D2'}, + "napE;": {'\u2A70', '\u0338'}, + "napid;": {'\u224B', '\u0338'}, + "nbump;": {'\u224E', '\u0338'}, + "nbumpe;": {'\u224F', '\u0338'}, + "ncongdot;": {'\u2A6D', '\u0338'}, + "nedot;": {'\u2250', '\u0338'}, + "nesim;": {'\u2242', '\u0338'}, + "ngE;": {'\u2267', '\u0338'}, + "ngeqq;": {'\u2267', '\u0338'}, + "ngeqslant;": {'\u2A7E', '\u0338'}, + "nges;": {'\u2A7E', '\u0338'}, + "nlE;": {'\u2266', '\u0338'}, + "nleqq;": {'\u2266', '\u0338'}, + "nleqslant;": {'\u2A7D', '\u0338'}, + "nles;": {'\u2A7D', '\u0338'}, + "notinE;": {'\u22F9', '\u0338'}, + "notindot;": {'\u22F5', '\u0338'}, + "nparsl;": {'\u2AFD', '\u20E5'}, + "npart;": {'\u2202', '\u0338'}, + "npre;": {'\u2AAF', '\u0338'}, + "npreceq;": {'\u2AAF', '\u0338'}, + "nrarrc;": {'\u2933', '\u0338'}, + "nrarrw;": {'\u219D', '\u0338'}, + "nsce;": {'\u2AB0', '\u0338'}, + "nsubE;": {'\u2AC5', '\u0338'}, + "nsubset;": {'\u2282', '\u20D2'}, + "nsubseteqq;": {'\u2AC5', '\u0338'}, + "nsucceq;": {'\u2AB0', '\u0338'}, + "nsupE;": {'\u2AC6', '\u0338'}, + "nsupset;": {'\u2283', '\u20D2'}, + "nsupseteqq;": {'\u2AC6', '\u0338'}, + "nvap;": {'\u224D', '\u20D2'}, + "nvge;": {'\u2265', '\u20D2'}, + "nvgt;": {'\u003E', '\u20D2'}, + "nvle;": {'\u2264', '\u20D2'}, + "nvlt;": {'\u003C', '\u20D2'}, + "nvltrie;": {'\u22B4', '\u20D2'}, + "nvrtrie;": {'\u22B5', '\u20D2'}, + "nvsim;": {'\u223C', '\u20D2'}, + "race;": {'\u223D', '\u0331'}, + "smtes;": {'\u2AAC', '\uFE00'}, + "sqcaps;": {'\u2293', '\uFE00'}, + "sqcups;": {'\u2294', '\uFE00'}, + "varsubsetneq;": {'\u228A', '\uFE00'}, + "varsubsetneqq;": {'\u2ACB', '\uFE00'}, + "varsupsetneq;": {'\u228B', '\uFE00'}, + "varsupsetneqq;": {'\u2ACC', '\uFE00'}, + "vnsub;": {'\u2282', '\u20D2'}, + "vnsup;": {'\u2283', '\u20D2'}, + "vsubnE;": {'\u2ACB', '\uFE00'}, + "vsubne;": {'\u228A', '\uFE00'}, + "vsupnE;": {'\u2ACC', '\uFE00'}, + "vsupne;": {'\u228B', '\uFE00'}, +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/entity_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/entity_test.go new file mode 100644 index 00000000..b53f866f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/entity_test.go @@ -0,0 +1,29 @@ +// 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 html + +import ( + "testing" + "unicode/utf8" +) + +func TestEntityLength(t *testing.T) { + // We verify that the length of UTF-8 encoding of each value is <= 1 + len(key). + // The +1 comes from the leading "&". This property implies that the length of + // unescaped text is <= the length of escaped text. + for k, v := range entity { + if 1+len(k) < utf8.RuneLen(v) { + t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v)) + } + if len(k) > longestEntityWithoutSemicolon && k[len(k)-1] != ';' { + t.Errorf("entity name %s is %d characters, but longestEntityWithoutSemicolon=%d", k, len(k), longestEntityWithoutSemicolon) + } + } + for k, v := range entity2 { + if 1+len(k) < utf8.RuneLen(v[0])+utf8.RuneLen(v[1]) { + t.Error("escaped entity &" + k + " is shorter than its UTF-8 encoding " + string(v[0]) + string(v[1])) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/escape.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/escape.go new file mode 100644 index 00000000..d8561396 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/escape.go @@ -0,0 +1,258 @@ +// 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 html + +import ( + "bytes" + "strings" + "unicode/utf8" +) + +// These replacements permit compatibility with old numeric entities that +// assumed Windows-1252 encoding. +// https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference +var replacementTable = [...]rune{ + '\u20AC', // First entry is what 0x80 should be replaced with. + '\u0081', + '\u201A', + '\u0192', + '\u201E', + '\u2026', + '\u2020', + '\u2021', + '\u02C6', + '\u2030', + '\u0160', + '\u2039', + '\u0152', + '\u008D', + '\u017D', + '\u008F', + '\u0090', + '\u2018', + '\u2019', + '\u201C', + '\u201D', + '\u2022', + '\u2013', + '\u2014', + '\u02DC', + '\u2122', + '\u0161', + '\u203A', + '\u0153', + '\u009D', + '\u017E', + '\u0178', // Last entry is 0x9F. + // 0x00->'\uFFFD' is handled programmatically. + // 0x0D->'\u000D' is a no-op. +} + +// unescapeEntity reads an entity like "<" from b[src:] and writes the +// corresponding "<" to b[dst:], returning the incremented dst and src cursors. +// Precondition: b[src] == '&' && dst <= src. +// attribute should be true if parsing an attribute value. +func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) { + // https://html.spec.whatwg.org/multipage/syntax.html#consume-a-character-reference + + // i starts at 1 because we already know that s[0] == '&'. + i, s := 1, b[src:] + + if len(s) <= 1 { + b[dst] = b[src] + return dst + 1, src + 1 + } + + if s[i] == '#' { + if len(s) <= 3 { // We need to have at least "&#.". + b[dst] = b[src] + return dst + 1, src + 1 + } + i++ + c := s[i] + hex := false + if c == 'x' || c == 'X' { + hex = true + i++ + } + + x := '\x00' + for i < len(s) { + c = s[i] + i++ + if hex { + if '0' <= c && c <= '9' { + x = 16*x + rune(c) - '0' + continue + } else if 'a' <= c && c <= 'f' { + x = 16*x + rune(c) - 'a' + 10 + continue + } else if 'A' <= c && c <= 'F' { + x = 16*x + rune(c) - 'A' + 10 + continue + } + } else if '0' <= c && c <= '9' { + x = 10*x + rune(c) - '0' + continue + } + if c != ';' { + i-- + } + break + } + + if i <= 3 { // No characters matched. + b[dst] = b[src] + return dst + 1, src + 1 + } + + if 0x80 <= x && x <= 0x9F { + // Replace characters from Windows-1252 with UTF-8 equivalents. + x = replacementTable[x-0x80] + } else if x == 0 || (0xD800 <= x && x <= 0xDFFF) || x > 0x10FFFF { + // Replace invalid characters with the replacement character. + x = '\uFFFD' + } + + return dst + utf8.EncodeRune(b[dst:], x), src + i + } + + // Consume the maximum number of characters possible, with the + // consumed characters matching one of the named references. + + for i < len(s) { + c := s[i] + i++ + // Lower-cased characters are more common in entities, so we check for them first. + if 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || '0' <= c && c <= '9' { + continue + } + if c != ';' { + i-- + } + break + } + + entityName := string(s[1:i]) + if entityName == "" { + // No-op. + } else if attribute && entityName[len(entityName)-1] != ';' && len(s) > i && s[i] == '=' { + // No-op. + } else if x := entity[entityName]; x != 0 { + return dst + utf8.EncodeRune(b[dst:], x), src + i + } else if x := entity2[entityName]; x[0] != 0 { + dst1 := dst + utf8.EncodeRune(b[dst:], x[0]) + return dst1 + utf8.EncodeRune(b[dst1:], x[1]), src + i + } else if !attribute { + maxLen := len(entityName) - 1 + if maxLen > longestEntityWithoutSemicolon { + maxLen = longestEntityWithoutSemicolon + } + for j := maxLen; j > 1; j-- { + if x := entity[entityName[:j]]; x != 0 { + return dst + utf8.EncodeRune(b[dst:], x), src + j + 1 + } + } + } + + dst1, src1 = dst+i, src+i + copy(b[dst:dst1], b[src:src1]) + return dst1, src1 +} + +// unescape unescapes b's entities in-place, so that "a<b" becomes "a': + esc = ">" + case '"': + // """ is shorter than """. + esc = """ + case '\r': + esc = " " + default: + panic("unrecognized escape character") + } + s = s[i+1:] + if _, err := w.WriteString(esc); err != nil { + return err + } + i = strings.IndexAny(s, escapedChars) + } + _, err := w.WriteString(s) + return err +} + +// EscapeString escapes special characters like "<" to become "<". It +// escapes only five such characters: <, >, &, ' and ". +// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't +// always true. +func EscapeString(s string) string { + if strings.IndexAny(s, escapedChars) == -1 { + return s + } + var buf bytes.Buffer + escape(&buf, s) + return buf.String() +} + +// UnescapeString unescapes entities like "<" to become "<". It unescapes a +// larger range of entities than EscapeString escapes. For example, "á" +// unescapes to "á", as does "á" and "&xE1;". +// UnescapeString(EscapeString(s)) == s always holds, but the converse isn't +// always true. +func UnescapeString(s string) string { + for _, c := range s { + if c == '&' { + return string(unescape([]byte(s), false)) + } + } + return s +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/escape_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/escape_test.go new file mode 100644 index 00000000..b405d4b4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/escape_test.go @@ -0,0 +1,97 @@ +// 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 html + +import "testing" + +type unescapeTest struct { + // A short description of the test case. + desc string + // The HTML text. + html string + // The unescaped text. + unescaped string +} + +var unescapeTests = []unescapeTest{ + // Handle no entities. + { + "copy", + "A\ttext\nstring", + "A\ttext\nstring", + }, + // Handle simple named entities. + { + "simple", + "& > <", + "& > <", + }, + // Handle hitting the end of the string. + { + "stringEnd", + "& &", + "& &", + }, + // Handle entities with two codepoints. + { + "multiCodepoint", + "text ⋛︀ blah", + "text \u22db\ufe00 blah", + }, + // Handle decimal numeric entities. + { + "decimalEntity", + "Delta = Δ ", + "Delta = Δ ", + }, + // Handle hexadecimal numeric entities. + { + "hexadecimalEntity", + "Lambda = λ = λ ", + "Lambda = λ = λ ", + }, + // Handle numeric early termination. + { + "numericEnds", + "&# &#x €43 © = ©f = ©", + "&# &#x €43 © = ©f = ©", + }, + // Handle numeric ISO-8859-1 entity replacements. + { + "numericReplacements", + "Footnote‡", + "Footnote‡", + }, +} + +func TestUnescape(t *testing.T) { + for _, tt := range unescapeTests { + unescaped := UnescapeString(tt.html) + if unescaped != tt.unescaped { + t.Errorf("TestUnescape %s: want %q, got %q", tt.desc, tt.unescaped, unescaped) + } + } +} + +func TestUnescapeEscape(t *testing.T) { + ss := []string{ + ``, + `abc def`, + `a & b`, + `a&b`, + `a & b`, + `"`, + `"`, + `"<&>"`, + `"<&>"`, + `3&5==1 && 0<1, "0<1", a+acute=á`, + `The special characters are: <, >, &, ' and "`, + } + for _, s := range ss { + if got := UnescapeString(EscapeString(s)); got != s { + t.Errorf("got %q want %q", got, s) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/example_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/example_test.go new file mode 100644 index 00000000..0b06ed77 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/example_test.go @@ -0,0 +1,40 @@ +// 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 example demonstrates parsing HTML data and walking the resulting tree. +package html_test + +import ( + "fmt" + "log" + "strings" + + "golang.org/x/net/html" +) + +func ExampleParse() { + s := `

Links:

` + doc, err := html.Parse(strings.NewReader(s)) + if err != nil { + log.Fatal(err) + } + var f func(*html.Node) + f = func(n *html.Node) { + if n.Type == html.ElementNode && n.Data == "a" { + for _, a := range n.Attr { + if a.Key == "href" { + fmt.Println(a.Val) + break + } + } + } + for c := n.FirstChild; c != nil; c = c.NextSibling { + f(c) + } + } + f(doc) + // Output: + // foo + // /bar/baz +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/foreign.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/foreign.go new file mode 100644 index 00000000..d3b38440 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/foreign.go @@ -0,0 +1,226 @@ +// 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 html + +import ( + "strings" +) + +func adjustAttributeNames(aa []Attribute, nameMap map[string]string) { + for i := range aa { + if newName, ok := nameMap[aa[i].Key]; ok { + aa[i].Key = newName + } + } +} + +func adjustForeignAttributes(aa []Attribute) { + for i, a := range aa { + if a.Key == "" || a.Key[0] != 'x' { + continue + } + switch a.Key { + case "xlink:actuate", "xlink:arcrole", "xlink:href", "xlink:role", "xlink:show", + "xlink:title", "xlink:type", "xml:base", "xml:lang", "xml:space", "xmlns:xlink": + j := strings.Index(a.Key, ":") + aa[i].Namespace = a.Key[:j] + aa[i].Key = a.Key[j+1:] + } + } +} + +func htmlIntegrationPoint(n *Node) bool { + if n.Type != ElementNode { + return false + } + switch n.Namespace { + case "math": + if n.Data == "annotation-xml" { + for _, a := range n.Attr { + if a.Key == "encoding" { + val := strings.ToLower(a.Val) + if val == "text/html" || val == "application/xhtml+xml" { + return true + } + } + } + } + case "svg": + switch n.Data { + case "desc", "foreignObject", "title": + return true + } + } + return false +} + +func mathMLTextIntegrationPoint(n *Node) bool { + if n.Namespace != "math" { + return false + } + switch n.Data { + case "mi", "mo", "mn", "ms", "mtext": + return true + } + return false +} + +// Section 12.2.5.5. +var breakout = map[string]bool{ + "b": true, + "big": true, + "blockquote": true, + "body": true, + "br": true, + "center": true, + "code": true, + "dd": true, + "div": true, + "dl": true, + "dt": true, + "em": true, + "embed": true, + "h1": true, + "h2": true, + "h3": true, + "h4": true, + "h5": true, + "h6": true, + "head": true, + "hr": true, + "i": true, + "img": true, + "li": true, + "listing": true, + "menu": true, + "meta": true, + "nobr": true, + "ol": true, + "p": true, + "pre": true, + "ruby": true, + "s": true, + "small": true, + "span": true, + "strong": true, + "strike": true, + "sub": true, + "sup": true, + "table": true, + "tt": true, + "u": true, + "ul": true, + "var": true, +} + +// Section 12.2.5.5. +var svgTagNameAdjustments = map[string]string{ + "altglyph": "altGlyph", + "altglyphdef": "altGlyphDef", + "altglyphitem": "altGlyphItem", + "animatecolor": "animateColor", + "animatemotion": "animateMotion", + "animatetransform": "animateTransform", + "clippath": "clipPath", + "feblend": "feBlend", + "fecolormatrix": "feColorMatrix", + "fecomponenttransfer": "feComponentTransfer", + "fecomposite": "feComposite", + "feconvolvematrix": "feConvolveMatrix", + "fediffuselighting": "feDiffuseLighting", + "fedisplacementmap": "feDisplacementMap", + "fedistantlight": "feDistantLight", + "feflood": "feFlood", + "fefunca": "feFuncA", + "fefuncb": "feFuncB", + "fefuncg": "feFuncG", + "fefuncr": "feFuncR", + "fegaussianblur": "feGaussianBlur", + "feimage": "feImage", + "femerge": "feMerge", + "femergenode": "feMergeNode", + "femorphology": "feMorphology", + "feoffset": "feOffset", + "fepointlight": "fePointLight", + "fespecularlighting": "feSpecularLighting", + "fespotlight": "feSpotLight", + "fetile": "feTile", + "feturbulence": "feTurbulence", + "foreignobject": "foreignObject", + "glyphref": "glyphRef", + "lineargradient": "linearGradient", + "radialgradient": "radialGradient", + "textpath": "textPath", +} + +// Section 12.2.5.1 +var mathMLAttributeAdjustments = map[string]string{ + "definitionurl": "definitionURL", +} + +var svgAttributeAdjustments = map[string]string{ + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan", +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/node.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/node.go new file mode 100644 index 00000000..26b657ae --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/node.go @@ -0,0 +1,193 @@ +// 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 html + +import ( + "golang.org/x/net/html/atom" +) + +// A NodeType is the type of a Node. +type NodeType uint32 + +const ( + ErrorNode NodeType = iota + TextNode + DocumentNode + ElementNode + CommentNode + DoctypeNode + scopeMarkerNode +) + +// Section 12.2.3.3 says "scope markers are inserted when entering applet +// elements, buttons, object elements, marquees, table cells, and table +// captions, and are used to prevent formatting from 'leaking'". +var scopeMarker = Node{Type: scopeMarkerNode} + +// A Node consists of a NodeType and some Data (tag name for element nodes, +// content for text) and are part of a tree of Nodes. Element nodes may also +// have a Namespace and contain a slice of Attributes. Data is unescaped, so +// that it looks like "a 0 { + return (*s)[i-1] + } + return nil +} + +// index returns the index of the top-most occurrence of n in the stack, or -1 +// if n is not present. +func (s *nodeStack) index(n *Node) int { + for i := len(*s) - 1; i >= 0; i-- { + if (*s)[i] == n { + return i + } + } + return -1 +} + +// insert inserts a node at the given index. +func (s *nodeStack) insert(i int, n *Node) { + (*s) = append(*s, nil) + copy((*s)[i+1:], (*s)[i:]) + (*s)[i] = n +} + +// remove removes a node from the stack. It is a no-op if n is not present. +func (s *nodeStack) remove(n *Node) { + i := s.index(n) + if i == -1 { + return + } + copy((*s)[i:], (*s)[i+1:]) + j := len(*s) - 1 + (*s)[j] = nil + *s = (*s)[:j] +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/node_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/node_test.go new file mode 100644 index 00000000..471102f3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/node_test.go @@ -0,0 +1,146 @@ +// 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 html + +import ( + "fmt" +) + +// checkTreeConsistency checks that a node and its descendants are all +// consistent in their parent/child/sibling relationships. +func checkTreeConsistency(n *Node) error { + return checkTreeConsistency1(n, 0) +} + +func checkTreeConsistency1(n *Node, depth int) error { + if depth == 1e4 { + return fmt.Errorf("html: tree looks like it contains a cycle") + } + if err := checkNodeConsistency(n); err != nil { + return err + } + for c := n.FirstChild; c != nil; c = c.NextSibling { + if err := checkTreeConsistency1(c, depth+1); err != nil { + return err + } + } + return nil +} + +// checkNodeConsistency checks that a node's parent/child/sibling relationships +// are consistent. +func checkNodeConsistency(n *Node) error { + if n == nil { + return nil + } + + nParent := 0 + for p := n.Parent; p != nil; p = p.Parent { + nParent++ + if nParent == 1e4 { + return fmt.Errorf("html: parent list looks like an infinite loop") + } + } + + nForward := 0 + for c := n.FirstChild; c != nil; c = c.NextSibling { + nForward++ + if nForward == 1e6 { + return fmt.Errorf("html: forward list of children looks like an infinite loop") + } + if c.Parent != n { + return fmt.Errorf("html: inconsistent child/parent relationship") + } + } + + nBackward := 0 + for c := n.LastChild; c != nil; c = c.PrevSibling { + nBackward++ + if nBackward == 1e6 { + return fmt.Errorf("html: backward list of children looks like an infinite loop") + } + if c.Parent != n { + return fmt.Errorf("html: inconsistent child/parent relationship") + } + } + + if n.Parent != nil { + if n.Parent == n { + return fmt.Errorf("html: inconsistent parent relationship") + } + if n.Parent == n.FirstChild { + return fmt.Errorf("html: inconsistent parent/first relationship") + } + if n.Parent == n.LastChild { + return fmt.Errorf("html: inconsistent parent/last relationship") + } + if n.Parent == n.PrevSibling { + return fmt.Errorf("html: inconsistent parent/prev relationship") + } + if n.Parent == n.NextSibling { + return fmt.Errorf("html: inconsistent parent/next relationship") + } + + parentHasNAsAChild := false + for c := n.Parent.FirstChild; c != nil; c = c.NextSibling { + if c == n { + parentHasNAsAChild = true + break + } + } + if !parentHasNAsAChild { + return fmt.Errorf("html: inconsistent parent/child relationship") + } + } + + if n.PrevSibling != nil && n.PrevSibling.NextSibling != n { + return fmt.Errorf("html: inconsistent prev/next relationship") + } + if n.NextSibling != nil && n.NextSibling.PrevSibling != n { + return fmt.Errorf("html: inconsistent next/prev relationship") + } + + if (n.FirstChild == nil) != (n.LastChild == nil) { + return fmt.Errorf("html: inconsistent first/last relationship") + } + if n.FirstChild != nil && n.FirstChild == n.LastChild { + // We have a sole child. + if n.FirstChild.PrevSibling != nil || n.FirstChild.NextSibling != nil { + return fmt.Errorf("html: inconsistent sole child's sibling relationship") + } + } + + seen := map[*Node]bool{} + + var last *Node + for c := n.FirstChild; c != nil; c = c.NextSibling { + if seen[c] { + return fmt.Errorf("html: inconsistent repeated child") + } + seen[c] = true + last = c + } + if last != n.LastChild { + return fmt.Errorf("html: inconsistent last relationship") + } + + var first *Node + for c := n.LastChild; c != nil; c = c.PrevSibling { + if !seen[c] { + return fmt.Errorf("html: inconsistent missing child") + } + delete(seen, c) + first = c + } + if first != n.FirstChild { + return fmt.Errorf("html: inconsistent first relationship") + } + + if len(seen) != 0 { + return fmt.Errorf("html: inconsistent forwards/backwards child list") + } + + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/parse.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/parse.go new file mode 100644 index 00000000..be4b2bf5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/parse.go @@ -0,0 +1,2094 @@ +// 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 html + +import ( + "errors" + "fmt" + "io" + "strings" + + a "golang.org/x/net/html/atom" +) + +// A parser implements the HTML5 parsing algorithm: +// https://html.spec.whatwg.org/multipage/syntax.html#tree-construction +type parser struct { + // tokenizer provides the tokens for the parser. + tokenizer *Tokenizer + // tok is the most recently read token. + tok Token + // Self-closing tags like
are treated as start tags, except that + // hasSelfClosingToken is set while they are being processed. + hasSelfClosingToken bool + // doc is the document root element. + doc *Node + // The stack of open elements (section 12.2.3.2) and active formatting + // elements (section 12.2.3.3). + oe, afe nodeStack + // Element pointers (section 12.2.3.4). + head, form *Node + // Other parsing state flags (section 12.2.3.5). + scripting, framesetOK bool + // im is the current insertion mode. + im insertionMode + // originalIM is the insertion mode to go back to after completing a text + // or inTableText insertion mode. + originalIM insertionMode + // fosterParenting is whether new elements should be inserted according to + // the foster parenting rules (section 12.2.5.3). + fosterParenting bool + // quirks is whether the parser is operating in "quirks mode." + quirks bool + // fragment is whether the parser is parsing an HTML fragment. + fragment bool + // context is the context element when parsing an HTML fragment + // (section 12.4). + context *Node +} + +func (p *parser) top() *Node { + if n := p.oe.top(); n != nil { + return n + } + return p.doc +} + +// Stop tags for use in popUntil. These come from section 12.2.3.2. +var ( + defaultScopeStopTags = map[string][]a.Atom{ + "": {a.Applet, a.Caption, a.Html, a.Table, a.Td, a.Th, a.Marquee, a.Object, a.Template}, + "math": {a.AnnotationXml, a.Mi, a.Mn, a.Mo, a.Ms, a.Mtext}, + "svg": {a.Desc, a.ForeignObject, a.Title}, + } +) + +type scope int + +const ( + defaultScope scope = iota + listItemScope + buttonScope + tableScope + tableRowScope + tableBodyScope + selectScope +) + +// popUntil pops the stack of open elements at the highest element whose tag +// is in matchTags, provided there is no higher element in the scope's stop +// tags (as defined in section 12.2.3.2). It returns whether or not there was +// such an element. If there was not, popUntil leaves the stack unchanged. +// +// For example, the set of stop tags for table scope is: "html", "table". If +// the stack was: +// ["html", "body", "font", "table", "b", "i", "u"] +// then popUntil(tableScope, "font") would return false, but +// popUntil(tableScope, "i") would return true and the stack would become: +// ["html", "body", "font", "table", "b"] +// +// If an element's tag is in both the stop tags and matchTags, then the stack +// will be popped and the function returns true (provided, of course, there was +// no higher element in the stack that was also in the stop tags). For example, +// popUntil(tableScope, "table") returns true and leaves: +// ["html", "body", "font"] +func (p *parser) popUntil(s scope, matchTags ...a.Atom) bool { + if i := p.indexOfElementInScope(s, matchTags...); i != -1 { + p.oe = p.oe[:i] + return true + } + return false +} + +// indexOfElementInScope returns the index in p.oe of the highest element whose +// tag is in matchTags that is in scope. If no matching element is in scope, it +// returns -1. +func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int { + for i := len(p.oe) - 1; i >= 0; i-- { + tagAtom := p.oe[i].DataAtom + if p.oe[i].Namespace == "" { + for _, t := range matchTags { + if t == tagAtom { + return i + } + } + switch s { + case defaultScope: + // No-op. + case listItemScope: + if tagAtom == a.Ol || tagAtom == a.Ul { + return -1 + } + case buttonScope: + if tagAtom == a.Button { + return -1 + } + case tableScope: + if tagAtom == a.Html || tagAtom == a.Table { + return -1 + } + case selectScope: + if tagAtom != a.Optgroup && tagAtom != a.Option { + return -1 + } + default: + panic("unreachable") + } + } + switch s { + case defaultScope, listItemScope, buttonScope: + for _, t := range defaultScopeStopTags[p.oe[i].Namespace] { + if t == tagAtom { + return -1 + } + } + } + } + return -1 +} + +// elementInScope is like popUntil, except that it doesn't modify the stack of +// open elements. +func (p *parser) elementInScope(s scope, matchTags ...a.Atom) bool { + return p.indexOfElementInScope(s, matchTags...) != -1 +} + +// clearStackToContext pops elements off the stack of open elements until a +// scope-defined element is found. +func (p *parser) clearStackToContext(s scope) { + for i := len(p.oe) - 1; i >= 0; i-- { + tagAtom := p.oe[i].DataAtom + switch s { + case tableScope: + if tagAtom == a.Html || tagAtom == a.Table { + p.oe = p.oe[:i+1] + return + } + case tableRowScope: + if tagAtom == a.Html || tagAtom == a.Tr { + p.oe = p.oe[:i+1] + return + } + case tableBodyScope: + if tagAtom == a.Html || tagAtom == a.Tbody || tagAtom == a.Tfoot || tagAtom == a.Thead { + p.oe = p.oe[:i+1] + return + } + default: + panic("unreachable") + } + } +} + +// generateImpliedEndTags pops nodes off the stack of open elements as long as +// the top node has a tag name of dd, dt, li, option, optgroup, p, rp, or rt. +// If exceptions are specified, nodes with that name will not be popped off. +func (p *parser) generateImpliedEndTags(exceptions ...string) { + var i int +loop: + for i = len(p.oe) - 1; i >= 0; i-- { + n := p.oe[i] + if n.Type == ElementNode { + switch n.DataAtom { + case a.Dd, a.Dt, a.Li, a.Option, a.Optgroup, a.P, a.Rp, a.Rt: + for _, except := range exceptions { + if n.Data == except { + break loop + } + } + continue + } + } + break + } + + p.oe = p.oe[:i+1] +} + +// addChild adds a child node n to the top element, and pushes n onto the stack +// of open elements if it is an element node. +func (p *parser) addChild(n *Node) { + if p.shouldFosterParent() { + p.fosterParent(n) + } else { + p.top().AppendChild(n) + } + + if n.Type == ElementNode { + p.oe = append(p.oe, n) + } +} + +// shouldFosterParent returns whether the next node to be added should be +// foster parented. +func (p *parser) shouldFosterParent() bool { + if p.fosterParenting { + switch p.top().DataAtom { + case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr: + return true + } + } + return false +} + +// fosterParent adds a child node according to the foster parenting rules. +// Section 12.2.5.3, "foster parenting". +func (p *parser) fosterParent(n *Node) { + var table, parent, prev *Node + var i int + for i = len(p.oe) - 1; i >= 0; i-- { + if p.oe[i].DataAtom == a.Table { + table = p.oe[i] + break + } + } + + if table == nil { + // The foster parent is the html element. + parent = p.oe[0] + } else { + parent = table.Parent + } + if parent == nil { + parent = p.oe[i-1] + } + + if table != nil { + prev = table.PrevSibling + } else { + prev = parent.LastChild + } + if prev != nil && prev.Type == TextNode && n.Type == TextNode { + prev.Data += n.Data + return + } + + parent.InsertBefore(n, table) +} + +// addText adds text to the preceding node if it is a text node, or else it +// calls addChild with a new text node. +func (p *parser) addText(text string) { + if text == "" { + return + } + + if p.shouldFosterParent() { + p.fosterParent(&Node{ + Type: TextNode, + Data: text, + }) + return + } + + t := p.top() + if n := t.LastChild; n != nil && n.Type == TextNode { + n.Data += text + return + } + p.addChild(&Node{ + Type: TextNode, + Data: text, + }) +} + +// addElement adds a child element based on the current token. +func (p *parser) addElement() { + p.addChild(&Node{ + Type: ElementNode, + DataAtom: p.tok.DataAtom, + Data: p.tok.Data, + Attr: p.tok.Attr, + }) +} + +// Section 12.2.3.3. +func (p *parser) addFormattingElement() { + tagAtom, attr := p.tok.DataAtom, p.tok.Attr + p.addElement() + + // Implement the Noah's Ark clause, but with three per family instead of two. + identicalElements := 0 +findIdenticalElements: + for i := len(p.afe) - 1; i >= 0; i-- { + n := p.afe[i] + if n.Type == scopeMarkerNode { + break + } + if n.Type != ElementNode { + continue + } + if n.Namespace != "" { + continue + } + if n.DataAtom != tagAtom { + continue + } + if len(n.Attr) != len(attr) { + continue + } + compareAttributes: + for _, t0 := range n.Attr { + for _, t1 := range attr { + if t0.Key == t1.Key && t0.Namespace == t1.Namespace && t0.Val == t1.Val { + // Found a match for this attribute, continue with the next attribute. + continue compareAttributes + } + } + // If we get here, there is no attribute that matches a. + // Therefore the element is not identical to the new one. + continue findIdenticalElements + } + + identicalElements++ + if identicalElements >= 3 { + p.afe.remove(n) + } + } + + p.afe = append(p.afe, p.top()) +} + +// Section 12.2.3.3. +func (p *parser) clearActiveFormattingElements() { + for { + n := p.afe.pop() + if len(p.afe) == 0 || n.Type == scopeMarkerNode { + return + } + } +} + +// Section 12.2.3.3. +func (p *parser) reconstructActiveFormattingElements() { + n := p.afe.top() + if n == nil { + return + } + if n.Type == scopeMarkerNode || p.oe.index(n) != -1 { + return + } + i := len(p.afe) - 1 + for n.Type != scopeMarkerNode && p.oe.index(n) == -1 { + if i == 0 { + i = -1 + break + } + i-- + n = p.afe[i] + } + for { + i++ + clone := p.afe[i].clone() + p.addChild(clone) + p.afe[i] = clone + if i == len(p.afe)-1 { + break + } + } +} + +// Section 12.2.4. +func (p *parser) acknowledgeSelfClosingTag() { + p.hasSelfClosingToken = false +} + +// An insertion mode (section 12.2.3.1) is the state transition function from +// a particular state in the HTML5 parser's state machine. It updates the +// parser's fields depending on parser.tok (where ErrorToken means EOF). +// It returns whether the token was consumed. +type insertionMode func(*parser) bool + +// setOriginalIM sets the insertion mode to return to after completing a text or +// inTableText insertion mode. +// Section 12.2.3.1, "using the rules for". +func (p *parser) setOriginalIM() { + if p.originalIM != nil { + panic("html: bad parser state: originalIM was set twice") + } + p.originalIM = p.im +} + +// Section 12.2.3.1, "reset the insertion mode". +func (p *parser) resetInsertionMode() { + for i := len(p.oe) - 1; i >= 0; i-- { + n := p.oe[i] + if i == 0 && p.context != nil { + n = p.context + } + + switch n.DataAtom { + case a.Select: + p.im = inSelectIM + case a.Td, a.Th: + p.im = inCellIM + case a.Tr: + p.im = inRowIM + case a.Tbody, a.Thead, a.Tfoot: + p.im = inTableBodyIM + case a.Caption: + p.im = inCaptionIM + case a.Colgroup: + p.im = inColumnGroupIM + case a.Table: + p.im = inTableIM + case a.Head: + p.im = inBodyIM + case a.Body: + p.im = inBodyIM + case a.Frameset: + p.im = inFramesetIM + case a.Html: + p.im = beforeHeadIM + default: + continue + } + return + } + p.im = inBodyIM +} + +const whitespace = " \t\r\n\f" + +// Section 12.2.5.4.1. +func initialIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) + if len(p.tok.Data) == 0 { + // It was all whitespace, so ignore it. + return true + } + case CommentToken: + p.doc.AppendChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + n, quirks := parseDoctype(p.tok.Data) + p.doc.AppendChild(n) + p.quirks = quirks + p.im = beforeHTMLIM + return true + } + p.quirks = true + p.im = beforeHTMLIM + return false +} + +// Section 12.2.5.4.2. +func beforeHTMLIM(p *parser) bool { + switch p.tok.Type { + case DoctypeToken: + // Ignore the token. + return true + case TextToken: + p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) + if len(p.tok.Data) == 0 { + // It was all whitespace, so ignore it. + return true + } + case StartTagToken: + if p.tok.DataAtom == a.Html { + p.addElement() + p.im = beforeHeadIM + return true + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Head, a.Body, a.Html, a.Br: + p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) + return false + default: + // Ignore the token. + return true + } + case CommentToken: + p.doc.AppendChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + } + p.parseImpliedToken(StartTagToken, a.Html, a.Html.String()) + return false +} + +// Section 12.2.5.4.3. +func beforeHeadIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + p.tok.Data = strings.TrimLeft(p.tok.Data, whitespace) + if len(p.tok.Data) == 0 { + // It was all whitespace, so ignore it. + return true + } + case StartTagToken: + switch p.tok.DataAtom { + case a.Head: + p.addElement() + p.head = p.top() + p.im = inHeadIM + return true + case a.Html: + return inBodyIM(p) + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Head, a.Body, a.Html, a.Br: + p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) + return false + default: + // Ignore the token. + return true + } + case CommentToken: + p.addChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + // Ignore the token. + return true + } + + p.parseImpliedToken(StartTagToken, a.Head, a.Head.String()) + return false +} + +// Section 12.2.5.4.4. +func inHeadIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) < len(p.tok.Data) { + // Add the initial whitespace to the current node. + p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) + if s == "" { + return true + } + p.tok.Data = s + } + case StartTagToken: + switch p.tok.DataAtom { + case a.Html: + return inBodyIM(p) + case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: + p.addElement() + p.oe.pop() + p.acknowledgeSelfClosingTag() + return true + case a.Script, a.Title, a.Noscript, a.Noframes, a.Style: + p.addElement() + p.setOriginalIM() + p.im = textIM + return true + case a.Head: + // Ignore the token. + return true + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Head: + n := p.oe.pop() + if n.DataAtom != a.Head { + panic("html: bad parser state: element not found, in the in-head insertion mode") + } + p.im = afterHeadIM + return true + case a.Body, a.Html, a.Br: + p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) + return false + default: + // Ignore the token. + return true + } + case CommentToken: + p.addChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + // Ignore the token. + return true + } + + p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) + return false +} + +// Section 12.2.5.4.6. +func afterHeadIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) < len(p.tok.Data) { + // Add the initial whitespace to the current node. + p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) + if s == "" { + return true + } + p.tok.Data = s + } + case StartTagToken: + switch p.tok.DataAtom { + case a.Html: + return inBodyIM(p) + case a.Body: + p.addElement() + p.framesetOK = false + p.im = inBodyIM + return true + case a.Frameset: + p.addElement() + p.im = inFramesetIM + return true + case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title: + p.oe = append(p.oe, p.head) + defer p.oe.remove(p.head) + return inHeadIM(p) + case a.Head: + // Ignore the token. + return true + } + case EndTagToken: + switch p.tok.DataAtom { + case a.Body, a.Html, a.Br: + // Drop down to creating an implied tag. + default: + // Ignore the token. + return true + } + case CommentToken: + p.addChild(&Node{ + Type: CommentNode, + Data: p.tok.Data, + }) + return true + case DoctypeToken: + // Ignore the token. + return true + } + + p.parseImpliedToken(StartTagToken, a.Body, a.Body.String()) + p.framesetOK = true + return false +} + +// copyAttributes copies attributes of src not found on dst to dst. +func copyAttributes(dst *Node, src Token) { + if len(src.Attr) == 0 { + return + } + attr := map[string]string{} + for _, t := range dst.Attr { + attr[t.Key] = t.Val + } + for _, t := range src.Attr { + if _, ok := attr[t.Key]; !ok { + dst.Attr = append(dst.Attr, t) + attr[t.Key] = t.Val + } + } +} + +// Section 12.2.5.4.7. +func inBodyIM(p *parser) bool { + switch p.tok.Type { + case TextToken: + d := p.tok.Data + switch n := p.oe.top(); n.DataAtom { + case a.Pre, a.Listing: + if n.FirstChild == nil { + // Ignore a newline at the start of a
 block.
+				if d != "" && d[0] == '\r' {
+					d = d[1:]
+				}
+				if d != "" && d[0] == '\n' {
+					d = d[1:]
+				}
+			}
+		}
+		d = strings.Replace(d, "\x00", "", -1)
+		if d == "" {
+			return true
+		}
+		p.reconstructActiveFormattingElements()
+		p.addText(d)
+		if p.framesetOK && strings.TrimLeft(d, whitespace) != "" {
+			// There were non-whitespace characters inserted.
+			p.framesetOK = false
+		}
+	case StartTagToken:
+		switch p.tok.DataAtom {
+		case a.Html:
+			copyAttributes(p.oe[0], p.tok)
+		case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Title:
+			return inHeadIM(p)
+		case a.Body:
+			if len(p.oe) >= 2 {
+				body := p.oe[1]
+				if body.Type == ElementNode && body.DataAtom == a.Body {
+					p.framesetOK = false
+					copyAttributes(body, p.tok)
+				}
+			}
+		case a.Frameset:
+			if !p.framesetOK || len(p.oe) < 2 || p.oe[1].DataAtom != a.Body {
+				// Ignore the token.
+				return true
+			}
+			body := p.oe[1]
+			if body.Parent != nil {
+				body.Parent.RemoveChild(body)
+			}
+			p.oe = p.oe[:1]
+			p.addElement()
+			p.im = inFramesetIM
+			return true
+		case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
+			p.popUntil(buttonScope, a.P)
+			switch n := p.top(); n.DataAtom {
+			case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
+				p.oe.pop()
+			}
+			p.addElement()
+		case a.Pre, a.Listing:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+			// The newline, if any, will be dealt with by the TextToken case.
+			p.framesetOK = false
+		case a.Form:
+			if p.form == nil {
+				p.popUntil(buttonScope, a.P)
+				p.addElement()
+				p.form = p.top()
+			}
+		case a.Li:
+			p.framesetOK = false
+			for i := len(p.oe) - 1; i >= 0; i-- {
+				node := p.oe[i]
+				switch node.DataAtom {
+				case a.Li:
+					p.oe = p.oe[:i]
+				case a.Address, a.Div, a.P:
+					continue
+				default:
+					if !isSpecialElement(node) {
+						continue
+					}
+				}
+				break
+			}
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.Dd, a.Dt:
+			p.framesetOK = false
+			for i := len(p.oe) - 1; i >= 0; i-- {
+				node := p.oe[i]
+				switch node.DataAtom {
+				case a.Dd, a.Dt:
+					p.oe = p.oe[:i]
+				case a.Address, a.Div, a.P:
+					continue
+				default:
+					if !isSpecialElement(node) {
+						continue
+					}
+				}
+				break
+			}
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.Plaintext:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+		case a.Button:
+			p.popUntil(defaultScope, a.Button)
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.framesetOK = false
+		case a.A:
+			for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
+				if n := p.afe[i]; n.Type == ElementNode && n.DataAtom == a.A {
+					p.inBodyEndTagFormatting(a.A)
+					p.oe.remove(n)
+					p.afe.remove(n)
+					break
+				}
+			}
+			p.reconstructActiveFormattingElements()
+			p.addFormattingElement()
+		case a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
+			p.reconstructActiveFormattingElements()
+			p.addFormattingElement()
+		case a.Nobr:
+			p.reconstructActiveFormattingElements()
+			if p.elementInScope(defaultScope, a.Nobr) {
+				p.inBodyEndTagFormatting(a.Nobr)
+				p.reconstructActiveFormattingElements()
+			}
+			p.addFormattingElement()
+		case a.Applet, a.Marquee, a.Object:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.afe = append(p.afe, &scopeMarker)
+			p.framesetOK = false
+		case a.Table:
+			if !p.quirks {
+				p.popUntil(buttonScope, a.P)
+			}
+			p.addElement()
+			p.framesetOK = false
+			p.im = inTableIM
+			return true
+		case a.Area, a.Br, a.Embed, a.Img, a.Input, a.Keygen, a.Wbr:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.oe.pop()
+			p.acknowledgeSelfClosingTag()
+			if p.tok.DataAtom == a.Input {
+				for _, t := range p.tok.Attr {
+					if t.Key == "type" {
+						if strings.ToLower(t.Val) == "hidden" {
+							// Skip setting framesetOK = false
+							return true
+						}
+					}
+				}
+			}
+			p.framesetOK = false
+		case a.Param, a.Source, a.Track:
+			p.addElement()
+			p.oe.pop()
+			p.acknowledgeSelfClosingTag()
+		case a.Hr:
+			p.popUntil(buttonScope, a.P)
+			p.addElement()
+			p.oe.pop()
+			p.acknowledgeSelfClosingTag()
+			p.framesetOK = false
+		case a.Image:
+			p.tok.DataAtom = a.Img
+			p.tok.Data = a.Img.String()
+			return false
+		case a.Isindex:
+			if p.form != nil {
+				// Ignore the token.
+				return true
+			}
+			action := ""
+			prompt := "This is a searchable index. Enter search keywords: "
+			attr := []Attribute{{Key: "name", Val: "isindex"}}
+			for _, t := range p.tok.Attr {
+				switch t.Key {
+				case "action":
+					action = t.Val
+				case "name":
+					// Ignore the attribute.
+				case "prompt":
+					prompt = t.Val
+				default:
+					attr = append(attr, t)
+				}
+			}
+			p.acknowledgeSelfClosingTag()
+			p.popUntil(buttonScope, a.P)
+			p.parseImpliedToken(StartTagToken, a.Form, a.Form.String())
+			if action != "" {
+				p.form.Attr = []Attribute{{Key: "action", Val: action}}
+			}
+			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
+			p.parseImpliedToken(StartTagToken, a.Label, a.Label.String())
+			p.addText(prompt)
+			p.addChild(&Node{
+				Type:     ElementNode,
+				DataAtom: a.Input,
+				Data:     a.Input.String(),
+				Attr:     attr,
+			})
+			p.oe.pop()
+			p.parseImpliedToken(EndTagToken, a.Label, a.Label.String())
+			p.parseImpliedToken(StartTagToken, a.Hr, a.Hr.String())
+			p.parseImpliedToken(EndTagToken, a.Form, a.Form.String())
+		case a.Textarea:
+			p.addElement()
+			p.setOriginalIM()
+			p.framesetOK = false
+			p.im = textIM
+		case a.Xmp:
+			p.popUntil(buttonScope, a.P)
+			p.reconstructActiveFormattingElements()
+			p.framesetOK = false
+			p.addElement()
+			p.setOriginalIM()
+			p.im = textIM
+		case a.Iframe:
+			p.framesetOK = false
+			p.addElement()
+			p.setOriginalIM()
+			p.im = textIM
+		case a.Noembed, a.Noscript:
+			p.addElement()
+			p.setOriginalIM()
+			p.im = textIM
+		case a.Select:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+			p.framesetOK = false
+			p.im = inSelectIM
+			return true
+		case a.Optgroup, a.Option:
+			if p.top().DataAtom == a.Option {
+				p.oe.pop()
+			}
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+		case a.Rp, a.Rt:
+			if p.elementInScope(defaultScope, a.Ruby) {
+				p.generateImpliedEndTags()
+			}
+			p.addElement()
+		case a.Math, a.Svg:
+			p.reconstructActiveFormattingElements()
+			if p.tok.DataAtom == a.Math {
+				adjustAttributeNames(p.tok.Attr, mathMLAttributeAdjustments)
+			} else {
+				adjustAttributeNames(p.tok.Attr, svgAttributeAdjustments)
+			}
+			adjustForeignAttributes(p.tok.Attr)
+			p.addElement()
+			p.top().Namespace = p.tok.Data
+			if p.hasSelfClosingToken {
+				p.oe.pop()
+				p.acknowledgeSelfClosingTag()
+			}
+			return true
+		case a.Caption, a.Col, a.Colgroup, a.Frame, a.Head, a.Tbody, a.Td, a.Tfoot, a.Th, a.Thead, a.Tr:
+			// Ignore the token.
+		default:
+			p.reconstructActiveFormattingElements()
+			p.addElement()
+		}
+	case EndTagToken:
+		switch p.tok.DataAtom {
+		case a.Body:
+			if p.elementInScope(defaultScope, a.Body) {
+				p.im = afterBodyIM
+			}
+		case a.Html:
+			if p.elementInScope(defaultScope, a.Body) {
+				p.parseImpliedToken(EndTagToken, a.Body, a.Body.String())
+				return false
+			}
+			return true
+		case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
+			p.popUntil(defaultScope, p.tok.DataAtom)
+		case a.Form:
+			node := p.form
+			p.form = nil
+			i := p.indexOfElementInScope(defaultScope, a.Form)
+			if node == nil || i == -1 || p.oe[i] != node {
+				// Ignore the token.
+				return true
+			}
+			p.generateImpliedEndTags()
+			p.oe.remove(node)
+		case a.P:
+			if !p.elementInScope(buttonScope, a.P) {
+				p.parseImpliedToken(StartTagToken, a.P, a.P.String())
+			}
+			p.popUntil(buttonScope, a.P)
+		case a.Li:
+			p.popUntil(listItemScope, a.Li)
+		case a.Dd, a.Dt:
+			p.popUntil(defaultScope, p.tok.DataAtom)
+		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
+			p.popUntil(defaultScope, a.H1, a.H2, a.H3, a.H4, a.H5, a.H6)
+		case a.A, a.B, a.Big, a.Code, a.Em, a.Font, a.I, a.Nobr, a.S, a.Small, a.Strike, a.Strong, a.Tt, a.U:
+			p.inBodyEndTagFormatting(p.tok.DataAtom)
+		case a.Applet, a.Marquee, a.Object:
+			if p.popUntil(defaultScope, p.tok.DataAtom) {
+				p.clearActiveFormattingElements()
+			}
+		case a.Br:
+			p.tok.Type = StartTagToken
+			return false
+		default:
+			p.inBodyEndTagOther(p.tok.DataAtom)
+		}
+	case CommentToken:
+		p.addChild(&Node{
+			Type: CommentNode,
+			Data: p.tok.Data,
+		})
+	}
+
+	return true
+}
+
+func (p *parser) inBodyEndTagFormatting(tagAtom a.Atom) {
+	// This is the "adoption agency" algorithm, described at
+	// https://html.spec.whatwg.org/multipage/syntax.html#adoptionAgency
+
+	// TODO: this is a fairly literal line-by-line translation of that algorithm.
+	// Once the code successfully parses the comprehensive test suite, we should
+	// refactor this code to be more idiomatic.
+
+	// Steps 1-4. The outer loop.
+	for i := 0; i < 8; i++ {
+		// Step 5. Find the formatting element.
+		var formattingElement *Node
+		for j := len(p.afe) - 1; j >= 0; j-- {
+			if p.afe[j].Type == scopeMarkerNode {
+				break
+			}
+			if p.afe[j].DataAtom == tagAtom {
+				formattingElement = p.afe[j]
+				break
+			}
+		}
+		if formattingElement == nil {
+			p.inBodyEndTagOther(tagAtom)
+			return
+		}
+		feIndex := p.oe.index(formattingElement)
+		if feIndex == -1 {
+			p.afe.remove(formattingElement)
+			return
+		}
+		if !p.elementInScope(defaultScope, tagAtom) {
+			// Ignore the tag.
+			return
+		}
+
+		// Steps 9-10. Find the furthest block.
+		var furthestBlock *Node
+		for _, e := range p.oe[feIndex:] {
+			if isSpecialElement(e) {
+				furthestBlock = e
+				break
+			}
+		}
+		if furthestBlock == nil {
+			e := p.oe.pop()
+			for e != formattingElement {
+				e = p.oe.pop()
+			}
+			p.afe.remove(e)
+			return
+		}
+
+		// Steps 11-12. Find the common ancestor and bookmark node.
+		commonAncestor := p.oe[feIndex-1]
+		bookmark := p.afe.index(formattingElement)
+
+		// Step 13. The inner loop. Find the lastNode to reparent.
+		lastNode := furthestBlock
+		node := furthestBlock
+		x := p.oe.index(node)
+		// Steps 13.1-13.2
+		for j := 0; j < 3; j++ {
+			// Step 13.3.
+			x--
+			node = p.oe[x]
+			// Step 13.4 - 13.5.
+			if p.afe.index(node) == -1 {
+				p.oe.remove(node)
+				continue
+			}
+			// Step 13.6.
+			if node == formattingElement {
+				break
+			}
+			// Step 13.7.
+			clone := node.clone()
+			p.afe[p.afe.index(node)] = clone
+			p.oe[p.oe.index(node)] = clone
+			node = clone
+			// Step 13.8.
+			if lastNode == furthestBlock {
+				bookmark = p.afe.index(node) + 1
+			}
+			// Step 13.9.
+			if lastNode.Parent != nil {
+				lastNode.Parent.RemoveChild(lastNode)
+			}
+			node.AppendChild(lastNode)
+			// Step 13.10.
+			lastNode = node
+		}
+
+		// Step 14. Reparent lastNode to the common ancestor,
+		// or for misnested table nodes, to the foster parent.
+		if lastNode.Parent != nil {
+			lastNode.Parent.RemoveChild(lastNode)
+		}
+		switch commonAncestor.DataAtom {
+		case a.Table, a.Tbody, a.Tfoot, a.Thead, a.Tr:
+			p.fosterParent(lastNode)
+		default:
+			commonAncestor.AppendChild(lastNode)
+		}
+
+		// Steps 15-17. Reparent nodes from the furthest block's children
+		// to a clone of the formatting element.
+		clone := formattingElement.clone()
+		reparentChildren(clone, furthestBlock)
+		furthestBlock.AppendChild(clone)
+
+		// Step 18. Fix up the list of active formatting elements.
+		if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
+			// Move the bookmark with the rest of the list.
+			bookmark--
+		}
+		p.afe.remove(formattingElement)
+		p.afe.insert(bookmark, clone)
+
+		// Step 19. Fix up the stack of open elements.
+		p.oe.remove(formattingElement)
+		p.oe.insert(p.oe.index(furthestBlock)+1, clone)
+	}
+}
+
+// inBodyEndTagOther performs the "any other end tag" algorithm for inBodyIM.
+// "Any other end tag" handling from 12.2.5.5 The rules for parsing tokens in foreign content
+// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inforeign
+func (p *parser) inBodyEndTagOther(tagAtom a.Atom) {
+	for i := len(p.oe) - 1; i >= 0; i-- {
+		if p.oe[i].DataAtom == tagAtom {
+			p.oe = p.oe[:i]
+			break
+		}
+		if isSpecialElement(p.oe[i]) {
+			break
+		}
+	}
+}
+
+// Section 12.2.5.4.8.
+func textIM(p *parser) bool {
+	switch p.tok.Type {
+	case ErrorToken:
+		p.oe.pop()
+	case TextToken:
+		d := p.tok.Data
+		if n := p.oe.top(); n.DataAtom == a.Textarea && n.FirstChild == nil {
+			// Ignore a newline at the start of a -->
+#errors
+#document
+| 
+|   
+|   
+|     -->
+#errors
+#document
+| 
+|   
+|   
+|     
+#errors
+Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE.
+#document
+| 
+|   
+|   
+|     
+#errors
+Line: 1 Col: 9 Unexpected end tag (strong). Expected DOCTYPE.
+Line: 1 Col: 9 Unexpected end tag (strong) after the (implied) root element.
+Line: 1 Col: 13 Unexpected end tag (b) after the (implied) root element.
+Line: 1 Col: 18 Unexpected end tag (em) after the (implied) root element.
+Line: 1 Col: 22 Unexpected end tag (i) after the (implied) root element.
+Line: 1 Col: 26 Unexpected end tag (u) after the (implied) root element.
+Line: 1 Col: 35 Unexpected end tag (strike) after the (implied) root element.
+Line: 1 Col: 39 Unexpected end tag (s) after the (implied) root element.
+Line: 1 Col: 47 Unexpected end tag (blink) after the (implied) root element.
+Line: 1 Col: 52 Unexpected end tag (tt) after the (implied) root element.
+Line: 1 Col: 58 Unexpected end tag (pre) after the (implied) root element.
+Line: 1 Col: 64 Unexpected end tag (big) after the (implied) root element.
+Line: 1 Col: 72 Unexpected end tag (small) after the (implied) root element.
+Line: 1 Col: 79 Unexpected end tag (font) after the (implied) root element.
+Line: 1 Col: 88 Unexpected end tag (select) after the (implied) root element.
+Line: 1 Col: 93 Unexpected end tag (h1) after the (implied) root element.
+Line: 1 Col: 98 Unexpected end tag (h2) after the (implied) root element.
+Line: 1 Col: 103 Unexpected end tag (h3) after the (implied) root element.
+Line: 1 Col: 108 Unexpected end tag (h4) after the (implied) root element.
+Line: 1 Col: 113 Unexpected end tag (h5) after the (implied) root element.
+Line: 1 Col: 118 Unexpected end tag (h6) after the (implied) root element.
+Line: 1 Col: 125 Unexpected end tag (body) after the (implied) root element.
+Line: 1 Col: 130 Unexpected end tag (br). Treated as br element.
+Line: 1 Col: 134 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 140 This element (img) has no end tag.
+Line: 1 Col: 148 Unexpected end tag (title). Ignored.
+Line: 1 Col: 155 Unexpected end tag (span). Ignored.
+Line: 1 Col: 163 Unexpected end tag (style). Ignored.
+Line: 1 Col: 172 Unexpected end tag (script). Ignored.
+Line: 1 Col: 180 Unexpected end tag (table). Ignored.
+Line: 1 Col: 185 Unexpected end tag (th). Ignored.
+Line: 1 Col: 190 Unexpected end tag (td). Ignored.
+Line: 1 Col: 195 Unexpected end tag (tr). Ignored.
+Line: 1 Col: 203 This element (frame) has no end tag.
+Line: 1 Col: 210 This element (area) has no end tag.
+Line: 1 Col: 217 Unexpected end tag (link). Ignored.
+Line: 1 Col: 225 This element (param) has no end tag.
+Line: 1 Col: 230 This element (hr) has no end tag.
+Line: 1 Col: 238 This element (input) has no end tag.
+Line: 1 Col: 244 Unexpected end tag (col). Ignored.
+Line: 1 Col: 251 Unexpected end tag (base). Ignored.
+Line: 1 Col: 258 Unexpected end tag (meta). Ignored.
+Line: 1 Col: 269 This element (basefont) has no end tag.
+Line: 1 Col: 279 This element (bgsound) has no end tag.
+Line: 1 Col: 287 This element (embed) has no end tag.
+Line: 1 Col: 296 This element (spacer) has no end tag.
+Line: 1 Col: 300 Unexpected end tag (p). Ignored.
+Line: 1 Col: 305 End tag (dd) seen too early. Expected other end tag.
+Line: 1 Col: 310 End tag (dt) seen too early. Expected other end tag.
+Line: 1 Col: 320 Unexpected end tag (caption). Ignored.
+Line: 1 Col: 331 Unexpected end tag (colgroup). Ignored.
+Line: 1 Col: 339 Unexpected end tag (tbody). Ignored.
+Line: 1 Col: 347 Unexpected end tag (tfoot). Ignored.
+Line: 1 Col: 355 Unexpected end tag (thead). Ignored.
+Line: 1 Col: 365 End tag (address) seen too early. Expected other end tag.
+Line: 1 Col: 378 End tag (blockquote) seen too early. Expected other end tag.
+Line: 1 Col: 387 End tag (center) seen too early. Expected other end tag.
+Line: 1 Col: 393 Unexpected end tag (dir). Ignored.
+Line: 1 Col: 399 End tag (div) seen too early. Expected other end tag.
+Line: 1 Col: 404 End tag (dl) seen too early. Expected other end tag.
+Line: 1 Col: 415 End tag (fieldset) seen too early. Expected other end tag.
+Line: 1 Col: 425 End tag (listing) seen too early. Expected other end tag.
+Line: 1 Col: 432 End tag (menu) seen too early. Expected other end tag.
+Line: 1 Col: 437 End tag (ol) seen too early. Expected other end tag.
+Line: 1 Col: 442 End tag (ul) seen too early. Expected other end tag.
+Line: 1 Col: 447 End tag (li) seen too early. Expected other end tag.
+Line: 1 Col: 454 End tag (nobr) violates step 1, paragraph 1 of the adoption agency algorithm.
+Line: 1 Col: 460 This element (wbr) has no end tag.
+Line: 1 Col: 476 End tag (button) seen too early. Expected other end tag.
+Line: 1 Col: 486 End tag (marquee) seen too early. Expected other end tag.
+Line: 1 Col: 495 End tag (object) seen too early. Expected other end tag.
+Line: 1 Col: 513 Unexpected end tag (html). Ignored.
+Line: 1 Col: 513 Unexpected end tag (frameset). Ignored.
+Line: 1 Col: 520 Unexpected end tag (head). Ignored.
+Line: 1 Col: 529 Unexpected end tag (iframe). Ignored.
+Line: 1 Col: 537 This element (image) has no end tag.
+Line: 1 Col: 547 This element (isindex) has no end tag.
+Line: 1 Col: 557 Unexpected end tag (noembed). Ignored.
+Line: 1 Col: 568 Unexpected end tag (noframes). Ignored.
+Line: 1 Col: 579 Unexpected end tag (noscript). Ignored.
+Line: 1 Col: 590 Unexpected end tag (optgroup). Ignored.
+Line: 1 Col: 599 Unexpected end tag (option). Ignored.
+Line: 1 Col: 611 Unexpected end tag (plaintext). Ignored.
+Line: 1 Col: 622 Unexpected end tag (textarea). Ignored.
+#document
+| 
+|   
+|   
+|     
+|

+ +#data +

+#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 20 Unexpected end tag (strong) in table context caused voodoo mode. +Line: 1 Col: 20 End tag (strong) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 24 Unexpected end tag (b) in table context caused voodoo mode. +Line: 1 Col: 24 End tag (b) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 29 Unexpected end tag (em) in table context caused voodoo mode. +Line: 1 Col: 29 End tag (em) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 33 Unexpected end tag (i) in table context caused voodoo mode. +Line: 1 Col: 33 End tag (i) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 37 Unexpected end tag (u) in table context caused voodoo mode. +Line: 1 Col: 37 End tag (u) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 46 Unexpected end tag (strike) in table context caused voodoo mode. +Line: 1 Col: 46 End tag (strike) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 50 Unexpected end tag (s) in table context caused voodoo mode. +Line: 1 Col: 50 End tag (s) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 58 Unexpected end tag (blink) in table context caused voodoo mode. +Line: 1 Col: 58 Unexpected end tag (blink). Ignored. +Line: 1 Col: 63 Unexpected end tag (tt) in table context caused voodoo mode. +Line: 1 Col: 63 End tag (tt) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 69 Unexpected end tag (pre) in table context caused voodoo mode. +Line: 1 Col: 69 End tag (pre) seen too early. Expected other end tag. +Line: 1 Col: 75 Unexpected end tag (big) in table context caused voodoo mode. +Line: 1 Col: 75 End tag (big) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 83 Unexpected end tag (small) in table context caused voodoo mode. +Line: 1 Col: 83 End tag (small) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 90 Unexpected end tag (font) in table context caused voodoo mode. +Line: 1 Col: 90 End tag (font) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 99 Unexpected end tag (select) in table context caused voodoo mode. +Line: 1 Col: 99 Unexpected end tag (select). Ignored. +Line: 1 Col: 104 Unexpected end tag (h1) in table context caused voodoo mode. +Line: 1 Col: 104 End tag (h1) seen too early. Expected other end tag. +Line: 1 Col: 109 Unexpected end tag (h2) in table context caused voodoo mode. +Line: 1 Col: 109 End tag (h2) seen too early. Expected other end tag. +Line: 1 Col: 114 Unexpected end tag (h3) in table context caused voodoo mode. +Line: 1 Col: 114 End tag (h3) seen too early. Expected other end tag. +Line: 1 Col: 119 Unexpected end tag (h4) in table context caused voodoo mode. +Line: 1 Col: 119 End tag (h4) seen too early. Expected other end tag. +Line: 1 Col: 124 Unexpected end tag (h5) in table context caused voodoo mode. +Line: 1 Col: 124 End tag (h5) seen too early. Expected other end tag. +Line: 1 Col: 129 Unexpected end tag (h6) in table context caused voodoo mode. +Line: 1 Col: 129 End tag (h6) seen too early. Expected other end tag. +Line: 1 Col: 136 Unexpected end tag (body) in the table row phase. Ignored. +Line: 1 Col: 141 Unexpected end tag (br) in table context caused voodoo mode. +Line: 1 Col: 141 Unexpected end tag (br). Treated as br element. +Line: 1 Col: 145 Unexpected end tag (a) in table context caused voodoo mode. +Line: 1 Col: 145 End tag (a) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 151 Unexpected end tag (img) in table context caused voodoo mode. +Line: 1 Col: 151 This element (img) has no end tag. +Line: 1 Col: 159 Unexpected end tag (title) in table context caused voodoo mode. +Line: 1 Col: 159 Unexpected end tag (title). Ignored. +Line: 1 Col: 166 Unexpected end tag (span) in table context caused voodoo mode. +Line: 1 Col: 166 Unexpected end tag (span). Ignored. +Line: 1 Col: 174 Unexpected end tag (style) in table context caused voodoo mode. +Line: 1 Col: 174 Unexpected end tag (style). Ignored. +Line: 1 Col: 183 Unexpected end tag (script) in table context caused voodoo mode. +Line: 1 Col: 183 Unexpected end tag (script). Ignored. +Line: 1 Col: 196 Unexpected end tag (th). Ignored. +Line: 1 Col: 201 Unexpected end tag (td). Ignored. +Line: 1 Col: 206 Unexpected end tag (tr). Ignored. +Line: 1 Col: 214 This element (frame) has no end tag. +Line: 1 Col: 221 This element (area) has no end tag. +Line: 1 Col: 228 Unexpected end tag (link). Ignored. +Line: 1 Col: 236 This element (param) has no end tag. +Line: 1 Col: 241 This element (hr) has no end tag. +Line: 1 Col: 249 This element (input) has no end tag. +Line: 1 Col: 255 Unexpected end tag (col). Ignored. +Line: 1 Col: 262 Unexpected end tag (base). Ignored. +Line: 1 Col: 269 Unexpected end tag (meta). Ignored. +Line: 1 Col: 280 This element (basefont) has no end tag. +Line: 1 Col: 290 This element (bgsound) has no end tag. +Line: 1 Col: 298 This element (embed) has no end tag. +Line: 1 Col: 307 This element (spacer) has no end tag. +Line: 1 Col: 311 Unexpected end tag (p). Ignored. +Line: 1 Col: 316 End tag (dd) seen too early. Expected other end tag. +Line: 1 Col: 321 End tag (dt) seen too early. Expected other end tag. +Line: 1 Col: 331 Unexpected end tag (caption). Ignored. +Line: 1 Col: 342 Unexpected end tag (colgroup). Ignored. +Line: 1 Col: 350 Unexpected end tag (tbody). Ignored. +Line: 1 Col: 358 Unexpected end tag (tfoot). Ignored. +Line: 1 Col: 366 Unexpected end tag (thead). Ignored. +Line: 1 Col: 376 End tag (address) seen too early. Expected other end tag. +Line: 1 Col: 389 End tag (blockquote) seen too early. Expected other end tag. +Line: 1 Col: 398 End tag (center) seen too early. Expected other end tag. +Line: 1 Col: 404 Unexpected end tag (dir). Ignored. +Line: 1 Col: 410 End tag (div) seen too early. Expected other end tag. +Line: 1 Col: 415 End tag (dl) seen too early. Expected other end tag. +Line: 1 Col: 426 End tag (fieldset) seen too early. Expected other end tag. +Line: 1 Col: 436 End tag (listing) seen too early. Expected other end tag. +Line: 1 Col: 443 End tag (menu) seen too early. Expected other end tag. +Line: 1 Col: 448 End tag (ol) seen too early. Expected other end tag. +Line: 1 Col: 453 End tag (ul) seen too early. Expected other end tag. +Line: 1 Col: 458 End tag (li) seen too early. Expected other end tag. +Line: 1 Col: 465 End tag (nobr) violates step 1, paragraph 1 of the adoption agency algorithm. +Line: 1 Col: 471 This element (wbr) has no end tag. +Line: 1 Col: 487 End tag (button) seen too early. Expected other end tag. +Line: 1 Col: 497 End tag (marquee) seen too early. Expected other end tag. +Line: 1 Col: 506 End tag (object) seen too early. Expected other end tag. +Line: 1 Col: 524 Unexpected end tag (html). Ignored. +Line: 1 Col: 524 Unexpected end tag (frameset). Ignored. +Line: 1 Col: 531 Unexpected end tag (head). Ignored. +Line: 1 Col: 540 Unexpected end tag (iframe). Ignored. +Line: 1 Col: 548 This element (image) has no end tag. +Line: 1 Col: 558 This element (isindex) has no end tag. +Line: 1 Col: 568 Unexpected end tag (noembed). Ignored. +Line: 1 Col: 579 Unexpected end tag (noframes). Ignored. +Line: 1 Col: 590 Unexpected end tag (noscript). Ignored. +Line: 1 Col: 601 Unexpected end tag (optgroup). Ignored. +Line: 1 Col: 610 Unexpected end tag (option). Ignored. +Line: 1 Col: 622 Unexpected end tag (plaintext). Ignored. +Line: 1 Col: 633 Unexpected end tag (textarea). Ignored. +#document +| +| +| +|
+| +| +| +|

+ +#data + +#errors +Line: 1 Col: 10 Unexpected start tag (frameset). Expected DOCTYPE. +Line: 1 Col: 10 Expected closing tag. Unexpected end of file. +#document +| +| +| diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests10.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests10.dat new file mode 100644 index 00000000..4f8df86f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests10.dat @@ -0,0 +1,799 @@ +#data + +#errors +#document +| +| +| +| +| + +#data +a +#errors +29: Bogus comment +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| + +#data + +#errors +35: Stray “svg” start tag. +42: Stray end tag “svg” +#document +| +| +| +| +| +#errors +43: Stray “svg” start tag. +50: Stray end tag “svg” +#document +| +| +| +| +|

+#errors +34: Start tag “svg” seen in “table”. +41: Stray end tag “svg”. +#document +| +| +| +| +| +| + +#data +
foo
+#errors +34: Start tag “svg” seen in “table”. +46: Stray end tag “g”. +53: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| + +#data +
foobar
+#errors +34: Start tag “svg” seen in “table”. +46: Stray end tag “g”. +58: Stray end tag “g”. +65: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| + +#data +
foobar
+#errors +41: Start tag “svg” seen in “table”. +53: Stray end tag “g”. +65: Stray end tag “g”. +72: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| +| + +#data +
foobar
+#errors +45: Start tag “svg” seen in “table”. +57: Stray end tag “g”. +69: Stray end tag “g”. +76: Stray end tag “svg”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +| +| +| + +#data +
foobar
+#errors +#document +| +| +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" + +#data +
foobar

baz

+#errors +#document +| +| +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +
foobar

baz

+#errors +#document +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +
foobar

baz

quux +#errors +70: HTML start tag “p” in a foreign namespace context. +81: “table” closed but “caption” was still open. +#document +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +|

+| "baz" +|

+| "quux" + +#data +
foobarbaz

quux +#errors +78: “table” closed but “caption” was still open. +78: Unclosed elements on stack. +#document +| +| +| +| +| +|
+| +| +| "foo" +| +| "bar" +| "baz" +|

+| "quux" + +#data +foobar

baz

quux +#errors +44: Start tag “svg” seen in “table”. +56: Stray end tag “g”. +68: Stray end tag “g”. +71: HTML start tag “p” in a foreign namespace context. +71: Start tag “p” seen in “table”. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

+| "baz" +| +| +|

+| "quux" + +#data +

quux +#errors +50: Stray “svg” start tag. +54: Stray “g” start tag. +62: Stray end tag “g” +66: Stray “g” start tag. +74: Stray end tag “g” +77: Stray “p” start tag. +88: “table” end tag with “select” open. +#document +| +| +| +| +| +| +| +|
+|

quux +#errors +36: Start tag “select” seen in “table”. +42: Stray “svg” start tag. +46: Stray “g” start tag. +54: Stray end tag “g” +58: Stray “g” start tag. +66: Stray end tag “g” +69: Stray “p” start tag. +80: “table” end tag with “select” open. +#document +| +| +| +| +| +|

+| "quux" + +#data +foobar

baz +#errors +41: Stray “svg” start tag. +68: HTML start tag “p” in a foreign namespace context. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +foobar

baz +#errors +34: Stray “svg” start tag. +61: HTML start tag “p” in a foreign namespace context. +#document +| +| +| +| +| +| +| "foo" +| +| "bar" +|

+| "baz" + +#data +

+#errors +31: Stray “svg” start tag. +35: Stray “g” start tag. +40: Stray end tag “g” +44: Stray “g” start tag. +49: Stray end tag “g” +52: Stray “p” start tag. +58: Stray “span” start tag. +58: End of file seen and there were open elements. +#document +| +| +| +| + +#data +

+#errors +42: Stray “svg” start tag. +46: Stray “g” start tag. +51: Stray end tag “g” +55: Stray “g” start tag. +60: Stray end tag “g” +63: Stray “p” start tag. +69: Stray “span” start tag. +#document +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| +| xlink href="foo" + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" + +#data + +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" + +#data +bar +#errors +#document +| +| +| +| +| xlink:href="foo" +| xml:lang="en" +| +| +| xlink href="foo" +| xml lang="en" +| "bar" + +#data + +#errors +#document +| +| +| +| + +#data +

a +#errors +#document +| +| +| +|
+| +| "a" + +#data +
a +#errors +#document +| +| +| +|
+| +| +| "a" + +#data +
+#errors +#document +| +| +| +|
+| +| +| + +#data +
a +#errors +#document +| +| +| +|
+| +| +| +| +| "a" + +#data +

a +#errors +#document +| +| +| +|

+| +| +| +|

+| "a" + +#data +
    a +#errors +40: HTML start tag “ul” in a foreign namespace context. +41: End of file in a foreign namespace context. +#document +| +| +| +| +| +| +|
    +| +|
      +| "a" + +#data +
        a +#errors +35: HTML start tag “ul” in a foreign namespace context. +36: End of file in a foreign namespace context. +#document +| +| +| +| +| +| +| +|
          +| "a" + +#data +

          +#errors +#document +| +| +| +| +|

          +| +| +|

          + +#data +

          +#errors +#document +| +| +| +| +|

          +| +| +|

          + +#data +

          +#errors +#document +| +| +| +|

          +| +| +| +|

          +|

          + +#data +
          +#errors +#document +| +| +| +| +| +|
          +| +|
          +| +| + +#data +
          +#errors +#document +| +| +| +| +| +| +| +|
          +|
          +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data +

+#errors +#document +| +| +| +| +|
+| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| + +#data +
+#errors +#document +| +| +| +| +| +| +| +|
+| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests11.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests11.dat new file mode 100644 index 00000000..638cde47 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests11.dat @@ -0,0 +1,482 @@ +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentScriptType="" +| contentStyleType="" +| diffuseConstant="" +| edgeMode="" +| externalResourcesRequired="" +| filterRes="" +| filterUnits="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentScriptType="" +| contentStyleType="" +| diffuseConstant="" +| edgeMode="" +| externalResourcesRequired="" +| filterRes="" +| filterUnits="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributeName="" +| attributeType="" +| baseFrequency="" +| baseProfile="" +| calcMode="" +| clipPathUnits="" +| contentScriptType="" +| contentStyleType="" +| diffuseConstant="" +| edgeMode="" +| externalResourcesRequired="" +| filterRes="" +| filterUnits="" +| glyphRef="" +| gradientTransform="" +| gradientUnits="" +| kernelMatrix="" +| kernelUnitLength="" +| keyPoints="" +| keySplines="" +| keyTimes="" +| lengthAdjust="" +| limitingConeAngle="" +| markerHeight="" +| markerUnits="" +| markerWidth="" +| maskContentUnits="" +| maskUnits="" +| numOctaves="" +| pathLength="" +| patternContentUnits="" +| patternTransform="" +| patternUnits="" +| pointsAtX="" +| pointsAtY="" +| pointsAtZ="" +| preserveAlpha="" +| preserveAspectRatio="" +| primitiveUnits="" +| refX="" +| refY="" +| repeatCount="" +| repeatDur="" +| requiredExtensions="" +| requiredFeatures="" +| specularConstant="" +| specularExponent="" +| spreadMethod="" +| startOffset="" +| stdDeviation="" +| stitchTiles="" +| surfaceScale="" +| systemLanguage="" +| tableValues="" +| targetX="" +| targetY="" +| textLength="" +| viewBox="" +| viewTarget="" +| xChannelSelector="" +| yChannelSelector="" +| zoomAndPan="" + +#data + +#errors +#document +| +| +| +| +| +| attributename="" +| attributetype="" +| basefrequency="" +| baseprofile="" +| calcmode="" +| clippathunits="" +| contentscripttype="" +| contentstyletype="" +| diffuseconstant="" +| edgemode="" +| externalresourcesrequired="" +| filterres="" +| filterunits="" +| glyphref="" +| gradienttransform="" +| gradientunits="" +| kernelmatrix="" +| kernelunitlength="" +| keypoints="" +| keysplines="" +| keytimes="" +| lengthadjust="" +| limitingconeangle="" +| markerheight="" +| markerunits="" +| markerwidth="" +| maskcontentunits="" +| maskunits="" +| numoctaves="" +| pathlength="" +| patterncontentunits="" +| patterntransform="" +| patternunits="" +| pointsatx="" +| pointsaty="" +| pointsatz="" +| preservealpha="" +| preserveaspectratio="" +| primitiveunits="" +| refx="" +| refy="" +| repeatcount="" +| repeatdur="" +| requiredextensions="" +| requiredfeatures="" +| specularconstant="" +| specularexponent="" +| spreadmethod="" +| startoffset="" +| stddeviation="" +| stitchtiles="" +| surfacescale="" +| systemlanguage="" +| tablevalues="" +| targetx="" +| targety="" +| textlength="" +| viewbox="" +| viewtarget="" +| xchannelselector="" +| ychannelselector="" +| zoomandpan="" + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests12.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests12.dat new file mode 100644 index 00000000..63107d27 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests12.dat @@ -0,0 +1,62 @@ +#data +

foobazeggs

spam

quuxbar +#errors +#document +| +| +| +| +|

+| "foo" +| +| +| +| "baz" +| +| +| +| +| "eggs" +| +| +|

+| "spam" +| +| +| +|
+| +| +| "quux" +| "bar" + +#data +foobazeggs

spam
quuxbar +#errors +#document +| +| +| +| +| "foo" +| +| +| +| "baz" +| +| +| +| +| "eggs" +| +| +|

+| "spam" +| +| +| +|
+| +| +| "quux" +| "bar" diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests14.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests14.dat new file mode 100644 index 00000000..b8713f88 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests14.dat @@ -0,0 +1,74 @@ +#data + +#errors +#document +| +| +| +| +| + +#data + +#errors +#document +| +| +| +| +| +| + +#data + +#errors +15: Unexpected start tag html +#document +| +| +| abc:def="gh" +| +| +| + +#data + +#errors +15: Unexpected start tag html +#document +| +| +| xml:lang="bar" +| +| + +#data + +#errors +#document +| +| +| 123="456" +| +| + +#data + +#errors +#document +| +| +| 123="456" +| 789="012" +| +| + +#data + +#errors +#document +| +| +| +| +| 789="012" diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests15.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests15.dat new file mode 100644 index 00000000..6ce1c0d1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests15.dat @@ -0,0 +1,208 @@ +#data +

X +#errors +Line: 1 Col: 31 Unexpected end tag (p). Ignored. +Line: 1 Col: 36 Expected closing tag. Unexpected end of file. +#document +| +| +| +| +|

+| +| +| +| +| +| +| " " +|

+| "X" + +#data +

+

X +#errors +Line: 1 Col: 3 Unexpected start tag (p). Expected DOCTYPE. +Line: 1 Col: 16 Unexpected end tag (p). Ignored. +Line: 2 Col: 4 Expected closing tag. Unexpected end of file. +#document +| +| +| +|

+| +| +| +| +| +| +| " +" +|

+| "X" + +#data + +#errors +Line: 1 Col: 22 Unexpected end tag (html) after the (implied) root element. +#document +| +| +| +| +| " " + +#data + +#errors +Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element. +#document +| +| +| +| +| + +#data + +#errors +Line: 1 Col: 6 Unexpected start tag (html). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end tag (html) after the (implied) root element. +#document +| +| +| +| + +#data +X +#errors +Line: 1 Col: 22 Unexpected end tag (body) after the (implied) root element. +#document +| +| +| +| +| +| "X" + +#data +<!doctype html><table> X<meta></table> +#errors +Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode. +Line: 1 Col: 30 Unexpected start tag (meta) in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " X" +| <meta> +| <table> + +#data +<!doctype html><table> x</table> +#errors +Line: 1 Col: 24 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x" +| <table> + +#data +<!doctype html><table> x </table> +#errors +Line: 1 Col: 25 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x " +| <table> + +#data +<!doctype html><table><tr> x</table> +#errors +Line: 1 Col: 28 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " x" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table>X<style> <tr>x </style> </table> +#errors +Line: 1 Col: 23 Unexpected non-space characters in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "X" +| <table> +| <style> +| " <tr>x " +| " " + +#data +<!doctype html><div><table><a>foo</a> <tr><td>bar</td> </tr></table></div> +#errors +Line: 1 Col: 30 Unexpected start tag (a) in table context caused voodoo mode. +Line: 1 Col: 37 Unexpected end tag (a) in table context caused voodoo mode. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| <a> +| "foo" +| <table> +| " " +| <tbody> +| <tr> +| <td> +| "bar" +| " " + +#data +<frame></frame></frame><frameset><frame><frameset><frame></frameset><noframes></frameset><noframes> +#errors +6: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”. +13: Stray start tag “frame”. +21: Stray end tag “frame”. +29: Stray end tag “frame”. +39: “frameset” start tag after “body” already open. +105: End of file seen inside an [R]CDATA element. +105: End of file seen and there were open elements. +XXX: These errors are wrong, please fix me! +#document +| <html> +| <head> +| <frameset> +| <frame> +| <frameset> +| <frame> +| <noframes> +| "</frameset><noframes>" + +#data +<!DOCTYPE html><object></html> +#errors +1: Expected closing tag. Unexpected end of file +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <object> diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests16.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests16.dat new file mode 100644 index 00000000..c8ef66f0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests16.dat @@ -0,0 +1,2299 @@ +#data +<!doctype html><script> +#errors +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script>a +#errors +Line: 1 Col: 24 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "a" +| <body> + +#data +<!doctype html><script>< +#errors +Line: 1 Col: 24 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<" +| <body> + +#data +<!doctype html><script></ +#errors +Line: 1 Col: 25 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</" +| <body> + +#data +<!doctype html><script></S +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</S" +| <body> + +#data +<!doctype html><script></SC +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SC" +| <body> + +#data +<!doctype html><script></SCR +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCR" +| <body> + +#data +<!doctype html><script></SCRI +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRI" +| <body> + +#data +<!doctype html><script></SCRIP +#errors +Line: 1 Col: 30 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRIP" +| <body> + +#data +<!doctype html><script></SCRIPT +#errors +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</SCRIPT" +| <body> + +#data +<!doctype html><script></SCRIPT +#errors +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script></s +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</s" +| <body> + +#data +<!doctype html><script></sc +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</sc" +| <body> + +#data +<!doctype html><script></scr +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scr" +| <body> + +#data +<!doctype html><script></scri +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scri" +| <body> + +#data +<!doctype html><script></scrip +#errors +Line: 1 Col: 30 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</scrip" +| <body> + +#data +<!doctype html><script></script +#errors +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "</script" +| <body> + +#data +<!doctype html><script></script +#errors +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| <body> + +#data +<!doctype html><script><! +#errors +Line: 1 Col: 25 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!" +| <body> + +#data +<!doctype html><script><!a +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!a" +| <body> + +#data +<!doctype html><script><!- +#errors +Line: 1 Col: 26 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!-" +| <body> + +#data +<!doctype html><script><!-a +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!-a" +| <body> + +#data +<!doctype html><script><!-- +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<!doctype html><script><!--a +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--a" +| <body> + +#data +<!doctype html><script><!--< +#errors +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<" +| <body> + +#data +<!doctype html><script><!--<a +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<a" +| <body> + +#data +<!doctype html><script><!--</ +#errors +Line: 1 Col: 27 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--</" +| <body> + +#data +<!doctype html><script><!--</script +#errors +Line: 1 Col: 35 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--</script" +| <body> + +#data +<!doctype html><script><!--</script +#errors +Line: 1 Col: 36 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<!doctype html><script><!--<s +#errors +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<s" +| <body> + +#data +<!doctype html><script><!--<script +#errors +Line: 1 Col: 34 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script" +| <body> + +#data +<!doctype html><script><!--<script +#errors +Line: 1 Col: 35 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script " +| <body> + +#data +<!doctype html><script><!--<script < +#errors +Line: 1 Col: 36 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script <" +| <body> + +#data +<!doctype html><script><!--<script <a +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script <a" +| <body> + +#data +<!doctype html><script><!--<script </ +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </" +| <body> + +#data +<!doctype html><script><!--<script </s +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </s" +| <body> + +#data +<!doctype html><script><!--<script </script +#errors +Line: 1 Col: 43 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script" +| <body> + +#data +<!doctype html><script><!--<script </scripta +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </scripta" +| <body> + +#data +<!doctype html><script><!--<script </script +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script> +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script>" +| <body> + +#data +<!doctype html><script><!--<script </script/ +#errors +Line: 1 Col: 44 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script/" +| <body> + +#data +<!doctype html><script><!--<script </script < +#errors +Line: 1 Col: 45 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script <" +| <body> + +#data +<!doctype html><script><!--<script </script <a +#errors +Line: 1 Col: 46 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script <a" +| <body> + +#data +<!doctype html><script><!--<script </script </ +#errors +Line: 1 Col: 46 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script </" +| <body> + +#data +<!doctype html><script><!--<script </script </script +#errors +Line: 1 Col: 52 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script </script" +| <body> + +#data +<!doctype html><script><!--<script </script </script +#errors +Line: 1 Col: 53 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script </script/ +#errors +Line: 1 Col: 53 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script </script </script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<!doctype html><script><!--<script - +#errors +Line: 1 Col: 36 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -" +| <body> + +#data +<!doctype html><script><!--<script -a +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -a" +| <body> + +#data +<!doctype html><script><!--<script -< +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -<" +| <body> + +#data +<!doctype html><script><!--<script -- +#errors +Line: 1 Col: 37 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --" +| <body> + +#data +<!doctype html><script><!--<script --a +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --a" +| <body> + +#data +<!doctype html><script><!--<script --< +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --<" +| <body> + +#data +<!doctype html><script><!--<script --> +#errors +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script -->< +#errors +Line: 1 Col: 39 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --><" +| <body> + +#data +<!doctype html><script><!--<script --></ +#errors +Line: 1 Col: 40 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --></" +| <body> + +#data +<!doctype html><script><!--<script --></script +#errors +Line: 1 Col: 46 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script --></script" +| <body> + +#data +<!doctype html><script><!--<script --></script +#errors +Line: 1 Col: 47 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script --></script/ +#errors +Line: 1 Col: 47 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script --></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<!doctype html><script><!--<script><\/script>--></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script><\/script>-->" +| <body> + +#data +<!doctype html><script><!--<script></scr'+'ipt>--></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt>-->" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>--><!--</script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>--><!--" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>-- ></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>-- >" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>- -></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- ->" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>- - ></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- - >" +| <body> + +#data +<!doctype html><script><!--<script></script><script></script>-></script> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>->" +| <body> + +#data +<!doctype html><script><!--<script>--!></script>X +#errors +Line: 1 Col: 49 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script>--!></script>X" +| <body> + +#data +<!doctype html><script><!--<scr'+'ipt></script>--></script> +#errors +Line: 1 Col: 59 Unexpected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<scr'+'ipt>" +| <body> +| "-->" + +#data +<!doctype html><script><!--<script></scr'+'ipt></script>X +#errors +Line: 1 Col: 57 Unexpected end of file. Expected end tag (script). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt></script>X" +| <body> + +#data +<!doctype html><style><!--<style></style>--></style> +#errors +Line: 1 Col: 52 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--<style>" +| <body> +| "-->" + +#data +<!doctype html><style><!--</style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--" +| <body> +| "X" + +#data +<!doctype html><style><!--...</style>...--></style> +#errors +Line: 1 Col: 51 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--..." +| <body> +| "...-->" + +#data +<!doctype html><style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>" +| <body> +| "X" + +#data +<!doctype html><style><!--...<style><!--...--!></style>--></style> +#errors +Line: 1 Col: 66 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--...<style><!--...--!>" +| <body> +| "-->" + +#data +<!doctype html><style><!--...</style><!-- --><style>@import ...</style> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "<!--..." +| <!-- --> +| <style> +| "@import ..." +| <body> + +#data +<!doctype html><style>...<style><!--...</style><!-- --></style> +#errors +Line: 1 Col: 63 Unexpected end tag (style). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "...<style><!--..." +| <!-- --> +| <body> + +#data +<!doctype html><style>...<!--[if IE]><style>...</style>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <style> +| "...<!--[if IE]><style>..." +| <body> +| "X" + +#data +<!doctype html><title><!--<title>--> +#errors +Line: 1 Col: 52 Unexpected end tag (title). +#document +| +| +| +| +| "<!--<title>" +| <body> +| "-->" + +#data +<!doctype html><title></title> +#errors +#document +| +| +| +| +| "" +| + +#data +foo/title><link></head><body>X +#errors +Line: 1 Col: 52 Unexpected end of file. Expected end tag (title). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <title> +| "foo/title><link></head><body>X" +| <body> + +#data +<!doctype html><noscript><!--<noscript></noscript>--></noscript> +#errors +Line: 1 Col: 64 Unexpected end tag (noscript). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<!--<noscript>" +| <body> +| "-->" + +#data +<!doctype html><noscript><!--</noscript>X<noscript>--></noscript> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<!--" +| <body> +| "X" +| <noscript> +| "-->" + +#data +<!doctype html><noscript><iframe></noscript>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noscript> +| "<iframe>" +| <body> +| "X" + +#data +<!doctype html><noframes><!--<noframes></noframes>--></noframes> +#errors +Line: 1 Col: 64 Unexpected end tag (noframes). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noframes> +| "<!--<noframes>" +| <body> +| "-->" + +#data +<!doctype html><noframes><body><script><!--...</script></body></noframes></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <noframes> +| "<body><script><!--...</script></body>" +| <body> + +#data +<!doctype html><textarea><!--<textarea></textarea>--></textarea> +#errors +Line: 1 Col: 64 Unexpected end tag (textarea). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "<!--<textarea>" +| "-->" + +#data +<!doctype html><textarea></textarea></textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "</textarea>" + +#data +<!doctype html><textarea><</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "<" + +#data +<!doctype html><textarea>a<b</textarea> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> +| "a<b" + +#data +<!doctype html><iframe><!--<iframe></iframe>--></iframe> +#errors +Line: 1 Col: 56 Unexpected end tag (iframe). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> +| "<!--<iframe>" +| "-->" + +#data +<!doctype html><iframe>...<!--X->...<!--/X->...</iframe> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> +| "...<!--X->...<!--/X->..." + +#data +<!doctype html><xmp><!--<xmp></xmp>--></xmp> +#errors +Line: 1 Col: 44 Unexpected end tag (xmp). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <xmp> +| "<!--<xmp>" +| "-->" + +#data +<!doctype html><noembed><!--<noembed></noembed>--></noembed> +#errors +Line: 1 Col: 60 Unexpected end tag (noembed). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <noembed> +| "<!--<noembed>" +| "-->" + +#data +<script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 8 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script>a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 9 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "a" +| <body> + +#data +<script>< +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 9 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<" +| <body> + +#data +<script></ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 10 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</" +| <body> + +#data +<script></S +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</S" +| <body> + +#data +<script></SC +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SC" +| <body> + +#data +<script></SCR +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCR" +| <body> + +#data +<script></SCRI +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCRI" +| <body> + +#data +<script></SCRIP +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 15 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCRIP" +| <body> + +#data +<script></SCRIPT +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 16 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</SCRIPT" +| <body> + +#data +<script></SCRIPT +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 17 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script></s +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</s" +| <body> + +#data +<script></sc +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</sc" +| <body> + +#data +<script></scr +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</scr" +| <body> + +#data +<script></scri +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</scri" +| <body> + +#data +<script></scrip +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 15 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</scrip" +| <body> + +#data +<script></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 16 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</script" +| <body> + +#data +<script></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 17 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| <body> + +#data +<script><! +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 10 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!" +| <body> + +#data +<script><!a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!a" +| <body> + +#data +<script><!- +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!-" +| <body> + +#data +<script><!-a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!-a" +| <body> + +#data +<script><!-- +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 12 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<script><!--a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--a" +| <body> + +#data +<script><!--< +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 13 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<" +| <body> + +#data +<script><!--<a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<a" +| <body> + +#data +<script><!--</ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--</" +| <body> + +#data +<script><!--</script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 20 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--</script" +| <body> + +#data +<script><!--</script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--" +| <body> + +#data +<script><!--<s +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 14 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<s" +| <body> + +#data +<script><!--<script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 19 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script" +| <body> + +#data +<script><!--<script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 20 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script " +| <body> + +#data +<script><!--<script < +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script <" +| <body> + +#data +<script><!--<script <a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script <a" +| <body> + +#data +<script><!--<script </ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </" +| <body> + +#data +<script><!--<script </s +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </s" +| <body> + +#data +<script><!--<script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 28 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script" +| <body> + +#data +<script><!--<script </scripta +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </scripta" +| <body> + +#data +<script><!--<script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script>" +| <body> + +#data +<script><!--<script </script/ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script/" +| <body> + +#data +<script><!--<script </script < +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 30 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script <" +| <body> + +#data +<script><!--<script </script <a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script <a" +| <body> + +#data +<script><!--<script </script </ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script </" +| <body> + +#data +<script><!--<script </script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script </script" +| <body> + +#data +<script><!--<script </script </script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script </script/ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 38 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script </script </script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script </script " +| <body> + +#data +<script><!--<script - +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -" +| <body> + +#data +<script><!--<script -a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -a" +| <body> + +#data +<script><!--<script -- +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --" +| <body> + +#data +<script><!--<script --a +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --a" +| <body> + +#data +<script><!--<script --> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script -->< +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 24 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --><" +| <body> + +#data +<script><!--<script --></ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 25 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --></" +| <body> + +#data +<script><!--<script --></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 31 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script --></script" +| <body> + +#data +<script><!--<script --></script +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script --></script/ +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 32 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script --></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script -->" +| <body> + +#data +<script><!--<script><\/script>--></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script><\/script>-->" +| <body> + +#data +<script><!--<script></scr'+'ipt>--></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt>-->" +| <body> + +#data +<script><!--<script></script><script></script></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>" +| <body> + +#data +<script><!--<script></script><script></script>--><!--</script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>--><!--" +| <body> + +#data +<script><!--<script></script><script></script>-- ></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>-- >" +| <body> + +#data +<script><!--<script></script><script></script>- -></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- ->" +| <body> + +#data +<script><!--<script></script><script></script>- - ></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>- - >" +| <body> + +#data +<script><!--<script></script><script></script>-></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +#document +| <html> +| <head> +| <script> +| "<!--<script></script><script></script>->" +| <body> + +#data +<script><!--<script>--!></script>X +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 34 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script>--!></script>X" +| <body> + +#data +<script><!--<scr'+'ipt></script>--></script> +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 44 Unexpected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<scr'+'ipt>" +| <body> +| "-->" + +#data +<script><!--<script></scr'+'ipt></script>X +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 42 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "<!--<script></scr'+'ipt></script>X" +| <body> + +#data +<style><!--<style></style>--></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 37 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "<!--<style>" +| <body> +| "-->" + +#data +<style><!--</style>X +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "<!--" +| <body> +| "X" + +#data +<style><!--...</style>...--></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 36 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "<!--..." +| <body> +| "...-->" + +#data +<style><!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style></style>X +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "<!--<br><html xmlns:v="urn:schemas-microsoft-com:vml"><!--[if !mso]><style>" +| <body> +| "X" + +#data +<style><!--...<style><!--...--!></style>--></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 51 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "<!--...<style><!--...--!>" +| <body> +| "-->" + +#data +<style><!--...</style><!-- --><style>@import ...</style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "<!--..." +| <!-- --> +| <style> +| "@import ..." +| <body> + +#data +<style>...<style><!--...</style><!-- --></style> +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 48 Unexpected end tag (style). +#document +| <html> +| <head> +| <style> +| "...<style><!--..." +| <!-- --> +| <body> + +#data +<style>...<!--[if IE]><style>...</style>X +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| <html> +| <head> +| <style> +| "...<!--[if IE]><style>..." +| <body> +| "X" + +#data +<title><!--<title>--> +#errors +Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE. +Line: 1 Col: 37 Unexpected end tag (title). +#document +| +| +| +| "<!--<title>" +| <body> +| "-->" + +#data +<title></title> +#errors +Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE. +#document +| +| +| +| "" +| + +#data +foo/title><link></head><body>X +#errors +Line: 1 Col: 7 Unexpected start tag (title). Expected DOCTYPE. +Line: 1 Col: 37 Unexpected end of file. Expected end tag (title). +#document +| <html> +| <head> +| <title> +| "foo/title><link></head><body>X" +| <body> + +#data +<noscript><!--<noscript></noscript>--></noscript> +#errors +Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE. +Line: 1 Col: 49 Unexpected end tag (noscript). +#document +| <html> +| <head> +| <noscript> +| "<!--<noscript>" +| <body> +| "-->" + +#data +<noscript><!--</noscript>X<noscript>--></noscript> +#errors +Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE. +#document +| <html> +| <head> +| <noscript> +| "<!--" +| <body> +| "X" +| <noscript> +| "-->" + +#data +<noscript><iframe></noscript>X +#errors +Line: 1 Col: 10 Unexpected start tag (noscript). Expected DOCTYPE. +#document +| <html> +| <head> +| <noscript> +| "<iframe>" +| <body> +| "X" + +#data +<noframes><!--<noframes></noframes>--></noframes> +#errors +Line: 1 Col: 10 Unexpected start tag (noframes). Expected DOCTYPE. +Line: 1 Col: 49 Unexpected end tag (noframes). +#document +| <html> +| <head> +| <noframes> +| "<!--<noframes>" +| <body> +| "-->" + +#data +<noframes><body><script><!--...</script></body></noframes></html> +#errors +Line: 1 Col: 10 Unexpected start tag (noframes). Expected DOCTYPE. +#document +| <html> +| <head> +| <noframes> +| "<body><script><!--...</script></body>" +| <body> + +#data +<textarea><!--<textarea></textarea>--></textarea> +#errors +Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE. +Line: 1 Col: 49 Unexpected end tag (textarea). +#document +| <html> +| <head> +| <body> +| <textarea> +| "<!--<textarea>" +| "-->" + +#data +<textarea></textarea></textarea> +#errors +Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| <textarea> +| "</textarea>" + +#data +<iframe><!--<iframe></iframe>--></iframe> +#errors +Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE. +Line: 1 Col: 41 Unexpected end tag (iframe). +#document +| <html> +| <head> +| <body> +| <iframe> +| "<!--<iframe>" +| "-->" + +#data +<iframe>...<!--X->...<!--/X->...</iframe> +#errors +Line: 1 Col: 8 Unexpected start tag (iframe). Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| <iframe> +| "...<!--X->...<!--/X->..." + +#data +<xmp><!--<xmp></xmp>--></xmp> +#errors +Line: 1 Col: 5 Unexpected start tag (xmp). Expected DOCTYPE. +Line: 1 Col: 29 Unexpected end tag (xmp). +#document +| <html> +| <head> +| <body> +| <xmp> +| "<!--<xmp>" +| "-->" + +#data +<noembed><!--<noembed></noembed>--></noembed> +#errors +Line: 1 Col: 9 Unexpected start tag (noembed). Expected DOCTYPE. +Line: 1 Col: 45 Unexpected end tag (noembed). +#document +| <html> +| <head> +| <body> +| <noembed> +| "<!--<noembed>" +| "-->" + +#data +<!doctype html><table> + +#errors +Line 2 Col 0 Unexpected end of file. Expected table content. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| " +" + +#data +<!doctype html><table><td><span><font></span><span> +#errors +Line 1 Col 26 Unexpected table cell start tag (td) in the table body phase. +Line 1 Col 45 Unexpected end tag (span). +Line 1 Col 51 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <span> +| <font> +| <font> +| <span> + +#data +<!doctype html><form><table></form><form></table></form> +#errors +35: Stray end tag “form”. +41: Start tag “form” seen in “table”. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <table> +| <form> diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests17.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests17.dat new file mode 100644 index 00000000..7b555f88 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests17.dat @@ -0,0 +1,153 @@ +#data +<!doctype html><table><tbody><select><tr> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><tr><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <table> +| <tbody> +| <tr> +| <td> + +#data +<!doctype html><table><tr><td><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <select> +| <td> + +#data +<!doctype html><table><tr><th><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <th> +| <select> +| <td> + +#data +<!doctype html><table><caption><select><tr> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <select> +| <tbody> +| <tr> + +#data +<!doctype html><select><tr> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><th> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><tbody> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><thead> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><tfoot> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><select><caption> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><table><tr></table>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| "a" diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests18.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests18.dat new file mode 100644 index 00000000..680e1f06 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests18.dat @@ -0,0 +1,269 @@ +#data +<!doctype html><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> + +#data +<!doctype html><table><tbody><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> + +#data +<!doctype html><table><tbody><tr><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><tbody><tr><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><td><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><caption><plaintext></plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <plaintext> +| "</plaintext>" + +#data +<!doctype html><table><tr><style></script></style>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <tbody> +| <tr> +| <style> +| "</script>" + +#data +<!doctype html><table><tr><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <tbody> +| <tr> +| <script> +| "</style>" + +#data +<!doctype html><table><caption><style></script></style>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| <style> +| "</script>" +| "abc" + +#data +<!doctype html><table><td><style></script></style>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <style> +| "</script>" +| "abc" + +#data +<!doctype html><select><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" + +#data +<!doctype html><table><select><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" +| <table> + +#data +<!doctype html><table><tr><select><script></style></script>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <script> +| "</style>" +| "abc" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><frameset></frameset><noframes>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" + +#data +<!doctype html><frameset></frameset><noframes>abc</noframes><!--abc--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" +| <!-- abc --> + +#data +<!doctype html><frameset></frameset></html><noframes>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" + +#data +<!doctype html><frameset></frameset></html><noframes>abc</noframes><!--abc--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <noframes> +| "abc" +| <!-- abc --> + +#data +<!doctype html><table><tr></tbody><tfoot> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <tfoot> + +#data +<!doctype html><table><td><svg></svg>abc<td> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <svg svg> +| "abc" +| <td> diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests19.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests19.dat new file mode 100644 index 00000000..0d62f5a5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests19.dat @@ -0,0 +1,1237 @@ +#data +<!doctype html><math><mn DefinitionUrl="foo"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> +| <math mn> +| definitionURL="foo" + +#data +<!doctype html><html></p><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <!-- foo --> +| <head> +| <body> + +#data +<!doctype html><head></head></p><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <!-- foo --> +| <body> + +#data +<!doctype html><body><p><pre> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <pre> + +#data +<!doctype html><body><p><listing> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <listing> + +#data +<!doctype html><p><plaintext> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <plaintext> + +#data +<!doctype html><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <h1> + +#data +<!doctype html><form><isindex> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> + +#data +<!doctype html><isindex action="POST"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| action="POST" +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| <hr> + +#data +<!doctype html><isindex prompt="this is isindex"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "this is isindex" +| <input> +| name="isindex" +| <hr> + +#data +<!doctype html><isindex type="hidden"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| type="hidden" +| <hr> + +#data +<!doctype html><isindex name="foo"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| <hr> + +#data +<!doctype html><ruby><p><rp> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <p> +| <rp> + +#data +<!doctype html><ruby><div><span><rp> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <span> +| <rp> + +#data +<!doctype html><ruby><div><p><rp> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <p> +| <rp> + +#data +<!doctype html><ruby><p><rt> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <p> +| <rt> + +#data +<!doctype html><ruby><div><span><rt> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <span> +| <rt> + +#data +<!doctype html><ruby><div><p><rt> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <ruby> +| <div> +| <p> +| <rt> + +#data +<!doctype html><math/><foo> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> +| <foo> + +#data +<!doctype html><svg/><foo> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <svg svg> +| <foo> + +#data +<!doctype html><div></body><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| <!-- foo --> + +#data +<!doctype html><h1><div><h3><span></h1>foo +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <h1> +| <div> +| <h3> +| <span> +| "foo" + +#data +<!doctype html><p></h3>foo +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "foo" + +#data +<!doctype html><h3><li>abc</h2>foo +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <h3> +| <li> +| "abc" +| "foo" + +#data +<!doctype html><table>abc<!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "abc" +| <table> +| <!-- foo --> + +#data +<!doctype html><table> <!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| " " +| <!-- foo --> + +#data +<!doctype html><table> b <!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| " b " +| <table> +| <!-- foo --> + +#data +<!doctype html><select><option><option> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> +| <option> + +#data +<!doctype html><select><option></optgroup> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> + +#data +<!doctype html><select><option></optgroup> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> + +#data +<!doctype html><p><math><mi><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mi> +| <p> +| <h1> + +#data +<!doctype html><p><math><mo><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mo> +| <p> +| <h1> + +#data +<!doctype html><p><math><mn><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mn> +| <p> +| <h1> + +#data +<!doctype html><p><math><ms><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math ms> +| <p> +| <h1> + +#data +<!doctype html><p><math><mtext><p><h1> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mtext> +| <p> +| <h1> + +#data +<!doctype html><frameset></noframes> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html c=d><body></html><html a=b> +#errors +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <body> + +#data +<!doctype html><html c=d><frameset></frameset></html><html a=b> +#errors +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html><!--foo--> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <!-- foo --> + +#data +<!doctype html><html><frameset></frameset></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| " " + +#data +<!doctype html><html><frameset></frameset></html>abc +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html><p> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><html><frameset></frameset></html></p> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<html><frameset></frameset></html><!doctype html> +#errors +#document +| <html> +| <head> +| <frameset> + +#data +<!doctype html><body><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> + +#data +<!doctype html><p><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><p>a<frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "a" + +#data +<!doctype html><p> <frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><pre><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <pre> + +#data +<!doctype html><listing><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <listing> + +#data +<!doctype html><li><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <li> + +#data +<!doctype html><dd><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dd> + +#data +<!doctype html><dt><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dt> + +#data +<!doctype html><button><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <button> + +#data +<!doctype html><applet><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <applet> + +#data +<!doctype html><marquee><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <marquee> + +#data +<!doctype html><object><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <object> + +#data +<!doctype html><table><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> + +#data +<!doctype html><area><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <area> + +#data +<!doctype html><basefont><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <basefont> +| <frameset> + +#data +<!doctype html><bgsound><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <bgsound> +| <frameset> + +#data +<!doctype html><br><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <br> + +#data +<!doctype html><embed><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <embed> + +#data +<!doctype html><img><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <img> + +#data +<!doctype html><input><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <input> + +#data +<!doctype html><keygen><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <keygen> + +#data +<!doctype html><wbr><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <wbr> + +#data +<!doctype html><hr><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <hr> + +#data +<!doctype html><textarea></textarea><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <textarea> + +#data +<!doctype html><xmp></xmp><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <xmp> + +#data +<!doctype html><iframe></iframe><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <iframe> + +#data +<!doctype html><select></select><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> + +#data +<!doctype html><svg></svg><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><math></math><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><svg><foreignObject><div> <frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<!doctype html><svg>a</svg><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <svg svg> +| "a" + +#data +<!doctype html><svg> </svg><frameset><frame> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> +| <frame> + +#data +<html>aaa<frameset></frameset> +#errors +#document +| <html> +| <head> +| <body> +| "aaa" + +#data +<html> a <frameset></frameset> +#errors +#document +| <html> +| <head> +| <body> +| "a " + +#data +<!doctype html><div><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!doctype html><div><body><frameset> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> + +#data +<!doctype html><p><math></p>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| "a" + +#data +<!doctype html><p><math><mn><span></p>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <math math> +| <math mn> +| <span> +| <p> +| "a" + +#data +<!doctype html><math></html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <math math> + +#data +<!doctype html><meta charset="ascii"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <meta> +| charset="ascii" +| <body> + +#data +<!doctype html><meta http-equiv="content-type" content="text/html;charset=ascii"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <meta> +| content="text/html;charset=ascii" +| http-equiv="content-type" +| <body> + +#data +<!doctype html><head><!--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa--><meta charset="utf8"> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <!-- aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --> +| <meta> +| charset="utf8" +| <body> + +#data +<!doctype html><html a=b><head></head><html c=d> +#errors +#document +| <!DOCTYPE html> +| <html> +| a="b" +| c="d" +| <head> +| <body> + +#data +<!doctype html><image/> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <img> + +#data +<!doctype html>a<i>b<table>c<b>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "a" +| <i> +| "bc" +| <b> +| "de" +| "f" +| <table> + +#data +<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" +| <table> + +#data +<!doctype html><i>a<b>b<div>c<a>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" + +#data +<!doctype html><table><i>a<b>b<div>c</i> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <i> +| "c" +| <table> + +#data +<!doctype html><table><i>a<b>b<div>c<a>d</i>e</b>f +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <b> +| "b" +| <b> +| <div> +| <b> +| <i> +| "c" +| <a> +| "d" +| <a> +| "e" +| <a> +| "f" +| <table> + +#data +<!doctype html><table><i>a<div>b<tr>c<b>d</i>e +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <i> +| "a" +| <div> +| "b" +| <i> +| "c" +| <b> +| "d" +| <b> +| "e" +| <table> +| <tbody> +| <tr> + +#data +<!doctype html><table><td><table><i>a<div>b<b>c</i>d +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| <i> +| "a" +| <div> +| <i> +| "b" +| <b> +| "c" +| <b> +| "d" +| <table> + +#data +<!doctype html><body><bgsound> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <bgsound> + +#data +<!doctype html><body><basefont> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <basefont> + +#data +<!doctype html><a><b></a><basefont> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <a> +| <b> +| <basefont> + +#data +<!doctype html><a><b></a><bgsound> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <a> +| <b> +| <bgsound> + +#data +<!doctype html><figcaption><article></figcaption>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <figcaption> +| <article> +| "a" + +#data +<!doctype html><summary><article></summary>a +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <summary> +| <article> +| "a" + +#data +<!doctype html><p><a><plaintext>b +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <a> +| <plaintext> +| <a> +| "b" + +#data +<!DOCTYPE html><div>a<a></div>b<p>c</p>d +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <div> +| "a" +| <a> +| <a> +| "b" +| <p> +| "c" +| "d" diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests2.dat b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests2.dat new file mode 100644 index 00000000..60d85922 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/html/testdata/webkit/tests2.dat @@ -0,0 +1,763 @@ +#data +<!DOCTYPE html>Test +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "Test" + +#data +<textarea>test</div>test +#errors +Line: 1 Col: 10 Unexpected start tag (textarea). Expected DOCTYPE. +Line: 1 Col: 24 Expected closing tag. Unexpected end of file. +#document +| <html> +| <head> +| <body> +| <textarea> +| "test</div>test" + +#data +<table><td> +#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase. +Line: 1 Col: 11 Expected closing tag. Unexpected end of file. +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> + +#data +<table><td>test</tbody></table> +#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected table cell start tag (td) in the table body phase. +#document +| <html> +| <head> +| <body> +| <table> +| <tbody> +| <tr> +| <td> +| "test" + +#data +<frame>test +#errors +Line: 1 Col: 7 Unexpected start tag (frame). Expected DOCTYPE. +Line: 1 Col: 7 Unexpected start tag frame. Ignored. +#document +| <html> +| <head> +| <body> +| "test" + +#data +<!DOCTYPE html><frameset>test +#errors +Line: 1 Col: 29 Unepxected characters in the frameset phase. Characters ignored. +Line: 1 Col: 29 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!DOCTYPE html><frameset><!DOCTYPE html> +#errors +Line: 1 Col: 40 Unexpected DOCTYPE. Ignored. +Line: 1 Col: 40 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <frameset> + +#data +<!DOCTYPE html><font><p><b>test</font> +#errors +Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm. +Line: 1 Col: 38 End tag (font) violates step 1, paragraph 3 of the adoption agency algorithm. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <font> +| <p> +| <font> +| <b> +| "test" + +#data +<!DOCTYPE html><dt><div><dd> +#errors +Line: 1 Col: 28 Missing end tag (div, dt). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <dt> +| <div> +| <dd> + +#data +<script></x +#errors +Line: 1 Col: 8 Unexpected start tag (script). Expected DOCTYPE. +Line: 1 Col: 11 Unexpected end of file. Expected end tag (script). +#document +| <html> +| <head> +| <script> +| "</x" +| <body> + +#data +<table><plaintext><td> +#errors +Line: 1 Col: 7 Unexpected start tag (table). Expected DOCTYPE. +Line: 1 Col: 18 Unexpected start tag (plaintext) in table context caused voodoo mode. +Line: 1 Col: 22 Unexpected end of file. Expected table content. +#document +| <html> +| <head> +| <body> +| <plaintext> +| "<td>" +| <table> + +#data +<plaintext></plaintext> +#errors +Line: 1 Col: 11 Unexpected start tag (plaintext). Expected DOCTYPE. +Line: 1 Col: 23 Expected closing tag. Unexpected end of file. +#document +| <html> +| <head> +| <body> +| <plaintext> +| "</plaintext>" + +#data +<!DOCTYPE html><table><tr>TEST +#errors +Line: 1 Col: 30 Unexpected non-space characters in table context caused voodoo mode. +Line: 1 Col: 30 Unexpected end of file. Expected table content. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "TEST" +| <table> +| <tbody> +| <tr> + +#data +<!DOCTYPE html><body t1=1><body t2=2><body t3=3 t4=4> +#errors +Line: 1 Col: 37 Unexpected start tag (body). +Line: 1 Col: 53 Unexpected start tag (body). +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| t1="1" +| t2="2" +| t3="3" +| t4="4" + +#data +</b test +#errors +Line: 1 Col: 8 Unexpected end of file in attribute name. +Line: 1 Col: 8 End tag contains unexpected attributes. +Line: 1 Col: 8 Unexpected end tag (b). Expected DOCTYPE. +Line: 1 Col: 8 Unexpected end tag (b) after the (implied) root element. +#document +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html></b test<b &=&>X +#errors +Line: 1 Col: 32 Named entity didn't end with ';'. +Line: 1 Col: 33 End tag contains unexpected attributes. +Line: 1 Col: 33 Unexpected end tag (b) after the (implied) root element. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "X" + +#data +<!doctypehtml><scrIPt type=text/x-foobar;baz>X</SCRipt +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +Line: 1 Col: 54 Unexpected end of file in the tag name. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <script> +| type="text/x-foobar;baz" +| "X</SCRipt" +| <body> + +#data +& +#errors +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&" + +#data +&# +#errors +Line: 1 Col: 1 Numeric entity expected. Got end of file instead. +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&#" + +#data +&#X +#errors +Line: 1 Col: 3 Numeric entity expected but none found. +Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&#X" + +#data +&#x +#errors +Line: 1 Col: 3 Numeric entity expected but none found. +Line: 1 Col: 3 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&#x" + +#data +- +#errors +Line: 1 Col: 4 Numeric entity didn't end with ';'. +Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "-" + +#data +&x-test +#errors +Line: 1 Col: 1 Named entity expected. Got none. +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&x-test" + +#data +<!doctypehtml><p><li> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <li> + +#data +<!doctypehtml><p><dt> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <dt> + +#data +<!doctypehtml><p><dd> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <dd> + +#data +<!doctypehtml><p><form> +#errors +Line: 1 Col: 9 No space after literal string 'DOCTYPE'. +Line: 1 Col: 23 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| <form> + +#data +<!DOCTYPE html><p></P>X +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <p> +| "X" + +#data +& +#errors +Line: 1 Col: 4 Named entity didn't end with ';'. +Line: 1 Col: 4 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&" + +#data +&AMp; +#errors +Line: 1 Col: 1 Named entity expected. Got none. +Line: 1 Col: 1 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "&AMp;" + +#data +<!DOCTYPE html><html><head></head><body><thisISasillyTESTelementNameToMakeSureCrazyTagNamesArePARSEDcorrectLY> +#errors +Line: 1 Col: 110 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <thisisasillytestelementnametomakesurecrazytagnamesareparsedcorrectly> + +#data +<!DOCTYPE html>X</body>X +#errors +Line: 1 Col: 24 Unexpected non-space characters in the after body phase. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| "XX" + +#data +<!DOCTYPE html><!-- X +#errors +Line: 1 Col: 21 Unexpected end of file in comment. +#document +| <!DOCTYPE html> +| <!-- X --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><table><caption>test TEST</caption><td>test +#errors +Line: 1 Col: 54 Unexpected table cell start tag (td) in the table body phase. +Line: 1 Col: 58 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <table> +| <caption> +| "test TEST" +| <tbody> +| <tr> +| <td> +| "test" + +#data +<!DOCTYPE html><select><option><optgroup> +#errors +Line: 1 Col: 41 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <option> +| <optgroup> + +#data +<!DOCTYPE html><select><optgroup><option></optgroup><option><select><option> +#errors +Line: 1 Col: 68 Unexpected select start tag in the select phase treated as select end tag. +Line: 1 Col: 76 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> +| <option> +| <option> +| <option> + +#data +<!DOCTYPE html><select><optgroup><option><optgroup> +#errors +Line: 1 Col: 51 Expected closing tag. Unexpected end of file. +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> +| <option> +| <optgroup> + +#data +<!DOCTYPE html><datalist><option>foo</datalist>bar +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <datalist> +| <option> +| "foo" +| "bar" + +#data +<!DOCTYPE html><font><input><input></font> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <font> +| <input> +| <input> + +#data +<!DOCTYPE html><!-- XXX - XXX --> +#errors +#document +| <!DOCTYPE html> +| <!-- XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><!-- XXX - XXX +#errors +Line: 1 Col: 29 Unexpected end of file in comment (-) +#document +| <!DOCTYPE html> +| <!-- XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><!-- XXX - XXX - XXX --> +#errors +#document +| <!DOCTYPE html> +| <!-- XXX - XXX - XXX --> +| <html> +| <head> +| <body> + +#data +<isindex test=x name=x> +#errors +Line: 1 Col: 23 Unexpected start tag (isindex). Expected DOCTYPE. +Line: 1 Col: 23 Unexpected start tag isindex. Don't use it! +#document +| <html> +| <head> +| <body> +| <form> +| <hr> +| <label> +| "This is a searchable index. Enter search keywords: " +| <input> +| name="isindex" +| test="x" +| <hr> + +#data +test +test +#errors +Line: 2 Col: 4 Unexpected non-space characters. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> +| "test +test" + +#data +<!DOCTYPE html><body><title>test</body> +#errors +#document +| +| +| +| +| +| "test</body>" + +#data +<!DOCTYPE html><body><title>X +#errors +#document +| +| +| +| +| +| "X" +| <meta> +| name="z" +| <link> +| rel="foo" +| <style> +| " +x { content:"</style" } " + +#data +<!DOCTYPE html><select><optgroup></optgroup></select> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> +| <select> +| <optgroup> + +#data + + +#errors +Line: 2 Col: 1 Unexpected End of file. Expected DOCTYPE. +#document +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html> <html> +#errors +#document +| <!DOCTYPE html> +| <html> +| <head> +| <body> + +#data +<!DOCTYPE html><script> +</script> <title>x +#errors +#document +| +| +| +| +#errors +Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE. +Line: 1 Col: 21 Unexpected start tag (script) that can be in head. Moved. +#document +| +| +| +#errors +Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE. +Line: 1 Col: 28 Unexpected start tag (style) that can be in head. Moved. +#document +| +| +| +#errors +Line: 1 Col: 6 Unexpected start tag (head). Expected DOCTYPE. +#document +| +| +| +| +| "x" +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +Line: 1 Col: 22 Unexpected end of file. Expected end tag (style). +#document +| +| +| --> x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +| x +#errors +Line: 1 Col: 7 Unexpected start tag (style). Expected DOCTYPE. +#document +| +| +|

+#errors +#document +| +| +| +| +| +| ddd +#errors +#document +| +| +| +#errors +#document +| +| +| +| +|
  • +| +| ", + " +
    << Back to Go HTTP/2 demo server`) + }) +} + +func httpsHost() string { + if *hostHTTPS != "" { + return *hostHTTPS + } + if v := *httpsAddr; strings.HasPrefix(v, ":") { + return "localhost" + v + } else { + return v + } +} + +func httpHost() string { + if *hostHTTP != "" { + return *hostHTTP + } + if v := *httpAddr; strings.HasPrefix(v, ":") { + return "localhost" + v + } else { + return v + } +} + +func serveProdTLS() error { + c, err := googlestorage.NewServiceClient() + if err != nil { + return err + } + slurp := func(key string) ([]byte, error) { + const bucket = "http2-demo-server-tls" + rc, _, err := c.GetObject(&googlestorage.Object{ + Bucket: bucket, + Key: key, + }) + if err != nil { + return nil, fmt.Errorf("Error fetching GCS object %q in bucket %q: %v", key, bucket, err) + } + defer rc.Close() + return ioutil.ReadAll(rc) + } + certPem, err := slurp("http2.golang.org.chained.pem") + if err != nil { + return err + } + keyPem, err := slurp("http2.golang.org.key") + if err != nil { + return err + } + cert, err := tls.X509KeyPair(certPem, keyPem) + if err != nil { + return err + } + srv := &http.Server{ + TLSConfig: &tls.Config{ + Certificates: []tls.Certificate{cert}, + }, + } + http2.ConfigureServer(srv, &http2.Server{}) + ln, err := net.Listen("tcp", ":443") + if err != nil { + return err + } + return srv.Serve(tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener)}, srv.TLSConfig)) +} + +type tcpKeepAliveListener struct { + *net.TCPListener +} + +func (ln tcpKeepAliveListener) Accept() (c net.Conn, err error) { + tc, err := ln.AcceptTCP() + if err != nil { + return + } + tc.SetKeepAlive(true) + tc.SetKeepAlivePeriod(3 * time.Minute) + return tc, nil +} + +func serveProd() error { + errc := make(chan error, 2) + go func() { errc <- http.ListenAndServe(":80", nil) }() + go func() { errc <- serveProdTLS() }() + return <-errc +} + +const idleTimeout = 5 * time.Minute +const activeTimeout = 10 * time.Minute + +// TODO: put this into the standard library and actually send +// PING frames and GOAWAY, etc: golang.org/issue/14204 +func idleTimeoutHook() func(net.Conn, http.ConnState) { + var mu sync.Mutex + m := map[net.Conn]*time.Timer{} + return func(c net.Conn, cs http.ConnState) { + mu.Lock() + defer mu.Unlock() + if t, ok := m[c]; ok { + delete(m, c) + t.Stop() + } + var d time.Duration + switch cs { + case http.StateNew, http.StateIdle: + d = idleTimeout + case http.StateActive: + d = activeTimeout + default: + return + } + m[c] = time.AfterFunc(d, func() { + log.Printf("closing idle conn %v after %v", c.RemoteAddr(), d) + go c.Close() + }) + } +} + +func main() { + var srv http.Server + flag.BoolVar(&http2.VerboseLogs, "verbose", false, "Verbose HTTP/2 debugging.") + flag.Parse() + srv.Addr = *httpsAddr + srv.ConnState = idleTimeoutHook() + + registerHandlers() + + if *prod { + *hostHTTP = "http2.golang.org" + *hostHTTPS = "http2.golang.org" + log.Fatal(serveProd()) + } + + url := "https://" + httpsHost() + "/" + log.Printf("Listening on " + url) + http2.ConfigureServer(&srv, &http2.Server{}) + + if *httpAddr != "" { + go func() { + log.Printf("Listening on http://" + httpHost() + "/ (for unencrypted HTTP/1)") + log.Fatal(http.ListenAndServe(*httpAddr, nil)) + }() + } + + go func() { + log.Fatal(srv.ListenAndServeTLS("server.crt", "server.key")) + }() + select {} +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/launch.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/launch.go new file mode 100644 index 00000000..13b1cfd7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/launch.go @@ -0,0 +1,302 @@ +// 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. + +// +build ignore + +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "net/http" + "os" + "strings" + "time" + + "golang.org/x/oauth2" + "golang.org/x/oauth2/google" + compute "google.golang.org/api/compute/v1" +) + +var ( + proj = flag.String("project", "symbolic-datum-552", "name of Project") + zone = flag.String("zone", "us-central1-a", "GCE zone") + mach = flag.String("machinetype", "n1-standard-1", "Machine type") + instName = flag.String("instance_name", "http2-demo", "Name of VM instance.") + sshPub = flag.String("ssh_public_key", "", "ssh public key file to authorize. Can modify later in Google's web UI anyway.") + staticIP = flag.String("static_ip", "130.211.116.44", "Static IP to use. If empty, automatic.") + + writeObject = flag.String("write_object", "", "If non-empty, a VM isn't created and the flag value is Google Cloud Storage bucket/object to write. The contents from stdin.") + publicObject = flag.Bool("write_object_is_public", false, "Whether the object created by --write_object should be public.") +) + +func readFile(v string) string { + slurp, err := ioutil.ReadFile(v) + if err != nil { + log.Fatalf("Error reading %s: %v", v, err) + } + return strings.TrimSpace(string(slurp)) +} + +var config = &oauth2.Config{ + // The client-id and secret should be for an "Installed Application" when using + // the CLI. Later we'll use a web application with a callback. + ClientID: readFile("client-id.dat"), + ClientSecret: readFile("client-secret.dat"), + Endpoint: google.Endpoint, + Scopes: []string{ + compute.DevstorageFullControlScope, + compute.ComputeScope, + "https://www.googleapis.com/auth/sqlservice", + "https://www.googleapis.com/auth/sqlservice.admin", + }, + RedirectURL: "urn:ietf:wg:oauth:2.0:oob", +} + +const baseConfig = `#cloud-config +coreos: + units: + - name: h2demo.service + command: start + content: | + [Unit] + Description=HTTP2 Demo + + [Service] + ExecStartPre=/bin/bash -c 'mkdir -p /opt/bin && curl -s -o /opt/bin/h2demo http://storage.googleapis.com/http2-demo-server-tls/h2demo && chmod +x /opt/bin/h2demo' + ExecStart=/opt/bin/h2demo --prod + RestartSec=5s + Restart=always + Type=simple + + [Install] + WantedBy=multi-user.target +` + +func main() { + flag.Parse() + if *proj == "" { + log.Fatalf("Missing --project flag") + } + prefix := "https://www.googleapis.com/compute/v1/projects/" + *proj + machType := prefix + "/zones/" + *zone + "/machineTypes/" + *mach + + const tokenFileName = "token.dat" + tokenFile := tokenCacheFile(tokenFileName) + tokenSource := oauth2.ReuseTokenSource(nil, tokenFile) + token, err := tokenSource.Token() + if err != nil { + if *writeObject != "" { + log.Fatalf("Can't use --write_object without a valid token.dat file already cached.") + } + log.Printf("Error getting token from %s: %v", tokenFileName, err) + log.Printf("Get auth code from %v", config.AuthCodeURL("my-state")) + fmt.Print("\nEnter auth code: ") + sc := bufio.NewScanner(os.Stdin) + sc.Scan() + authCode := strings.TrimSpace(sc.Text()) + token, err = config.Exchange(oauth2.NoContext, authCode) + if err != nil { + log.Fatalf("Error exchanging auth code for a token: %v", err) + } + if err := tokenFile.WriteToken(token); err != nil { + log.Fatalf("Error writing to %s: %v", tokenFileName, err) + } + tokenSource = oauth2.ReuseTokenSource(token, nil) + } + + oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource) + + if *writeObject != "" { + writeCloudStorageObject(oauthClient) + return + } + + computeService, _ := compute.New(oauthClient) + + natIP := *staticIP + if natIP == "" { + // Try to find it by name. + aggAddrList, err := computeService.Addresses.AggregatedList(*proj).Do() + if err != nil { + log.Fatal(err) + } + // http://godoc.org/code.google.com/p/google-api-go-client/compute/v1#AddressAggregatedList + IPLoop: + for _, asl := range aggAddrList.Items { + for _, addr := range asl.Addresses { + if addr.Name == *instName+"-ip" && addr.Status == "RESERVED" { + natIP = addr.Address + break IPLoop + } + } + } + } + + cloudConfig := baseConfig + if *sshPub != "" { + key := strings.TrimSpace(readFile(*sshPub)) + cloudConfig += fmt.Sprintf("\nssh_authorized_keys:\n - %s\n", key) + } + if os.Getenv("USER") == "bradfitz" { + cloudConfig += fmt.Sprintf("\nssh_authorized_keys:\n - %s\n", "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEAwks9dwWKlRC+73gRbvYtVg0vdCwDSuIlyt4z6xa/YU/jTDynM4R4W10hm2tPjy8iR1k8XhDv4/qdxe6m07NjG/By1tkmGpm1mGwho4Pr5kbAAy/Qg+NLCSdAYnnE00FQEcFOC15GFVMOW2AzDGKisReohwH9eIzHPzdYQNPRWXE= bradfitz@papag.bradfitz.com") + } + const maxCloudConfig = 32 << 10 // per compute API docs + if len(cloudConfig) > maxCloudConfig { + log.Fatalf("cloud config length of %d bytes is over %d byte limit", len(cloudConfig), maxCloudConfig) + } + + instance := &compute.Instance{ + Name: *instName, + Description: "Go Builder", + MachineType: machType, + Disks: []*compute.AttachedDisk{instanceDisk(computeService)}, + Tags: &compute.Tags{ + Items: []string{"http-server", "https-server"}, + }, + Metadata: &compute.Metadata{ + Items: []*compute.MetadataItems{ + { + Key: "user-data", + Value: &cloudConfig, + }, + }, + }, + NetworkInterfaces: []*compute.NetworkInterface{ + &compute.NetworkInterface{ + AccessConfigs: []*compute.AccessConfig{ + &compute.AccessConfig{ + Type: "ONE_TO_ONE_NAT", + Name: "External NAT", + NatIP: natIP, + }, + }, + Network: prefix + "/global/networks/default", + }, + }, + ServiceAccounts: []*compute.ServiceAccount{ + { + Email: "default", + Scopes: []string{ + compute.DevstorageFullControlScope, + compute.ComputeScope, + }, + }, + }, + } + + log.Printf("Creating instance...") + op, err := computeService.Instances.Insert(*proj, *zone, instance).Do() + if err != nil { + log.Fatalf("Failed to create instance: %v", err) + } + opName := op.Name + log.Printf("Created. Waiting on operation %v", opName) +OpLoop: + for { + time.Sleep(2 * time.Second) + op, err := computeService.ZoneOperations.Get(*proj, *zone, opName).Do() + if err != nil { + log.Fatalf("Failed to get op %s: %v", opName, err) + } + switch op.Status { + case "PENDING", "RUNNING": + log.Printf("Waiting on operation %v", opName) + continue + case "DONE": + if op.Error != nil { + for _, operr := range op.Error.Errors { + log.Printf("Error: %+v", operr) + } + log.Fatalf("Failed to start.") + } + log.Printf("Success. %+v", op) + break OpLoop + default: + log.Fatalf("Unknown status %q: %+v", op.Status, op) + } + } + + inst, err := computeService.Instances.Get(*proj, *zone, *instName).Do() + if err != nil { + log.Fatalf("Error getting instance after creation: %v", err) + } + ij, _ := json.MarshalIndent(inst, "", " ") + log.Printf("Instance: %s", ij) +} + +func instanceDisk(svc *compute.Service) *compute.AttachedDisk { + const imageURL = "https://www.googleapis.com/compute/v1/projects/coreos-cloud/global/images/coreos-stable-444-5-0-v20141016" + diskName := *instName + "-disk" + + return &compute.AttachedDisk{ + AutoDelete: true, + Boot: true, + Type: "PERSISTENT", + InitializeParams: &compute.AttachedDiskInitializeParams{ + DiskName: diskName, + SourceImage: imageURL, + DiskSizeGb: 50, + }, + } +} + +func writeCloudStorageObject(httpClient *http.Client) { + content := os.Stdin + const maxSlurp = 1 << 20 + var buf bytes.Buffer + n, err := io.CopyN(&buf, content, maxSlurp) + if err != nil && err != io.EOF { + log.Fatalf("Error reading from stdin: %v, %v", n, err) + } + contentType := http.DetectContentType(buf.Bytes()) + + req, err := http.NewRequest("PUT", "https://storage.googleapis.com/"+*writeObject, io.MultiReader(&buf, content)) + if err != nil { + log.Fatal(err) + } + req.Header.Set("x-goog-api-version", "2") + if *publicObject { + req.Header.Set("x-goog-acl", "public-read") + } + req.Header.Set("Content-Type", contentType) + res, err := httpClient.Do(req) + if err != nil { + log.Fatal(err) + } + if res.StatusCode != 200 { + res.Write(os.Stderr) + log.Fatalf("Failed.") + } + log.Printf("Success.") + os.Exit(0) +} + +type tokenCacheFile string + +func (f tokenCacheFile) Token() (*oauth2.Token, error) { + slurp, err := ioutil.ReadFile(string(f)) + if err != nil { + return nil, err + } + t := new(oauth2.Token) + if err := json.Unmarshal(slurp, t); err != nil { + return nil, err + } + return t, nil +} + +func (f tokenCacheFile) WriteToken(t *oauth2.Token) error { + jt, err := json.Marshal(t) + if err != nil { + return err + } + return ioutil.WriteFile(string(f), jt, 0600) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.key b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.key new file mode 100644 index 00000000..a15a6aba --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAt5fAjp4fTcekWUTfzsp0kyih1OYbsGL0KX1eRbSSR8Od0+9Q +62Hyny+GFwMTb4A/KU8mssoHvcceSAAbwfbxFK/+s51TobqUnORZrOoTZjkUygby +XDSK99YBbcR1Pip8vwMTm4XKuLtCigeBBdjjAQdgUO28LENGlsMnmeYkJfODVGnV +mr5Ltb9ANA8IKyTfsnHJ4iOCS/PlPbUj2q7YnoVLposUBMlgUb/CykX3mOoLb4yJ +JQyA/iST6ZxiIEj36D4yWZ5lg7YJl+UiiBQHGCnPdGyipqV06ex0heYWcaiW8LWZ +SUQ93jQ+WVCH8hT7DQO1dmsvUmXlq/JeAlwQ/QIDAQABAoIBAFFHV7JMAqPWnMYA +nezY6J81v9+XN+7xABNWM2Q8uv4WdksbigGLTXR3/680Z2hXqJ7LMeC5XJACFT/e +/Gr0vmpgOCygnCPfjGehGKpavtfksXV3edikUlnCXsOP1C//c1bFL+sMYmFCVgTx +qYdDK8yKzXNGrKYT6q5YG7IglyRNV1rsQa8lM/5taFYiD1Ck/3tQi3YIq8Lcuser +hrxsMABcQ6mi+EIvG6Xr4mfJug0dGJMHG4RG1UGFQn6RXrQq2+q53fC8ZbVUSi0j +NQ918aKFzktwv+DouKU0ME4I9toks03gM860bAL7zCbKGmwR3hfgX/TqzVCWpG9E +LDVfvekCgYEA8fk9N53jbBRmULUGEf4qWypcLGiZnNU0OeXWpbPV9aa3H0VDytA7 +8fCN2dPAVDPqlthMDdVe983NCNwp2Yo8ZimDgowyIAKhdC25s1kejuaiH9OAPj3c +0f8KbriYX4n8zNHxFwK6Ae3pQ6EqOLJVCUsziUaZX9nyKY5aZlyX6xcCgYEAwjws +K62PjC64U5wYddNLp+kNdJ4edx+a7qBb3mEgPvSFT2RO3/xafJyG8kQB30Mfstjd +bRxyUV6N0vtX1zA7VQtRUAvfGCecpMo+VQZzcHXKzoRTnQ7eZg4Lmj5fQ9tOAKAo +QCVBoSW/DI4PZL26CAMDcAba4Pa22ooLapoRIQsCgYA6pIfkkbxLNkpxpt2YwLtt +Kr/590O7UaR9n6k8sW/aQBRDXNsILR1KDl2ifAIxpf9lnXgZJiwE7HiTfCAcW7c1 +nzwDCI0hWuHcMTS/NYsFYPnLsstyyjVZI3FY0h4DkYKV9Q9z3zJLQ2hz/nwoD3gy +b2pHC7giFcTts1VPV4Nt8wKBgHeFn4ihHJweg76vZz3Z78w7VNRWGFklUalVdDK7 +gaQ7w2y/ROn/146mo0OhJaXFIFRlrpvdzVrU3GDf2YXJYDlM5ZRkObwbZADjksev +WInzcgDy3KDg7WnPasRXbTfMU4t/AkW2p1QKbi3DnSVYuokDkbH2Beo45vxDxhKr +C69RAoGBAIyo3+OJenoZmoNzNJl2WPW5MeBUzSh8T/bgyjFTdqFHF5WiYRD/lfHj +x9Glyw2nutuT4hlOqHvKhgTYdDMsF2oQ72fe3v8Q5FU7FuKndNPEAyvKNXZaShVA +hnlhv5DjXKb0wFWnt5PCCiQLtzG0yyHaITrrEme7FikkIcTxaX/Y +-----END RSA PRIVATE KEY----- diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.pem b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.pem new file mode 100644 index 00000000..3a323e77 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIEWjCCA0KgAwIBAgIJALfRlWsI8YQHMA0GCSqGSIb3DQEBBQUAMHsxCzAJBgNV +BAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEUMBIG +A1UEChMLQnJhZGZpdHppbmMxEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsGCSqGSIb3 +DQEJARYOYnJhZEBkYW5nYS5jb20wHhcNMTQwNzE1MjA0NjA1WhcNMTcwNTA0MjA0 +NjA1WjB7MQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBG +cmFuY2lzY28xFDASBgNVBAoTC0JyYWRmaXR6aW5jMRIwEAYDVQQDEwlsb2NhbGhv +c3QxHTAbBgkqhkiG9w0BCQEWDmJyYWRAZGFuZ2EuY29tMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAt5fAjp4fTcekWUTfzsp0kyih1OYbsGL0KX1eRbSS +R8Od0+9Q62Hyny+GFwMTb4A/KU8mssoHvcceSAAbwfbxFK/+s51TobqUnORZrOoT +ZjkUygbyXDSK99YBbcR1Pip8vwMTm4XKuLtCigeBBdjjAQdgUO28LENGlsMnmeYk +JfODVGnVmr5Ltb9ANA8IKyTfsnHJ4iOCS/PlPbUj2q7YnoVLposUBMlgUb/CykX3 +mOoLb4yJJQyA/iST6ZxiIEj36D4yWZ5lg7YJl+UiiBQHGCnPdGyipqV06ex0heYW +caiW8LWZSUQ93jQ+WVCH8hT7DQO1dmsvUmXlq/JeAlwQ/QIDAQABo4HgMIHdMB0G +A1UdDgQWBBRcAROthS4P4U7vTfjByC569R7E6DCBrQYDVR0jBIGlMIGigBRcAROt +hS4P4U7vTfjByC569R7E6KF/pH0wezELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNB +MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRQwEgYDVQQKEwtCcmFkZml0emluYzES +MBAGA1UEAxMJbG9jYWxob3N0MR0wGwYJKoZIhvcNAQkBFg5icmFkQGRhbmdhLmNv +bYIJALfRlWsI8YQHMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAG6h +U9f9sNH0/6oBbGGy2EVU0UgITUQIrFWo9rFkrW5k/XkDjQm+3lzjT0iGR4IxE/Ao +eU6sQhua7wrWeFEn47GL98lnCsJdD7oZNhFmQ95Tb/LnDUjs5Yj9brP0NWzXfYU4 +UK2ZnINJRcJpB8iRCaCxE8DdcUF0XqIEq6pA272snoLmiXLMvNl3kYEdm+je6voD +58SNVEUsztzQyXmJEhCpwVI0A6QCjzXj+qvpmw3ZZHi8JwXei8ZZBLTSFBki8Z7n +sH9BBH38/SzUmAN4QHSPy1gjqm00OAE8NaYDkh/bzE4d7mLGGMWp/WE3KPSu82HF +kPe6XoSbiLm/kxk32T0= +-----END CERTIFICATE----- diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.srl b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.srl new file mode 100644 index 00000000..6db38918 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/rootCA.srl @@ -0,0 +1 @@ +E2CE26BF3285059C diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/server.crt b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/server.crt new file mode 100644 index 00000000..c59059bd --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/server.crt @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiYCCQDizia/MoUFnDANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJV +UzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xFDASBgNVBAoT +C0JyYWRmaXR6aW5jMRIwEAYDVQQDEwlsb2NhbGhvc3QxHTAbBgkqhkiG9w0BCQEW +DmJyYWRAZGFuZ2EuY29tMB4XDTE0MDcxNTIwNTAyN1oXDTE1MTEyNzIwNTAyN1ow +RzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMQswCQYDVQQHEwJTRjEeMBwGA1UE +ChMVYnJhZGZpdHogaHR0cDIgc2VydmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAs1Y9CyLFrdL8VQWN1WaifDqaZFnoqjHhCMlc1TfG2zA+InDifx2l +gZD3o8FeNnAcfM2sPlk3+ZleOYw9P/CklFVDlvqmpCv9ss/BEp/dDaWvy1LmJ4c2 +dbQJfmTxn7CV1H3TsVJvKdwFmdoABb41NoBp6+NNO7OtDyhbIMiCI0pL3Nefb3HL +A7hIMo3DYbORTtJLTIH9W8YKrEWL0lwHLrYFx/UdutZnv+HjdmO6vCN4na55mjws +/vjKQUmc7xeY7Xe20xDEG2oDKVkL2eD7FfyrYMS3rO1ExP2KSqlXYG/1S9I/fz88 +F0GK7HX55b5WjZCl2J3ERVdnv/0MQv+sYQIDAQABMA0GCSqGSIb3DQEBBQUAA4IB +AQC0zL+n/YpRZOdulSu9tS8FxrstXqGWoxfe+vIUgqfMZ5+0MkjJ/vW0FqlLDl2R +rn4XaR3e7FmWkwdDVbq/UB6lPmoAaFkCgh9/5oapMaclNVNnfF3fjCJfRr+qj/iD +EmJStTIN0ZuUjAlpiACmfnpEU55PafT5Zx+i1yE4FGjw8bJpFoyD4Hnm54nGjX19 +KeCuvcYFUPnBm3lcL0FalF2AjqV02WTHYNQk7YF/oeO7NKBoEgvGvKG3x+xaOeBI +dwvdq175ZsGul30h+QjrRlXhH/twcuaT3GSdoysDl9cCYE8f1Mk8PD6gan3uBCJU +90p6/CbU71bGbfpM2PHot2fm +-----END CERTIFICATE----- diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/server.key b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/server.key new file mode 100644 index 00000000..f329c142 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2demo/server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAs1Y9CyLFrdL8VQWN1WaifDqaZFnoqjHhCMlc1TfG2zA+InDi +fx2lgZD3o8FeNnAcfM2sPlk3+ZleOYw9P/CklFVDlvqmpCv9ss/BEp/dDaWvy1Lm +J4c2dbQJfmTxn7CV1H3TsVJvKdwFmdoABb41NoBp6+NNO7OtDyhbIMiCI0pL3Nef +b3HLA7hIMo3DYbORTtJLTIH9W8YKrEWL0lwHLrYFx/UdutZnv+HjdmO6vCN4na55 +mjws/vjKQUmc7xeY7Xe20xDEG2oDKVkL2eD7FfyrYMS3rO1ExP2KSqlXYG/1S9I/ +fz88F0GK7HX55b5WjZCl2J3ERVdnv/0MQv+sYQIDAQABAoIBADQ2spUwbY+bcz4p +3M66ECrNQTBggP40gYl2XyHxGGOu2xhZ94f9ELf1hjRWU2DUKWco1rJcdZClV6q3 +qwmXvcM2Q/SMS8JW0ImkNVl/0/NqPxGatEnj8zY30d/L8hGFb0orzFu/XYA5gCP4 +NbN2WrXgk3ZLeqwcNxHHtSiJWGJ/fPyeDWAu/apy75u9Xf2GlzBZmV6HYD9EfK80 +LTlI60f5FO487CrJnboL7ovPJrIHn+k05xRQqwma4orpz932rTXnTjs9Lg6KtbQN +a7PrqfAntIISgr11a66Mng3IYH1lYqJsWJJwX/xHT4WLEy0EH4/0+PfYemJekz2+ +Co62drECgYEA6O9zVJZXrLSDsIi54cfxA7nEZWm5CAtkYWeAHa4EJ+IlZ7gIf9sL +W8oFcEfFGpvwVqWZ+AsQ70dsjXAv3zXaG0tmg9FtqWp7pzRSMPidifZcQwWkKeTO +gJnFmnVyed8h6GfjTEu4gxo1/S5U0V+mYSha01z5NTnN6ltKx1Or3b0CgYEAxRgm +S30nZxnyg/V7ys61AZhst1DG2tkZXEMcA7dYhabMoXPJAP/EfhlWwpWYYUs/u0gS +Wwmf5IivX5TlYScgmkvb/NYz0u4ZmOXkLTnLPtdKKFXhjXJcHjUP67jYmOxNlJLp +V4vLRnFxTpffAV+OszzRxsXX6fvruwZBANYJeXUCgYBVouLFsFgfWGYp2rpr9XP4 +KK25kvrBqF6JKOIDB1zjxNJ3pUMKrl8oqccCFoCyXa4oTM2kUX0yWxHfleUjrMq4 +yimwQKiOZmV7fVLSSjSw6e/VfBd0h3gb82ygcplZkN0IclkwTY5SNKqwn/3y07V5 +drqdhkrgdJXtmQ6O5YYECQKBgATERcDToQ1USlI4sKrB/wyv1AlG8dg/IebiVJ4e +ZAyvcQmClFzq0qS+FiQUnB/WQw9TeeYrwGs1hxBHuJh16srwhLyDrbMvQP06qh8R +48F8UXXSRec22dV9MQphaROhu2qZdv1AC0WD3tqov6L33aqmEOi+xi8JgbT/PLk5 +c/c1AoGBAI1A/02ryksW6/wc7/6SP2M2rTy4m1sD/GnrTc67EHnRcVBdKO6qH2RY +nqC8YcveC2ZghgPTDsA3VGuzuBXpwY6wTyV99q6jxQJ6/xcrD9/NUG6Uwv/xfCxl +IJLeBYEqQundSSny3VtaAUK8Ul1nxpTvVRNwtcyWTo8RHAAyNPWd +-----END RSA PRIVATE KEY----- diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2i/README.md b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2i/README.md new file mode 100644 index 00000000..fb5c5efb --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2i/README.md @@ -0,0 +1,97 @@ +# h2i + +**h2i** is an interactive HTTP/2 ("h2") console debugger. Miss the good ol' +days of telnetting to your HTTP/1.n servers? We're bringing you +back. + +Features: +- send raw HTTP/2 frames + - PING + - SETTINGS + - HEADERS + - etc +- type in HTTP/1.n and have it auto-HPACK/frame-ify it for HTTP/2 +- pretty print all received HTTP/2 frames from the peer (including HPACK decoding) +- tab completion of commands, options + +Not yet features, but soon: +- unnecessary CONTINUATION frames on short boundaries, to test peer implementations +- request bodies (DATA frames) +- send invalid frames for testing server implementations (supported by underlying Framer) + +Later: +- act like a server + +## Installation + +``` +$ go get golang.org/x/net/http2/h2i +$ h2i +``` + +## Demo + +``` +$ h2i +Usage: h2i + + -insecure + Whether to skip TLS cert validation + -nextproto string + Comma-separated list of NPN/ALPN protocol names to negotiate. (default "h2,h2-14") + +$ h2i google.com +Connecting to google.com:443 ... +Connected to 74.125.224.41:443 +Negotiated protocol "h2-14" +[FrameHeader SETTINGS len=18] + [MAX_CONCURRENT_STREAMS = 100] + [INITIAL_WINDOW_SIZE = 1048576] + [MAX_FRAME_SIZE = 16384] +[FrameHeader WINDOW_UPDATE len=4] + Window-Increment = 983041 + +h2i> PING h2iSayHI +[FrameHeader PING flags=ACK len=8] + Data = "h2iSayHI" +h2i> headers +(as HTTP/1.1)> GET / HTTP/1.1 +(as HTTP/1.1)> Host: ip.appspot.com +(as HTTP/1.1)> User-Agent: h2i/brad-n-blake +(as HTTP/1.1)> +Opening Stream-ID 1: + :authority = ip.appspot.com + :method = GET + :path = / + :scheme = https + user-agent = h2i/brad-n-blake +[FrameHeader HEADERS flags=END_HEADERS stream=1 len=77] + :status = "200" + alternate-protocol = "443:quic,p=1" + content-length = "15" + content-type = "text/html" + date = "Fri, 01 May 2015 23:06:56 GMT" + server = "Google Frontend" +[FrameHeader DATA flags=END_STREAM stream=1 len=15] + "173.164.155.78\n" +[FrameHeader PING len=8] + Data = "\x00\x00\x00\x00\x00\x00\x00\x00" +h2i> ping +[FrameHeader PING flags=ACK len=8] + Data = "h2i_ping" +h2i> ping +[FrameHeader PING flags=ACK len=8] + Data = "h2i_ping" +h2i> ping +[FrameHeader GOAWAY len=22] + Last-Stream-ID = 1; Error-Code = PROTOCOL_ERROR (1) + +ReadFrame: EOF +``` + +## Status + +Quick few hour hack. So much yet to do. Feel free to file issues for +bugs or wishlist items, but [@bmizerany](https://github.com/bmizerany/) +and I aren't yet accepting pull requests until things settle down. + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2i/h2i.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2i/h2i.go new file mode 100644 index 00000000..5e9a8678 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/h2i/h2i.go @@ -0,0 +1,501 @@ +// 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 !plan9,!solaris + +/* +The h2i command is an interactive HTTP/2 console. + +Usage: + $ h2i [flags] + +Interactive commands in the console: (all parts case-insensitive) + + ping [data] + settings ack + settings FOO=n BAR=z + headers (open a new stream by typing HTTP/1.1) +*/ +package main + +import ( + "bufio" + "bytes" + "crypto/tls" + "errors" + "flag" + "fmt" + "io" + "log" + "net" + "net/http" + "os" + "regexp" + "strconv" + "strings" + + "golang.org/x/crypto/ssh/terminal" + "golang.org/x/net/http2" + "golang.org/x/net/http2/hpack" +) + +// Flags +var ( + flagNextProto = flag.String("nextproto", "h2,h2-14", "Comma-separated list of NPN/ALPN protocol names to negotiate.") + flagInsecure = flag.Bool("insecure", false, "Whether to skip TLS cert validation") + flagSettings = flag.String("settings", "empty", "comma-separated list of KEY=value settings for the initial SETTINGS frame. The magic value 'empty' sends an empty initial settings frame, and the magic value 'omit' causes no initial settings frame to be sent.") +) + +type command struct { + run func(*h2i, []string) error // required + + // complete optionally specifies tokens (case-insensitive) which are + // valid for this subcommand. + complete func() []string +} + +var commands = map[string]command{ + "ping": command{run: (*h2i).cmdPing}, + "settings": command{ + run: (*h2i).cmdSettings, + complete: func() []string { + return []string{ + "ACK", + http2.SettingHeaderTableSize.String(), + http2.SettingEnablePush.String(), + http2.SettingMaxConcurrentStreams.String(), + http2.SettingInitialWindowSize.String(), + http2.SettingMaxFrameSize.String(), + http2.SettingMaxHeaderListSize.String(), + } + }, + }, + "quit": command{run: (*h2i).cmdQuit}, + "headers": command{run: (*h2i).cmdHeaders}, +} + +func usage() { + fmt.Fprintf(os.Stderr, "Usage: h2i \n\n") + flag.PrintDefaults() + os.Exit(1) +} + +// withPort adds ":443" if another port isn't already present. +func withPort(host string) string { + if _, _, err := net.SplitHostPort(host); err != nil { + return net.JoinHostPort(host, "443") + } + return host +} + +// h2i is the app's state. +type h2i struct { + host string + tc *tls.Conn + framer *http2.Framer + term *terminal.Terminal + + // owned by the command loop: + streamID uint32 + hbuf bytes.Buffer + henc *hpack.Encoder + + // owned by the readFrames loop: + peerSetting map[http2.SettingID]uint32 + hdec *hpack.Decoder +} + +func main() { + flag.Usage = usage + flag.Parse() + if flag.NArg() != 1 { + usage() + } + log.SetFlags(0) + + host := flag.Arg(0) + app := &h2i{ + host: host, + peerSetting: make(map[http2.SettingID]uint32), + } + app.henc = hpack.NewEncoder(&app.hbuf) + + if err := app.Main(); err != nil { + if app.term != nil { + app.logf("%v\n", err) + } else { + fmt.Fprintf(os.Stderr, "%v\n", err) + } + os.Exit(1) + } + fmt.Fprintf(os.Stdout, "\n") +} + +func (app *h2i) Main() error { + cfg := &tls.Config{ + ServerName: app.host, + NextProtos: strings.Split(*flagNextProto, ","), + InsecureSkipVerify: *flagInsecure, + } + + hostAndPort := withPort(app.host) + log.Printf("Connecting to %s ...", hostAndPort) + tc, err := tls.Dial("tcp", hostAndPort, cfg) + if err != nil { + return fmt.Errorf("Error dialing %s: %v", withPort(app.host), err) + } + log.Printf("Connected to %v", tc.RemoteAddr()) + defer tc.Close() + + if err := tc.Handshake(); err != nil { + return fmt.Errorf("TLS handshake: %v", err) + } + if !*flagInsecure { + if err := tc.VerifyHostname(app.host); err != nil { + return fmt.Errorf("VerifyHostname: %v", err) + } + } + state := tc.ConnectionState() + log.Printf("Negotiated protocol %q", state.NegotiatedProtocol) + if !state.NegotiatedProtocolIsMutual || state.NegotiatedProtocol == "" { + return fmt.Errorf("Could not negotiate protocol mutually") + } + + if _, err := io.WriteString(tc, http2.ClientPreface); err != nil { + return err + } + + app.framer = http2.NewFramer(tc, tc) + + oldState, err := terminal.MakeRaw(0) + if err != nil { + return err + } + defer terminal.Restore(0, oldState) + + var screen = struct { + io.Reader + io.Writer + }{os.Stdin, os.Stdout} + + app.term = terminal.NewTerminal(screen, "h2i> ") + lastWord := regexp.MustCompile(`.+\W(\w+)$`) + app.term.AutoCompleteCallback = func(line string, pos int, key rune) (newLine string, newPos int, ok bool) { + if key != '\t' { + return + } + if pos != len(line) { + // TODO: we're being lazy for now, only supporting tab completion at the end. + return + } + // Auto-complete for the command itself. + if !strings.Contains(line, " ") { + var name string + name, _, ok = lookupCommand(line) + if !ok { + return + } + return name, len(name), true + } + _, c, ok := lookupCommand(line[:strings.IndexByte(line, ' ')]) + if !ok || c.complete == nil { + return + } + if strings.HasSuffix(line, " ") { + app.logf("%s", strings.Join(c.complete(), " ")) + return line, pos, true + } + m := lastWord.FindStringSubmatch(line) + if m == nil { + return line, len(line), true + } + soFar := m[1] + var match []string + for _, cand := range c.complete() { + if len(soFar) > len(cand) || !strings.EqualFold(cand[:len(soFar)], soFar) { + continue + } + match = append(match, cand) + } + if len(match) == 0 { + return + } + if len(match) > 1 { + // TODO: auto-complete any common prefix + app.logf("%s", strings.Join(match, " ")) + return line, pos, true + } + newLine = line[:len(line)-len(soFar)] + match[0] + return newLine, len(newLine), true + + } + + errc := make(chan error, 2) + go func() { errc <- app.readFrames() }() + go func() { errc <- app.readConsole() }() + return <-errc +} + +func (app *h2i) logf(format string, args ...interface{}) { + fmt.Fprintf(app.term, format+"\n", args...) +} + +func (app *h2i) readConsole() error { + if s := *flagSettings; s != "omit" { + var args []string + if s != "empty" { + args = strings.Split(s, ",") + } + _, c, ok := lookupCommand("settings") + if !ok { + panic("settings command not found") + } + c.run(app, args) + } + + for { + line, err := app.term.ReadLine() + if err == io.EOF { + return nil + } + if err != nil { + return fmt.Errorf("terminal.ReadLine: %v", err) + } + f := strings.Fields(line) + if len(f) == 0 { + continue + } + cmd, args := f[0], f[1:] + if _, c, ok := lookupCommand(cmd); ok { + err = c.run(app, args) + } else { + app.logf("Unknown command %q", line) + } + if err == errExitApp { + return nil + } + if err != nil { + return err + } + } +} + +func lookupCommand(prefix string) (name string, c command, ok bool) { + prefix = strings.ToLower(prefix) + if c, ok = commands[prefix]; ok { + return prefix, c, ok + } + + for full, candidate := range commands { + if strings.HasPrefix(full, prefix) { + if c.run != nil { + return "", command{}, false // ambiguous + } + c = candidate + name = full + } + } + return name, c, c.run != nil +} + +var errExitApp = errors.New("internal sentinel error value to quit the console reading loop") + +func (a *h2i) cmdQuit(args []string) error { + if len(args) > 0 { + a.logf("the QUIT command takes no argument") + return nil + } + return errExitApp +} + +func (a *h2i) cmdSettings(args []string) error { + if len(args) == 1 && strings.EqualFold(args[0], "ACK") { + return a.framer.WriteSettingsAck() + } + var settings []http2.Setting + for _, arg := range args { + if strings.EqualFold(arg, "ACK") { + a.logf("Error: ACK must be only argument with the SETTINGS command") + return nil + } + eq := strings.Index(arg, "=") + if eq == -1 { + a.logf("Error: invalid argument %q (expected SETTING_NAME=nnnn)", arg) + return nil + } + sid, ok := settingByName(arg[:eq]) + if !ok { + a.logf("Error: unknown setting name %q", arg[:eq]) + return nil + } + val, err := strconv.ParseUint(arg[eq+1:], 10, 32) + if err != nil { + a.logf("Error: invalid argument %q (expected SETTING_NAME=nnnn)", arg) + return nil + } + settings = append(settings, http2.Setting{ + ID: sid, + Val: uint32(val), + }) + } + a.logf("Sending: %v", settings) + return a.framer.WriteSettings(settings...) +} + +func settingByName(name string) (http2.SettingID, bool) { + for _, sid := range [...]http2.SettingID{ + http2.SettingHeaderTableSize, + http2.SettingEnablePush, + http2.SettingMaxConcurrentStreams, + http2.SettingInitialWindowSize, + http2.SettingMaxFrameSize, + http2.SettingMaxHeaderListSize, + } { + if strings.EqualFold(sid.String(), name) { + return sid, true + } + } + return 0, false +} + +func (app *h2i) cmdPing(args []string) error { + if len(args) > 1 { + app.logf("invalid PING usage: only accepts 0 or 1 args") + return nil // nil means don't end the program + } + var data [8]byte + if len(args) == 1 { + copy(data[:], args[0]) + } else { + copy(data[:], "h2i_ping") + } + return app.framer.WritePing(false, data) +} + +func (app *h2i) cmdHeaders(args []string) error { + if len(args) > 0 { + app.logf("Error: HEADERS doesn't yet take arguments.") + // TODO: flags for restricting window size, to force CONTINUATION + // frames. + return nil + } + var h1req bytes.Buffer + app.term.SetPrompt("(as HTTP/1.1)> ") + defer app.term.SetPrompt("h2i> ") + for { + line, err := app.term.ReadLine() + if err != nil { + return err + } + h1req.WriteString(line) + h1req.WriteString("\r\n") + if line == "" { + break + } + } + req, err := http.ReadRequest(bufio.NewReader(&h1req)) + if err != nil { + app.logf("Invalid HTTP/1.1 request: %v", err) + return nil + } + if app.streamID == 0 { + app.streamID = 1 + } else { + app.streamID += 2 + } + app.logf("Opening Stream-ID %d:", app.streamID) + hbf := app.encodeHeaders(req) + if len(hbf) > 16<<10 { + app.logf("TODO: h2i doesn't yet write CONTINUATION frames. Copy it from transport.go") + return nil + } + return app.framer.WriteHeaders(http2.HeadersFrameParam{ + StreamID: app.streamID, + BlockFragment: hbf, + EndStream: req.Method == "GET" || req.Method == "HEAD", // good enough for now + EndHeaders: true, // for now + }) +} + +func (app *h2i) readFrames() error { + for { + f, err := app.framer.ReadFrame() + if err != nil { + return fmt.Errorf("ReadFrame: %v", err) + } + app.logf("%v", f) + switch f := f.(type) { + case *http2.PingFrame: + app.logf(" Data = %q", f.Data) + case *http2.SettingsFrame: + f.ForeachSetting(func(s http2.Setting) error { + app.logf(" %v", s) + app.peerSetting[s.ID] = s.Val + return nil + }) + case *http2.WindowUpdateFrame: + app.logf(" Window-Increment = %v\n", f.Increment) + case *http2.GoAwayFrame: + app.logf(" Last-Stream-ID = %d; Error-Code = %v (%d)\n", f.LastStreamID, f.ErrCode, f.ErrCode) + case *http2.DataFrame: + app.logf(" %q", f.Data()) + case *http2.HeadersFrame: + if f.HasPriority() { + app.logf(" PRIORITY = %v", f.Priority) + } + if app.hdec == nil { + // TODO: if the user uses h2i to send a SETTINGS frame advertising + // something larger, we'll need to respect SETTINGS_HEADER_TABLE_SIZE + // and stuff here instead of using the 4k default. But for now: + tableSize := uint32(4 << 10) + app.hdec = hpack.NewDecoder(tableSize, app.onNewHeaderField) + } + app.hdec.Write(f.HeaderBlockFragment()) + } + } +} + +// called from readLoop +func (app *h2i) onNewHeaderField(f hpack.HeaderField) { + if f.Sensitive { + app.logf(" %s = %q (SENSITIVE)", f.Name, f.Value) + } + app.logf(" %s = %q", f.Name, f.Value) +} + +func (app *h2i) encodeHeaders(req *http.Request) []byte { + app.hbuf.Reset() + + // TODO(bradfitz): figure out :authority-vs-Host stuff between http2 and Go + host := req.Host + if host == "" { + host = req.URL.Host + } + + path := req.URL.Path + if path == "" { + path = "/" + } + + app.writeHeader(":authority", host) // probably not right for all sites + app.writeHeader(":method", req.Method) + app.writeHeader(":path", path) + app.writeHeader(":scheme", "https") + + for k, vv := range req.Header { + lowKey := strings.ToLower(k) + if lowKey == "host" { + continue + } + for _, v := range vv { + app.writeHeader(lowKey, v) + } + } + return app.hbuf.Bytes() +} + +func (app *h2i) writeHeader(name, value string) { + app.henc.WriteField(hpack.HeaderField{Name: name, Value: value}) + app.logf(" %s = %s", name, value) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/headermap.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/headermap.go new file mode 100644 index 00000000..c2805f6a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/headermap.go @@ -0,0 +1,78 @@ +// 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. + +package http2 + +import ( + "net/http" + "strings" +) + +var ( + commonLowerHeader = map[string]string{} // Go-Canonical-Case -> lower-case + commonCanonHeader = map[string]string{} // lower-case -> Go-Canonical-Case +) + +func init() { + for _, v := range []string{ + "accept", + "accept-charset", + "accept-encoding", + "accept-language", + "accept-ranges", + "age", + "access-control-allow-origin", + "allow", + "authorization", + "cache-control", + "content-disposition", + "content-encoding", + "content-language", + "content-length", + "content-location", + "content-range", + "content-type", + "cookie", + "date", + "etag", + "expect", + "expires", + "from", + "host", + "if-match", + "if-modified-since", + "if-none-match", + "if-unmodified-since", + "last-modified", + "link", + "location", + "max-forwards", + "proxy-authenticate", + "proxy-authorization", + "range", + "referer", + "refresh", + "retry-after", + "server", + "set-cookie", + "strict-transport-security", + "trailer", + "transfer-encoding", + "user-agent", + "vary", + "via", + "www-authenticate", + } { + chk := http.CanonicalHeaderKey(v) + commonLowerHeader[chk] = v + commonCanonHeader[v] = chk + } +} + +func lowerHeader(v string) string { + if s, ok := commonLowerHeader[v]; ok { + return s + } + return strings.ToLower(v) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/encode.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/encode.go new file mode 100644 index 00000000..80d621cf --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/encode.go @@ -0,0 +1,251 @@ +// 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. + +package hpack + +import ( + "io" +) + +const ( + uint32Max = ^uint32(0) + initialHeaderTableSize = 4096 +) + +type Encoder struct { + dynTab dynamicTable + // minSize is the minimum table size set by + // SetMaxDynamicTableSize after the previous Header Table Size + // Update. + minSize uint32 + // maxSizeLimit is the maximum table size this encoder + // supports. This will protect the encoder from too large + // size. + maxSizeLimit uint32 + // tableSizeUpdate indicates whether "Header Table Size + // Update" is required. + tableSizeUpdate bool + w io.Writer + buf []byte +} + +// NewEncoder returns a new Encoder which performs HPACK encoding. An +// encoded data is written to w. +func NewEncoder(w io.Writer) *Encoder { + e := &Encoder{ + minSize: uint32Max, + maxSizeLimit: initialHeaderTableSize, + tableSizeUpdate: false, + w: w, + } + e.dynTab.setMaxSize(initialHeaderTableSize) + return e +} + +// WriteField encodes f into a single Write to e's underlying Writer. +// This function may also produce bytes for "Header Table Size Update" +// if necessary. If produced, it is done before encoding f. +func (e *Encoder) WriteField(f HeaderField) error { + e.buf = e.buf[:0] + + if e.tableSizeUpdate { + e.tableSizeUpdate = false + if e.minSize < e.dynTab.maxSize { + e.buf = appendTableSize(e.buf, e.minSize) + } + e.minSize = uint32Max + e.buf = appendTableSize(e.buf, e.dynTab.maxSize) + } + + idx, nameValueMatch := e.searchTable(f) + if nameValueMatch { + e.buf = appendIndexed(e.buf, idx) + } else { + indexing := e.shouldIndex(f) + if indexing { + e.dynTab.add(f) + } + + if idx == 0 { + e.buf = appendNewName(e.buf, f, indexing) + } else { + e.buf = appendIndexedName(e.buf, f, idx, indexing) + } + } + n, err := e.w.Write(e.buf) + if err == nil && n != len(e.buf) { + err = io.ErrShortWrite + } + return err +} + +// searchTable searches f in both stable and dynamic header tables. +// The static header table is searched first. Only when there is no +// exact match for both name and value, the dynamic header table is +// then searched. If there is no match, i is 0. If both name and value +// match, i is the matched index and nameValueMatch becomes true. If +// only name matches, i points to that index and nameValueMatch +// becomes false. +func (e *Encoder) searchTable(f HeaderField) (i uint64, nameValueMatch bool) { + for idx, hf := range staticTable { + if !constantTimeStringCompare(hf.Name, f.Name) { + continue + } + if i == 0 { + i = uint64(idx + 1) + } + if f.Sensitive { + continue + } + if !constantTimeStringCompare(hf.Value, f.Value) { + continue + } + i = uint64(idx + 1) + nameValueMatch = true + return + } + + j, nameValueMatch := e.dynTab.search(f) + if nameValueMatch || (i == 0 && j != 0) { + i = j + uint64(len(staticTable)) + } + return +} + +// SetMaxDynamicTableSize changes the dynamic header table size to v. +// The actual size is bounded by the value passed to +// SetMaxDynamicTableSizeLimit. +func (e *Encoder) SetMaxDynamicTableSize(v uint32) { + if v > e.maxSizeLimit { + v = e.maxSizeLimit + } + if v < e.minSize { + e.minSize = v + } + e.tableSizeUpdate = true + e.dynTab.setMaxSize(v) +} + +// SetMaxDynamicTableSizeLimit changes the maximum value that can be +// specified in SetMaxDynamicTableSize to v. By default, it is set to +// 4096, which is the same size of the default dynamic header table +// size described in HPACK specification. If the current maximum +// dynamic header table size is strictly greater than v, "Header Table +// Size Update" will be done in the next WriteField call and the +// maximum dynamic header table size is truncated to v. +func (e *Encoder) SetMaxDynamicTableSizeLimit(v uint32) { + e.maxSizeLimit = v + if e.dynTab.maxSize > v { + e.tableSizeUpdate = true + e.dynTab.setMaxSize(v) + } +} + +// shouldIndex reports whether f should be indexed. +func (e *Encoder) shouldIndex(f HeaderField) bool { + return !f.Sensitive && f.size() <= e.dynTab.maxSize +} + +// appendIndexed appends index i, as encoded in "Indexed Header Field" +// representation, to dst and returns the extended buffer. +func appendIndexed(dst []byte, i uint64) []byte { + first := len(dst) + dst = appendVarInt(dst, 7, i) + dst[first] |= 0x80 + return dst +} + +// appendNewName appends f, as encoded in one of "Literal Header field +// - New Name" representation variants, to dst and returns the +// extended buffer. +// +// If f.Sensitive is true, "Never Indexed" representation is used. If +// f.Sensitive is false and indexing is true, "Inremental Indexing" +// representation is used. +func appendNewName(dst []byte, f HeaderField, indexing bool) []byte { + dst = append(dst, encodeTypeByte(indexing, f.Sensitive)) + dst = appendHpackString(dst, f.Name) + return appendHpackString(dst, f.Value) +} + +// appendIndexedName appends f and index i referring indexed name +// entry, as encoded in one of "Literal Header field - Indexed Name" +// representation variants, to dst and returns the extended buffer. +// +// If f.Sensitive is true, "Never Indexed" representation is used. If +// f.Sensitive is false and indexing is true, "Incremental Indexing" +// representation is used. +func appendIndexedName(dst []byte, f HeaderField, i uint64, indexing bool) []byte { + first := len(dst) + var n byte + if indexing { + n = 6 + } else { + n = 4 + } + dst = appendVarInt(dst, n, i) + dst[first] |= encodeTypeByte(indexing, f.Sensitive) + return appendHpackString(dst, f.Value) +} + +// appendTableSize appends v, as encoded in "Header Table Size Update" +// representation, to dst and returns the extended buffer. +func appendTableSize(dst []byte, v uint32) []byte { + first := len(dst) + dst = appendVarInt(dst, 5, uint64(v)) + dst[first] |= 0x20 + return dst +} + +// appendVarInt appends i, as encoded in variable integer form using n +// bit prefix, to dst and returns the extended buffer. +// +// See +// http://http2.github.io/http2-spec/compression.html#integer.representation +func appendVarInt(dst []byte, n byte, i uint64) []byte { + k := uint64((1 << n) - 1) + if i < k { + return append(dst, byte(i)) + } + dst = append(dst, byte(k)) + i -= k + for ; i >= 128; i >>= 7 { + dst = append(dst, byte(0x80|(i&0x7f))) + } + return append(dst, byte(i)) +} + +// appendHpackString appends s, as encoded in "String Literal" +// representation, to dst and returns the the extended buffer. +// +// s will be encoded in Huffman codes only when it produces strictly +// shorter byte string. +func appendHpackString(dst []byte, s string) []byte { + huffmanLength := HuffmanEncodeLength(s) + if huffmanLength < uint64(len(s)) { + first := len(dst) + dst = appendVarInt(dst, 7, huffmanLength) + dst = AppendHuffmanString(dst, s) + dst[first] |= 0x80 + } else { + dst = appendVarInt(dst, 7, uint64(len(s))) + dst = append(dst, s...) + } + return dst +} + +// encodeTypeByte returns type byte. If sensitive is true, type byte +// for "Never Indexed" representation is returned. If sensitive is +// false and indexing is true, type byte for "Incremental Indexing" +// representation is returned. Otherwise, type byte for "Without +// Indexing" is returned. +func encodeTypeByte(indexing, sensitive bool) byte { + if sensitive { + return 0x10 + } + if indexing { + return 0x40 + } + return 0 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/encode_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/encode_test.go new file mode 100644 index 00000000..92286f3b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/encode_test.go @@ -0,0 +1,330 @@ +// 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. + +package hpack + +import ( + "bytes" + "encoding/hex" + "reflect" + "strings" + "testing" +) + +func TestEncoderTableSizeUpdate(t *testing.T) { + tests := []struct { + size1, size2 uint32 + wantHex string + }{ + // Should emit 2 table size updates (2048 and 4096) + {2048, 4096, "3fe10f 3fe11f 82"}, + + // Should emit 1 table size update (2048) + {16384, 2048, "3fe10f 82"}, + } + for _, tt := range tests { + var buf bytes.Buffer + e := NewEncoder(&buf) + e.SetMaxDynamicTableSize(tt.size1) + e.SetMaxDynamicTableSize(tt.size2) + if err := e.WriteField(pair(":method", "GET")); err != nil { + t.Fatal(err) + } + want := removeSpace(tt.wantHex) + if got := hex.EncodeToString(buf.Bytes()); got != want { + t.Errorf("e.SetDynamicTableSize %v, %v = %q; want %q", tt.size1, tt.size2, got, want) + } + } +} + +func TestEncoderWriteField(t *testing.T) { + var buf bytes.Buffer + e := NewEncoder(&buf) + var got []HeaderField + d := NewDecoder(4<<10, func(f HeaderField) { + got = append(got, f) + }) + + tests := []struct { + hdrs []HeaderField + }{ + {[]HeaderField{ + pair(":method", "GET"), + pair(":scheme", "http"), + pair(":path", "/"), + pair(":authority", "www.example.com"), + }}, + {[]HeaderField{ + pair(":method", "GET"), + pair(":scheme", "http"), + pair(":path", "/"), + pair(":authority", "www.example.com"), + pair("cache-control", "no-cache"), + }}, + {[]HeaderField{ + pair(":method", "GET"), + pair(":scheme", "https"), + pair(":path", "/index.html"), + pair(":authority", "www.example.com"), + pair("custom-key", "custom-value"), + }}, + } + for i, tt := range tests { + buf.Reset() + got = got[:0] + for _, hf := range tt.hdrs { + if err := e.WriteField(hf); err != nil { + t.Fatal(err) + } + } + _, err := d.Write(buf.Bytes()) + if err != nil { + t.Errorf("%d. Decoder Write = %v", i, err) + } + if !reflect.DeepEqual(got, tt.hdrs) { + t.Errorf("%d. Decoded %+v; want %+v", i, got, tt.hdrs) + } + } +} + +func TestEncoderSearchTable(t *testing.T) { + e := NewEncoder(nil) + + e.dynTab.add(pair("foo", "bar")) + e.dynTab.add(pair("blake", "miz")) + e.dynTab.add(pair(":method", "GET")) + + tests := []struct { + hf HeaderField + wantI uint64 + wantMatch bool + }{ + // Name and Value match + {pair("foo", "bar"), uint64(len(staticTable) + 3), true}, + {pair("blake", "miz"), uint64(len(staticTable) + 2), true}, + {pair(":method", "GET"), 2, true}, + + // Only name match because Sensitive == true + {HeaderField{":method", "GET", true}, 2, false}, + + // Only Name matches + {pair("foo", "..."), uint64(len(staticTable) + 3), false}, + {pair("blake", "..."), uint64(len(staticTable) + 2), false}, + {pair(":method", "..."), 2, false}, + + // None match + {pair("foo-", "bar"), 0, false}, + } + for _, tt := range tests { + if gotI, gotMatch := e.searchTable(tt.hf); gotI != tt.wantI || gotMatch != tt.wantMatch { + t.Errorf("d.search(%+v) = %v, %v; want %v, %v", tt.hf, gotI, gotMatch, tt.wantI, tt.wantMatch) + } + } +} + +func TestAppendVarInt(t *testing.T) { + tests := []struct { + n byte + i uint64 + want []byte + }{ + // Fits in a byte: + {1, 0, []byte{0}}, + {2, 2, []byte{2}}, + {3, 6, []byte{6}}, + {4, 14, []byte{14}}, + {5, 30, []byte{30}}, + {6, 62, []byte{62}}, + {7, 126, []byte{126}}, + {8, 254, []byte{254}}, + + // Multiple bytes: + {5, 1337, []byte{31, 154, 10}}, + } + for _, tt := range tests { + got := appendVarInt(nil, tt.n, tt.i) + if !bytes.Equal(got, tt.want) { + t.Errorf("appendVarInt(nil, %v, %v) = %v; want %v", tt.n, tt.i, got, tt.want) + } + } +} + +func TestAppendHpackString(t *testing.T) { + tests := []struct { + s, wantHex string + }{ + // Huffman encoded + {"www.example.com", "8c f1e3 c2e5 f23a 6ba0 ab90 f4ff"}, + + // Not Huffman encoded + {"a", "01 61"}, + + // zero length + {"", "00"}, + } + for _, tt := range tests { + want := removeSpace(tt.wantHex) + buf := appendHpackString(nil, tt.s) + if got := hex.EncodeToString(buf); want != got { + t.Errorf("appendHpackString(nil, %q) = %q; want %q", tt.s, got, want) + } + } +} + +func TestAppendIndexed(t *testing.T) { + tests := []struct { + i uint64 + wantHex string + }{ + // 1 byte + {1, "81"}, + {126, "fe"}, + + // 2 bytes + {127, "ff00"}, + {128, "ff01"}, + } + for _, tt := range tests { + want := removeSpace(tt.wantHex) + buf := appendIndexed(nil, tt.i) + if got := hex.EncodeToString(buf); want != got { + t.Errorf("appendIndex(nil, %v) = %q; want %q", tt.i, got, want) + } + } +} + +func TestAppendNewName(t *testing.T) { + tests := []struct { + f HeaderField + indexing bool + wantHex string + }{ + // Incremental indexing + {HeaderField{"custom-key", "custom-value", false}, true, "40 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"}, + + // Without indexing + {HeaderField{"custom-key", "custom-value", false}, false, "00 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"}, + + // Never indexed + {HeaderField{"custom-key", "custom-value", true}, true, "10 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"}, + {HeaderField{"custom-key", "custom-value", true}, false, "10 88 25a8 49e9 5ba9 7d7f 89 25a8 49e9 5bb8 e8b4 bf"}, + } + for _, tt := range tests { + want := removeSpace(tt.wantHex) + buf := appendNewName(nil, tt.f, tt.indexing) + if got := hex.EncodeToString(buf); want != got { + t.Errorf("appendNewName(nil, %+v, %v) = %q; want %q", tt.f, tt.indexing, got, want) + } + } +} + +func TestAppendIndexedName(t *testing.T) { + tests := []struct { + f HeaderField + i uint64 + indexing bool + wantHex string + }{ + // Incremental indexing + {HeaderField{":status", "302", false}, 8, true, "48 82 6402"}, + + // Without indexing + {HeaderField{":status", "302", false}, 8, false, "08 82 6402"}, + + // Never indexed + {HeaderField{":status", "302", true}, 8, true, "18 82 6402"}, + {HeaderField{":status", "302", true}, 8, false, "18 82 6402"}, + } + for _, tt := range tests { + want := removeSpace(tt.wantHex) + buf := appendIndexedName(nil, tt.f, tt.i, tt.indexing) + if got := hex.EncodeToString(buf); want != got { + t.Errorf("appendIndexedName(nil, %+v, %v) = %q; want %q", tt.f, tt.indexing, got, want) + } + } +} + +func TestAppendTableSize(t *testing.T) { + tests := []struct { + i uint32 + wantHex string + }{ + // Fits into 1 byte + {30, "3e"}, + + // Extra byte + {31, "3f00"}, + {32, "3f01"}, + } + for _, tt := range tests { + want := removeSpace(tt.wantHex) + buf := appendTableSize(nil, tt.i) + if got := hex.EncodeToString(buf); want != got { + t.Errorf("appendTableSize(nil, %v) = %q; want %q", tt.i, got, want) + } + } +} + +func TestEncoderSetMaxDynamicTableSize(t *testing.T) { + var buf bytes.Buffer + e := NewEncoder(&buf) + tests := []struct { + v uint32 + wantUpdate bool + wantMinSize uint32 + wantMaxSize uint32 + }{ + // Set new table size to 2048 + {2048, true, 2048, 2048}, + + // Set new table size to 16384, but still limited to + // 4096 + {16384, true, 2048, 4096}, + } + for _, tt := range tests { + e.SetMaxDynamicTableSize(tt.v) + if got := e.tableSizeUpdate; tt.wantUpdate != got { + t.Errorf("e.tableSizeUpdate = %v; want %v", got, tt.wantUpdate) + } + if got := e.minSize; tt.wantMinSize != got { + t.Errorf("e.minSize = %v; want %v", got, tt.wantMinSize) + } + if got := e.dynTab.maxSize; tt.wantMaxSize != got { + t.Errorf("e.maxSize = %v; want %v", got, tt.wantMaxSize) + } + } +} + +func TestEncoderSetMaxDynamicTableSizeLimit(t *testing.T) { + e := NewEncoder(nil) + // 4095 < initialHeaderTableSize means maxSize is truncated to + // 4095. + e.SetMaxDynamicTableSizeLimit(4095) + if got, want := e.dynTab.maxSize, uint32(4095); got != want { + t.Errorf("e.dynTab.maxSize = %v; want %v", got, want) + } + if got, want := e.maxSizeLimit, uint32(4095); got != want { + t.Errorf("e.maxSizeLimit = %v; want %v", got, want) + } + if got, want := e.tableSizeUpdate, true; got != want { + t.Errorf("e.tableSizeUpdate = %v; want %v", got, want) + } + // maxSize will be truncated to maxSizeLimit + e.SetMaxDynamicTableSize(16384) + if got, want := e.dynTab.maxSize, uint32(4095); got != want { + t.Errorf("e.dynTab.maxSize = %v; want %v", got, want) + } + // 8192 > current maxSizeLimit, so maxSize does not change. + e.SetMaxDynamicTableSizeLimit(8192) + if got, want := e.dynTab.maxSize, uint32(4095); got != want { + t.Errorf("e.dynTab.maxSize = %v; want %v", got, want) + } + if got, want := e.maxSizeLimit, uint32(8192); got != want { + t.Errorf("e.maxSizeLimit = %v; want %v", got, want) + } +} + +func removeSpace(s string) string { + return strings.Replace(s, " ", "", -1) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/hpack.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/hpack.go new file mode 100644 index 00000000..2ea4949a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/hpack.go @@ -0,0 +1,533 @@ +// 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. + +// Package hpack implements HPACK, a compression format for +// efficiently representing HTTP header fields in the context of HTTP/2. +// +// See http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-09 +package hpack + +import ( + "bytes" + "errors" + "fmt" +) + +// A DecodingError is something the spec defines as a decoding error. +type DecodingError struct { + Err error +} + +func (de DecodingError) Error() string { + return fmt.Sprintf("decoding error: %v", de.Err) +} + +// An InvalidIndexError is returned when an encoder references a table +// entry before the static table or after the end of the dynamic table. +type InvalidIndexError int + +func (e InvalidIndexError) Error() string { + return fmt.Sprintf("invalid indexed representation index %d", int(e)) +} + +// A HeaderField is a name-value pair. Both the name and value are +// treated as opaque sequences of octets. +type HeaderField struct { + Name, Value string + + // Sensitive means that this header field should never be + // indexed. + Sensitive bool +} + +func (hf HeaderField) String() string { + var suffix string + if hf.Sensitive { + suffix = " (sensitive)" + } + return fmt.Sprintf("header field %q = %q%s", hf.Name, hf.Value, suffix) +} + +func (hf *HeaderField) size() uint32 { + // http://http2.github.io/http2-spec/compression.html#rfc.section.4.1 + // "The size of the dynamic table is the sum of the size of + // its entries. The size of an entry is the sum of its name's + // length in octets (as defined in Section 5.2), its value's + // length in octets (see Section 5.2), plus 32. The size of + // an entry is calculated using the length of the name and + // value without any Huffman encoding applied." + + // This can overflow if somebody makes a large HeaderField + // Name and/or Value by hand, but we don't care, because that + // won't happen on the wire because the encoding doesn't allow + // it. + return uint32(len(hf.Name) + len(hf.Value) + 32) +} + +// A Decoder is the decoding context for incremental processing of +// header blocks. +type Decoder struct { + dynTab dynamicTable + emit func(f HeaderField) + + emitEnabled bool // whether calls to emit are enabled + maxStrLen int // 0 means unlimited + + // buf is the unparsed buffer. It's only written to + // saveBuf if it was truncated in the middle of a header + // block. Because it's usually not owned, we can only + // process it under Write. + buf []byte // not owned; only valid during Write + + // saveBuf is previous data passed to Write which we weren't able + // to fully parse before. Unlike buf, we own this data. + saveBuf bytes.Buffer +} + +// NewDecoder returns a new decoder with the provided maximum dynamic +// table size. The emitFunc will be called for each valid field +// parsed, in the same goroutine as calls to Write, before Write returns. +func NewDecoder(maxDynamicTableSize uint32, emitFunc func(f HeaderField)) *Decoder { + d := &Decoder{ + emit: emitFunc, + emitEnabled: true, + } + d.dynTab.allowedMaxSize = maxDynamicTableSize + d.dynTab.setMaxSize(maxDynamicTableSize) + return d +} + +// ErrStringLength is returned by Decoder.Write when the max string length +// (as configured by Decoder.SetMaxStringLength) would be violated. +var ErrStringLength = errors.New("hpack: string too long") + +// SetMaxStringLength sets the maximum size of a HeaderField name or +// value string. If a string exceeds this length (even after any +// decompression), Write will return ErrStringLength. +// A value of 0 means unlimited and is the default from NewDecoder. +func (d *Decoder) SetMaxStringLength(n int) { + d.maxStrLen = n +} + +// SetEmitFunc changes the callback used when new header fields +// are decoded. +// It must be non-nil. It does not affect EmitEnabled. +func (d *Decoder) SetEmitFunc(emitFunc func(f HeaderField)) { + d.emit = emitFunc +} + +// SetEmitEnabled controls whether the emitFunc provided to NewDecoder +// should be called. The default is true. +// +// This facility exists to let servers enforce MAX_HEADER_LIST_SIZE +// while still decoding and keeping in-sync with decoder state, but +// without doing unnecessary decompression or generating unnecessary +// garbage for header fields past the limit. +func (d *Decoder) SetEmitEnabled(v bool) { d.emitEnabled = v } + +// EmitEnabled reports whether calls to the emitFunc provided to NewDecoder +// are currently enabled. The default is true. +func (d *Decoder) EmitEnabled() bool { return d.emitEnabled } + +// TODO: add method *Decoder.Reset(maxSize, emitFunc) to let callers re-use Decoders and their +// underlying buffers for garbage reasons. + +func (d *Decoder) SetMaxDynamicTableSize(v uint32) { + d.dynTab.setMaxSize(v) +} + +// SetAllowedMaxDynamicTableSize sets the upper bound that the encoded +// stream (via dynamic table size updates) may set the maximum size +// to. +func (d *Decoder) SetAllowedMaxDynamicTableSize(v uint32) { + d.dynTab.allowedMaxSize = v +} + +type dynamicTable struct { + // ents is the FIFO described at + // http://http2.github.io/http2-spec/compression.html#rfc.section.2.3.2 + // The newest (low index) is append at the end, and items are + // evicted from the front. + ents []HeaderField + size uint32 + maxSize uint32 // current maxSize + allowedMaxSize uint32 // maxSize may go up to this, inclusive +} + +func (dt *dynamicTable) setMaxSize(v uint32) { + dt.maxSize = v + dt.evict() +} + +// TODO: change dynamicTable to be a struct with a slice and a size int field, +// per http://http2.github.io/http2-spec/compression.html#rfc.section.4.1: +// +// +// Then make add increment the size. maybe the max size should move from Decoder to +// dynamicTable and add should return an ok bool if there was enough space. +// +// Later we'll need a remove operation on dynamicTable. + +func (dt *dynamicTable) add(f HeaderField) { + dt.ents = append(dt.ents, f) + dt.size += f.size() + dt.evict() +} + +// If we're too big, evict old stuff (front of the slice) +func (dt *dynamicTable) evict() { + base := dt.ents // keep base pointer of slice + for dt.size > dt.maxSize { + dt.size -= dt.ents[0].size() + dt.ents = dt.ents[1:] + } + + // Shift slice contents down if we evicted things. + if len(dt.ents) != len(base) { + copy(base, dt.ents) + dt.ents = base[:len(dt.ents)] + } +} + +// constantTimeStringCompare compares string a and b in a constant +// time manner. +func constantTimeStringCompare(a, b string) bool { + if len(a) != len(b) { + return false + } + + c := byte(0) + + for i := 0; i < len(a); i++ { + c |= a[i] ^ b[i] + } + + return c == 0 +} + +// Search searches f in the table. The return value i is 0 if there is +// no name match. If there is name match or name/value match, i is the +// index of that entry (1-based). If both name and value match, +// nameValueMatch becomes true. +func (dt *dynamicTable) search(f HeaderField) (i uint64, nameValueMatch bool) { + l := len(dt.ents) + for j := l - 1; j >= 0; j-- { + ent := dt.ents[j] + if !constantTimeStringCompare(ent.Name, f.Name) { + continue + } + if i == 0 { + i = uint64(l - j) + } + if f.Sensitive { + continue + } + if !constantTimeStringCompare(ent.Value, f.Value) { + continue + } + i = uint64(l - j) + nameValueMatch = true + return + } + return +} + +func (d *Decoder) maxTableIndex() int { + return len(d.dynTab.ents) + len(staticTable) +} + +func (d *Decoder) at(i uint64) (hf HeaderField, ok bool) { + if i < 1 { + return + } + if i > uint64(d.maxTableIndex()) { + return + } + if i <= uint64(len(staticTable)) { + return staticTable[i-1], true + } + dents := d.dynTab.ents + return dents[len(dents)-(int(i)-len(staticTable))], true +} + +// Decode decodes an entire block. +// +// TODO: remove this method and make it incremental later? This is +// easier for debugging now. +func (d *Decoder) DecodeFull(p []byte) ([]HeaderField, error) { + var hf []HeaderField + saveFunc := d.emit + defer func() { d.emit = saveFunc }() + d.emit = func(f HeaderField) { hf = append(hf, f) } + if _, err := d.Write(p); err != nil { + return nil, err + } + if err := d.Close(); err != nil { + return nil, err + } + return hf, nil +} + +func (d *Decoder) Close() error { + if d.saveBuf.Len() > 0 { + d.saveBuf.Reset() + return DecodingError{errors.New("truncated headers")} + } + return nil +} + +func (d *Decoder) Write(p []byte) (n int, err error) { + if len(p) == 0 { + // Prevent state machine CPU attacks (making us redo + // work up to the point of finding out we don't have + // enough data) + return + } + // Only copy the data if we have to. Optimistically assume + // that p will contain a complete header block. + if d.saveBuf.Len() == 0 { + d.buf = p + } else { + d.saveBuf.Write(p) + d.buf = d.saveBuf.Bytes() + d.saveBuf.Reset() + } + + for len(d.buf) > 0 { + err = d.parseHeaderFieldRepr() + if err == errNeedMore { + // Extra paranoia, making sure saveBuf won't + // get too large. All the varint and string + // reading code earlier should already catch + // overlong things and return ErrStringLength, + // but keep this as a last resort. + const varIntOverhead = 8 // conservative + if d.maxStrLen != 0 && int64(len(d.buf)) > 2*(int64(d.maxStrLen)+varIntOverhead) { + return 0, ErrStringLength + } + d.saveBuf.Write(d.buf) + return len(p), nil + } + if err != nil { + break + } + } + return len(p), err +} + +// errNeedMore is an internal sentinel error value that means the +// buffer is truncated and we need to read more data before we can +// continue parsing. +var errNeedMore = errors.New("need more data") + +type indexType int + +const ( + indexedTrue indexType = iota + indexedFalse + indexedNever +) + +func (v indexType) indexed() bool { return v == indexedTrue } +func (v indexType) sensitive() bool { return v == indexedNever } + +// returns errNeedMore if there isn't enough data available. +// any other error is fatal. +// consumes d.buf iff it returns nil. +// precondition: must be called with len(d.buf) > 0 +func (d *Decoder) parseHeaderFieldRepr() error { + b := d.buf[0] + switch { + case b&128 != 0: + // Indexed representation. + // High bit set? + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.1 + return d.parseFieldIndexed() + case b&192 == 64: + // 6.2.1 Literal Header Field with Incremental Indexing + // 0b10xxxxxx: top two bits are 10 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.1 + return d.parseFieldLiteral(6, indexedTrue) + case b&240 == 0: + // 6.2.2 Literal Header Field without Indexing + // 0b0000xxxx: top four bits are 0000 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.2 + return d.parseFieldLiteral(4, indexedFalse) + case b&240 == 16: + // 6.2.3 Literal Header Field never Indexed + // 0b0001xxxx: top four bits are 0001 + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.2.3 + return d.parseFieldLiteral(4, indexedNever) + case b&224 == 32: + // 6.3 Dynamic Table Size Update + // Top three bits are '001'. + // http://http2.github.io/http2-spec/compression.html#rfc.section.6.3 + return d.parseDynamicTableSizeUpdate() + } + + return DecodingError{errors.New("invalid encoding")} +} + +// (same invariants and behavior as parseHeaderFieldRepr) +func (d *Decoder) parseFieldIndexed() error { + buf := d.buf + idx, buf, err := readVarInt(7, buf) + if err != nil { + return err + } + hf, ok := d.at(idx) + if !ok { + return DecodingError{InvalidIndexError(idx)} + } + d.buf = buf + return d.callEmit(HeaderField{Name: hf.Name, Value: hf.Value}) +} + +// (same invariants and behavior as parseHeaderFieldRepr) +func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error { + buf := d.buf + nameIdx, buf, err := readVarInt(n, buf) + if err != nil { + return err + } + + var hf HeaderField + wantStr := d.emitEnabled || it.indexed() + if nameIdx > 0 { + ihf, ok := d.at(nameIdx) + if !ok { + return DecodingError{InvalidIndexError(nameIdx)} + } + hf.Name = ihf.Name + } else { + hf.Name, buf, err = d.readString(buf, wantStr) + if err != nil { + return err + } + } + hf.Value, buf, err = d.readString(buf, wantStr) + if err != nil { + return err + } + d.buf = buf + if it.indexed() { + d.dynTab.add(hf) + } + hf.Sensitive = it.sensitive() + return d.callEmit(hf) +} + +func (d *Decoder) callEmit(hf HeaderField) error { + if d.maxStrLen != 0 { + if len(hf.Name) > d.maxStrLen || len(hf.Value) > d.maxStrLen { + return ErrStringLength + } + } + if d.emitEnabled { + d.emit(hf) + } + return nil +} + +// (same invariants and behavior as parseHeaderFieldRepr) +func (d *Decoder) parseDynamicTableSizeUpdate() error { + buf := d.buf + size, buf, err := readVarInt(5, buf) + if err != nil { + return err + } + if size > uint64(d.dynTab.allowedMaxSize) { + return DecodingError{errors.New("dynamic table size update too large")} + } + d.dynTab.setMaxSize(uint32(size)) + d.buf = buf + return nil +} + +var errVarintOverflow = DecodingError{errors.New("varint integer overflow")} + +// readVarInt reads an unsigned variable length integer off the +// beginning of p. n is the parameter as described in +// http://http2.github.io/http2-spec/compression.html#rfc.section.5.1. +// +// n must always be between 1 and 8. +// +// The returned remain buffer is either a smaller suffix of p, or err != nil. +// The error is errNeedMore if p doesn't contain a complete integer. +func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) { + if n < 1 || n > 8 { + panic("bad n") + } + if len(p) == 0 { + return 0, p, errNeedMore + } + i = uint64(p[0]) + if n < 8 { + i &= (1 << uint64(n)) - 1 + } + if i < (1< 0 { + b := p[0] + p = p[1:] + i += uint64(b&127) << m + if b&128 == 0 { + return i, p, nil + } + m += 7 + if m >= 63 { // TODO: proper overflow check. making this up. + return 0, origP, errVarintOverflow + } + } + return 0, origP, errNeedMore +} + +// readString decodes an hpack string from p. +// +// wantStr is whether s will be used. If false, decompression and +// []byte->string garbage are skipped if s will be ignored +// anyway. This does mean that huffman decoding errors for non-indexed +// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server +// is returning an error anyway, and because they're not indexed, the error +// won't affect the decoding state. +func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) { + if len(p) == 0 { + return "", p, errNeedMore + } + isHuff := p[0]&128 != 0 + strLen, p, err := readVarInt(7, p) + if err != nil { + return "", p, err + } + if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) { + return "", nil, ErrStringLength + } + if uint64(len(p)) < strLen { + return "", p, errNeedMore + } + if !isHuff { + if wantStr { + s = string(p[:strLen]) + } + return s, p[strLen:], nil + } + + if wantStr { + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() // don't trust others + defer bufPool.Put(buf) + if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil { + buf.Reset() + return "", nil, err + } + s = buf.String() + buf.Reset() // be nice to GC + } + return s, p[strLen:], nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/hpack_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/hpack_test.go new file mode 100644 index 00000000..6dc69f95 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/hpack_test.go @@ -0,0 +1,813 @@ +// 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. + +package hpack + +import ( + "bufio" + "bytes" + "encoding/hex" + "fmt" + "math/rand" + "reflect" + "regexp" + "strconv" + "strings" + "testing" + "time" +) + +func TestStaticTable(t *testing.T) { + fromSpec := ` + +-------+-----------------------------+---------------+ + | 1 | :authority | | + | 2 | :method | GET | + | 3 | :method | POST | + | 4 | :path | / | + | 5 | :path | /index.html | + | 6 | :scheme | http | + | 7 | :scheme | https | + | 8 | :status | 200 | + | 9 | :status | 204 | + | 10 | :status | 206 | + | 11 | :status | 304 | + | 12 | :status | 400 | + | 13 | :status | 404 | + | 14 | :status | 500 | + | 15 | accept-charset | | + | 16 | accept-encoding | gzip, deflate | + | 17 | accept-language | | + | 18 | accept-ranges | | + | 19 | accept | | + | 20 | access-control-allow-origin | | + | 21 | age | | + | 22 | allow | | + | 23 | authorization | | + | 24 | cache-control | | + | 25 | content-disposition | | + | 26 | content-encoding | | + | 27 | content-language | | + | 28 | content-length | | + | 29 | content-location | | + | 30 | content-range | | + | 31 | content-type | | + | 32 | cookie | | + | 33 | date | | + | 34 | etag | | + | 35 | expect | | + | 36 | expires | | + | 37 | from | | + | 38 | host | | + | 39 | if-match | | + | 40 | if-modified-since | | + | 41 | if-none-match | | + | 42 | if-range | | + | 43 | if-unmodified-since | | + | 44 | last-modified | | + | 45 | link | | + | 46 | location | | + | 47 | max-forwards | | + | 48 | proxy-authenticate | | + | 49 | proxy-authorization | | + | 50 | range | | + | 51 | referer | | + | 52 | refresh | | + | 53 | retry-after | | + | 54 | server | | + | 55 | set-cookie | | + | 56 | strict-transport-security | | + | 57 | transfer-encoding | | + | 58 | user-agent | | + | 59 | vary | | + | 60 | via | | + | 61 | www-authenticate | | + +-------+-----------------------------+---------------+ +` + bs := bufio.NewScanner(strings.NewReader(fromSpec)) + re := regexp.MustCompile(`\| (\d+)\s+\| (\S+)\s*\| (\S(.*\S)?)?\s+\|`) + for bs.Scan() { + l := bs.Text() + if !strings.Contains(l, "|") { + continue + } + m := re.FindStringSubmatch(l) + if m == nil { + continue + } + i, err := strconv.Atoi(m[1]) + if err != nil { + t.Errorf("Bogus integer on line %q", l) + continue + } + if i < 1 || i > len(staticTable) { + t.Errorf("Bogus index %d on line %q", i, l) + continue + } + if got, want := staticTable[i-1].Name, m[2]; got != want { + t.Errorf("header index %d name = %q; want %q", i, got, want) + } + if got, want := staticTable[i-1].Value, m[3]; got != want { + t.Errorf("header index %d value = %q; want %q", i, got, want) + } + } + if err := bs.Err(); err != nil { + t.Error(err) + } +} + +func (d *Decoder) mustAt(idx int) HeaderField { + if hf, ok := d.at(uint64(idx)); !ok { + panic(fmt.Sprintf("bogus index %d", idx)) + } else { + return hf + } +} + +func TestDynamicTableAt(t *testing.T) { + d := NewDecoder(4096, nil) + at := d.mustAt + if got, want := at(2), (pair(":method", "GET")); got != want { + t.Errorf("at(2) = %v; want %v", got, want) + } + d.dynTab.add(pair("foo", "bar")) + d.dynTab.add(pair("blake", "miz")) + if got, want := at(len(staticTable)+1), (pair("blake", "miz")); got != want { + t.Errorf("at(dyn 1) = %v; want %v", got, want) + } + if got, want := at(len(staticTable)+2), (pair("foo", "bar")); got != want { + t.Errorf("at(dyn 2) = %v; want %v", got, want) + } + if got, want := at(3), (pair(":method", "POST")); got != want { + t.Errorf("at(3) = %v; want %v", got, want) + } +} + +func TestDynamicTableSearch(t *testing.T) { + dt := dynamicTable{} + dt.setMaxSize(4096) + + dt.add(pair("foo", "bar")) + dt.add(pair("blake", "miz")) + dt.add(pair(":method", "GET")) + + tests := []struct { + hf HeaderField + wantI uint64 + wantMatch bool + }{ + // Name and Value match + {pair("foo", "bar"), 3, true}, + {pair(":method", "GET"), 1, true}, + + // Only name match because of Sensitive == true + {HeaderField{"blake", "miz", true}, 2, false}, + + // Only Name matches + {pair("foo", "..."), 3, false}, + {pair("blake", "..."), 2, false}, + {pair(":method", "..."), 1, false}, + + // None match + {pair("foo-", "bar"), 0, false}, + } + for _, tt := range tests { + if gotI, gotMatch := dt.search(tt.hf); gotI != tt.wantI || gotMatch != tt.wantMatch { + t.Errorf("d.search(%+v) = %v, %v; want %v, %v", tt.hf, gotI, gotMatch, tt.wantI, tt.wantMatch) + } + } +} + +func TestDynamicTableSizeEvict(t *testing.T) { + d := NewDecoder(4096, nil) + if want := uint32(0); d.dynTab.size != want { + t.Fatalf("size = %d; want %d", d.dynTab.size, want) + } + add := d.dynTab.add + add(pair("blake", "eats pizza")) + if want := uint32(15 + 32); d.dynTab.size != want { + t.Fatalf("after pizza, size = %d; want %d", d.dynTab.size, want) + } + add(pair("foo", "bar")) + if want := uint32(15 + 32 + 6 + 32); d.dynTab.size != want { + t.Fatalf("after foo bar, size = %d; want %d", d.dynTab.size, want) + } + d.dynTab.setMaxSize(15 + 32 + 1 /* slop */) + if want := uint32(6 + 32); d.dynTab.size != want { + t.Fatalf("after setMaxSize, size = %d; want %d", d.dynTab.size, want) + } + if got, want := d.mustAt(len(staticTable)+1), (pair("foo", "bar")); got != want { + t.Errorf("at(dyn 1) = %v; want %v", got, want) + } + add(pair("long", strings.Repeat("x", 500))) + if want := uint32(0); d.dynTab.size != want { + t.Fatalf("after big one, size = %d; want %d", d.dynTab.size, want) + } +} + +func TestDecoderDecode(t *testing.T) { + tests := []struct { + name string + in []byte + want []HeaderField + wantDynTab []HeaderField // newest entry first + }{ + // C.2.1 Literal Header Field with Indexing + // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.1 + {"C.2.1", dehex("400a 6375 7374 6f6d 2d6b 6579 0d63 7573 746f 6d2d 6865 6164 6572"), + []HeaderField{pair("custom-key", "custom-header")}, + []HeaderField{pair("custom-key", "custom-header")}, + }, + + // C.2.2 Literal Header Field without Indexing + // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.2 + {"C.2.2", dehex("040c 2f73 616d 706c 652f 7061 7468"), + []HeaderField{pair(":path", "/sample/path")}, + []HeaderField{}}, + + // C.2.3 Literal Header Field never Indexed + // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.3 + {"C.2.3", dehex("1008 7061 7373 776f 7264 0673 6563 7265 74"), + []HeaderField{{"password", "secret", true}}, + []HeaderField{}}, + + // C.2.4 Indexed Header Field + // http://http2.github.io/http2-spec/compression.html#rfc.section.C.2.4 + {"C.2.4", []byte("\x82"), + []HeaderField{pair(":method", "GET")}, + []HeaderField{}}, + } + for _, tt := range tests { + d := NewDecoder(4096, nil) + hf, err := d.DecodeFull(tt.in) + if err != nil { + t.Errorf("%s: %v", tt.name, err) + continue + } + if !reflect.DeepEqual(hf, tt.want) { + t.Errorf("%s: Got %v; want %v", tt.name, hf, tt.want) + } + gotDynTab := d.dynTab.reverseCopy() + if !reflect.DeepEqual(gotDynTab, tt.wantDynTab) { + t.Errorf("%s: dynamic table after = %v; want %v", tt.name, gotDynTab, tt.wantDynTab) + } + } +} + +func (dt *dynamicTable) reverseCopy() (hf []HeaderField) { + hf = make([]HeaderField, len(dt.ents)) + for i := range hf { + hf[i] = dt.ents[len(dt.ents)-1-i] + } + return +} + +type encAndWant struct { + enc []byte + want []HeaderField + wantDynTab []HeaderField + wantDynSize uint32 +} + +// C.3 Request Examples without Huffman Coding +// http://http2.github.io/http2-spec/compression.html#rfc.section.C.3 +func TestDecodeC3_NoHuffman(t *testing.T) { + testDecodeSeries(t, 4096, []encAndWant{ + {dehex("8286 8441 0f77 7777 2e65 7861 6d70 6c65 2e63 6f6d"), + []HeaderField{ + pair(":method", "GET"), + pair(":scheme", "http"), + pair(":path", "/"), + pair(":authority", "www.example.com"), + }, + []HeaderField{ + pair(":authority", "www.example.com"), + }, + 57, + }, + {dehex("8286 84be 5808 6e6f 2d63 6163 6865"), + []HeaderField{ + pair(":method", "GET"), + pair(":scheme", "http"), + pair(":path", "/"), + pair(":authority", "www.example.com"), + pair("cache-control", "no-cache"), + }, + []HeaderField{ + pair("cache-control", "no-cache"), + pair(":authority", "www.example.com"), + }, + 110, + }, + {dehex("8287 85bf 400a 6375 7374 6f6d 2d6b 6579 0c63 7573 746f 6d2d 7661 6c75 65"), + []HeaderField{ + pair(":method", "GET"), + pair(":scheme", "https"), + pair(":path", "/index.html"), + pair(":authority", "www.example.com"), + pair("custom-key", "custom-value"), + }, + []HeaderField{ + pair("custom-key", "custom-value"), + pair("cache-control", "no-cache"), + pair(":authority", "www.example.com"), + }, + 164, + }, + }) +} + +// C.4 Request Examples with Huffman Coding +// http://http2.github.io/http2-spec/compression.html#rfc.section.C.4 +func TestDecodeC4_Huffman(t *testing.T) { + testDecodeSeries(t, 4096, []encAndWant{ + {dehex("8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4 ff"), + []HeaderField{ + pair(":method", "GET"), + pair(":scheme", "http"), + pair(":path", "/"), + pair(":authority", "www.example.com"), + }, + []HeaderField{ + pair(":authority", "www.example.com"), + }, + 57, + }, + {dehex("8286 84be 5886 a8eb 1064 9cbf"), + []HeaderField{ + pair(":method", "GET"), + pair(":scheme", "http"), + pair(":path", "/"), + pair(":authority", "www.example.com"), + pair("cache-control", "no-cache"), + }, + []HeaderField{ + pair("cache-control", "no-cache"), + pair(":authority", "www.example.com"), + }, + 110, + }, + {dehex("8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 a849 e95b b8e8 b4bf"), + []HeaderField{ + pair(":method", "GET"), + pair(":scheme", "https"), + pair(":path", "/index.html"), + pair(":authority", "www.example.com"), + pair("custom-key", "custom-value"), + }, + []HeaderField{ + pair("custom-key", "custom-value"), + pair("cache-control", "no-cache"), + pair(":authority", "www.example.com"), + }, + 164, + }, + }) +} + +// http://http2.github.io/http2-spec/compression.html#rfc.section.C.5 +// "This section shows several consecutive header lists, corresponding +// to HTTP responses, on the same connection. The HTTP/2 setting +// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 +// octets, causing some evictions to occur." +func TestDecodeC5_ResponsesNoHuff(t *testing.T) { + testDecodeSeries(t, 256, []encAndWant{ + {dehex(` +4803 3330 3258 0770 7269 7661 7465 611d +4d6f 6e2c 2032 3120 4f63 7420 3230 3133 +2032 303a 3133 3a32 3120 474d 546e 1768 +7474 7073 3a2f 2f77 7777 2e65 7861 6d70 +6c65 2e63 6f6d +`), + []HeaderField{ + pair(":status", "302"), + pair("cache-control", "private"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("location", "https://www.example.com"), + }, + []HeaderField{ + pair("location", "https://www.example.com"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("cache-control", "private"), + pair(":status", "302"), + }, + 222, + }, + {dehex("4803 3330 37c1 c0bf"), + []HeaderField{ + pair(":status", "307"), + pair("cache-control", "private"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("location", "https://www.example.com"), + }, + []HeaderField{ + pair(":status", "307"), + pair("location", "https://www.example.com"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("cache-control", "private"), + }, + 222, + }, + {dehex(` +88c1 611d 4d6f 6e2c 2032 3120 4f63 7420 +3230 3133 2032 303a 3133 3a32 3220 474d +54c0 5a04 677a 6970 7738 666f 6f3d 4153 +444a 4b48 514b 425a 584f 5157 454f 5049 +5541 5851 5745 4f49 553b 206d 6178 2d61 +6765 3d33 3630 303b 2076 6572 7369 6f6e +3d31 +`), + []HeaderField{ + pair(":status", "200"), + pair("cache-control", "private"), + pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), + pair("location", "https://www.example.com"), + pair("content-encoding", "gzip"), + pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"), + }, + []HeaderField{ + pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"), + pair("content-encoding", "gzip"), + pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), + }, + 215, + }, + }) +} + +// http://http2.github.io/http2-spec/compression.html#rfc.section.C.6 +// "This section shows the same examples as the previous section, but +// using Huffman encoding for the literal values. The HTTP/2 setting +// parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 +// octets, causing some evictions to occur. The eviction mechanism +// uses the length of the decoded literal values, so the same +// evictions occurs as in the previous section." +func TestDecodeC6_ResponsesHuffman(t *testing.T) { + testDecodeSeries(t, 256, []encAndWant{ + {dehex(` +4882 6402 5885 aec3 771a 4b61 96d0 7abe +9410 54d4 44a8 2005 9504 0b81 66e0 82a6 +2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8 +e9ae 82ae 43d3 +`), + []HeaderField{ + pair(":status", "302"), + pair("cache-control", "private"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("location", "https://www.example.com"), + }, + []HeaderField{ + pair("location", "https://www.example.com"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("cache-control", "private"), + pair(":status", "302"), + }, + 222, + }, + {dehex("4883 640e ffc1 c0bf"), + []HeaderField{ + pair(":status", "307"), + pair("cache-control", "private"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("location", "https://www.example.com"), + }, + []HeaderField{ + pair(":status", "307"), + pair("location", "https://www.example.com"), + pair("date", "Mon, 21 Oct 2013 20:13:21 GMT"), + pair("cache-control", "private"), + }, + 222, + }, + {dehex(` +88c1 6196 d07a be94 1054 d444 a820 0595 +040b 8166 e084 a62d 1bff c05a 839b d9ab +77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b +3960 d5af 2708 7f36 72c1 ab27 0fb5 291f +9587 3160 65c0 03ed 4ee5 b106 3d50 07 +`), + []HeaderField{ + pair(":status", "200"), + pair("cache-control", "private"), + pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), + pair("location", "https://www.example.com"), + pair("content-encoding", "gzip"), + pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"), + }, + []HeaderField{ + pair("set-cookie", "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"), + pair("content-encoding", "gzip"), + pair("date", "Mon, 21 Oct 2013 20:13:22 GMT"), + }, + 215, + }, + }) +} + +func testDecodeSeries(t *testing.T, size uint32, steps []encAndWant) { + d := NewDecoder(size, nil) + for i, step := range steps { + hf, err := d.DecodeFull(step.enc) + if err != nil { + t.Fatalf("Error at step index %d: %v", i, err) + } + if !reflect.DeepEqual(hf, step.want) { + t.Fatalf("At step index %d: Got headers %v; want %v", i, hf, step.want) + } + gotDynTab := d.dynTab.reverseCopy() + if !reflect.DeepEqual(gotDynTab, step.wantDynTab) { + t.Errorf("After step index %d, dynamic table = %v; want %v", i, gotDynTab, step.wantDynTab) + } + if d.dynTab.size != step.wantDynSize { + t.Errorf("After step index %d, dynamic table size = %v; want %v", i, d.dynTab.size, step.wantDynSize) + } + } +} + +func TestHuffmanDecode(t *testing.T) { + tests := []struct { + inHex, want string + }{ + {"f1e3 c2e5 f23a 6ba0 ab90 f4ff", "www.example.com"}, + {"a8eb 1064 9cbf", "no-cache"}, + {"25a8 49e9 5ba9 7d7f", "custom-key"}, + {"25a8 49e9 5bb8 e8b4 bf", "custom-value"}, + {"6402", "302"}, + {"aec3 771a 4b", "private"}, + {"d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff", "Mon, 21 Oct 2013 20:13:21 GMT"}, + {"9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3", "https://www.example.com"}, + {"9bd9 ab", "gzip"}, + {"94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07", + "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"}, + } + for i, tt := range tests { + var buf bytes.Buffer + in, err := hex.DecodeString(strings.Replace(tt.inHex, " ", "", -1)) + if err != nil { + t.Errorf("%d. hex input error: %v", i, err) + continue + } + if _, err := HuffmanDecode(&buf, in); err != nil { + t.Errorf("%d. decode error: %v", i, err) + continue + } + if got := buf.String(); tt.want != got { + t.Errorf("%d. decode = %q; want %q", i, got, tt.want) + } + } +} + +func TestAppendHuffmanString(t *testing.T) { + tests := []struct { + in, want string + }{ + {"www.example.com", "f1e3 c2e5 f23a 6ba0 ab90 f4ff"}, + {"no-cache", "a8eb 1064 9cbf"}, + {"custom-key", "25a8 49e9 5ba9 7d7f"}, + {"custom-value", "25a8 49e9 5bb8 e8b4 bf"}, + {"302", "6402"}, + {"private", "aec3 771a 4b"}, + {"Mon, 21 Oct 2013 20:13:21 GMT", "d07a be94 1054 d444 a820 0595 040b 8166 e082 a62d 1bff"}, + {"https://www.example.com", "9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 d3"}, + {"gzip", "9bd9 ab"}, + {"foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1", + "94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 3160 65c0 03ed 4ee5 b106 3d50 07"}, + } + for i, tt := range tests { + buf := []byte{} + want := strings.Replace(tt.want, " ", "", -1) + buf = AppendHuffmanString(buf, tt.in) + if got := hex.EncodeToString(buf); want != got { + t.Errorf("%d. encode = %q; want %q", i, got, want) + } + } +} + +func TestHuffmanMaxStrLen(t *testing.T) { + const msg = "Some string" + huff := AppendHuffmanString(nil, msg) + + testGood := func(max int) { + var out bytes.Buffer + if err := huffmanDecode(&out, max, huff); err != nil { + t.Errorf("For maxLen=%d, unexpected error: %v", max, err) + } + if out.String() != msg { + t.Errorf("For maxLen=%d, out = %q; want %q", max, out.String(), msg) + } + } + testGood(0) + testGood(len(msg)) + testGood(len(msg) + 1) + + var out bytes.Buffer + if err := huffmanDecode(&out, len(msg)-1, huff); err != ErrStringLength { + t.Errorf("err = %v; want ErrStringLength", err) + } +} + +func TestHuffmanRoundtripStress(t *testing.T) { + const Len = 50 // of uncompressed string + input := make([]byte, Len) + var output bytes.Buffer + var huff []byte + + n := 5000 + if testing.Short() { + n = 100 + } + seed := time.Now().UnixNano() + t.Logf("Seed = %v", seed) + src := rand.New(rand.NewSource(seed)) + var encSize int64 + for i := 0; i < n; i++ { + for l := range input { + input[l] = byte(src.Intn(256)) + } + huff = AppendHuffmanString(huff[:0], string(input)) + encSize += int64(len(huff)) + output.Reset() + if err := huffmanDecode(&output, 0, huff); err != nil { + t.Errorf("Failed to decode %q -> %q -> error %v", input, huff, err) + continue + } + if !bytes.Equal(output.Bytes(), input) { + t.Errorf("Roundtrip failure on %q -> %q -> %q", input, huff, output.Bytes()) + } + } + t.Logf("Compressed size of original: %0.02f%% (%v -> %v)", 100*(float64(encSize)/(Len*float64(n))), Len*n, encSize) +} + +func TestHuffmanDecodeFuzz(t *testing.T) { + const Len = 50 // of compressed + var buf, zbuf bytes.Buffer + + n := 5000 + if testing.Short() { + n = 100 + } + seed := time.Now().UnixNano() + t.Logf("Seed = %v", seed) + src := rand.New(rand.NewSource(seed)) + numFail := 0 + for i := 0; i < n; i++ { + zbuf.Reset() + if i == 0 { + // Start with at least one invalid one. + zbuf.WriteString("00\x91\xff\xff\xff\xff\xc8") + } else { + for l := 0; l < Len; l++ { + zbuf.WriteByte(byte(src.Intn(256))) + } + } + + buf.Reset() + if err := huffmanDecode(&buf, 0, zbuf.Bytes()); err != nil { + if err == ErrInvalidHuffman { + numFail++ + continue + } + t.Errorf("Failed to decode %q: %v", zbuf.Bytes(), err) + continue + } + } + t.Logf("%0.02f%% are invalid (%d / %d)", 100*float64(numFail)/float64(n), numFail, n) + if numFail < 1 { + t.Error("expected at least one invalid huffman encoding (test starts with one)") + } +} + +func TestReadVarInt(t *testing.T) { + type res struct { + i uint64 + consumed int + err error + } + tests := []struct { + n byte + p []byte + want res + }{ + // Fits in a byte: + {1, []byte{0}, res{0, 1, nil}}, + {2, []byte{2}, res{2, 1, nil}}, + {3, []byte{6}, res{6, 1, nil}}, + {4, []byte{14}, res{14, 1, nil}}, + {5, []byte{30}, res{30, 1, nil}}, + {6, []byte{62}, res{62, 1, nil}}, + {7, []byte{126}, res{126, 1, nil}}, + {8, []byte{254}, res{254, 1, nil}}, + + // Doesn't fit in a byte: + {1, []byte{1}, res{0, 0, errNeedMore}}, + {2, []byte{3}, res{0, 0, errNeedMore}}, + {3, []byte{7}, res{0, 0, errNeedMore}}, + {4, []byte{15}, res{0, 0, errNeedMore}}, + {5, []byte{31}, res{0, 0, errNeedMore}}, + {6, []byte{63}, res{0, 0, errNeedMore}}, + {7, []byte{127}, res{0, 0, errNeedMore}}, + {8, []byte{255}, res{0, 0, errNeedMore}}, + + // Ignoring top bits: + {5, []byte{255, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 111 + {5, []byte{159, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 100 + {5, []byte{191, 154, 10}, res{1337, 3, nil}}, // high dummy three bits: 101 + + // Extra byte: + {5, []byte{191, 154, 10, 2}, res{1337, 3, nil}}, // extra byte + + // Short a byte: + {5, []byte{191, 154}, res{0, 0, errNeedMore}}, + + // integer overflow: + {1, []byte{255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, res{0, 0, errVarintOverflow}}, + } + for _, tt := range tests { + i, remain, err := readVarInt(tt.n, tt.p) + consumed := len(tt.p) - len(remain) + got := res{i, consumed, err} + if got != tt.want { + t.Errorf("readVarInt(%d, %v ~ %x) = %+v; want %+v", tt.n, tt.p, tt.p, got, tt.want) + } + } +} + +// Fuzz crash, originally reported at https://github.com/bradfitz/http2/issues/56 +func TestHuffmanFuzzCrash(t *testing.T) { + got, err := HuffmanDecodeToString([]byte("00\x91\xff\xff\xff\xff\xc8")) + if got != "" { + t.Errorf("Got %q; want empty string", got) + } + if err != ErrInvalidHuffman { + t.Errorf("Err = %v; want ErrInvalidHuffman", err) + } +} + +func dehex(s string) []byte { + s = strings.Replace(s, " ", "", -1) + s = strings.Replace(s, "\n", "", -1) + b, err := hex.DecodeString(s) + if err != nil { + panic(err) + } + return b +} + +func TestEmitEnabled(t *testing.T) { + var buf bytes.Buffer + enc := NewEncoder(&buf) + enc.WriteField(HeaderField{Name: "foo", Value: "bar"}) + enc.WriteField(HeaderField{Name: "foo", Value: "bar"}) + + numCallback := 0 + var dec *Decoder + dec = NewDecoder(8<<20, func(HeaderField) { + numCallback++ + dec.SetEmitEnabled(false) + }) + if !dec.EmitEnabled() { + t.Errorf("initial emit enabled = false; want true") + } + if _, err := dec.Write(buf.Bytes()); err != nil { + t.Error(err) + } + if numCallback != 1 { + t.Errorf("num callbacks = %d; want 1", numCallback) + } + if dec.EmitEnabled() { + t.Errorf("emit enabled = true; want false") + } +} + +func TestSaveBufLimit(t *testing.T) { + const maxStr = 1 << 10 + var got []HeaderField + dec := NewDecoder(initialHeaderTableSize, func(hf HeaderField) { + got = append(got, hf) + }) + dec.SetMaxStringLength(maxStr) + var frag []byte + frag = append(frag[:0], encodeTypeByte(false, false)) + frag = appendVarInt(frag, 7, 3) + frag = append(frag, "foo"...) + frag = appendVarInt(frag, 7, 3) + frag = append(frag, "bar"...) + + if _, err := dec.Write(frag); err != nil { + t.Fatal(err) + } + + want := []HeaderField{{Name: "foo", Value: "bar"}} + if !reflect.DeepEqual(got, want) { + t.Errorf("After small writes, got %v; want %v", got, want) + } + + frag = append(frag[:0], encodeTypeByte(false, false)) + frag = appendVarInt(frag, 7, maxStr*3) + frag = append(frag, make([]byte, maxStr*3)...) + + _, err := dec.Write(frag) + if err != ErrStringLength { + t.Fatalf("Write error = %v; want ErrStringLength", err) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/huffman.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/huffman.go new file mode 100644 index 00000000..eb4b1f05 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/huffman.go @@ -0,0 +1,190 @@ +// 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. + +package hpack + +import ( + "bytes" + "errors" + "io" + "sync" +) + +var bufPool = sync.Pool{ + New: func() interface{} { return new(bytes.Buffer) }, +} + +// HuffmanDecode decodes the string in v and writes the expanded +// result to w, returning the number of bytes written to w and the +// Write call's return value. At most one Write call is made. +func HuffmanDecode(w io.Writer, v []byte) (int, error) { + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + defer bufPool.Put(buf) + if err := huffmanDecode(buf, 0, v); err != nil { + return 0, err + } + return w.Write(buf.Bytes()) +} + +// HuffmanDecodeToString decodes the string in v. +func HuffmanDecodeToString(v []byte) (string, error) { + buf := bufPool.Get().(*bytes.Buffer) + buf.Reset() + defer bufPool.Put(buf) + if err := huffmanDecode(buf, 0, v); err != nil { + return "", err + } + return buf.String(), nil +} + +// ErrInvalidHuffman is returned for errors found decoding +// Huffman-encoded strings. +var ErrInvalidHuffman = errors.New("hpack: invalid Huffman-encoded data") + +// huffmanDecode decodes v to buf. +// If maxLen is greater than 0, attempts to write more to buf than +// maxLen bytes will return ErrStringLength. +func huffmanDecode(buf *bytes.Buffer, maxLen int, v []byte) error { + n := rootHuffmanNode + cur, nbits := uint(0), uint8(0) + for _, b := range v { + cur = cur<<8 | uint(b) + nbits += 8 + for nbits >= 8 { + idx := byte(cur >> (nbits - 8)) + n = n.children[idx] + if n == nil { + return ErrInvalidHuffman + } + if n.children == nil { + if maxLen != 0 && buf.Len() == maxLen { + return ErrStringLength + } + buf.WriteByte(n.sym) + nbits -= n.codeLen + n = rootHuffmanNode + } else { + nbits -= 8 + } + } + } + for nbits > 0 { + n = n.children[byte(cur<<(8-nbits))] + if n.children != nil || n.codeLen > nbits { + break + } + buf.WriteByte(n.sym) + nbits -= n.codeLen + n = rootHuffmanNode + } + return nil +} + +type node struct { + // children is non-nil for internal nodes + children []*node + + // The following are only valid if children is nil: + codeLen uint8 // number of bits that led to the output of sym + sym byte // output symbol +} + +func newInternalNode() *node { + return &node{children: make([]*node, 256)} +} + +var rootHuffmanNode = newInternalNode() + +func init() { + if len(huffmanCodes) != 256 { + panic("unexpected size") + } + for i, code := range huffmanCodes { + addDecoderNode(byte(i), code, huffmanCodeLen[i]) + } +} + +func addDecoderNode(sym byte, code uint32, codeLen uint8) { + cur := rootHuffmanNode + for codeLen > 8 { + codeLen -= 8 + i := uint8(code >> codeLen) + if cur.children[i] == nil { + cur.children[i] = newInternalNode() + } + cur = cur.children[i] + } + shift := 8 - codeLen + start, end := int(uint8(code<> (nbits - rembits)) + dst[len(dst)-1] |= t + } + + return dst +} + +// HuffmanEncodeLength returns the number of bytes required to encode +// s in Huffman codes. The result is round up to byte boundary. +func HuffmanEncodeLength(s string) uint64 { + n := uint64(0) + for i := 0; i < len(s); i++ { + n += uint64(huffmanCodeLen[s[i]]) + } + return (n + 7) / 8 +} + +// appendByteToHuffmanCode appends Huffman code for c to dst and +// returns the extended buffer and the remaining bits in the last +// element. The appending is not byte aligned and the remaining bits +// in the last element of dst is given in rembits. +func appendByteToHuffmanCode(dst []byte, rembits uint8, c byte) ([]byte, uint8) { + code := huffmanCodes[c] + nbits := huffmanCodeLen[c] + + for { + if rembits > nbits { + t := uint8(code << (rembits - nbits)) + dst[len(dst)-1] |= t + rembits -= nbits + break + } + + t := uint8(code >> (nbits - rembits)) + dst[len(dst)-1] |= t + + nbits -= rembits + rembits = 8 + + if nbits == 0 { + break + } + + dst = append(dst, 0) + } + + return dst, rembits +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/tables.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/tables.go new file mode 100644 index 00000000..b9283a02 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/hpack/tables.go @@ -0,0 +1,352 @@ +// 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. + +package hpack + +func pair(name, value string) HeaderField { + return HeaderField{Name: name, Value: value} +} + +// http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07#appendix-B +var staticTable = [...]HeaderField{ + pair(":authority", ""), // index 1 (1-based) + pair(":method", "GET"), + pair(":method", "POST"), + pair(":path", "/"), + pair(":path", "/index.html"), + pair(":scheme", "http"), + pair(":scheme", "https"), + pair(":status", "200"), + pair(":status", "204"), + pair(":status", "206"), + pair(":status", "304"), + pair(":status", "400"), + pair(":status", "404"), + pair(":status", "500"), + pair("accept-charset", ""), + pair("accept-encoding", "gzip, deflate"), + pair("accept-language", ""), + pair("accept-ranges", ""), + pair("accept", ""), + pair("access-control-allow-origin", ""), + pair("age", ""), + pair("allow", ""), + pair("authorization", ""), + pair("cache-control", ""), + pair("content-disposition", ""), + pair("content-encoding", ""), + pair("content-language", ""), + pair("content-length", ""), + pair("content-location", ""), + pair("content-range", ""), + pair("content-type", ""), + pair("cookie", ""), + pair("date", ""), + pair("etag", ""), + pair("expect", ""), + pair("expires", ""), + pair("from", ""), + pair("host", ""), + pair("if-match", ""), + pair("if-modified-since", ""), + pair("if-none-match", ""), + pair("if-range", ""), + pair("if-unmodified-since", ""), + pair("last-modified", ""), + pair("link", ""), + pair("location", ""), + pair("max-forwards", ""), + pair("proxy-authenticate", ""), + pair("proxy-authorization", ""), + pair("range", ""), + pair("referer", ""), + pair("refresh", ""), + pair("retry-after", ""), + pair("server", ""), + pair("set-cookie", ""), + pair("strict-transport-security", ""), + pair("transfer-encoding", ""), + pair("user-agent", ""), + pair("vary", ""), + pair("via", ""), + pair("www-authenticate", ""), +} + +var huffmanCodes = [256]uint32{ + 0x1ff8, + 0x7fffd8, + 0xfffffe2, + 0xfffffe3, + 0xfffffe4, + 0xfffffe5, + 0xfffffe6, + 0xfffffe7, + 0xfffffe8, + 0xffffea, + 0x3ffffffc, + 0xfffffe9, + 0xfffffea, + 0x3ffffffd, + 0xfffffeb, + 0xfffffec, + 0xfffffed, + 0xfffffee, + 0xfffffef, + 0xffffff0, + 0xffffff1, + 0xffffff2, + 0x3ffffffe, + 0xffffff3, + 0xffffff4, + 0xffffff5, + 0xffffff6, + 0xffffff7, + 0xffffff8, + 0xffffff9, + 0xffffffa, + 0xffffffb, + 0x14, + 0x3f8, + 0x3f9, + 0xffa, + 0x1ff9, + 0x15, + 0xf8, + 0x7fa, + 0x3fa, + 0x3fb, + 0xf9, + 0x7fb, + 0xfa, + 0x16, + 0x17, + 0x18, + 0x0, + 0x1, + 0x2, + 0x19, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x5c, + 0xfb, + 0x7ffc, + 0x20, + 0xffb, + 0x3fc, + 0x1ffa, + 0x21, + 0x5d, + 0x5e, + 0x5f, + 0x60, + 0x61, + 0x62, + 0x63, + 0x64, + 0x65, + 0x66, + 0x67, + 0x68, + 0x69, + 0x6a, + 0x6b, + 0x6c, + 0x6d, + 0x6e, + 0x6f, + 0x70, + 0x71, + 0x72, + 0xfc, + 0x73, + 0xfd, + 0x1ffb, + 0x7fff0, + 0x1ffc, + 0x3ffc, + 0x22, + 0x7ffd, + 0x3, + 0x23, + 0x4, + 0x24, + 0x5, + 0x25, + 0x26, + 0x27, + 0x6, + 0x74, + 0x75, + 0x28, + 0x29, + 0x2a, + 0x7, + 0x2b, + 0x76, + 0x2c, + 0x8, + 0x9, + 0x2d, + 0x77, + 0x78, + 0x79, + 0x7a, + 0x7b, + 0x7ffe, + 0x7fc, + 0x3ffd, + 0x1ffd, + 0xffffffc, + 0xfffe6, + 0x3fffd2, + 0xfffe7, + 0xfffe8, + 0x3fffd3, + 0x3fffd4, + 0x3fffd5, + 0x7fffd9, + 0x3fffd6, + 0x7fffda, + 0x7fffdb, + 0x7fffdc, + 0x7fffdd, + 0x7fffde, + 0xffffeb, + 0x7fffdf, + 0xffffec, + 0xffffed, + 0x3fffd7, + 0x7fffe0, + 0xffffee, + 0x7fffe1, + 0x7fffe2, + 0x7fffe3, + 0x7fffe4, + 0x1fffdc, + 0x3fffd8, + 0x7fffe5, + 0x3fffd9, + 0x7fffe6, + 0x7fffe7, + 0xffffef, + 0x3fffda, + 0x1fffdd, + 0xfffe9, + 0x3fffdb, + 0x3fffdc, + 0x7fffe8, + 0x7fffe9, + 0x1fffde, + 0x7fffea, + 0x3fffdd, + 0x3fffde, + 0xfffff0, + 0x1fffdf, + 0x3fffdf, + 0x7fffeb, + 0x7fffec, + 0x1fffe0, + 0x1fffe1, + 0x3fffe0, + 0x1fffe2, + 0x7fffed, + 0x3fffe1, + 0x7fffee, + 0x7fffef, + 0xfffea, + 0x3fffe2, + 0x3fffe3, + 0x3fffe4, + 0x7ffff0, + 0x3fffe5, + 0x3fffe6, + 0x7ffff1, + 0x3ffffe0, + 0x3ffffe1, + 0xfffeb, + 0x7fff1, + 0x3fffe7, + 0x7ffff2, + 0x3fffe8, + 0x1ffffec, + 0x3ffffe2, + 0x3ffffe3, + 0x3ffffe4, + 0x7ffffde, + 0x7ffffdf, + 0x3ffffe5, + 0xfffff1, + 0x1ffffed, + 0x7fff2, + 0x1fffe3, + 0x3ffffe6, + 0x7ffffe0, + 0x7ffffe1, + 0x3ffffe7, + 0x7ffffe2, + 0xfffff2, + 0x1fffe4, + 0x1fffe5, + 0x3ffffe8, + 0x3ffffe9, + 0xffffffd, + 0x7ffffe3, + 0x7ffffe4, + 0x7ffffe5, + 0xfffec, + 0xfffff3, + 0xfffed, + 0x1fffe6, + 0x3fffe9, + 0x1fffe7, + 0x1fffe8, + 0x7ffff3, + 0x3fffea, + 0x3fffeb, + 0x1ffffee, + 0x1ffffef, + 0xfffff4, + 0xfffff5, + 0x3ffffea, + 0x7ffff4, + 0x3ffffeb, + 0x7ffffe6, + 0x3ffffec, + 0x3ffffed, + 0x7ffffe7, + 0x7ffffe8, + 0x7ffffe9, + 0x7ffffea, + 0x7ffffeb, + 0xffffffe, + 0x7ffffec, + 0x7ffffed, + 0x7ffffee, + 0x7ffffef, + 0x7fffff0, + 0x3ffffee, +} + +var huffmanCodeLen = [256]uint8{ + 13, 23, 28, 28, 28, 28, 28, 28, 28, 24, 30, 28, 28, 30, 28, 28, + 28, 28, 28, 28, 28, 28, 30, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 6, 10, 10, 12, 13, 6, 8, 11, 10, 10, 8, 11, 8, 6, 6, 6, + 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 8, 15, 6, 12, 10, + 13, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 8, 7, 8, 13, 19, 13, 14, 6, + 15, 5, 6, 5, 6, 5, 6, 6, 6, 5, 7, 7, 6, 6, 6, 5, + 6, 7, 6, 5, 5, 6, 7, 7, 7, 7, 7, 15, 11, 14, 13, 28, + 20, 22, 20, 20, 22, 22, 22, 23, 22, 23, 23, 23, 23, 23, 24, 23, + 24, 24, 22, 23, 24, 23, 23, 23, 23, 21, 22, 23, 22, 23, 23, 24, + 22, 21, 20, 22, 22, 23, 23, 21, 23, 22, 22, 24, 21, 22, 23, 23, + 21, 21, 22, 21, 23, 22, 23, 23, 20, 22, 22, 22, 23, 22, 22, 23, + 26, 26, 20, 19, 22, 23, 22, 25, 26, 26, 26, 27, 27, 26, 24, 25, + 19, 21, 26, 27, 27, 26, 27, 24, 21, 21, 26, 26, 28, 27, 27, 27, + 20, 24, 20, 21, 22, 21, 21, 23, 22, 22, 25, 25, 24, 24, 26, 23, + 26, 27, 26, 26, 27, 27, 27, 27, 27, 28, 27, 27, 27, 27, 27, 26, +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/http2.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/http2.go new file mode 100644 index 00000000..4c5e11ac --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/http2.go @@ -0,0 +1,429 @@ +// 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. + +// Package http2 implements the HTTP/2 protocol. +// +// This package is low-level and intended to be used directly by very +// few people. Most users will use it indirectly through the automatic +// use by the net/http package (from Go 1.6 and later). +// For use in earlier Go versions see ConfigureServer. (Transport support +// requires Go 1.6 or later) +// +// See https://http2.github.io/ for more information on HTTP/2. +// +// See https://http2.golang.org/ for a test server running this code. +package http2 + +import ( + "bufio" + "crypto/tls" + "errors" + "fmt" + "io" + "net/http" + "os" + "strconv" + "strings" + "sync" +) + +var ( + VerboseLogs bool + logFrameWrites bool + logFrameReads bool +) + +func init() { + e := os.Getenv("GODEBUG") + if strings.Contains(e, "http2debug=1") { + VerboseLogs = true + } + if strings.Contains(e, "http2debug=2") { + VerboseLogs = true + logFrameWrites = true + logFrameReads = true + } +} + +const ( + // ClientPreface is the string that must be sent by new + // connections from clients. + ClientPreface = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n" + + // SETTINGS_MAX_FRAME_SIZE default + // http://http2.github.io/http2-spec/#rfc.section.6.5.2 + initialMaxFrameSize = 16384 + + // NextProtoTLS is the NPN/ALPN protocol negotiated during + // HTTP/2's TLS setup. + NextProtoTLS = "h2" + + // http://http2.github.io/http2-spec/#SettingValues + initialHeaderTableSize = 4096 + + initialWindowSize = 65535 // 6.9.2 Initial Flow Control Window Size + + defaultMaxReadFrameSize = 1 << 20 +) + +var ( + clientPreface = []byte(ClientPreface) +) + +type streamState int + +const ( + stateIdle streamState = iota + stateOpen + stateHalfClosedLocal + stateHalfClosedRemote + stateResvLocal + stateResvRemote + stateClosed +) + +var stateName = [...]string{ + stateIdle: "Idle", + stateOpen: "Open", + stateHalfClosedLocal: "HalfClosedLocal", + stateHalfClosedRemote: "HalfClosedRemote", + stateResvLocal: "ResvLocal", + stateResvRemote: "ResvRemote", + stateClosed: "Closed", +} + +func (st streamState) String() string { + return stateName[st] +} + +// Setting is a setting parameter: which setting it is, and its value. +type Setting struct { + // ID is which setting is being set. + // See http://http2.github.io/http2-spec/#SettingValues + ID SettingID + + // Val is the value. + Val uint32 +} + +func (s Setting) String() string { + return fmt.Sprintf("[%v = %d]", s.ID, s.Val) +} + +// Valid reports whether the setting is valid. +func (s Setting) Valid() error { + // Limits and error codes from 6.5.2 Defined SETTINGS Parameters + switch s.ID { + case SettingEnablePush: + if s.Val != 1 && s.Val != 0 { + return ConnectionError(ErrCodeProtocol) + } + case SettingInitialWindowSize: + if s.Val > 1<<31-1 { + return ConnectionError(ErrCodeFlowControl) + } + case SettingMaxFrameSize: + if s.Val < 16384 || s.Val > 1<<24-1 { + return ConnectionError(ErrCodeProtocol) + } + } + return nil +} + +// A SettingID is an HTTP/2 setting as defined in +// http://http2.github.io/http2-spec/#iana-settings +type SettingID uint16 + +const ( + SettingHeaderTableSize SettingID = 0x1 + SettingEnablePush SettingID = 0x2 + SettingMaxConcurrentStreams SettingID = 0x3 + SettingInitialWindowSize SettingID = 0x4 + SettingMaxFrameSize SettingID = 0x5 + SettingMaxHeaderListSize SettingID = 0x6 +) + +var settingName = map[SettingID]string{ + SettingHeaderTableSize: "HEADER_TABLE_SIZE", + SettingEnablePush: "ENABLE_PUSH", + SettingMaxConcurrentStreams: "MAX_CONCURRENT_STREAMS", + SettingInitialWindowSize: "INITIAL_WINDOW_SIZE", + SettingMaxFrameSize: "MAX_FRAME_SIZE", + SettingMaxHeaderListSize: "MAX_HEADER_LIST_SIZE", +} + +func (s SettingID) String() string { + if v, ok := settingName[s]; ok { + return v + } + return fmt.Sprintf("UNKNOWN_SETTING_%d", uint16(s)) +} + +var ( + errInvalidHeaderFieldName = errors.New("http2: invalid header field name") + errInvalidHeaderFieldValue = errors.New("http2: invalid header field value") +) + +// validHeaderFieldName reports whether v is a valid header field name (key). +// RFC 7230 says: +// header-field = field-name ":" OWS field-value OWS +// field-name = token +// tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / +// "^" / "_" / " +// Further, http2 says: +// "Just as in HTTP/1.x, header field names are strings of ASCII +// characters that are compared in a case-insensitive +// fashion. However, header field names MUST be converted to +// lowercase prior to their encoding in HTTP/2. " +func validHeaderFieldName(v string) bool { + if len(v) == 0 { + return false + } + for _, r := range v { + if int(r) >= len(isTokenTable) || ('A' <= r && r <= 'Z') { + return false + } + if !isTokenTable[byte(r)] { + return false + } + } + return true +} + +// validHeaderFieldValue reports whether v is a valid header field value. +// +// RFC 7230 says: +// field-value = *( field-content / obs-fold ) +// obj-fold = N/A to http2, and deprecated +// field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] +// field-vchar = VCHAR / obs-text +// obs-text = %x80-FF +// VCHAR = "any visible [USASCII] character" +// +// http2 further says: "Similarly, HTTP/2 allows header field values +// that are not valid. While most of the values that can be encoded +// will not alter header field parsing, carriage return (CR, ASCII +// 0xd), line feed (LF, ASCII 0xa), and the zero character (NUL, ASCII +// 0x0) might be exploited by an attacker if they are translated +// verbatim. Any request or response that contains a character not +// permitted in a header field value MUST be treated as malformed +// (Section 8.1.2.6). Valid characters are defined by the +// field-content ABNF rule in Section 3.2 of [RFC7230]." +// +// This function does not (yet?) properly handle the rejection of +// strings that begin or end with SP or HTAB. +func validHeaderFieldValue(v string) bool { + for i := 0; i < len(v); i++ { + if b := v[i]; b < ' ' && b != '\t' || b == 0x7f { + return false + } + } + return true +} + +var httpCodeStringCommon = map[int]string{} // n -> strconv.Itoa(n) + +func init() { + for i := 100; i <= 999; i++ { + if v := http.StatusText(i); v != "" { + httpCodeStringCommon[i] = strconv.Itoa(i) + } + } +} + +func httpCodeString(code int) string { + if s, ok := httpCodeStringCommon[code]; ok { + return s + } + return strconv.Itoa(code) +} + +// from pkg io +type stringWriter interface { + WriteString(s string) (n int, err error) +} + +// A gate lets two goroutines coordinate their activities. +type gate chan struct{} + +func (g gate) Done() { g <- struct{}{} } +func (g gate) Wait() { <-g } + +// A closeWaiter is like a sync.WaitGroup but only goes 1 to 0 (open to closed). +type closeWaiter chan struct{} + +// Init makes a closeWaiter usable. +// It exists because so a closeWaiter value can be placed inside a +// larger struct and have the Mutex and Cond's memory in the same +// allocation. +func (cw *closeWaiter) Init() { + *cw = make(chan struct{}) +} + +// Close marks the closeWaiter as closed and unblocks any waiters. +func (cw closeWaiter) Close() { + close(cw) +} + +// Wait waits for the closeWaiter to become closed. +func (cw closeWaiter) Wait() { + <-cw +} + +// bufferedWriter is a buffered writer that writes to w. +// Its buffered writer is lazily allocated as needed, to minimize +// idle memory usage with many connections. +type bufferedWriter struct { + w io.Writer // immutable + bw *bufio.Writer // non-nil when data is buffered +} + +func newBufferedWriter(w io.Writer) *bufferedWriter { + return &bufferedWriter{w: w} +} + +var bufWriterPool = sync.Pool{ + New: func() interface{} { + // TODO: pick something better? this is a bit under + // (3 x typical 1500 byte MTU) at least. + return bufio.NewWriterSize(nil, 4<<10) + }, +} + +func (w *bufferedWriter) Write(p []byte) (n int, err error) { + if w.bw == nil { + bw := bufWriterPool.Get().(*bufio.Writer) + bw.Reset(w.w) + w.bw = bw + } + return w.bw.Write(p) +} + +func (w *bufferedWriter) Flush() error { + bw := w.bw + if bw == nil { + return nil + } + err := bw.Flush() + bw.Reset(nil) + bufWriterPool.Put(bw) + w.bw = nil + return err +} + +func mustUint31(v int32) uint32 { + if v < 0 || v > 2147483647 { + panic("out of range") + } + return uint32(v) +} + +// bodyAllowedForStatus reports whether a given response status code +// permits a body. See RFC2616, section 4.4. +func bodyAllowedForStatus(status int) bool { + switch { + case status >= 100 && status <= 199: + return false + case status == 204: + return false + case status == 304: + return false + } + return true +} + +type httpError struct { + msg string + timeout bool +} + +func (e *httpError) Error() string { return e.msg } +func (e *httpError) Timeout() bool { return e.timeout } +func (e *httpError) Temporary() bool { return true } + +var errTimeout error = &httpError{msg: "http2: timeout awaiting response headers", timeout: true} + +var isTokenTable = [127]bool{ + '!': true, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '*': true, + '+': true, + '-': true, + '.': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'W': true, + 'V': true, + 'X': true, + 'Y': true, + 'Z': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '|': true, + '~': true, +} + +type connectionStater interface { + ConnectionState() tls.ConnectionState +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/http2_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/http2_test.go new file mode 100644 index 00000000..0a4da46a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/http2_test.go @@ -0,0 +1,174 @@ +// 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. + +package http2 + +import ( + "bytes" + "errors" + "flag" + "fmt" + "net/http" + "os/exec" + "strconv" + "strings" + "testing" + + "golang.org/x/net/http2/hpack" +) + +var knownFailing = flag.Bool("known_failing", false, "Run known-failing tests.") + +func condSkipFailingTest(t *testing.T) { + if !*knownFailing { + t.Skip("Skipping known-failing test without --known_failing") + } +} + +func init() { + DebugGoroutines = true + flag.BoolVar(&VerboseLogs, "verboseh2", false, "Verbose HTTP/2 debug logging") +} + +func TestSettingString(t *testing.T) { + tests := []struct { + s Setting + want string + }{ + {Setting{SettingMaxFrameSize, 123}, "[MAX_FRAME_SIZE = 123]"}, + {Setting{1<<16 - 1, 123}, "[UNKNOWN_SETTING_65535 = 123]"}, + } + for i, tt := range tests { + got := fmt.Sprint(tt.s) + if got != tt.want { + t.Errorf("%d. for %#v, string = %q; want %q", i, tt.s, got, tt.want) + } + } +} + +type twriter struct { + t testing.TB + st *serverTester // optional +} + +func (w twriter) Write(p []byte) (n int, err error) { + if w.st != nil { + ps := string(p) + for _, phrase := range w.st.logFilter { + if strings.Contains(ps, phrase) { + return len(p), nil // no logging + } + } + } + w.t.Logf("%s", p) + return len(p), nil +} + +// like encodeHeader, but don't add implicit psuedo headers. +func encodeHeaderNoImplicit(t *testing.T, headers ...string) []byte { + var buf bytes.Buffer + enc := hpack.NewEncoder(&buf) + for len(headers) > 0 { + k, v := headers[0], headers[1] + headers = headers[2:] + if err := enc.WriteField(hpack.HeaderField{Name: k, Value: v}); err != nil { + t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err) + } + } + return buf.Bytes() +} + +// Verify that curl has http2. +func requireCurl(t *testing.T) { + out, err := dockerLogs(curl(t, "--version")) + if err != nil { + t.Skipf("failed to determine curl features; skipping test") + } + if !strings.Contains(string(out), "HTTP2") { + t.Skip("curl doesn't support HTTP2; skipping test") + } +} + +func curl(t *testing.T, args ...string) (container string) { + out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "gohttp2/curl"}, args...)...).Output() + if err != nil { + t.Skipf("Failed to run curl in docker: %v, %s", err, out) + } + return strings.TrimSpace(string(out)) +} + +// Verify that h2load exists. +func requireH2load(t *testing.T) { + out, err := dockerLogs(h2load(t, "--version")) + if err != nil { + t.Skipf("failed to probe h2load; skipping test: %s", out) + } + if !strings.Contains(string(out), "h2load nghttp2/") { + t.Skipf("h2load not present; skipping test. (Output=%q)", out) + } +} + +func h2load(t *testing.T, args ...string) (container string) { + out, err := exec.Command("docker", append([]string{"run", "-d", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl"}, args...)...).Output() + if err != nil { + t.Skipf("Failed to run h2load in docker: %v, %s", err, out) + } + return strings.TrimSpace(string(out)) +} + +type puppetCommand struct { + fn func(w http.ResponseWriter, r *http.Request) + done chan<- bool +} + +type handlerPuppet struct { + ch chan puppetCommand +} + +func newHandlerPuppet() *handlerPuppet { + return &handlerPuppet{ + ch: make(chan puppetCommand), + } +} + +func (p *handlerPuppet) act(w http.ResponseWriter, r *http.Request) { + for cmd := range p.ch { + cmd.fn(w, r) + cmd.done <- true + } +} + +func (p *handlerPuppet) done() { close(p.ch) } +func (p *handlerPuppet) do(fn func(http.ResponseWriter, *http.Request)) { + done := make(chan bool) + p.ch <- puppetCommand{fn, done} + <-done +} +func dockerLogs(container string) ([]byte, error) { + out, err := exec.Command("docker", "wait", container).CombinedOutput() + if err != nil { + return out, err + } + exitStatus, err := strconv.Atoi(strings.TrimSpace(string(out))) + if err != nil { + return out, errors.New("unexpected exit status from docker wait") + } + out, err = exec.Command("docker", "logs", container).CombinedOutput() + exec.Command("docker", "rm", container).Run() + if err == nil && exitStatus != 0 { + err = fmt.Errorf("exit status %d: %s", exitStatus, out) + } + return out, err +} + +func kill(container string) { + exec.Command("docker", "kill", container).Run() + exec.Command("docker", "rm", container).Run() +} + +func cleanDate(res *http.Response) { + if d := res.Header["Date"]; len(d) == 1 { + d[0] = "XXX" + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/not_go15.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/not_go15.go new file mode 100644 index 00000000..d0fa5c89 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/not_go15.go @@ -0,0 +1,11 @@ +// 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 !go1.5 + +package http2 + +import "net/http" + +func requestCancel(req *http.Request) <-chan struct{} { return nil } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/not_go16.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/not_go16.go new file mode 100644 index 00000000..db53c5b8 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/not_go16.go @@ -0,0 +1,13 @@ +// 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 !go1.6 + +package http2 + +import "net/http" + +func configureTransport(t1 *http.Transport) (*Transport, error) { + return nil, errTransportVersion +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/pipe.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/pipe.go new file mode 100644 index 00000000..69446e7a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/pipe.go @@ -0,0 +1,147 @@ +// 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. + +package http2 + +import ( + "errors" + "io" + "sync" +) + +// pipe is a goroutine-safe io.Reader/io.Writer pair. It's like +// io.Pipe except there are no PipeReader/PipeWriter halves, and the +// underlying buffer is an interface. (io.Pipe is always unbuffered) +type pipe struct { + mu sync.Mutex + c sync.Cond // c.L lazily initialized to &p.mu + b pipeBuffer + err error // read error once empty. non-nil means closed. + breakErr error // immediate read error (caller doesn't see rest of b) + donec chan struct{} // closed on error + readFn func() // optional code to run in Read before error +} + +type pipeBuffer interface { + Len() int + io.Writer + io.Reader +} + +// Read waits until data is available and copies bytes +// from the buffer into p. +func (p *pipe) Read(d []byte) (n int, err error) { + p.mu.Lock() + defer p.mu.Unlock() + if p.c.L == nil { + p.c.L = &p.mu + } + for { + if p.breakErr != nil { + return 0, p.breakErr + } + if p.b.Len() > 0 { + return p.b.Read(d) + } + if p.err != nil { + if p.readFn != nil { + p.readFn() // e.g. copy trailers + p.readFn = nil // not sticky like p.err + } + return 0, p.err + } + p.c.Wait() + } +} + +var errClosedPipeWrite = errors.New("write on closed buffer") + +// Write copies bytes from p into the buffer and wakes a reader. +// It is an error to write more data than the buffer can hold. +func (p *pipe) Write(d []byte) (n int, err error) { + p.mu.Lock() + defer p.mu.Unlock() + if p.c.L == nil { + p.c.L = &p.mu + } + defer p.c.Signal() + if p.err != nil { + return 0, errClosedPipeWrite + } + return p.b.Write(d) +} + +// CloseWithError causes the next Read (waking up a current blocked +// Read if needed) to return the provided err after all data has been +// read. +// +// The error must be non-nil. +func (p *pipe) CloseWithError(err error) { p.closeWithError(&p.err, err, nil) } + +// BreakWithError causes the next Read (waking up a current blocked +// Read if needed) to return the provided err immediately, without +// waiting for unread data. +func (p *pipe) BreakWithError(err error) { p.closeWithError(&p.breakErr, err, nil) } + +// closeWithErrorAndCode is like CloseWithError but also sets some code to run +// in the caller's goroutine before returning the error. +func (p *pipe) closeWithErrorAndCode(err error, fn func()) { p.closeWithError(&p.err, err, fn) } + +func (p *pipe) closeWithError(dst *error, err error, fn func()) { + if err == nil { + panic("err must be non-nil") + } + p.mu.Lock() + defer p.mu.Unlock() + if p.c.L == nil { + p.c.L = &p.mu + } + defer p.c.Signal() + if *dst != nil { + // Already been done. + return + } + p.readFn = fn + *dst = err + p.closeDoneLocked() +} + +// requires p.mu be held. +func (p *pipe) closeDoneLocked() { + if p.donec == nil { + return + } + // Close if unclosed. This isn't racy since we always + // hold p.mu while closing. + select { + case <-p.donec: + default: + close(p.donec) + } +} + +// Err returns the error (if any) first set by BreakWithError or CloseWithError. +func (p *pipe) Err() error { + p.mu.Lock() + defer p.mu.Unlock() + if p.breakErr != nil { + return p.breakErr + } + return p.err +} + +// Done returns a channel which is closed if and when this pipe is closed +// with CloseWithError. +func (p *pipe) Done() <-chan struct{} { + p.mu.Lock() + defer p.mu.Unlock() + if p.donec == nil { + p.donec = make(chan struct{}) + if p.err != nil || p.breakErr != nil { + // Already hit an error. + p.closeDoneLocked() + } + } + return p.donec +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/pipe_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/pipe_test.go new file mode 100644 index 00000000..76322999 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/pipe_test.go @@ -0,0 +1,109 @@ +// 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. + +package http2 + +import ( + "bytes" + "errors" + "io" + "io/ioutil" + "testing" +) + +func TestPipeClose(t *testing.T) { + var p pipe + p.b = new(bytes.Buffer) + a := errors.New("a") + b := errors.New("b") + p.CloseWithError(a) + p.CloseWithError(b) + _, err := p.Read(make([]byte, 1)) + if err != a { + t.Errorf("err = %v want %v", err, a) + } +} + +func TestPipeDoneChan(t *testing.T) { + var p pipe + done := p.Done() + select { + case <-done: + t.Fatal("done too soon") + default: + } + p.CloseWithError(io.EOF) + select { + case <-done: + default: + t.Fatal("should be done") + } +} + +func TestPipeDoneChan_ErrFirst(t *testing.T) { + var p pipe + p.CloseWithError(io.EOF) + done := p.Done() + select { + case <-done: + default: + t.Fatal("should be done") + } +} + +func TestPipeDoneChan_Break(t *testing.T) { + var p pipe + done := p.Done() + select { + case <-done: + t.Fatal("done too soon") + default: + } + p.BreakWithError(io.EOF) + select { + case <-done: + default: + t.Fatal("should be done") + } +} + +func TestPipeDoneChan_Break_ErrFirst(t *testing.T) { + var p pipe + p.BreakWithError(io.EOF) + done := p.Done() + select { + case <-done: + default: + t.Fatal("should be done") + } +} + +func TestPipeCloseWithError(t *testing.T) { + p := &pipe{b: new(bytes.Buffer)} + const body = "foo" + io.WriteString(p, body) + a := errors.New("test error") + p.CloseWithError(a) + all, err := ioutil.ReadAll(p) + if string(all) != body { + t.Errorf("read bytes = %q; want %q", all, body) + } + if err != a { + t.Logf("read error = %v, %v", err, a) + } +} + +func TestPipeBreakWithError(t *testing.T) { + p := &pipe{b: new(bytes.Buffer)} + io.WriteString(p, "foo") + a := errors.New("test err") + p.BreakWithError(a) + all, err := ioutil.ReadAll(p) + if string(all) != "" { + t.Errorf("read bytes = %q; want empty string", all) + } + if err != a { + t.Logf("read error = %v, %v", err, a) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/priority_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/priority_test.go new file mode 100644 index 00000000..a3fe2bb4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/priority_test.go @@ -0,0 +1,118 @@ +// 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. + +package http2 + +import ( + "testing" +) + +func TestPriority(t *testing.T) { + // A -> B + // move A's parent to B + streams := make(map[uint32]*stream) + a := &stream{ + parent: nil, + weight: 16, + } + streams[1] = a + b := &stream{ + parent: a, + weight: 16, + } + streams[2] = b + adjustStreamPriority(streams, 1, PriorityParam{ + Weight: 20, + StreamDep: 2, + }) + if a.parent != b { + t.Errorf("Expected A's parent to be B") + } + if a.weight != 20 { + t.Errorf("Expected A's weight to be 20; got %d", a.weight) + } + if b.parent != nil { + t.Errorf("Expected B to have no parent") + } + if b.weight != 16 { + t.Errorf("Expected B's weight to be 16; got %d", b.weight) + } +} + +func TestPriorityExclusiveZero(t *testing.T) { + // A B and C are all children of the 0 stream. + // Exclusive reprioritization to any of the streams + // should bring the rest of the streams under the + // reprioritized stream + streams := make(map[uint32]*stream) + a := &stream{ + parent: nil, + weight: 16, + } + streams[1] = a + b := &stream{ + parent: nil, + weight: 16, + } + streams[2] = b + c := &stream{ + parent: nil, + weight: 16, + } + streams[3] = c + adjustStreamPriority(streams, 3, PriorityParam{ + Weight: 20, + StreamDep: 0, + Exclusive: true, + }) + if a.parent != c { + t.Errorf("Expected A's parent to be C") + } + if a.weight != 16 { + t.Errorf("Expected A's weight to be 16; got %d", a.weight) + } + if b.parent != c { + t.Errorf("Expected B's parent to be C") + } + if b.weight != 16 { + t.Errorf("Expected B's weight to be 16; got %d", b.weight) + } + if c.parent != nil { + t.Errorf("Expected C to have no parent") + } + if c.weight != 20 { + t.Errorf("Expected C's weight to be 20; got %d", b.weight) + } +} + +func TestPriorityOwnParent(t *testing.T) { + streams := make(map[uint32]*stream) + a := &stream{ + parent: nil, + weight: 16, + } + streams[1] = a + b := &stream{ + parent: a, + weight: 16, + } + streams[2] = b + adjustStreamPriority(streams, 1, PriorityParam{ + Weight: 20, + StreamDep: 1, + }) + if a.parent != nil { + t.Errorf("Expected A's parent to be nil") + } + if a.weight != 20 { + t.Errorf("Expected A's weight to be 20; got %d", a.weight) + } + if b.parent != a { + t.Errorf("Expected B's parent to be A") + } + if b.weight != 16 { + t.Errorf("Expected B's weight to be 16; got %d", b.weight) + } + +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/server.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/server.go new file mode 100644 index 00000000..6f4c2bb7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/server.go @@ -0,0 +1,2308 @@ +// 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. + +// TODO: replace all <-sc.doneServing with reads from the stream's cw +// instead, and make sure that on close we close all open +// streams. then remove doneServing? + +// TODO: re-audit GOAWAY support. Consider each incoming frame type and +// whether it should be ignored during graceful shutdown. + +// TODO: disconnect idle clients. GFE seems to do 4 minutes. make +// configurable? or maximum number of idle clients and remove the +// oldest? + +// TODO: turn off the serve goroutine when idle, so +// an idle conn only has the readFrames goroutine active. (which could +// also be optimized probably to pin less memory in crypto/tls). This +// would involve tracking when the serve goroutine is active (atomic +// int32 read/CAS probably?) and starting it up when frames arrive, +// and shutting it down when all handlers exit. the occasional PING +// packets could use time.AfterFunc to call sc.wakeStartServeLoop() +// (which is a no-op if already running) and then queue the PING write +// as normal. The serve loop would then exit in most cases (if no +// Handlers running) and not be woken up again until the PING packet +// returns. + +// TODO (maybe): add a mechanism for Handlers to going into +// half-closed-local mode (rw.(io.Closer) test?) but not exit their +// handler, and continue to be able to read from the +// Request.Body. This would be a somewhat semantic change from HTTP/1 +// (or at least what we expose in net/http), so I'd probably want to +// add it there too. For now, this package says that returning from +// the Handler ServeHTTP function means you're both done reading and +// done writing, without a way to stop just one or the other. + +package http2 + +import ( + "bufio" + "bytes" + "crypto/tls" + "errors" + "fmt" + "io" + "log" + "net" + "net/http" + "net/textproto" + "net/url" + "os" + "reflect" + "runtime" + "sort" + "strconv" + "strings" + "sync" + "time" + + "golang.org/x/net/http2/hpack" +) + +const ( + prefaceTimeout = 10 * time.Second + firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway + handlerChunkWriteSize = 4 << 10 + defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to? +) + +var ( + errClientDisconnected = errors.New("client disconnected") + errClosedBody = errors.New("body closed by handler") + errHandlerComplete = errors.New("http2: request body closed due to handler exiting") + errStreamClosed = errors.New("http2: stream closed") +) + +var responseWriterStatePool = sync.Pool{ + New: func() interface{} { + rws := &responseWriterState{} + rws.bw = bufio.NewWriterSize(chunkWriter{rws}, handlerChunkWriteSize) + return rws + }, +} + +// Test hooks. +var ( + testHookOnConn func() + testHookGetServerConn func(*serverConn) + testHookOnPanicMu *sync.Mutex // nil except in tests + testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool) +) + +// Server is an HTTP/2 server. +type Server struct { + // MaxHandlers limits the number of http.Handler ServeHTTP goroutines + // which may run at a time over all connections. + // Negative or zero no limit. + // TODO: implement + MaxHandlers int + + // MaxConcurrentStreams optionally specifies the number of + // concurrent streams that each client may have open at a + // time. This is unrelated to the number of http.Handler goroutines + // which may be active globally, which is MaxHandlers. + // If zero, MaxConcurrentStreams defaults to at least 100, per + // the HTTP/2 spec's recommendations. + MaxConcurrentStreams uint32 + + // MaxReadFrameSize optionally specifies the largest frame + // this server is willing to read. A valid value is between + // 16k and 16M, inclusive. If zero or otherwise invalid, a + // default value is used. + MaxReadFrameSize uint32 + + // PermitProhibitedCipherSuites, if true, permits the use of + // cipher suites prohibited by the HTTP/2 spec. + PermitProhibitedCipherSuites bool +} + +func (s *Server) maxReadFrameSize() uint32 { + if v := s.MaxReadFrameSize; v >= minMaxFrameSize && v <= maxFrameSize { + return v + } + return defaultMaxReadFrameSize +} + +func (s *Server) maxConcurrentStreams() uint32 { + if v := s.MaxConcurrentStreams; v > 0 { + return v + } + return defaultMaxStreams +} + +// ConfigureServer adds HTTP/2 support to a net/http Server. +// +// The configuration conf may be nil. +// +// ConfigureServer must be called before s begins serving. +func ConfigureServer(s *http.Server, conf *Server) error { + if conf == nil { + conf = new(Server) + } + + if s.TLSConfig == nil { + s.TLSConfig = new(tls.Config) + } else if s.TLSConfig.CipherSuites != nil { + // If they already provided a CipherSuite list, return + // an error if it has a bad order or is missing + // ECDHE_RSA_WITH_AES_128_GCM_SHA256. + const requiredCipher = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + haveRequired := false + sawBad := false + for i, cs := range s.TLSConfig.CipherSuites { + if cs == requiredCipher { + haveRequired = true + } + if isBadCipher(cs) { + sawBad = true + } else if sawBad { + return fmt.Errorf("http2: TLSConfig.CipherSuites index %d contains an HTTP/2-approved cipher suite (%#04x), but it comes after unapproved cipher suites. With this configuration, clients that don't support previous, approved cipher suites may be given an unapproved one and reject the connection.", i, cs) + } + } + if !haveRequired { + return fmt.Errorf("http2: TLSConfig.CipherSuites is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256") + } + } + + // Note: not setting MinVersion to tls.VersionTLS12, + // as we don't want to interfere with HTTP/1.1 traffic + // on the user's server. We enforce TLS 1.2 later once + // we accept a connection. Ideally this should be done + // during next-proto selection, but using TLS <1.2 with + // HTTP/2 is still the client's bug. + + s.TLSConfig.PreferServerCipherSuites = true + + haveNPN := false + for _, p := range s.TLSConfig.NextProtos { + if p == NextProtoTLS { + haveNPN = true + break + } + } + if !haveNPN { + s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, NextProtoTLS) + } + // h2-14 is temporary (as of 2015-03-05) while we wait for all browsers + // to switch to "h2". + s.TLSConfig.NextProtos = append(s.TLSConfig.NextProtos, "h2-14") + + if s.TLSNextProto == nil { + s.TLSNextProto = map[string]func(*http.Server, *tls.Conn, http.Handler){} + } + protoHandler := func(hs *http.Server, c *tls.Conn, h http.Handler) { + if testHookOnConn != nil { + testHookOnConn() + } + conf.ServeConn(c, &ServeConnOpts{ + Handler: h, + BaseConfig: hs, + }) + } + s.TLSNextProto[NextProtoTLS] = protoHandler + s.TLSNextProto["h2-14"] = protoHandler // temporary; see above. + return nil +} + +// ServeConnOpts are options for the Server.ServeConn method. +type ServeConnOpts struct { + // BaseConfig optionally sets the base configuration + // for values. If nil, defaults are used. + BaseConfig *http.Server + + // Handler specifies which handler to use for processing + // requests. If nil, BaseConfig.Handler is used. If BaseConfig + // or BaseConfig.Handler is nil, http.DefaultServeMux is used. + Handler http.Handler +} + +func (o *ServeConnOpts) baseConfig() *http.Server { + if o != nil && o.BaseConfig != nil { + return o.BaseConfig + } + return new(http.Server) +} + +func (o *ServeConnOpts) handler() http.Handler { + if o != nil { + if o.Handler != nil { + return o.Handler + } + if o.BaseConfig != nil && o.BaseConfig.Handler != nil { + return o.BaseConfig.Handler + } + } + return http.DefaultServeMux +} + +// ServeConn serves HTTP/2 requests on the provided connection and +// blocks until the connection is no longer readable. +// +// ServeConn starts speaking HTTP/2 assuming that c has not had any +// reads or writes. It writes its initial settings frame and expects +// to be able to read the preface and settings frame from the +// client. If c has a ConnectionState method like a *tls.Conn, the +// ConnectionState is used to verify the TLS ciphersuite and to set +// the Request.TLS field in Handlers. +// +// ServeConn does not support h2c by itself. Any h2c support must be +// implemented in terms of providing a suitably-behaving net.Conn. +// +// The opts parameter is optional. If nil, default values are used. +func (s *Server) ServeConn(c net.Conn, opts *ServeConnOpts) { + sc := &serverConn{ + srv: s, + hs: opts.baseConfig(), + conn: c, + remoteAddrStr: c.RemoteAddr().String(), + bw: newBufferedWriter(c), + handler: opts.handler(), + streams: make(map[uint32]*stream), + readFrameCh: make(chan readFrameResult), + wantWriteFrameCh: make(chan frameWriteMsg, 8), + wroteFrameCh: make(chan frameWriteResult, 1), // buffered; one send in writeFrameAsync + bodyReadCh: make(chan bodyReadMsg), // buffering doesn't matter either way + doneServing: make(chan struct{}), + advMaxStreams: s.maxConcurrentStreams(), + writeSched: writeScheduler{ + maxFrameSize: initialMaxFrameSize, + }, + initialWindowSize: initialWindowSize, + headerTableSize: initialHeaderTableSize, + serveG: newGoroutineLock(), + pushEnabled: true, + } + sc.flow.add(initialWindowSize) + sc.inflow.add(initialWindowSize) + sc.hpackEncoder = hpack.NewEncoder(&sc.headerWriteBuf) + sc.hpackDecoder = hpack.NewDecoder(initialHeaderTableSize, nil) + sc.hpackDecoder.SetMaxStringLength(sc.maxHeaderStringLen()) + + fr := NewFramer(sc.bw, c) + fr.SetMaxReadFrameSize(s.maxReadFrameSize()) + sc.framer = fr + + if tc, ok := c.(connectionStater); ok { + sc.tlsState = new(tls.ConnectionState) + *sc.tlsState = tc.ConnectionState() + // 9.2 Use of TLS Features + // An implementation of HTTP/2 over TLS MUST use TLS + // 1.2 or higher with the restrictions on feature set + // and cipher suite described in this section. Due to + // implementation limitations, it might not be + // possible to fail TLS negotiation. An endpoint MUST + // immediately terminate an HTTP/2 connection that + // does not meet the TLS requirements described in + // this section with a connection error (Section + // 5.4.1) of type INADEQUATE_SECURITY. + if sc.tlsState.Version < tls.VersionTLS12 { + sc.rejectConn(ErrCodeInadequateSecurity, "TLS version too low") + return + } + + if sc.tlsState.ServerName == "" { + // Client must use SNI, but we don't enforce that anymore, + // since it was causing problems when connecting to bare IP + // addresses during development. + // + // TODO: optionally enforce? Or enforce at the time we receive + // a new request, and verify the the ServerName matches the :authority? + // But that precludes proxy situations, perhaps. + // + // So for now, do nothing here again. + } + + if !s.PermitProhibitedCipherSuites && isBadCipher(sc.tlsState.CipherSuite) { + // "Endpoints MAY choose to generate a connection error + // (Section 5.4.1) of type INADEQUATE_SECURITY if one of + // the prohibited cipher suites are negotiated." + // + // We choose that. In my opinion, the spec is weak + // here. It also says both parties must support at least + // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 so there's no + // excuses here. If we really must, we could allow an + // "AllowInsecureWeakCiphers" option on the server later. + // Let's see how it plays out first. + sc.rejectConn(ErrCodeInadequateSecurity, fmt.Sprintf("Prohibited TLS 1.2 Cipher Suite: %x", sc.tlsState.CipherSuite)) + return + } + } + + if hook := testHookGetServerConn; hook != nil { + hook(sc) + } + sc.serve() +} + +// isBadCipher reports whether the cipher is blacklisted by the HTTP/2 spec. +func isBadCipher(cipher uint16) bool { + switch cipher { + case tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA, + tls.TLS_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + // Reject cipher suites from Appendix A. + // "This list includes those cipher suites that do not + // offer an ephemeral key exchange and those that are + // based on the TLS null, stream or block cipher type" + return true + default: + return false + } +} + +func (sc *serverConn) rejectConn(err ErrCode, debug string) { + sc.vlogf("http2: server rejecting conn: %v, %s", err, debug) + // ignoring errors. hanging up anyway. + sc.framer.WriteGoAway(0, err, []byte(debug)) + sc.bw.Flush() + sc.conn.Close() +} + +type serverConn struct { + // Immutable: + srv *Server + hs *http.Server + conn net.Conn + bw *bufferedWriter // writing to conn + handler http.Handler + framer *Framer + hpackDecoder *hpack.Decoder + doneServing chan struct{} // closed when serverConn.serve ends + readFrameCh chan readFrameResult // written by serverConn.readFrames + wantWriteFrameCh chan frameWriteMsg // from handlers -> serve + wroteFrameCh chan frameWriteResult // from writeFrameAsync -> serve, tickles more frame writes + bodyReadCh chan bodyReadMsg // from handlers -> serve + testHookCh chan func(int) // code to run on the serve loop + flow flow // conn-wide (not stream-specific) outbound flow control + inflow flow // conn-wide inbound flow control + tlsState *tls.ConnectionState // shared by all handlers, like net/http + remoteAddrStr string + + // Everything following is owned by the serve loop; use serveG.check(): + serveG goroutineLock // used to verify funcs are on serve() + pushEnabled bool + sawFirstSettings bool // got the initial SETTINGS frame after the preface + needToSendSettingsAck bool + unackedSettings int // how many SETTINGS have we sent without ACKs? + clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) + advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client + curOpenStreams uint32 // client's number of open streams + maxStreamID uint32 // max ever seen + streams map[uint32]*stream + initialWindowSize int32 + headerTableSize uint32 + peerMaxHeaderListSize uint32 // zero means unknown (default) + canonHeader map[string]string // http2-lower-case -> Go-Canonical-Case + req requestParam // non-zero while reading request headers + writingFrame bool // started write goroutine but haven't heard back on wroteFrameCh + needsFrameFlush bool // last frame write wasn't a flush + writeSched writeScheduler + inGoAway bool // we've started to or sent GOAWAY + needToSendGoAway bool // we need to schedule a GOAWAY frame write + goAwayCode ErrCode + shutdownTimerCh <-chan time.Time // nil until used + shutdownTimer *time.Timer // nil until used + + // Owned by the writeFrameAsync goroutine: + headerWriteBuf bytes.Buffer + hpackEncoder *hpack.Encoder +} + +func (sc *serverConn) maxHeaderStringLen() int { + v := sc.maxHeaderListSize() + if uint32(int(v)) == v { + return int(v) + } + // They had a crazy big number for MaxHeaderBytes anyway, + // so give them unlimited header lengths: + return 0 +} + +func (sc *serverConn) maxHeaderListSize() uint32 { + n := sc.hs.MaxHeaderBytes + if n <= 0 { + n = http.DefaultMaxHeaderBytes + } + // http2's count is in a slightly different unit and includes 32 bytes per pair. + // So, take the net/http.Server value and pad it up a bit, assuming 10 headers. + const perFieldOverhead = 32 // per http2 spec + const typicalHeaders = 10 // conservative + return uint32(n + typicalHeaders*perFieldOverhead) +} + +// requestParam is the state of the next request, initialized over +// potentially several frames HEADERS + zero or more CONTINUATION +// frames. +type requestParam struct { + // stream is non-nil if we're reading (HEADER or CONTINUATION) + // frames for a request (but not DATA). + stream *stream + header http.Header + method, path string + scheme, authority string + sawRegularHeader bool // saw a non-pseudo header already + invalidHeader bool // an invalid header was seen + headerListSize int64 // actually uint32, but easier math this way +} + +// stream represents a stream. This is the minimal metadata needed by +// the serve goroutine. Most of the actual stream state is owned by +// the http.Handler's goroutine in the responseWriter. Because the +// responseWriter's responseWriterState is recycled at the end of a +// handler, this struct intentionally has no pointer to the +// *responseWriter{,State} itself, as the Handler ending nils out the +// responseWriter's state field. +type stream struct { + // immutable: + sc *serverConn + id uint32 + body *pipe // non-nil if expecting DATA frames + cw closeWaiter // closed wait stream transitions to closed state + + // owned by serverConn's serve loop: + bodyBytes int64 // body bytes seen so far + declBodyBytes int64 // or -1 if undeclared + flow flow // limits writing from Handler to client + inflow flow // what the client is allowed to POST/etc to us + parent *stream // or nil + numTrailerValues int64 + weight uint8 + state streamState + sentReset bool // only true once detached from streams map + gotReset bool // only true once detacted from streams map + gotTrailerHeader bool // HEADER frame for trailers was seen + + trailer http.Header // accumulated trailers + reqTrailer http.Header // handler's Request.Trailer +} + +func (sc *serverConn) Framer() *Framer { return sc.framer } +func (sc *serverConn) CloseConn() error { return sc.conn.Close() } +func (sc *serverConn) Flush() error { return sc.bw.Flush() } +func (sc *serverConn) HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) { + return sc.hpackEncoder, &sc.headerWriteBuf +} + +func (sc *serverConn) state(streamID uint32) (streamState, *stream) { + sc.serveG.check() + // http://http2.github.io/http2-spec/#rfc.section.5.1 + if st, ok := sc.streams[streamID]; ok { + return st.state, st + } + // "The first use of a new stream identifier implicitly closes all + // streams in the "idle" state that might have been initiated by + // that peer with a lower-valued stream identifier. For example, if + // a client sends a HEADERS frame on stream 7 without ever sending a + // frame on stream 5, then stream 5 transitions to the "closed" + // state when the first frame for stream 7 is sent or received." + if streamID <= sc.maxStreamID { + return stateClosed, nil + } + return stateIdle, nil +} + +// setConnState calls the net/http ConnState hook for this connection, if configured. +// Note that the net/http package does StateNew and StateClosed for us. +// There is currently no plan for StateHijacked or hijacking HTTP/2 connections. +func (sc *serverConn) setConnState(state http.ConnState) { + if sc.hs.ConnState != nil { + sc.hs.ConnState(sc.conn, state) + } +} + +func (sc *serverConn) vlogf(format string, args ...interface{}) { + if VerboseLogs { + sc.logf(format, args...) + } +} + +func (sc *serverConn) logf(format string, args ...interface{}) { + if lg := sc.hs.ErrorLog; lg != nil { + lg.Printf(format, args...) + } else { + log.Printf(format, args...) + } +} + +// errno returns v's underlying uintptr, else 0. +// +// TODO: remove this helper function once http2 can use build +// tags. See comment in isClosedConnError. +func errno(v error) uintptr { + if rv := reflect.ValueOf(v); rv.Kind() == reflect.Uintptr { + return uintptr(rv.Uint()) + } + return 0 +} + +// isClosedConnError reports whether err is an error from use of a closed +// network connection. +func isClosedConnError(err error) bool { + if err == nil { + return false + } + + // TODO: remove this string search and be more like the Windows + // case below. That might involve modifying the standard library + // to return better error types. + str := err.Error() + if strings.Contains(str, "use of closed network connection") { + return true + } + + // TODO(bradfitz): x/tools/cmd/bundle doesn't really support + // build tags, so I can't make an http2_windows.go file with + // Windows-specific stuff. Fix that and move this, once we + // have a way to bundle this into std's net/http somehow. + if runtime.GOOS == "windows" { + if oe, ok := err.(*net.OpError); ok && oe.Op == "read" { + if se, ok := oe.Err.(*os.SyscallError); ok && se.Syscall == "wsarecv" { + const WSAECONNABORTED = 10053 + const WSAECONNRESET = 10054 + if n := errno(se.Err); n == WSAECONNRESET || n == WSAECONNABORTED { + return true + } + } + } + } + return false +} + +func (sc *serverConn) condlogf(err error, format string, args ...interface{}) { + if err == nil { + return + } + if err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) { + // Boring, expected errors. + sc.vlogf(format, args...) + } else { + sc.logf(format, args...) + } +} + +func (sc *serverConn) onNewHeaderField(f hpack.HeaderField) { + sc.serveG.check() + if VerboseLogs { + sc.vlogf("http2: server decoded %v", f) + } + switch { + case !validHeaderFieldValue(f.Value): // f.Name checked _after_ pseudo check, since ':' is invalid + sc.req.invalidHeader = true + case strings.HasPrefix(f.Name, ":"): + if sc.req.sawRegularHeader { + sc.logf("pseudo-header after regular header") + sc.req.invalidHeader = true + return + } + var dst *string + switch f.Name { + case ":method": + dst = &sc.req.method + case ":path": + dst = &sc.req.path + case ":scheme": + dst = &sc.req.scheme + case ":authority": + dst = &sc.req.authority + default: + // 8.1.2.1 Pseudo-Header Fields + // "Endpoints MUST treat a request or response + // that contains undefined or invalid + // pseudo-header fields as malformed (Section + // 8.1.2.6)." + sc.logf("invalid pseudo-header %q", f.Name) + sc.req.invalidHeader = true + return + } + if *dst != "" { + sc.logf("duplicate pseudo-header %q sent", f.Name) + sc.req.invalidHeader = true + return + } + *dst = f.Value + case !validHeaderFieldName(f.Name): + sc.req.invalidHeader = true + default: + sc.req.sawRegularHeader = true + sc.req.header.Add(sc.canonicalHeader(f.Name), f.Value) + const headerFieldOverhead = 32 // per spec + sc.req.headerListSize += int64(len(f.Name)) + int64(len(f.Value)) + headerFieldOverhead + if sc.req.headerListSize > int64(sc.maxHeaderListSize()) { + sc.hpackDecoder.SetEmitEnabled(false) + } + } +} + +func (st *stream) onNewTrailerField(f hpack.HeaderField) { + sc := st.sc + sc.serveG.check() + if VerboseLogs { + sc.vlogf("http2: server decoded trailer %v", f) + } + switch { + case strings.HasPrefix(f.Name, ":"): + sc.req.invalidHeader = true + return + case !validHeaderFieldName(f.Name) || !validHeaderFieldValue(f.Value): + sc.req.invalidHeader = true + return + default: + key := sc.canonicalHeader(f.Name) + if st.trailer != nil { + vv := append(st.trailer[key], f.Value) + st.trailer[key] = vv + + // arbitrary; TODO: read spec about header list size limits wrt trailers + const tooBig = 1000 + if len(vv) >= tooBig { + sc.hpackDecoder.SetEmitEnabled(false) + } + } + } +} + +func (sc *serverConn) canonicalHeader(v string) string { + sc.serveG.check() + cv, ok := commonCanonHeader[v] + if ok { + return cv + } + cv, ok = sc.canonHeader[v] + if ok { + return cv + } + if sc.canonHeader == nil { + sc.canonHeader = make(map[string]string) + } + cv = http.CanonicalHeaderKey(v) + sc.canonHeader[v] = cv + return cv +} + +type readFrameResult struct { + f Frame // valid until readMore is called + err error + + // readMore should be called once the consumer no longer needs or + // retains f. After readMore, f is invalid and more frames can be + // read. + readMore func() +} + +// readFrames is the loop that reads incoming frames. +// It takes care to only read one frame at a time, blocking until the +// consumer is done with the frame. +// It's run on its own goroutine. +func (sc *serverConn) readFrames() { + gate := make(gate) + for { + f, err := sc.framer.ReadFrame() + select { + case sc.readFrameCh <- readFrameResult{f, err, gate.Done}: + case <-sc.doneServing: + return + } + select { + case <-gate: + case <-sc.doneServing: + return + } + if terminalReadFrameError(err) { + return + } + } +} + +// frameWriteResult is the message passed from writeFrameAsync to the serve goroutine. +type frameWriteResult struct { + wm frameWriteMsg // what was written (or attempted) + err error // result of the writeFrame call +} + +// writeFrameAsync runs in its own goroutine and writes a single frame +// and then reports when it's done. +// At most one goroutine can be running writeFrameAsync at a time per +// serverConn. +func (sc *serverConn) writeFrameAsync(wm frameWriteMsg) { + err := wm.write.writeFrame(sc) + sc.wroteFrameCh <- frameWriteResult{wm, err} +} + +func (sc *serverConn) closeAllStreamsOnConnClose() { + sc.serveG.check() + for _, st := range sc.streams { + sc.closeStream(st, errClientDisconnected) + } +} + +func (sc *serverConn) stopShutdownTimer() { + sc.serveG.check() + if t := sc.shutdownTimer; t != nil { + t.Stop() + } +} + +func (sc *serverConn) notePanic() { + // Note: this is for serverConn.serve panicking, not http.Handler code. + if testHookOnPanicMu != nil { + testHookOnPanicMu.Lock() + defer testHookOnPanicMu.Unlock() + } + if testHookOnPanic != nil { + if e := recover(); e != nil { + if testHookOnPanic(sc, e) { + panic(e) + } + } + } +} + +func (sc *serverConn) serve() { + sc.serveG.check() + defer sc.notePanic() + defer sc.conn.Close() + defer sc.closeAllStreamsOnConnClose() + defer sc.stopShutdownTimer() + defer close(sc.doneServing) // unblocks handlers trying to send + + if VerboseLogs { + sc.vlogf("http2: server connection from %v on %p", sc.conn.RemoteAddr(), sc.hs) + } + + sc.writeFrame(frameWriteMsg{ + write: writeSettings{ + {SettingMaxFrameSize, sc.srv.maxReadFrameSize()}, + {SettingMaxConcurrentStreams, sc.advMaxStreams}, + {SettingMaxHeaderListSize, sc.maxHeaderListSize()}, + + // TODO: more actual settings, notably + // SettingInitialWindowSize, but then we also + // want to bump up the conn window size the + // same amount here right after the settings + }, + }) + sc.unackedSettings++ + + if err := sc.readPreface(); err != nil { + sc.condlogf(err, "http2: server: error reading preface from client %v: %v", sc.conn.RemoteAddr(), err) + return + } + // Now that we've got the preface, get us out of the + // "StateNew" state. We can't go directly to idle, though. + // Active means we read some data and anticipate a request. We'll + // do another Active when we get a HEADERS frame. + sc.setConnState(http.StateActive) + sc.setConnState(http.StateIdle) + + go sc.readFrames() // closed by defer sc.conn.Close above + + settingsTimer := time.NewTimer(firstSettingsTimeout) + loopNum := 0 + for { + loopNum++ + select { + case wm := <-sc.wantWriteFrameCh: + sc.writeFrame(wm) + case res := <-sc.wroteFrameCh: + sc.wroteFrame(res) + case res := <-sc.readFrameCh: + if !sc.processFrameFromReader(res) { + return + } + res.readMore() + if settingsTimer.C != nil { + settingsTimer.Stop() + settingsTimer.C = nil + } + case m := <-sc.bodyReadCh: + sc.noteBodyRead(m.st, m.n) + case <-settingsTimer.C: + sc.logf("timeout waiting for SETTINGS frames from %v", sc.conn.RemoteAddr()) + return + case <-sc.shutdownTimerCh: + sc.vlogf("GOAWAY close timer fired; closing conn from %v", sc.conn.RemoteAddr()) + return + case fn := <-sc.testHookCh: + fn(loopNum) + } + } +} + +// readPreface reads the ClientPreface greeting from the peer +// or returns an error on timeout or an invalid greeting. +func (sc *serverConn) readPreface() error { + errc := make(chan error, 1) + go func() { + // Read the client preface + buf := make([]byte, len(ClientPreface)) + if _, err := io.ReadFull(sc.conn, buf); err != nil { + errc <- err + } else if !bytes.Equal(buf, clientPreface) { + errc <- fmt.Errorf("bogus greeting %q", buf) + } else { + errc <- nil + } + }() + timer := time.NewTimer(prefaceTimeout) // TODO: configurable on *Server? + defer timer.Stop() + select { + case <-timer.C: + return errors.New("timeout waiting for client preface") + case err := <-errc: + if err == nil { + if VerboseLogs { + sc.vlogf("http2: server: client %v said hello", sc.conn.RemoteAddr()) + } + } + return err + } +} + +var errChanPool = sync.Pool{ + New: func() interface{} { return make(chan error, 1) }, +} + +var writeDataPool = sync.Pool{ + New: func() interface{} { return new(writeData) }, +} + +// writeDataFromHandler writes DATA response frames from a handler on +// the given stream. +func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error { + ch := errChanPool.Get().(chan error) + writeArg := writeDataPool.Get().(*writeData) + *writeArg = writeData{stream.id, data, endStream} + err := sc.writeFrameFromHandler(frameWriteMsg{ + write: writeArg, + stream: stream, + done: ch, + }) + if err != nil { + return err + } + var frameWriteDone bool // the frame write is done (successfully or not) + select { + case err = <-ch: + frameWriteDone = true + case <-sc.doneServing: + return errClientDisconnected + case <-stream.cw: + // If both ch and stream.cw were ready (as might + // happen on the final Write after an http.Handler + // ends), prefer the write result. Otherwise this + // might just be us successfully closing the stream. + // The writeFrameAsync and serve goroutines guarantee + // that the ch send will happen before the stream.cw + // close. + select { + case err = <-ch: + frameWriteDone = true + default: + return errStreamClosed + } + } + errChanPool.Put(ch) + if frameWriteDone { + writeDataPool.Put(writeArg) + } + return err +} + +// writeFrameFromHandler sends wm to sc.wantWriteFrameCh, but aborts +// if the connection has gone away. +// +// This must not be run from the serve goroutine itself, else it might +// deadlock writing to sc.wantWriteFrameCh (which is only mildly +// buffered and is read by serve itself). If you're on the serve +// goroutine, call writeFrame instead. +func (sc *serverConn) writeFrameFromHandler(wm frameWriteMsg) error { + sc.serveG.checkNotOn() // NOT + select { + case sc.wantWriteFrameCh <- wm: + return nil + case <-sc.doneServing: + // Serve loop is gone. + // Client has closed their connection to the server. + return errClientDisconnected + } +} + +// writeFrame schedules a frame to write and sends it if there's nothing +// already being written. +// +// There is no pushback here (the serve goroutine never blocks). It's +// the http.Handlers that block, waiting for their previous frames to +// make it onto the wire +// +// If you're not on the serve goroutine, use writeFrameFromHandler instead. +func (sc *serverConn) writeFrame(wm frameWriteMsg) { + sc.serveG.check() + sc.writeSched.add(wm) + sc.scheduleFrameWrite() +} + +// startFrameWrite starts a goroutine to write wm (in a separate +// goroutine since that might block on the network), and updates the +// serve goroutine's state about the world, updated from info in wm. +func (sc *serverConn) startFrameWrite(wm frameWriteMsg) { + sc.serveG.check() + if sc.writingFrame { + panic("internal error: can only be writing one frame at a time") + } + + st := wm.stream + if st != nil { + switch st.state { + case stateHalfClosedLocal: + panic("internal error: attempt to send frame on half-closed-local stream") + case stateClosed: + if st.sentReset || st.gotReset { + // Skip this frame. + sc.scheduleFrameWrite() + return + } + panic(fmt.Sprintf("internal error: attempt to send a write %v on a closed stream", wm)) + } + } + + sc.writingFrame = true + sc.needsFrameFlush = true + go sc.writeFrameAsync(wm) +} + +// errHandlerPanicked is the error given to any callers blocked in a read from +// Request.Body when the main goroutine panics. Since most handlers read in the +// the main ServeHTTP goroutine, this will show up rarely. +var errHandlerPanicked = errors.New("http2: handler panicked") + +// wroteFrame is called on the serve goroutine with the result of +// whatever happened on writeFrameAsync. +func (sc *serverConn) wroteFrame(res frameWriteResult) { + sc.serveG.check() + if !sc.writingFrame { + panic("internal error: expected to be already writing a frame") + } + sc.writingFrame = false + + wm := res.wm + st := wm.stream + + closeStream := endsStream(wm.write) + + if _, ok := wm.write.(handlerPanicRST); ok { + sc.closeStream(st, errHandlerPanicked) + } + + // Reply (if requested) to the blocked ServeHTTP goroutine. + if ch := wm.done; ch != nil { + select { + case ch <- res.err: + default: + panic(fmt.Sprintf("unbuffered done channel passed in for type %T", wm.write)) + } + } + wm.write = nil // prevent use (assume it's tainted after wm.done send) + + if closeStream { + if st == nil { + panic("internal error: expecting non-nil stream") + } + switch st.state { + case stateOpen: + // Here we would go to stateHalfClosedLocal in + // theory, but since our handler is done and + // the net/http package provides no mechanism + // for finishing writing to a ResponseWriter + // while still reading data (see possible TODO + // at top of this file), we go into closed + // state here anyway, after telling the peer + // we're hanging up on them. + st.state = stateHalfClosedLocal // won't last long, but necessary for closeStream via resetStream + errCancel := StreamError{st.id, ErrCodeCancel} + sc.resetStream(errCancel) + case stateHalfClosedRemote: + sc.closeStream(st, errHandlerComplete) + } + } + + sc.scheduleFrameWrite() +} + +// scheduleFrameWrite tickles the frame writing scheduler. +// +// If a frame is already being written, nothing happens. This will be called again +// when the frame is done being written. +// +// If a frame isn't being written we need to send one, the best frame +// to send is selected, preferring first things that aren't +// stream-specific (e.g. ACKing settings), and then finding the +// highest priority stream. +// +// If a frame isn't being written and there's nothing else to send, we +// flush the write buffer. +func (sc *serverConn) scheduleFrameWrite() { + sc.serveG.check() + if sc.writingFrame { + return + } + if sc.needToSendGoAway { + sc.needToSendGoAway = false + sc.startFrameWrite(frameWriteMsg{ + write: &writeGoAway{ + maxStreamID: sc.maxStreamID, + code: sc.goAwayCode, + }, + }) + return + } + if sc.needToSendSettingsAck { + sc.needToSendSettingsAck = false + sc.startFrameWrite(frameWriteMsg{write: writeSettingsAck{}}) + return + } + if !sc.inGoAway { + if wm, ok := sc.writeSched.take(); ok { + sc.startFrameWrite(wm) + return + } + } + if sc.needsFrameFlush { + sc.startFrameWrite(frameWriteMsg{write: flushFrameWriter{}}) + sc.needsFrameFlush = false // after startFrameWrite, since it sets this true + return + } +} + +func (sc *serverConn) goAway(code ErrCode) { + sc.serveG.check() + if sc.inGoAway { + return + } + if code != ErrCodeNo { + sc.shutDownIn(250 * time.Millisecond) + } else { + // TODO: configurable + sc.shutDownIn(1 * time.Second) + } + sc.inGoAway = true + sc.needToSendGoAway = true + sc.goAwayCode = code + sc.scheduleFrameWrite() +} + +func (sc *serverConn) shutDownIn(d time.Duration) { + sc.serveG.check() + sc.shutdownTimer = time.NewTimer(d) + sc.shutdownTimerCh = sc.shutdownTimer.C +} + +func (sc *serverConn) resetStream(se StreamError) { + sc.serveG.check() + sc.writeFrame(frameWriteMsg{write: se}) + if st, ok := sc.streams[se.StreamID]; ok { + st.sentReset = true + sc.closeStream(st, se) + } +} + +// processFrameFromReader processes the serve loop's read from readFrameCh from the +// frame-reading goroutine. +// processFrameFromReader returns whether the connection should be kept open. +func (sc *serverConn) processFrameFromReader(res readFrameResult) bool { + sc.serveG.check() + err := res.err + if err != nil { + if err == ErrFrameTooLarge { + sc.goAway(ErrCodeFrameSize) + return true // goAway will close the loop + } + clientGone := err == io.EOF || err == io.ErrUnexpectedEOF || isClosedConnError(err) + if clientGone { + // TODO: could we also get into this state if + // the peer does a half close + // (e.g. CloseWrite) because they're done + // sending frames but they're still wanting + // our open replies? Investigate. + // TODO: add CloseWrite to crypto/tls.Conn first + // so we have a way to test this? I suppose + // just for testing we could have a non-TLS mode. + return false + } + } else { + f := res.f + if VerboseLogs { + sc.vlogf("http2: server read frame %v", summarizeFrame(f)) + } + err = sc.processFrame(f) + if err == nil { + return true + } + } + + switch ev := err.(type) { + case StreamError: + sc.resetStream(ev) + return true + case goAwayFlowError: + sc.goAway(ErrCodeFlowControl) + return true + case ConnectionError: + sc.logf("http2: server connection error from %v: %v", sc.conn.RemoteAddr(), ev) + sc.goAway(ErrCode(ev)) + return true // goAway will handle shutdown + default: + if res.err != nil { + sc.vlogf("http2: server closing client connection; error reading frame from client %s: %v", sc.conn.RemoteAddr(), err) + } else { + sc.logf("http2: server closing client connection: %v", err) + } + return false + } +} + +func (sc *serverConn) processFrame(f Frame) error { + sc.serveG.check() + + // First frame received must be SETTINGS. + if !sc.sawFirstSettings { + if _, ok := f.(*SettingsFrame); !ok { + return ConnectionError(ErrCodeProtocol) + } + sc.sawFirstSettings = true + } + + switch f := f.(type) { + case *SettingsFrame: + return sc.processSettings(f) + case *HeadersFrame: + return sc.processHeaders(f) + case *ContinuationFrame: + return sc.processContinuation(f) + case *WindowUpdateFrame: + return sc.processWindowUpdate(f) + case *PingFrame: + return sc.processPing(f) + case *DataFrame: + return sc.processData(f) + case *RSTStreamFrame: + return sc.processResetStream(f) + case *PriorityFrame: + return sc.processPriority(f) + case *PushPromiseFrame: + // A client cannot push. Thus, servers MUST treat the receipt of a PUSH_PROMISE + // frame as a connection error (Section 5.4.1) of type PROTOCOL_ERROR. + return ConnectionError(ErrCodeProtocol) + default: + sc.vlogf("http2: server ignoring frame: %v", f.Header()) + return nil + } +} + +func (sc *serverConn) processPing(f *PingFrame) error { + sc.serveG.check() + if f.IsAck() { + // 6.7 PING: " An endpoint MUST NOT respond to PING frames + // containing this flag." + return nil + } + if f.StreamID != 0 { + // "PING frames are not associated with any individual + // stream. If a PING frame is received with a stream + // identifier field value other than 0x0, the recipient MUST + // respond with a connection error (Section 5.4.1) of type + // PROTOCOL_ERROR." + return ConnectionError(ErrCodeProtocol) + } + sc.writeFrame(frameWriteMsg{write: writePingAck{f}}) + return nil +} + +func (sc *serverConn) processWindowUpdate(f *WindowUpdateFrame) error { + sc.serveG.check() + switch { + case f.StreamID != 0: // stream-level flow control + st := sc.streams[f.StreamID] + if st == nil { + // "WINDOW_UPDATE can be sent by a peer that has sent a + // frame bearing the END_STREAM flag. This means that a + // receiver could receive a WINDOW_UPDATE frame on a "half + // closed (remote)" or "closed" stream. A receiver MUST + // NOT treat this as an error, see Section 5.1." + return nil + } + if !st.flow.add(int32(f.Increment)) { + return StreamError{f.StreamID, ErrCodeFlowControl} + } + default: // connection-level flow control + if !sc.flow.add(int32(f.Increment)) { + return goAwayFlowError{} + } + } + sc.scheduleFrameWrite() + return nil +} + +func (sc *serverConn) processResetStream(f *RSTStreamFrame) error { + sc.serveG.check() + + state, st := sc.state(f.StreamID) + if state == stateIdle { + // 6.4 "RST_STREAM frames MUST NOT be sent for a + // stream in the "idle" state. If a RST_STREAM frame + // identifying an idle stream is received, the + // recipient MUST treat this as a connection error + // (Section 5.4.1) of type PROTOCOL_ERROR. + return ConnectionError(ErrCodeProtocol) + } + if st != nil { + st.gotReset = true + sc.closeStream(st, StreamError{f.StreamID, f.ErrCode}) + } + return nil +} + +func (sc *serverConn) closeStream(st *stream, err error) { + sc.serveG.check() + if st.state == stateIdle || st.state == stateClosed { + panic(fmt.Sprintf("invariant; can't close stream in state %v", st.state)) + } + st.state = stateClosed + sc.curOpenStreams-- + if sc.curOpenStreams == 0 { + sc.setConnState(http.StateIdle) + } + delete(sc.streams, st.id) + if p := st.body; p != nil { + p.CloseWithError(err) + } + st.cw.Close() // signals Handler's CloseNotifier, unblocks writes, etc + sc.writeSched.forgetStream(st.id) +} + +func (sc *serverConn) processSettings(f *SettingsFrame) error { + sc.serveG.check() + if f.IsAck() { + sc.unackedSettings-- + if sc.unackedSettings < 0 { + // Why is the peer ACKing settings we never sent? + // The spec doesn't mention this case, but + // hang up on them anyway. + return ConnectionError(ErrCodeProtocol) + } + return nil + } + if err := f.ForeachSetting(sc.processSetting); err != nil { + return err + } + sc.needToSendSettingsAck = true + sc.scheduleFrameWrite() + return nil +} + +func (sc *serverConn) processSetting(s Setting) error { + sc.serveG.check() + if err := s.Valid(); err != nil { + return err + } + if VerboseLogs { + sc.vlogf("http2: server processing setting %v", s) + } + switch s.ID { + case SettingHeaderTableSize: + sc.headerTableSize = s.Val + sc.hpackEncoder.SetMaxDynamicTableSize(s.Val) + case SettingEnablePush: + sc.pushEnabled = s.Val != 0 + case SettingMaxConcurrentStreams: + sc.clientMaxStreams = s.Val + case SettingInitialWindowSize: + return sc.processSettingInitialWindowSize(s.Val) + case SettingMaxFrameSize: + sc.writeSched.maxFrameSize = s.Val + case SettingMaxHeaderListSize: + sc.peerMaxHeaderListSize = s.Val + default: + // Unknown setting: "An endpoint that receives a SETTINGS + // frame with any unknown or unsupported identifier MUST + // ignore that setting." + if VerboseLogs { + sc.vlogf("http2: server ignoring unknown setting %v", s) + } + } + return nil +} + +func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { + sc.serveG.check() + // Note: val already validated to be within range by + // processSetting's Valid call. + + // "A SETTINGS frame can alter the initial flow control window + // size for all current streams. When the value of + // SETTINGS_INITIAL_WINDOW_SIZE changes, a receiver MUST + // adjust the size of all stream flow control windows that it + // maintains by the difference between the new value and the + // old value." + old := sc.initialWindowSize + sc.initialWindowSize = int32(val) + growth := sc.initialWindowSize - old // may be negative + for _, st := range sc.streams { + if !st.flow.add(growth) { + // 6.9.2 Initial Flow Control Window Size + // "An endpoint MUST treat a change to + // SETTINGS_INITIAL_WINDOW_SIZE that causes any flow + // control window to exceed the maximum size as a + // connection error (Section 5.4.1) of type + // FLOW_CONTROL_ERROR." + return ConnectionError(ErrCodeFlowControl) + } + } + return nil +} + +func (sc *serverConn) processData(f *DataFrame) error { + sc.serveG.check() + // "If a DATA frame is received whose stream is not in "open" + // or "half closed (local)" state, the recipient MUST respond + // with a stream error (Section 5.4.2) of type STREAM_CLOSED." + id := f.Header().StreamID + st, ok := sc.streams[id] + if !ok || st.state != stateOpen || st.gotTrailerHeader { + // This includes sending a RST_STREAM if the stream is + // in stateHalfClosedLocal (which currently means that + // the http.Handler returned, so it's done reading & + // done writing). Try to stop the client from sending + // more DATA. + return StreamError{id, ErrCodeStreamClosed} + } + if st.body == nil { + panic("internal error: should have a body in this state") + } + data := f.Data() + + // Sender sending more than they'd declared? + if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { + st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) + return StreamError{id, ErrCodeStreamClosed} + } + if len(data) > 0 { + // Check whether the client has flow control quota. + if int(st.inflow.available()) < len(data) { + return StreamError{id, ErrCodeFlowControl} + } + st.inflow.take(int32(len(data))) + wrote, err := st.body.Write(data) + if err != nil { + return StreamError{id, ErrCodeStreamClosed} + } + if wrote != len(data) { + panic("internal error: bad Writer") + } + st.bodyBytes += int64(len(data)) + } + if f.StreamEnded() { + st.endStream() + } + return nil +} + +// endStream closes a Request.Body's pipe. It is called when a DATA +// frame says a request body is over (or after trailers). +func (st *stream) endStream() { + sc := st.sc + sc.serveG.check() + + if st.declBodyBytes != -1 && st.declBodyBytes != st.bodyBytes { + st.body.CloseWithError(fmt.Errorf("request declared a Content-Length of %d but only wrote %d bytes", + st.declBodyBytes, st.bodyBytes)) + } else { + st.body.closeWithErrorAndCode(io.EOF, st.copyTrailersToHandlerRequest) + st.body.CloseWithError(io.EOF) + } + st.state = stateHalfClosedRemote +} + +// copyTrailersToHandlerRequest is run in the Handler's goroutine in +// its Request.Body.Read just before it gets io.EOF. +func (st *stream) copyTrailersToHandlerRequest() { + for k, vv := range st.trailer { + if _, ok := st.reqTrailer[k]; ok { + // Only copy it over it was pre-declared. + st.reqTrailer[k] = vv + } + } +} + +func (sc *serverConn) processHeaders(f *HeadersFrame) error { + sc.serveG.check() + id := f.Header().StreamID + if sc.inGoAway { + // Ignore. + return nil + } + // http://http2.github.io/http2-spec/#rfc.section.5.1.1 + // Streams initiated by a client MUST use odd-numbered stream + // identifiers. [...] An endpoint that receives an unexpected + // stream identifier MUST respond with a connection error + // (Section 5.4.1) of type PROTOCOL_ERROR. + if id%2 != 1 { + return ConnectionError(ErrCodeProtocol) + } + // A HEADERS frame can be used to create a new stream or + // send a trailer for an open one. If we already have a stream + // open, let it process its own HEADERS frame (trailers at this + // point, if it's valid). + st := sc.streams[f.Header().StreamID] + if st != nil { + return st.processTrailerHeaders(f) + } + + // [...] The identifier of a newly established stream MUST be + // numerically greater than all streams that the initiating + // endpoint has opened or reserved. [...] An endpoint that + // receives an unexpected stream identifier MUST respond with + // a connection error (Section 5.4.1) of type PROTOCOL_ERROR. + if id <= sc.maxStreamID || sc.req.stream != nil { + return ConnectionError(ErrCodeProtocol) + } + + if id > sc.maxStreamID { + sc.maxStreamID = id + } + st = &stream{ + sc: sc, + id: id, + state: stateOpen, + } + if f.StreamEnded() { + st.state = stateHalfClosedRemote + } + st.cw.Init() + + st.flow.conn = &sc.flow // link to conn-level counter + st.flow.add(sc.initialWindowSize) + st.inflow.conn = &sc.inflow // link to conn-level counter + st.inflow.add(initialWindowSize) // TODO: update this when we send a higher initial window size in the initial settings + + sc.streams[id] = st + if f.HasPriority() { + adjustStreamPriority(sc.streams, st.id, f.Priority) + } + sc.curOpenStreams++ + if sc.curOpenStreams == 1 { + sc.setConnState(http.StateActive) + } + sc.req = requestParam{ + stream: st, + header: make(http.Header), + } + sc.hpackDecoder.SetEmitFunc(sc.onNewHeaderField) + sc.hpackDecoder.SetEmitEnabled(true) + return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded()) +} + +func (st *stream) processTrailerHeaders(f *HeadersFrame) error { + sc := st.sc + sc.serveG.check() + if st.gotTrailerHeader { + return ConnectionError(ErrCodeProtocol) + } + st.gotTrailerHeader = true + if !f.StreamEnded() { + return StreamError{st.id, ErrCodeProtocol} + } + sc.resetPendingRequest() // we use invalidHeader from it for trailers + return st.processTrailerHeaderBlockFragment(f.HeaderBlockFragment(), f.HeadersEnded()) +} + +func (sc *serverConn) processContinuation(f *ContinuationFrame) error { + sc.serveG.check() + st := sc.streams[f.Header().StreamID] + if st.gotTrailerHeader { + return st.processTrailerHeaderBlockFragment(f.HeaderBlockFragment(), f.HeadersEnded()) + } + return sc.processHeaderBlockFragment(st, f.HeaderBlockFragment(), f.HeadersEnded()) +} + +func (sc *serverConn) processHeaderBlockFragment(st *stream, frag []byte, end bool) error { + sc.serveG.check() + if _, err := sc.hpackDecoder.Write(frag); err != nil { + return ConnectionError(ErrCodeCompression) + } + if !end { + return nil + } + if err := sc.hpackDecoder.Close(); err != nil { + return ConnectionError(ErrCodeCompression) + } + defer sc.resetPendingRequest() + if sc.curOpenStreams > sc.advMaxStreams { + // "Endpoints MUST NOT exceed the limit set by their + // peer. An endpoint that receives a HEADERS frame + // that causes their advertised concurrent stream + // limit to be exceeded MUST treat this as a stream + // error (Section 5.4.2) of type PROTOCOL_ERROR or + // REFUSED_STREAM." + if sc.unackedSettings == 0 { + // They should know better. + return StreamError{st.id, ErrCodeProtocol} + } + // Assume it's a network race, where they just haven't + // received our last SETTINGS update. But actually + // this can't happen yet, because we don't yet provide + // a way for users to adjust server parameters at + // runtime. + return StreamError{st.id, ErrCodeRefusedStream} + } + + rw, req, err := sc.newWriterAndRequest() + if err != nil { + return err + } + st.reqTrailer = req.Trailer + if st.reqTrailer != nil { + st.trailer = make(http.Header) + } + st.body = req.Body.(*requestBody).pipe // may be nil + st.declBodyBytes = req.ContentLength + + handler := sc.handler.ServeHTTP + if !sc.hpackDecoder.EmitEnabled() { + // Their header list was too long. Send a 431 error. + handler = handleHeaderListTooLong + } + + go sc.runHandler(rw, req, handler) + return nil +} + +func (st *stream) processTrailerHeaderBlockFragment(frag []byte, end bool) error { + sc := st.sc + sc.serveG.check() + sc.hpackDecoder.SetEmitFunc(st.onNewTrailerField) + if _, err := sc.hpackDecoder.Write(frag); err != nil { + return ConnectionError(ErrCodeCompression) + } + if !end { + return nil + } + + rp := &sc.req + if rp.invalidHeader { + return StreamError{rp.stream.id, ErrCodeProtocol} + } + + err := sc.hpackDecoder.Close() + st.endStream() + if err != nil { + return ConnectionError(ErrCodeCompression) + } + return nil +} + +func (sc *serverConn) processPriority(f *PriorityFrame) error { + adjustStreamPriority(sc.streams, f.StreamID, f.PriorityParam) + return nil +} + +func adjustStreamPriority(streams map[uint32]*stream, streamID uint32, priority PriorityParam) { + st, ok := streams[streamID] + if !ok { + // TODO: not quite correct (this streamID might + // already exist in the dep tree, but be closed), but + // close enough for now. + return + } + st.weight = priority.Weight + parent := streams[priority.StreamDep] // might be nil + if parent == st { + // if client tries to set this stream to be the parent of itself + // ignore and keep going + return + } + + // section 5.3.3: If a stream is made dependent on one of its + // own dependencies, the formerly dependent stream is first + // moved to be dependent on the reprioritized stream's previous + // parent. The moved dependency retains its weight. + for piter := parent; piter != nil; piter = piter.parent { + if piter == st { + parent.parent = st.parent + break + } + } + st.parent = parent + if priority.Exclusive && (st.parent != nil || priority.StreamDep == 0) { + for _, openStream := range streams { + if openStream != st && openStream.parent == st.parent { + openStream.parent = st + } + } + } +} + +// resetPendingRequest zeros out all state related to a HEADERS frame +// and its zero or more CONTINUATION frames sent to start a new +// request. +func (sc *serverConn) resetPendingRequest() { + sc.serveG.check() + sc.req = requestParam{} +} + +func (sc *serverConn) newWriterAndRequest() (*responseWriter, *http.Request, error) { + sc.serveG.check() + rp := &sc.req + + if rp.invalidHeader { + return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol} + } + + isConnect := rp.method == "CONNECT" + if isConnect { + if rp.path != "" || rp.scheme != "" || rp.authority == "" { + return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol} + } + } else if rp.method == "" || rp.path == "" || + (rp.scheme != "https" && rp.scheme != "http") { + // See 8.1.2.6 Malformed Requests and Responses: + // + // Malformed requests or responses that are detected + // MUST be treated as a stream error (Section 5.4.2) + // of type PROTOCOL_ERROR." + // + // 8.1.2.3 Request Pseudo-Header Fields + // "All HTTP/2 requests MUST include exactly one valid + // value for the :method, :scheme, and :path + // pseudo-header fields" + return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol} + } + + bodyOpen := rp.stream.state == stateOpen + if rp.method == "HEAD" && bodyOpen { + // HEAD requests can't have bodies + return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol} + } + var tlsState *tls.ConnectionState // nil if not scheme https + + if rp.scheme == "https" { + tlsState = sc.tlsState + } + authority := rp.authority + if authority == "" { + authority = rp.header.Get("Host") + } + needsContinue := rp.header.Get("Expect") == "100-continue" + if needsContinue { + rp.header.Del("Expect") + } + // Merge Cookie headers into one "; "-delimited value. + if cookies := rp.header["Cookie"]; len(cookies) > 1 { + rp.header.Set("Cookie", strings.Join(cookies, "; ")) + } + + // Setup Trailers + var trailer http.Header + for _, v := range rp.header["Trailer"] { + for _, key := range strings.Split(v, ",") { + key = http.CanonicalHeaderKey(strings.TrimSpace(key)) + switch key { + case "Transfer-Encoding", "Trailer", "Content-Length": + // Bogus. (copy of http1 rules) + // Ignore. + default: + if trailer == nil { + trailer = make(http.Header) + } + trailer[key] = nil + } + } + } + delete(rp.header, "Trailer") + + body := &requestBody{ + conn: sc, + stream: rp.stream, + needsContinue: needsContinue, + } + var url_ *url.URL + var requestURI string + if isConnect { + url_ = &url.URL{Host: rp.authority} + requestURI = rp.authority // mimic HTTP/1 server behavior + } else { + var err error + url_, err = url.ParseRequestURI(rp.path) + if err != nil { + return nil, nil, StreamError{rp.stream.id, ErrCodeProtocol} + } + requestURI = rp.path + } + req := &http.Request{ + Method: rp.method, + URL: url_, + RemoteAddr: sc.remoteAddrStr, + Header: rp.header, + RequestURI: requestURI, + Proto: "HTTP/2.0", + ProtoMajor: 2, + ProtoMinor: 0, + TLS: tlsState, + Host: authority, + Body: body, + Trailer: trailer, + } + if bodyOpen { + body.pipe = &pipe{ + b: &fixedBuffer{buf: make([]byte, initialWindowSize)}, // TODO: garbage + } + + if vv, ok := rp.header["Content-Length"]; ok { + req.ContentLength, _ = strconv.ParseInt(vv[0], 10, 64) + } else { + req.ContentLength = -1 + } + } + + rws := responseWriterStatePool.Get().(*responseWriterState) + bwSave := rws.bw + *rws = responseWriterState{} // zero all the fields + rws.conn = sc + rws.bw = bwSave + rws.bw.Reset(chunkWriter{rws}) + rws.stream = rp.stream + rws.req = req + rws.body = body + + rw := &responseWriter{rws: rws} + return rw, req, nil +} + +// Run on its own goroutine. +func (sc *serverConn) runHandler(rw *responseWriter, req *http.Request, handler func(http.ResponseWriter, *http.Request)) { + didPanic := true + defer func() { + if didPanic { + e := recover() + // Same as net/http: + const size = 64 << 10 + buf := make([]byte, size) + buf = buf[:runtime.Stack(buf, false)] + sc.writeFrameFromHandler(frameWriteMsg{ + write: handlerPanicRST{rw.rws.stream.id}, + stream: rw.rws.stream, + }) + sc.logf("http2: panic serving %v: %v\n%s", sc.conn.RemoteAddr(), e, buf) + return + } + rw.handlerDone() + }() + handler(rw, req) + didPanic = false +} + +func handleHeaderListTooLong(w http.ResponseWriter, r *http.Request) { + // 10.5.1 Limits on Header Block Size: + // .. "A server that receives a larger header block than it is + // willing to handle can send an HTTP 431 (Request Header Fields Too + // Large) status code" + const statusRequestHeaderFieldsTooLarge = 431 // only in Go 1.6+ + w.WriteHeader(statusRequestHeaderFieldsTooLarge) + io.WriteString(w, "

    HTTP Error 431

    Request Header Field(s) Too Large

    ") +} + +// called from handler goroutines. +// h may be nil. +func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) error { + sc.serveG.checkNotOn() // NOT on + var errc chan error + if headerData.h != nil { + // If there's a header map (which we don't own), so we have to block on + // waiting for this frame to be written, so an http.Flush mid-handler + // writes out the correct value of keys, before a handler later potentially + // mutates it. + errc = errChanPool.Get().(chan error) + } + if err := sc.writeFrameFromHandler(frameWriteMsg{ + write: headerData, + stream: st, + done: errc, + }); err != nil { + return err + } + if errc != nil { + select { + case err := <-errc: + errChanPool.Put(errc) + return err + case <-sc.doneServing: + return errClientDisconnected + case <-st.cw: + return errStreamClosed + } + } + return nil +} + +// called from handler goroutines. +func (sc *serverConn) write100ContinueHeaders(st *stream) { + sc.writeFrameFromHandler(frameWriteMsg{ + write: write100ContinueHeadersFrame{st.id}, + stream: st, + }) +} + +// A bodyReadMsg tells the server loop that the http.Handler read n +// bytes of the DATA from the client on the given stream. +type bodyReadMsg struct { + st *stream + n int +} + +// called from handler goroutines. +// Notes that the handler for the given stream ID read n bytes of its body +// and schedules flow control tokens to be sent. +func (sc *serverConn) noteBodyReadFromHandler(st *stream, n int) { + sc.serveG.checkNotOn() // NOT on + select { + case sc.bodyReadCh <- bodyReadMsg{st, n}: + case <-sc.doneServing: + } +} + +func (sc *serverConn) noteBodyRead(st *stream, n int) { + sc.serveG.check() + sc.sendWindowUpdate(nil, n) // conn-level + if st.state != stateHalfClosedRemote && st.state != stateClosed { + // Don't send this WINDOW_UPDATE if the stream is closed + // remotely. + sc.sendWindowUpdate(st, n) + } +} + +// st may be nil for conn-level +func (sc *serverConn) sendWindowUpdate(st *stream, n int) { + sc.serveG.check() + // "The legal range for the increment to the flow control + // window is 1 to 2^31-1 (2,147,483,647) octets." + // A Go Read call on 64-bit machines could in theory read + // a larger Read than this. Very unlikely, but we handle it here + // rather than elsewhere for now. + const maxUint31 = 1<<31 - 1 + for n >= maxUint31 { + sc.sendWindowUpdate32(st, maxUint31) + n -= maxUint31 + } + sc.sendWindowUpdate32(st, int32(n)) +} + +// st may be nil for conn-level +func (sc *serverConn) sendWindowUpdate32(st *stream, n int32) { + sc.serveG.check() + if n == 0 { + return + } + if n < 0 { + panic("negative update") + } + var streamID uint32 + if st != nil { + streamID = st.id + } + sc.writeFrame(frameWriteMsg{ + write: writeWindowUpdate{streamID: streamID, n: uint32(n)}, + stream: st, + }) + var ok bool + if st == nil { + ok = sc.inflow.add(n) + } else { + ok = st.inflow.add(n) + } + if !ok { + panic("internal error; sent too many window updates without decrements?") + } +} + +type requestBody struct { + stream *stream + conn *serverConn + closed bool + pipe *pipe // non-nil if we have a HTTP entity message body + needsContinue bool // need to send a 100-continue +} + +func (b *requestBody) Close() error { + if b.pipe != nil { + b.pipe.CloseWithError(errClosedBody) + } + b.closed = true + return nil +} + +func (b *requestBody) Read(p []byte) (n int, err error) { + if b.needsContinue { + b.needsContinue = false + b.conn.write100ContinueHeaders(b.stream) + } + if b.pipe == nil { + return 0, io.EOF + } + n, err = b.pipe.Read(p) + if n > 0 { + b.conn.noteBodyReadFromHandler(b.stream, n) + } + return +} + +// responseWriter is the http.ResponseWriter implementation. It's +// intentionally small (1 pointer wide) to minimize garbage. The +// responseWriterState pointer inside is zeroed at the end of a +// request (in handlerDone) and calls on the responseWriter thereafter +// simply crash (caller's mistake), but the much larger responseWriterState +// and buffers are reused between multiple requests. +type responseWriter struct { + rws *responseWriterState +} + +// Optional http.ResponseWriter interfaces implemented. +var ( + _ http.CloseNotifier = (*responseWriter)(nil) + _ http.Flusher = (*responseWriter)(nil) + _ stringWriter = (*responseWriter)(nil) +) + +type responseWriterState struct { + // immutable within a request: + stream *stream + req *http.Request + body *requestBody // to close at end of request, if DATA frames didn't + conn *serverConn + + // TODO: adjust buffer writing sizes based on server config, frame size updates from peer, etc + bw *bufio.Writer // writing to a chunkWriter{this *responseWriterState} + + // mutated by http.Handler goroutine: + handlerHeader http.Header // nil until called + snapHeader http.Header // snapshot of handlerHeader at WriteHeader time + trailers []string // set in writeChunk + status int // status code passed to WriteHeader + wroteHeader bool // WriteHeader called (explicitly or implicitly). Not necessarily sent to user yet. + sentHeader bool // have we sent the header frame? + handlerDone bool // handler has finished + + sentContentLen int64 // non-zero if handler set a Content-Length header + wroteBytes int64 + + closeNotifierMu sync.Mutex // guards closeNotifierCh + closeNotifierCh chan bool // nil until first used +} + +type chunkWriter struct{ rws *responseWriterState } + +func (cw chunkWriter) Write(p []byte) (n int, err error) { return cw.rws.writeChunk(p) } + +func (rws *responseWriterState) hasTrailers() bool { return len(rws.trailers) != 0 } + +// declareTrailer is called for each Trailer header when the +// response header is written. It notes that a header will need to be +// written in the trailers at the end of the response. +func (rws *responseWriterState) declareTrailer(k string) { + k = http.CanonicalHeaderKey(k) + switch k { + case "Transfer-Encoding", "Content-Length", "Trailer": + // Forbidden by RFC 2616 14.40. + return + } + if !strSliceContains(rws.trailers, k) { + rws.trailers = append(rws.trailers, k) + } +} + +// writeChunk writes chunks from the bufio.Writer. But because +// bufio.Writer may bypass its chunking, sometimes p may be +// arbitrarily large. +// +// writeChunk is also responsible (on the first chunk) for sending the +// HEADER response. +func (rws *responseWriterState) writeChunk(p []byte) (n int, err error) { + if !rws.wroteHeader { + rws.writeHeader(200) + } + + isHeadResp := rws.req.Method == "HEAD" + if !rws.sentHeader { + rws.sentHeader = true + var ctype, clen string + if clen = rws.snapHeader.Get("Content-Length"); clen != "" { + rws.snapHeader.Del("Content-Length") + clen64, err := strconv.ParseInt(clen, 10, 64) + if err == nil && clen64 >= 0 { + rws.sentContentLen = clen64 + } else { + clen = "" + } + } + if clen == "" && rws.handlerDone && bodyAllowedForStatus(rws.status) && (len(p) > 0 || !isHeadResp) { + clen = strconv.Itoa(len(p)) + } + _, hasContentType := rws.snapHeader["Content-Type"] + if !hasContentType && bodyAllowedForStatus(rws.status) { + ctype = http.DetectContentType(p) + } + var date string + if _, ok := rws.snapHeader["Date"]; !ok { + // TODO(bradfitz): be faster here, like net/http? measure. + date = time.Now().UTC().Format(http.TimeFormat) + } + + for _, v := range rws.snapHeader["Trailer"] { + foreachHeaderElement(v, rws.declareTrailer) + } + + endStream := (rws.handlerDone && !rws.hasTrailers() && len(p) == 0) || isHeadResp + err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ + streamID: rws.stream.id, + httpResCode: rws.status, + h: rws.snapHeader, + endStream: endStream, + contentType: ctype, + contentLength: clen, + date: date, + }) + if err != nil { + return 0, err + } + if endStream { + return 0, nil + } + } + if isHeadResp { + return len(p), nil + } + if len(p) == 0 && !rws.handlerDone { + return 0, nil + } + + if rws.handlerDone { + rws.promoteUndeclaredTrailers() + } + + endStream := rws.handlerDone && !rws.hasTrailers() + if len(p) > 0 || endStream { + // only send a 0 byte DATA frame if we're ending the stream. + if err := rws.conn.writeDataFromHandler(rws.stream, p, endStream); err != nil { + return 0, err + } + } + + if rws.handlerDone && rws.hasTrailers() { + err = rws.conn.writeHeaders(rws.stream, &writeResHeaders{ + streamID: rws.stream.id, + h: rws.handlerHeader, + trailers: rws.trailers, + endStream: true, + }) + return len(p), err + } + return len(p), nil +} + +// TrailerPrefix is a magic prefix for ResponseWriter.Header map keys +// that, if present, signals that the map entry is actually for +// the response trailers, and not the response headers. The prefix +// is stripped after the ServeHTTP call finishes and the values are +// sent in the trailers. +// +// This mechanism is intended only for trailers that are not known +// prior to the headers being written. If the set of trailers is fixed +// or known before the header is written, the normal Go trailers mechanism +// is preferred: +// https://golang.org/pkg/net/http/#ResponseWriter +// https://golang.org/pkg/net/http/#example_ResponseWriter_trailers +const TrailerPrefix = "Trailer:" + +// promoteUndeclaredTrailers permits http.Handlers to set trailers +// after the header has already been flushed. Because the Go +// ResponseWriter interface has no way to set Trailers (only the +// Header), and because we didn't want to expand the ResponseWriter +// interface, and because nobody used trailers, and because RFC 2616 +// says you SHOULD (but not must) predeclare any trailers in the +// header, the official ResponseWriter rules said trailers in Go must +// be predeclared, and then we reuse the same ResponseWriter.Header() +// map to mean both Headers and Trailers. When it's time to write the +// Trailers, we pick out the fields of Headers that were declared as +// trailers. That worked for a while, until we found the first major +// user of Trailers in the wild: gRPC (using them only over http2), +// and gRPC libraries permit setting trailers mid-stream without +// predeclarnig them. So: change of plans. We still permit the old +// way, but we also permit this hack: if a Header() key begins with +// "Trailer:", the suffix of that key is a Trailer. Because ':' is an +// invalid token byte anyway, there is no ambiguity. (And it's already +// filtered out) It's mildly hacky, but not terrible. +// +// This method runs after the Handler is done and promotes any Header +// fields to be trailers. +func (rws *responseWriterState) promoteUndeclaredTrailers() { + for k, vv := range rws.handlerHeader { + if !strings.HasPrefix(k, TrailerPrefix) { + continue + } + trailerKey := strings.TrimPrefix(k, TrailerPrefix) + rws.declareTrailer(trailerKey) + rws.handlerHeader[http.CanonicalHeaderKey(trailerKey)] = vv + } + sort.Strings(rws.trailers) +} + +func (w *responseWriter) Flush() { + rws := w.rws + if rws == nil { + panic("Header called after Handler finished") + } + if rws.bw.Buffered() > 0 { + if err := rws.bw.Flush(); err != nil { + // Ignore the error. The frame writer already knows. + return + } + } else { + // The bufio.Writer won't call chunkWriter.Write + // (writeChunk with zero bytes, so we have to do it + // ourselves to force the HTTP response header and/or + // final DATA frame (with END_STREAM) to be sent. + rws.writeChunk(nil) + } +} + +func (w *responseWriter) CloseNotify() <-chan bool { + rws := w.rws + if rws == nil { + panic("CloseNotify called after Handler finished") + } + rws.closeNotifierMu.Lock() + ch := rws.closeNotifierCh + if ch == nil { + ch = make(chan bool, 1) + rws.closeNotifierCh = ch + go func() { + rws.stream.cw.Wait() // wait for close + ch <- true + }() + } + rws.closeNotifierMu.Unlock() + return ch +} + +func (w *responseWriter) Header() http.Header { + rws := w.rws + if rws == nil { + panic("Header called after Handler finished") + } + if rws.handlerHeader == nil { + rws.handlerHeader = make(http.Header) + } + return rws.handlerHeader +} + +func (w *responseWriter) WriteHeader(code int) { + rws := w.rws + if rws == nil { + panic("WriteHeader called after Handler finished") + } + rws.writeHeader(code) +} + +func (rws *responseWriterState) writeHeader(code int) { + if !rws.wroteHeader { + rws.wroteHeader = true + rws.status = code + if len(rws.handlerHeader) > 0 { + rws.snapHeader = cloneHeader(rws.handlerHeader) + } + } +} + +func cloneHeader(h http.Header) http.Header { + h2 := make(http.Header, len(h)) + for k, vv := range h { + vv2 := make([]string, len(vv)) + copy(vv2, vv) + h2[k] = vv2 + } + return h2 +} + +// The Life Of A Write is like this: +// +// * Handler calls w.Write or w.WriteString -> +// * -> rws.bw (*bufio.Writer) -> +// * (Handler migth call Flush) +// * -> chunkWriter{rws} +// * -> responseWriterState.writeChunk(p []byte) +// * -> responseWriterState.writeChunk (most of the magic; see comment there) +func (w *responseWriter) Write(p []byte) (n int, err error) { + return w.write(len(p), p, "") +} + +func (w *responseWriter) WriteString(s string) (n int, err error) { + return w.write(len(s), nil, s) +} + +// either dataB or dataS is non-zero. +func (w *responseWriter) write(lenData int, dataB []byte, dataS string) (n int, err error) { + rws := w.rws + if rws == nil { + panic("Write called after Handler finished") + } + if !rws.wroteHeader { + w.WriteHeader(200) + } + if !bodyAllowedForStatus(rws.status) { + return 0, http.ErrBodyNotAllowed + } + rws.wroteBytes += int64(len(dataB)) + int64(len(dataS)) // only one can be set + if rws.sentContentLen != 0 && rws.wroteBytes > rws.sentContentLen { + // TODO: send a RST_STREAM + return 0, errors.New("http2: handler wrote more than declared Content-Length") + } + + if dataB != nil { + return rws.bw.Write(dataB) + } else { + return rws.bw.WriteString(dataS) + } +} + +func (w *responseWriter) handlerDone() { + rws := w.rws + rws.handlerDone = true + w.Flush() + w.rws = nil + responseWriterStatePool.Put(rws) +} + +// foreachHeaderElement splits v according to the "#rule" construction +// in RFC 2616 section 2.1 and calls fn for each non-empty element. +func foreachHeaderElement(v string, fn func(string)) { + v = textproto.TrimString(v) + if v == "" { + return + } + if !strings.Contains(v, ",") { + fn(v) + return + } + for _, f := range strings.Split(v, ",") { + if f = textproto.TrimString(f); f != "" { + fn(f) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/server_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/server_test.go new file mode 100644 index 00000000..2d1578e7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/server_test.go @@ -0,0 +1,3082 @@ +// 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. + +package http2 + +import ( + "bytes" + "crypto/tls" + "errors" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "net" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "reflect" + "runtime" + "strconv" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + "golang.org/x/net/http2/hpack" +) + +var stderrVerbose = flag.Bool("stderr_verbose", false, "Mirror verbosity to stderr, unbuffered") + +func stderrv() io.Writer { + if *stderrVerbose { + return os.Stderr + } + + return ioutil.Discard +} + +type serverTester struct { + cc net.Conn // client conn + t testing.TB + ts *httptest.Server + fr *Framer + logBuf *bytes.Buffer + logFilter []string // substrings to filter out + scMu sync.Mutex // guards sc + sc *serverConn + hpackDec *hpack.Decoder + decodedHeaders [][2]string + + // writing headers: + headerBuf bytes.Buffer + hpackEnc *hpack.Encoder + + // reading frames: + frc chan Frame + frErrc chan error + readTimer *time.Timer +} + +func init() { + testHookOnPanicMu = new(sync.Mutex) +} + +func resetHooks() { + testHookOnPanicMu.Lock() + testHookOnPanic = nil + testHookOnPanicMu.Unlock() +} + +type serverTesterOpt string + +var optOnlyServer = serverTesterOpt("only_server") +var optQuiet = serverTesterOpt("quiet_logging") + +func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester { + resetHooks() + + logBuf := new(bytes.Buffer) + ts := httptest.NewUnstartedServer(handler) + + tlsConfig := &tls.Config{ + InsecureSkipVerify: true, + // The h2-14 is temporary, until curl is updated. (as used by unit tests + // in Docker) + NextProtos: []string{NextProtoTLS, "h2-14"}, + } + + var onlyServer, quiet bool + for _, opt := range opts { + switch v := opt.(type) { + case func(*tls.Config): + v(tlsConfig) + case func(*httptest.Server): + v(ts) + case serverTesterOpt: + switch v { + case optOnlyServer: + onlyServer = true + case optQuiet: + quiet = true + } + default: + t.Fatalf("unknown newServerTester option type %T", v) + } + } + + ConfigureServer(ts.Config, &Server{}) + + st := &serverTester{ + t: t, + ts: ts, + logBuf: logBuf, + frc: make(chan Frame, 1), + frErrc: make(chan error, 1), + } + st.hpackEnc = hpack.NewEncoder(&st.headerBuf) + st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField) + + ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config + if quiet { + ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0) + } else { + ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, logBuf), "", log.LstdFlags) + } + ts.StartTLS() + + if VerboseLogs { + t.Logf("Running test server at: %s", ts.URL) + } + testHookGetServerConn = func(v *serverConn) { + st.scMu.Lock() + defer st.scMu.Unlock() + st.sc = v + st.sc.testHookCh = make(chan func(int)) + } + log.SetOutput(io.MultiWriter(stderrv(), twriter{t: t, st: st})) + if !onlyServer { + cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig) + if err != nil { + t.Fatal(err) + } + st.cc = cc + st.fr = NewFramer(cc, cc) + } + return st +} + +func (st *serverTester) closeConn() { + st.scMu.Lock() + defer st.scMu.Unlock() + st.sc.conn.Close() +} + +func (st *serverTester) addLogFilter(phrase string) { + st.logFilter = append(st.logFilter, phrase) +} + +func (st *serverTester) stream(id uint32) *stream { + ch := make(chan *stream, 1) + st.sc.testHookCh <- func(int) { + ch <- st.sc.streams[id] + } + return <-ch +} + +func (st *serverTester) streamState(id uint32) streamState { + ch := make(chan streamState, 1) + st.sc.testHookCh <- func(int) { + state, _ := st.sc.state(id) + ch <- state + } + return <-ch +} + +// loopNum reports how many times this conn's select loop has gone around. +func (st *serverTester) loopNum() int { + lastc := make(chan int, 1) + st.sc.testHookCh <- func(loopNum int) { + lastc <- loopNum + } + return <-lastc +} + +// awaitIdle heuristically awaits for the server conn's select loop to be idle. +// The heuristic is that the server connection's serve loop must schedule +// 50 times in a row without any channel sends or receives occuring. +func (st *serverTester) awaitIdle() { + remain := 50 + last := st.loopNum() + for remain > 0 { + n := st.loopNum() + if n == last+1 { + remain-- + } else { + remain = 50 + } + last = n + } +} + +func (st *serverTester) Close() { + st.ts.Close() + if st.cc != nil { + st.cc.Close() + } + log.SetOutput(os.Stderr) +} + +// greet initiates the client's HTTP/2 connection into a state where +// frames may be sent. +func (st *serverTester) greet() { + st.writePreface() + st.writeInitialSettings() + st.wantSettings() + st.writeSettingsAck() + st.wantSettingsAck() +} + +func (st *serverTester) writePreface() { + n, err := st.cc.Write(clientPreface) + if err != nil { + st.t.Fatalf("Error writing client preface: %v", err) + } + if n != len(clientPreface) { + st.t.Fatalf("Writing client preface, wrote %d bytes; want %d", n, len(clientPreface)) + } +} + +func (st *serverTester) writeInitialSettings() { + if err := st.fr.WriteSettings(); err != nil { + st.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err) + } +} + +func (st *serverTester) writeSettingsAck() { + if err := st.fr.WriteSettingsAck(); err != nil { + st.t.Fatalf("Error writing ACK of server's SETTINGS: %v", err) + } +} + +func (st *serverTester) writeHeaders(p HeadersFrameParam) { + if err := st.fr.WriteHeaders(p); err != nil { + st.t.Fatalf("Error writing HEADERS: %v", err) + } +} + +func (st *serverTester) encodeHeaderField(k, v string) { + err := st.hpackEnc.WriteField(hpack.HeaderField{Name: k, Value: v}) + if err != nil { + st.t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err) + } +} + +// encodeHeaderRaw is the magic-free version of encodeHeader. +// It takes 0 or more (k, v) pairs and encodes them. +func (st *serverTester) encodeHeaderRaw(headers ...string) []byte { + if len(headers)%2 == 1 { + panic("odd number of kv args") + } + st.headerBuf.Reset() + for len(headers) > 0 { + k, v := headers[0], headers[1] + st.encodeHeaderField(k, v) + headers = headers[2:] + } + return st.headerBuf.Bytes() +} + +// encodeHeader encodes headers and returns their HPACK bytes. headers +// must contain an even number of key/value pairs. There may be +// multiple pairs for keys (e.g. "cookie"). The :method, :path, and +// :scheme headers default to GET, / and https. +func (st *serverTester) encodeHeader(headers ...string) []byte { + if len(headers)%2 == 1 { + panic("odd number of kv args") + } + + st.headerBuf.Reset() + + if len(headers) == 0 { + // Fast path, mostly for benchmarks, so test code doesn't pollute + // profiles when we're looking to improve server allocations. + st.encodeHeaderField(":method", "GET") + st.encodeHeaderField(":path", "/") + st.encodeHeaderField(":scheme", "https") + return st.headerBuf.Bytes() + } + + if len(headers) == 2 && headers[0] == ":method" { + // Another fast path for benchmarks. + st.encodeHeaderField(":method", headers[1]) + st.encodeHeaderField(":path", "/") + st.encodeHeaderField(":scheme", "https") + return st.headerBuf.Bytes() + } + + pseudoCount := map[string]int{} + keys := []string{":method", ":path", ":scheme"} + vals := map[string][]string{ + ":method": {"GET"}, + ":path": {"/"}, + ":scheme": {"https"}, + } + for len(headers) > 0 { + k, v := headers[0], headers[1] + headers = headers[2:] + if _, ok := vals[k]; !ok { + keys = append(keys, k) + } + if strings.HasPrefix(k, ":") { + pseudoCount[k]++ + if pseudoCount[k] == 1 { + vals[k] = []string{v} + } else { + // Allows testing of invalid headers w/ dup pseudo fields. + vals[k] = append(vals[k], v) + } + } else { + vals[k] = append(vals[k], v) + } + } + for _, k := range keys { + for _, v := range vals[k] { + st.encodeHeaderField(k, v) + } + } + return st.headerBuf.Bytes() +} + +// bodylessReq1 writes a HEADERS frames with StreamID 1 and EndStream and EndHeaders set. +func (st *serverTester) bodylessReq1(headers ...string) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(headers...), + EndStream: true, + EndHeaders: true, + }) +} + +func (st *serverTester) writeData(streamID uint32, endStream bool, data []byte) { + if err := st.fr.WriteData(streamID, endStream, data); err != nil { + st.t.Fatalf("Error writing DATA: %v", err) + } +} + +func (st *serverTester) readFrame() (Frame, error) { + go func() { + fr, err := st.fr.ReadFrame() + if err != nil { + st.frErrc <- err + } else { + st.frc <- fr + } + }() + t := st.readTimer + if t == nil { + t = time.NewTimer(2 * time.Second) + st.readTimer = t + } + t.Reset(2 * time.Second) + defer t.Stop() + select { + case f := <-st.frc: + return f, nil + case err := <-st.frErrc: + return nil, err + case <-t.C: + return nil, errors.New("timeout waiting for frame") + } +} + +func (st *serverTester) wantHeaders() *HeadersFrame { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting a HEADERS frame: %v", err) + } + hf, ok := f.(*HeadersFrame) + if !ok { + st.t.Fatalf("got a %T; want *HeadersFrame", f) + } + return hf +} + +func (st *serverTester) wantContinuation() *ContinuationFrame { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting a CONTINUATION frame: %v", err) + } + cf, ok := f.(*ContinuationFrame) + if !ok { + st.t.Fatalf("got a %T; want *ContinuationFrame", f) + } + return cf +} + +func (st *serverTester) wantData() *DataFrame { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting a DATA frame: %v", err) + } + df, ok := f.(*DataFrame) + if !ok { + st.t.Fatalf("got a %T; want *DataFrame", f) + } + return df +} + +func (st *serverTester) wantSettings() *SettingsFrame { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting a SETTINGS frame: %v", err) + } + sf, ok := f.(*SettingsFrame) + if !ok { + st.t.Fatalf("got a %T; want *SettingsFrame", f) + } + return sf +} + +func (st *serverTester) wantPing() *PingFrame { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting a PING frame: %v", err) + } + pf, ok := f.(*PingFrame) + if !ok { + st.t.Fatalf("got a %T; want *PingFrame", f) + } + return pf +} + +func (st *serverTester) wantGoAway() *GoAwayFrame { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting a GOAWAY frame: %v", err) + } + gf, ok := f.(*GoAwayFrame) + if !ok { + st.t.Fatalf("got a %T; want *GoAwayFrame", f) + } + return gf +} + +func (st *serverTester) wantRSTStream(streamID uint32, errCode ErrCode) { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting an RSTStream frame: %v", err) + } + rs, ok := f.(*RSTStreamFrame) + if !ok { + st.t.Fatalf("got a %T; want *RSTStreamFrame", f) + } + if rs.FrameHeader.StreamID != streamID { + st.t.Fatalf("RSTStream StreamID = %d; want %d", rs.FrameHeader.StreamID, streamID) + } + if rs.ErrCode != errCode { + st.t.Fatalf("RSTStream ErrCode = %d (%s); want %d (%s)", rs.ErrCode, rs.ErrCode, errCode, errCode) + } +} + +func (st *serverTester) wantWindowUpdate(streamID, incr uint32) { + f, err := st.readFrame() + if err != nil { + st.t.Fatalf("Error while expecting a WINDOW_UPDATE frame: %v", err) + } + wu, ok := f.(*WindowUpdateFrame) + if !ok { + st.t.Fatalf("got a %T; want *WindowUpdateFrame", f) + } + if wu.FrameHeader.StreamID != streamID { + st.t.Fatalf("WindowUpdate StreamID = %d; want %d", wu.FrameHeader.StreamID, streamID) + } + if wu.Increment != incr { + st.t.Fatalf("WindowUpdate increment = %d; want %d", wu.Increment, incr) + } +} + +func (st *serverTester) wantSettingsAck() { + f, err := st.readFrame() + if err != nil { + st.t.Fatal(err) + } + sf, ok := f.(*SettingsFrame) + if !ok { + st.t.Fatalf("Wanting a settings ACK, received a %T", f) + } + if !sf.Header().Flags.Has(FlagSettingsAck) { + st.t.Fatal("Settings Frame didn't have ACK set") + } + +} + +func TestServer(t *testing.T) { + gotReq := make(chan bool, 1) + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Foo", "Bar") + gotReq <- true + }) + defer st.Close() + + covers("3.5", ` + The server connection preface consists of a potentially empty + SETTINGS frame ([SETTINGS]) that MUST be the first frame the + server sends in the HTTP/2 connection. + `) + + st.writePreface() + st.writeInitialSettings() + st.wantSettings() + st.writeSettingsAck() + st.wantSettingsAck() + + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(), + EndStream: true, // no DATA frames + EndHeaders: true, + }) + + select { + case <-gotReq: + case <-time.After(2 * time.Second): + t.Error("timeout waiting for request") + } +} + +func TestServer_Request_Get(t *testing.T) { + testServerRequest(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader("foo-bar", "some-value"), + EndStream: true, // no DATA frames + EndHeaders: true, + }) + }, func(r *http.Request) { + if r.Method != "GET" { + t.Errorf("Method = %q; want GET", r.Method) + } + if r.URL.Path != "/" { + t.Errorf("URL.Path = %q; want /", r.URL.Path) + } + if r.ContentLength != 0 { + t.Errorf("ContentLength = %v; want 0", r.ContentLength) + } + if r.Close { + t.Error("Close = true; want false") + } + if !strings.Contains(r.RemoteAddr, ":") { + t.Errorf("RemoteAddr = %q; want something with a colon", r.RemoteAddr) + } + if r.Proto != "HTTP/2.0" || r.ProtoMajor != 2 || r.ProtoMinor != 0 { + t.Errorf("Proto = %q Major=%v,Minor=%v; want HTTP/2.0", r.Proto, r.ProtoMajor, r.ProtoMinor) + } + wantHeader := http.Header{ + "Foo-Bar": []string{"some-value"}, + } + if !reflect.DeepEqual(r.Header, wantHeader) { + t.Errorf("Header = %#v; want %#v", r.Header, wantHeader) + } + if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 { + t.Errorf("Read = %d, %v; want 0, EOF", n, err) + } + }) +} + +func TestServer_Request_Get_PathSlashes(t *testing.T) { + testServerRequest(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":path", "/%2f/"), + EndStream: true, // no DATA frames + EndHeaders: true, + }) + }, func(r *http.Request) { + if r.RequestURI != "/%2f/" { + t.Errorf("RequestURI = %q; want /%%2f/", r.RequestURI) + } + if r.URL.Path != "///" { + t.Errorf("URL.Path = %q; want ///", r.URL.Path) + } + }) +} + +// TODO: add a test with EndStream=true on the HEADERS but setting a +// Content-Length anyway. Should we just omit it and force it to +// zero? + +func TestServer_Request_Post_NoContentLength_EndStream(t *testing.T) { + testServerRequest(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: true, + EndHeaders: true, + }) + }, func(r *http.Request) { + if r.Method != "POST" { + t.Errorf("Method = %q; want POST", r.Method) + } + if r.ContentLength != 0 { + t.Errorf("ContentLength = %v; want 0", r.ContentLength) + } + if n, err := r.Body.Read([]byte(" ")); err != io.EOF || n != 0 { + t.Errorf("Read = %d, %v; want 0, EOF", n, err) + } + }) +} + +func TestServer_Request_Post_Body_ImmediateEOF(t *testing.T) { + testBodyContents(t, -1, "", func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, // to say DATA frames are coming + EndHeaders: true, + }) + st.writeData(1, true, nil) // just kidding. empty body. + }) +} + +func TestServer_Request_Post_Body_OneData(t *testing.T) { + const content = "Some content" + testBodyContents(t, -1, content, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, // to say DATA frames are coming + EndHeaders: true, + }) + st.writeData(1, true, []byte(content)) + }) +} + +func TestServer_Request_Post_Body_TwoData(t *testing.T) { + const content = "Some content" + testBodyContents(t, -1, content, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, // to say DATA frames are coming + EndHeaders: true, + }) + st.writeData(1, false, []byte(content[:5])) + st.writeData(1, true, []byte(content[5:])) + }) +} + +func TestServer_Request_Post_Body_ContentLength_Correct(t *testing.T) { + const content = "Some content" + testBodyContents(t, int64(len(content)), content, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader( + ":method", "POST", + "content-length", strconv.Itoa(len(content)), + ), + EndStream: false, // to say DATA frames are coming + EndHeaders: true, + }) + st.writeData(1, true, []byte(content)) + }) +} + +func TestServer_Request_Post_Body_ContentLength_TooLarge(t *testing.T) { + testBodyContentsFail(t, 3, "request declared a Content-Length of 3 but only wrote 2 bytes", + func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader( + ":method", "POST", + "content-length", "3", + ), + EndStream: false, // to say DATA frames are coming + EndHeaders: true, + }) + st.writeData(1, true, []byte("12")) + }) +} + +func TestServer_Request_Post_Body_ContentLength_TooSmall(t *testing.T) { + testBodyContentsFail(t, 4, "sender tried to send more than declared Content-Length of 4 bytes", + func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader( + ":method", "POST", + "content-length", "4", + ), + EndStream: false, // to say DATA frames are coming + EndHeaders: true, + }) + st.writeData(1, true, []byte("12345")) + }) +} + +func testBodyContents(t *testing.T, wantContentLength int64, wantBody string, write func(st *serverTester)) { + testServerRequest(t, write, func(r *http.Request) { + if r.Method != "POST" { + t.Errorf("Method = %q; want POST", r.Method) + } + if r.ContentLength != wantContentLength { + t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength) + } + all, err := ioutil.ReadAll(r.Body) + if err != nil { + t.Fatal(err) + } + if string(all) != wantBody { + t.Errorf("Read = %q; want %q", all, wantBody) + } + if err := r.Body.Close(); err != nil { + t.Fatalf("Close: %v", err) + } + }) +} + +func testBodyContentsFail(t *testing.T, wantContentLength int64, wantReadError string, write func(st *serverTester)) { + testServerRequest(t, write, func(r *http.Request) { + if r.Method != "POST" { + t.Errorf("Method = %q; want POST", r.Method) + } + if r.ContentLength != wantContentLength { + t.Errorf("ContentLength = %v; want %d", r.ContentLength, wantContentLength) + } + all, err := ioutil.ReadAll(r.Body) + if err == nil { + t.Fatalf("expected an error (%q) reading from the body. Successfully read %q instead.", + wantReadError, all) + } + if !strings.Contains(err.Error(), wantReadError) { + t.Fatalf("Body.Read = %v; want substring %q", err, wantReadError) + } + if err := r.Body.Close(); err != nil { + t.Fatalf("Close: %v", err) + } + }) +} + +// Using a Host header, instead of :authority +func TestServer_Request_Get_Host(t *testing.T) { + const host = "example.com" + testServerRequest(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader("host", host), + EndStream: true, + EndHeaders: true, + }) + }, func(r *http.Request) { + if r.Host != host { + t.Errorf("Host = %q; want %q", r.Host, host) + } + }) +} + +// Using an :authority pseudo-header, instead of Host +func TestServer_Request_Get_Authority(t *testing.T) { + const host = "example.com" + testServerRequest(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":authority", host), + EndStream: true, + EndHeaders: true, + }) + }, func(r *http.Request) { + if r.Host != host { + t.Errorf("Host = %q; want %q", r.Host, host) + } + }) +} + +func TestServer_Request_WithContinuation(t *testing.T) { + wantHeader := http.Header{ + "Foo-One": []string{"value-one"}, + "Foo-Two": []string{"value-two"}, + "Foo-Three": []string{"value-three"}, + } + testServerRequest(t, func(st *serverTester) { + fullHeaders := st.encodeHeader( + "foo-one", "value-one", + "foo-two", "value-two", + "foo-three", "value-three", + ) + remain := fullHeaders + chunks := 0 + for len(remain) > 0 { + const maxChunkSize = 5 + chunk := remain + if len(chunk) > maxChunkSize { + chunk = chunk[:maxChunkSize] + } + remain = remain[len(chunk):] + + if chunks == 0 { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: chunk, + EndStream: true, // no DATA frames + EndHeaders: false, // we'll have continuation frames + }) + } else { + err := st.fr.WriteContinuation(1, len(remain) == 0, chunk) + if err != nil { + t.Fatal(err) + } + } + chunks++ + } + if chunks < 2 { + t.Fatal("too few chunks") + } + }, func(r *http.Request) { + if !reflect.DeepEqual(r.Header, wantHeader) { + t.Errorf("Header = %#v; want %#v", r.Header, wantHeader) + } + }) +} + +// Concatenated cookie headers. ("8.1.2.5 Compressing the Cookie Header Field") +func TestServer_Request_CookieConcat(t *testing.T) { + const host = "example.com" + testServerRequest(t, func(st *serverTester) { + st.bodylessReq1( + ":authority", host, + "cookie", "a=b", + "cookie", "c=d", + "cookie", "e=f", + ) + }, func(r *http.Request) { + const want = "a=b; c=d; e=f" + if got := r.Header.Get("Cookie"); got != want { + t.Errorf("Cookie = %q; want %q", got, want) + } + }) +} + +func TestServer_Request_Reject_CapitalHeader(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("UPPER", "v") }) +} + +func TestServer_Request_Reject_HeaderFieldNameColon(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has:colon", "v") }) +} + +func TestServer_Request_Reject_HeaderFieldNameNULL(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("has\x00null", "v") }) +} + +func TestServer_Request_Reject_HeaderFieldNameEmpty(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("", "v") }) +} + +func TestServer_Request_Reject_HeaderFieldValueNewline(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\nnewline") }) +} + +func TestServer_Request_Reject_HeaderFieldValueCR(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\rcarriage") }) +} + +func TestServer_Request_Reject_HeaderFieldValueDEL(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1("foo", "has\x7fdel") }) +} + +func TestServer_Request_Reject_Pseudo_Missing_method(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":method", "") }) +} + +func TestServer_Request_Reject_Pseudo_ExactlyOne(t *testing.T) { + // 8.1.2.3 Request Pseudo-Header Fields + // "All HTTP/2 requests MUST include exactly one valid value" ... + testRejectRequest(t, func(st *serverTester) { + st.addLogFilter("duplicate pseudo-header") + st.bodylessReq1(":method", "GET", ":method", "POST") + }) +} + +func TestServer_Request_Reject_Pseudo_AfterRegular(t *testing.T) { + // 8.1.2.3 Request Pseudo-Header Fields + // "All pseudo-header fields MUST appear in the header block + // before regular header fields. Any request or response that + // contains a pseudo-header field that appears in a header + // block after a regular header field MUST be treated as + // malformed (Section 8.1.2.6)." + testRejectRequest(t, func(st *serverTester) { + st.addLogFilter("pseudo-header after regular header") + var buf bytes.Buffer + enc := hpack.NewEncoder(&buf) + enc.WriteField(hpack.HeaderField{Name: ":method", Value: "GET"}) + enc.WriteField(hpack.HeaderField{Name: "regular", Value: "foobar"}) + enc.WriteField(hpack.HeaderField{Name: ":path", Value: "/"}) + enc.WriteField(hpack.HeaderField{Name: ":scheme", Value: "https"}) + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: buf.Bytes(), + EndStream: true, + EndHeaders: true, + }) + }) +} + +func TestServer_Request_Reject_Pseudo_Missing_path(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":path", "") }) +} + +func TestServer_Request_Reject_Pseudo_Missing_scheme(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "") }) +} + +func TestServer_Request_Reject_Pseudo_scheme_invalid(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { st.bodylessReq1(":scheme", "bogus") }) +} + +func TestServer_Request_Reject_Pseudo_Unknown(t *testing.T) { + testRejectRequest(t, func(st *serverTester) { + st.addLogFilter(`invalid pseudo-header ":unknown_thing"`) + st.bodylessReq1(":unknown_thing", "") + }) +} + +func testRejectRequest(t *testing.T, send func(*serverTester)) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + t.Fatal("server request made it to handler; should've been rejected") + }) + defer st.Close() + + st.greet() + send(st) + st.wantRSTStream(1, ErrCodeProtocol) +} + +func TestServer_Request_Connect(t *testing.T) { + testServerRequest(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeaderRaw( + ":method", "CONNECT", + ":authority", "example.com:123", + ), + EndStream: true, + EndHeaders: true, + }) + }, func(r *http.Request) { + if g, w := r.Method, "CONNECT"; g != w { + t.Errorf("Method = %q; want %q", g, w) + } + if g, w := r.RequestURI, "example.com:123"; g != w { + t.Errorf("RequestURI = %q; want %q", g, w) + } + if g, w := r.URL.Host, "example.com:123"; g != w { + t.Errorf("URL.Host = %q; want %q", g, w) + } + }) +} + +func TestServer_Request_Connect_InvalidPath(t *testing.T) { + testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeaderRaw( + ":method", "CONNECT", + ":authority", "example.com:123", + ":path", "/bogus", + ), + EndStream: true, + EndHeaders: true, + }) + }) +} + +func TestServer_Request_Connect_InvalidScheme(t *testing.T) { + testServerRejectsStream(t, ErrCodeProtocol, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeaderRaw( + ":method", "CONNECT", + ":authority", "example.com:123", + ":scheme", "https", + ), + EndStream: true, + EndHeaders: true, + }) + }) +} + +func TestServer_Ping(t *testing.T) { + st := newServerTester(t, nil) + defer st.Close() + st.greet() + + // Server should ignore this one, since it has ACK set. + ackPingData := [8]byte{1, 2, 4, 8, 16, 32, 64, 128} + if err := st.fr.WritePing(true, ackPingData); err != nil { + t.Fatal(err) + } + + // But the server should reply to this one, since ACK is false. + pingData := [8]byte{1, 2, 3, 4, 5, 6, 7, 8} + if err := st.fr.WritePing(false, pingData); err != nil { + t.Fatal(err) + } + + pf := st.wantPing() + if !pf.Flags.Has(FlagPingAck) { + t.Error("response ping doesn't have ACK set") + } + if pf.Data != pingData { + t.Errorf("response ping has data %q; want %q", pf.Data, pingData) + } +} + +func TestServer_RejectsLargeFrames(t *testing.T) { + if runtime.GOOS == "windows" { + t.Skip("see golang.org/issue/13434") + } + + st := newServerTester(t, nil) + defer st.Close() + st.greet() + + // Write too large of a frame (too large by one byte) + // We ignore the return value because it's expected that the server + // will only read the first 9 bytes (the headre) and then disconnect. + st.fr.WriteRawFrame(0xff, 0, 0, make([]byte, defaultMaxReadFrameSize+1)) + + gf := st.wantGoAway() + if gf.ErrCode != ErrCodeFrameSize { + t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFrameSize) + } + if st.logBuf.Len() != 0 { + // Previously we spun here for a bit until the GOAWAY disconnect + // timer fired, logging while we fired. + t.Errorf("unexpected server output: %.500s\n", st.logBuf.Bytes()) + } +} + +func TestServer_Handler_Sends_WindowUpdate(t *testing.T) { + puppet := newHandlerPuppet() + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + puppet.act(w, r) + }) + defer st.Close() + defer puppet.done() + + st.greet() + + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, // data coming + EndHeaders: true, + }) + st.writeData(1, false, []byte("abcdef")) + puppet.do(readBodyHandler(t, "abc")) + st.wantWindowUpdate(0, 3) + st.wantWindowUpdate(1, 3) + + puppet.do(readBodyHandler(t, "def")) + st.wantWindowUpdate(0, 3) + st.wantWindowUpdate(1, 3) + + st.writeData(1, true, []byte("ghijkl")) // END_STREAM here + puppet.do(readBodyHandler(t, "ghi")) + puppet.do(readBodyHandler(t, "jkl")) + st.wantWindowUpdate(0, 3) + st.wantWindowUpdate(0, 3) // no more stream-level, since END_STREAM +} + +func TestServer_Send_GoAway_After_Bogus_WindowUpdate(t *testing.T) { + st := newServerTester(t, nil) + defer st.Close() + st.greet() + if err := st.fr.WriteWindowUpdate(0, 1<<31-1); err != nil { + t.Fatal(err) + } + gf := st.wantGoAway() + if gf.ErrCode != ErrCodeFlowControl { + t.Errorf("GOAWAY err = %v; want %v", gf.ErrCode, ErrCodeFlowControl) + } + if gf.LastStreamID != 0 { + t.Errorf("GOAWAY last stream ID = %v; want %v", gf.LastStreamID, 0) + } +} + +func TestServer_Send_RstStream_After_Bogus_WindowUpdate(t *testing.T) { + inHandler := make(chan bool) + blockHandler := make(chan bool) + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + inHandler <- true + <-blockHandler + }) + defer st.Close() + defer close(blockHandler) + st.greet() + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, // keep it open + EndHeaders: true, + }) + <-inHandler + // Send a bogus window update: + if err := st.fr.WriteWindowUpdate(1, 1<<31-1); err != nil { + t.Fatal(err) + } + st.wantRSTStream(1, ErrCodeFlowControl) +} + +// testServerPostUnblock sends a hanging POST with unsent data to handler, +// then runs fn once in the handler, and verifies that the error returned from +// handler is acceptable. It fails if takes over 5 seconds for handler to exit. +func testServerPostUnblock(t *testing.T, + handler func(http.ResponseWriter, *http.Request) error, + fn func(*serverTester), + checkErr func(error), + otherHeaders ...string) { + inHandler := make(chan bool) + errc := make(chan error, 1) + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + inHandler <- true + errc <- handler(w, r) + }) + st.greet() + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(append([]string{":method", "POST"}, otherHeaders...)...), + EndStream: false, // keep it open + EndHeaders: true, + }) + <-inHandler + fn(st) + select { + case err := <-errc: + if checkErr != nil { + checkErr(err) + } + case <-time.After(5 * time.Second): + t.Fatal("timeout waiting for Handler to return") + } + st.Close() +} + +func TestServer_RSTStream_Unblocks_Read(t *testing.T) { + testServerPostUnblock(t, + func(w http.ResponseWriter, r *http.Request) (err error) { + _, err = r.Body.Read(make([]byte, 1)) + return + }, + func(st *serverTester) { + if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { + t.Fatal(err) + } + }, + func(err error) { + want := StreamError{StreamID: 0x1, Code: 0x8} + if !reflect.DeepEqual(err, want) { + t.Errorf("Read error = %v; want %v", err, want) + } + }, + ) +} + +func TestServer_RSTStream_Unblocks_Header_Write(t *testing.T) { + // Run this test a bunch, because it doesn't always + // deadlock. But with a bunch, it did. + n := 50 + if testing.Short() { + n = 5 + } + for i := 0; i < n; i++ { + testServer_RSTStream_Unblocks_Header_Write(t) + } +} + +func testServer_RSTStream_Unblocks_Header_Write(t *testing.T) { + inHandler := make(chan bool, 1) + unblockHandler := make(chan bool, 1) + headerWritten := make(chan bool, 1) + wroteRST := make(chan bool, 1) + + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + inHandler <- true + <-wroteRST + w.Header().Set("foo", "bar") + w.WriteHeader(200) + w.(http.Flusher).Flush() + headerWritten <- true + <-unblockHandler + }) + defer st.Close() + + st.greet() + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, // keep it open + EndHeaders: true, + }) + <-inHandler + if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { + t.Fatal(err) + } + wroteRST <- true + st.awaitIdle() + select { + case <-headerWritten: + case <-time.After(2 * time.Second): + t.Error("timeout waiting for header write") + } + unblockHandler <- true +} + +func TestServer_DeadConn_Unblocks_Read(t *testing.T) { + testServerPostUnblock(t, + func(w http.ResponseWriter, r *http.Request) (err error) { + _, err = r.Body.Read(make([]byte, 1)) + return + }, + func(st *serverTester) { st.cc.Close() }, + func(err error) { + if err == nil { + t.Error("unexpected nil error from Request.Body.Read") + } + }, + ) +} + +var blockUntilClosed = func(w http.ResponseWriter, r *http.Request) error { + <-w.(http.CloseNotifier).CloseNotify() + return nil +} + +func TestServer_CloseNotify_After_RSTStream(t *testing.T) { + testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { + if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { + t.Fatal(err) + } + }, nil) +} + +func TestServer_CloseNotify_After_ConnClose(t *testing.T) { + testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { st.cc.Close() }, nil) +} + +// that CloseNotify unblocks after a stream error due to the client's +// problem that's unrelated to them explicitly canceling it (which is +// TestServer_CloseNotify_After_RSTStream above) +func TestServer_CloseNotify_After_StreamError(t *testing.T) { + testServerPostUnblock(t, blockUntilClosed, func(st *serverTester) { + // data longer than declared Content-Length => stream error + st.writeData(1, true, []byte("1234")) + }, nil, "content-length", "3") +} + +func TestServer_StateTransitions(t *testing.T) { + var st *serverTester + inHandler := make(chan bool) + writeData := make(chan bool) + leaveHandler := make(chan bool) + st = newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + inHandler <- true + if st.stream(1) == nil { + t.Errorf("nil stream 1 in handler") + } + if got, want := st.streamState(1), stateOpen; got != want { + t.Errorf("in handler, state is %v; want %v", got, want) + } + writeData <- true + if n, err := r.Body.Read(make([]byte, 1)); n != 0 || err != io.EOF { + t.Errorf("body read = %d, %v; want 0, EOF", n, err) + } + if got, want := st.streamState(1), stateHalfClosedRemote; got != want { + t.Errorf("in handler, state is %v; want %v", got, want) + } + + <-leaveHandler + }) + st.greet() + if st.stream(1) != nil { + t.Fatal("stream 1 should be empty") + } + if got := st.streamState(1); got != stateIdle { + t.Fatalf("stream 1 should be idle; got %v", got) + } + + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, // keep it open + EndHeaders: true, + }) + <-inHandler + <-writeData + st.writeData(1, true, nil) + + leaveHandler <- true + hf := st.wantHeaders() + if !hf.StreamEnded() { + t.Fatal("expected END_STREAM flag") + } + + if got, want := st.streamState(1), stateClosed; got != want { + t.Errorf("at end, state is %v; want %v", got, want) + } + if st.stream(1) != nil { + t.Fatal("at end, stream 1 should be gone") + } +} + +// test HEADERS w/o EndHeaders + another HEADERS (should get rejected) +func TestServer_Rejects_HeadersNoEnd_Then_Headers(t *testing.T) { + testServerRejectsConn(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: false, + }) + st.writeHeaders(HeadersFrameParam{ // Not a continuation. + StreamID: 3, // different stream. + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: true, + }) + }) +} + +// test HEADERS w/o EndHeaders + PING (should get rejected) +func TestServer_Rejects_HeadersNoEnd_Then_Ping(t *testing.T) { + testServerRejectsConn(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: false, + }) + if err := st.fr.WritePing(false, [8]byte{}); err != nil { + t.Fatal(err) + } + }) +} + +// test HEADERS w/ EndHeaders + a continuation HEADERS (should get rejected) +func TestServer_Rejects_HeadersEnd_Then_Continuation(t *testing.T) { + testServerRejectsConn(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: true, + }) + st.wantHeaders() + if err := st.fr.WriteContinuation(1, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil { + t.Fatal(err) + } + }) +} + +// test HEADERS w/o EndHeaders + a continuation HEADERS on wrong stream ID +func TestServer_Rejects_HeadersNoEnd_Then_ContinuationWrongStream(t *testing.T) { + testServerRejectsConn(t, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: false, + }) + if err := st.fr.WriteContinuation(3, true, encodeHeaderNoImplicit(t, "foo", "bar")); err != nil { + t.Fatal(err) + } + }) +} + +// No HEADERS on stream 0. +func TestServer_Rejects_Headers0(t *testing.T) { + testServerRejectsConn(t, func(st *serverTester) { + st.fr.AllowIllegalWrites = true + st.writeHeaders(HeadersFrameParam{ + StreamID: 0, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: true, + }) + }) +} + +// No CONTINUATION on stream 0. +func TestServer_Rejects_Continuation0(t *testing.T) { + testServerRejectsConn(t, func(st *serverTester) { + st.fr.AllowIllegalWrites = true + if err := st.fr.WriteContinuation(0, true, st.encodeHeader()); err != nil { + t.Fatal(err) + } + }) +} + +func TestServer_Rejects_PushPromise(t *testing.T) { + testServerRejectsConn(t, func(st *serverTester) { + pp := PushPromiseParam{ + StreamID: 1, + PromiseID: 3, + } + if err := st.fr.WritePushPromise(pp); err != nil { + t.Fatal(err) + } + }) +} + +// testServerRejectsConn tests that the server hangs up with a GOAWAY +// frame and a server close after the client does something +// deserving a CONNECTION_ERROR. +func testServerRejectsConn(t *testing.T, writeReq func(*serverTester)) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}) + st.addLogFilter("connection error: PROTOCOL_ERROR") + defer st.Close() + st.greet() + writeReq(st) + + st.wantGoAway() + errc := make(chan error, 1) + go func() { + fr, err := st.fr.ReadFrame() + if err == nil { + err = fmt.Errorf("got frame of type %T", fr) + } + errc <- err + }() + select { + case err := <-errc: + if err != io.EOF { + t.Errorf("ReadFrame = %v; want io.EOF", err) + } + case <-time.After(2 * time.Second): + t.Error("timeout waiting for disconnect") + } +} + +// testServerRejectsStream tests that the server sends a RST_STREAM with the provided +// error code after a client sends a bogus request. +func testServerRejectsStream(t *testing.T, code ErrCode, writeReq func(*serverTester)) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}) + defer st.Close() + st.greet() + writeReq(st) + st.wantRSTStream(1, code) +} + +// testServerRequest sets up an idle HTTP/2 connection and lets you +// write a single request with writeReq, and then verify that the +// *http.Request is built correctly in checkReq. +func testServerRequest(t *testing.T, writeReq func(*serverTester), checkReq func(*http.Request)) { + gotReq := make(chan bool, 1) + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + if r.Body == nil { + t.Fatal("nil Body") + } + checkReq(r) + gotReq <- true + }) + defer st.Close() + + st.greet() + writeReq(st) + + select { + case <-gotReq: + case <-time.After(2 * time.Second): + t.Error("timeout waiting for request") + } +} + +func getSlash(st *serverTester) { st.bodylessReq1() } + +func TestServer_Response_NoData(t *testing.T) { + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + // Nothing. + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if !hf.StreamEnded() { + t.Fatal("want END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + }) +} + +func TestServer_Response_NoData_Header_FooBar(t *testing.T) { + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Set("Foo-Bar", "some-value") + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if !hf.StreamEnded() { + t.Fatal("want END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"foo-bar", "some-value"}, + {"content-type", "text/plain; charset=utf-8"}, + {"content-length", "0"}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + }) +} + +func TestServer_Response_Data_Sniff_DoesntOverride(t *testing.T) { + const msg = "this is HTML." + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Set("Content-Type", "foo/bar") + io.WriteString(w, msg) + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("don't want END_STREAM, expecting data") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"content-type", "foo/bar"}, + {"content-length", strconv.Itoa(len(msg))}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + df := st.wantData() + if !df.StreamEnded() { + t.Error("expected DATA to have END_STREAM flag") + } + if got := string(df.Data()); got != msg { + t.Errorf("got DATA %q; want %q", got, msg) + } + }) +} + +func TestServer_Response_TransferEncoding_chunked(t *testing.T) { + const msg = "hi" + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Set("Transfer-Encoding", "chunked") // should be stripped + io.WriteString(w, msg) + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"content-type", "text/plain; charset=utf-8"}, + {"content-length", strconv.Itoa(len(msg))}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + }) +} + +// Header accessed only after the initial write. +func TestServer_Response_Data_IgnoreHeaderAfterWrite_After(t *testing.T) { + const msg = "this is HTML." + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + io.WriteString(w, msg) + w.Header().Set("foo", "should be ignored") + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"content-type", "text/html; charset=utf-8"}, + {"content-length", strconv.Itoa(len(msg))}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + }) +} + +// Header accessed before the initial write and later mutated. +func TestServer_Response_Data_IgnoreHeaderAfterWrite_Overwrite(t *testing.T) { + const msg = "this is HTML." + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Set("foo", "proper value") + io.WriteString(w, msg) + w.Header().Set("foo", "should be ignored") + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"foo", "proper value"}, + {"content-type", "text/html; charset=utf-8"}, + {"content-length", strconv.Itoa(len(msg))}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + }) +} + +func TestServer_Response_Data_SniffLenType(t *testing.T) { + const msg = "this is HTML." + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + io.WriteString(w, msg) + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("don't want END_STREAM, expecting data") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"content-type", "text/html; charset=utf-8"}, + {"content-length", strconv.Itoa(len(msg))}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + df := st.wantData() + if !df.StreamEnded() { + t.Error("expected DATA to have END_STREAM flag") + } + if got := string(df.Data()); got != msg { + t.Errorf("got DATA %q; want %q", got, msg) + } + }) +} + +func TestServer_Response_Header_Flush_MidWrite(t *testing.T) { + const msg = "this is HTML" + const msg2 = ", and this is the next chunk" + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + io.WriteString(w, msg) + w.(http.Flusher).Flush() + io.WriteString(w, msg2) + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"content-type", "text/html; charset=utf-8"}, // sniffed + // and no content-length + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + { + df := st.wantData() + if df.StreamEnded() { + t.Error("unexpected END_STREAM flag") + } + if got := string(df.Data()); got != msg { + t.Errorf("got DATA %q; want %q", got, msg) + } + } + { + df := st.wantData() + if !df.StreamEnded() { + t.Error("wanted END_STREAM flag on last data chunk") + } + if got := string(df.Data()); got != msg2 { + t.Errorf("got DATA %q; want %q", got, msg2) + } + } + }) +} + +func TestServer_Response_LargeWrite(t *testing.T) { + const size = 1 << 20 + const maxFrameSize = 16 << 10 + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + n, err := w.Write(bytes.Repeat([]byte("a"), size)) + if err != nil { + return fmt.Errorf("Write error: %v", err) + } + if n != size { + return fmt.Errorf("wrong size %d from Write", n) + } + return nil + }, func(st *serverTester) { + if err := st.fr.WriteSettings( + Setting{SettingInitialWindowSize, 0}, + Setting{SettingMaxFrameSize, maxFrameSize}, + ); err != nil { + t.Fatal(err) + } + st.wantSettingsAck() + + getSlash(st) // make the single request + + // Give the handler quota to write: + if err := st.fr.WriteWindowUpdate(1, size); err != nil { + t.Fatal(err) + } + // Give the handler quota to write to connection-level + // window as well + if err := st.fr.WriteWindowUpdate(0, size); err != nil { + t.Fatal(err) + } + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"content-type", "text/plain; charset=utf-8"}, // sniffed + // and no content-length + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + var bytes, frames int + for { + df := st.wantData() + bytes += len(df.Data()) + frames++ + for _, b := range df.Data() { + if b != 'a' { + t.Fatal("non-'a' byte seen in DATA") + } + } + if df.StreamEnded() { + break + } + } + if bytes != size { + t.Errorf("Got %d bytes; want %d", bytes, size) + } + if want := int(size / maxFrameSize); frames < want || frames > want*2 { + t.Errorf("Got %d frames; want %d", frames, size) + } + }) +} + +// Test that the handler can't write more than the client allows +func TestServer_Response_LargeWrite_FlowControlled(t *testing.T) { + const size = 1 << 20 + const maxFrameSize = 16 << 10 + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.(http.Flusher).Flush() + n, err := w.Write(bytes.Repeat([]byte("a"), size)) + if err != nil { + return fmt.Errorf("Write error: %v", err) + } + if n != size { + return fmt.Errorf("wrong size %d from Write", n) + } + return nil + }, func(st *serverTester) { + // Set the window size to something explicit for this test. + // It's also how much initial data we expect. + const initWindowSize = 123 + if err := st.fr.WriteSettings( + Setting{SettingInitialWindowSize, initWindowSize}, + Setting{SettingMaxFrameSize, maxFrameSize}, + ); err != nil { + t.Fatal(err) + } + st.wantSettingsAck() + + getSlash(st) // make the single request + defer func() { st.fr.WriteRSTStream(1, ErrCodeCancel) }() + + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + + df := st.wantData() + if got := len(df.Data()); got != initWindowSize { + t.Fatalf("Initial window size = %d but got DATA with %d bytes", initWindowSize, got) + } + + for _, quota := range []int{1, 13, 127} { + if err := st.fr.WriteWindowUpdate(1, uint32(quota)); err != nil { + t.Fatal(err) + } + df := st.wantData() + if int(quota) != len(df.Data()) { + t.Fatalf("read %d bytes after giving %d quota", len(df.Data()), quota) + } + } + + if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { + t.Fatal(err) + } + }) +} + +// Test that the handler blocked in a Write is unblocked if the server sends a RST_STREAM. +func TestServer_Response_RST_Unblocks_LargeWrite(t *testing.T) { + const size = 1 << 20 + const maxFrameSize = 16 << 10 + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.(http.Flusher).Flush() + errc := make(chan error, 1) + go func() { + _, err := w.Write(bytes.Repeat([]byte("a"), size)) + errc <- err + }() + select { + case err := <-errc: + if err == nil { + return errors.New("unexpected nil error from Write in handler") + } + return nil + case <-time.After(2 * time.Second): + return errors.New("timeout waiting for Write in handler") + } + }, func(st *serverTester) { + if err := st.fr.WriteSettings( + Setting{SettingInitialWindowSize, 0}, + Setting{SettingMaxFrameSize, maxFrameSize}, + ); err != nil { + t.Fatal(err) + } + st.wantSettingsAck() + + getSlash(st) // make the single request + + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + + if err := st.fr.WriteRSTStream(1, ErrCodeCancel); err != nil { + t.Fatal(err) + } + }) +} + +func TestServer_Response_Empty_Data_Not_FlowControlled(t *testing.T) { + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.(http.Flusher).Flush() + // Nothing; send empty DATA + return nil + }, func(st *serverTester) { + // Handler gets no data quota: + if err := st.fr.WriteSettings(Setting{SettingInitialWindowSize, 0}); err != nil { + t.Fatal(err) + } + st.wantSettingsAck() + + getSlash(st) // make the single request + + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + + df := st.wantData() + if got := len(df.Data()); got != 0 { + t.Fatalf("unexpected %d DATA bytes; want 0", got) + } + if !df.StreamEnded() { + t.Fatal("DATA didn't have END_STREAM") + } + }) +} + +func TestServer_Response_Automatic100Continue(t *testing.T) { + const msg = "foo" + const reply = "bar" + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + if v := r.Header.Get("Expect"); v != "" { + t.Errorf("Expect header = %q; want empty", v) + } + buf := make([]byte, len(msg)) + // This read should trigger the 100-continue being sent. + if n, err := io.ReadFull(r.Body, buf); err != nil || n != len(msg) || string(buf) != msg { + return fmt.Errorf("ReadFull = %q, %v; want %q, nil", buf[:n], err, msg) + } + _, err := io.WriteString(w, reply) + return err + }, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "POST", "expect", "100-continue"), + EndStream: false, + EndHeaders: true, + }) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "100"}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Fatalf("Got headers %v; want %v", goth, wanth) + } + + // Okay, they sent status 100, so we can send our + // gigantic and/or sensitive "foo" payload now. + st.writeData(1, true, []byte(msg)) + + st.wantWindowUpdate(0, uint32(len(msg))) + + hf = st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("expected data to follow") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + goth = st.decodeHeader(hf.HeaderBlockFragment()) + wanth = [][2]string{ + {":status", "200"}, + {"content-type", "text/plain; charset=utf-8"}, + {"content-length", strconv.Itoa(len(reply))}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Got headers %v; want %v", goth, wanth) + } + + df := st.wantData() + if string(df.Data()) != reply { + t.Errorf("Client read %q; want %q", df.Data(), reply) + } + if !df.StreamEnded() { + t.Errorf("expect data stream end") + } + }) +} + +func TestServer_HandlerWriteErrorOnDisconnect(t *testing.T) { + errc := make(chan error, 1) + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + p := []byte("some data.\n") + for { + _, err := w.Write(p) + if err != nil { + errc <- err + return nil + } + } + }, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: false, + EndHeaders: true, + }) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("unexpected END_STREAM flag") + } + if !hf.HeadersEnded() { + t.Fatal("want END_HEADERS flag") + } + // Close the connection and wait for the handler to (hopefully) notice. + st.cc.Close() + select { + case <-errc: + case <-time.After(5 * time.Second): + t.Error("timeout") + } + }) +} + +func TestServer_Rejects_Too_Many_Streams(t *testing.T) { + const testPath = "/some/path" + + inHandler := make(chan uint32) + leaveHandler := make(chan bool) + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + id := w.(*responseWriter).rws.stream.id + inHandler <- id + if id == 1+(defaultMaxStreams+1)*2 && r.URL.Path != testPath { + t.Errorf("decoded final path as %q; want %q", r.URL.Path, testPath) + } + <-leaveHandler + }) + defer st.Close() + st.greet() + nextStreamID := uint32(1) + streamID := func() uint32 { + defer func() { nextStreamID += 2 }() + return nextStreamID + } + sendReq := func(id uint32, headers ...string) { + st.writeHeaders(HeadersFrameParam{ + StreamID: id, + BlockFragment: st.encodeHeader(headers...), + EndStream: true, + EndHeaders: true, + }) + } + for i := 0; i < defaultMaxStreams; i++ { + sendReq(streamID()) + <-inHandler + } + defer func() { + for i := 0; i < defaultMaxStreams; i++ { + leaveHandler <- true + } + }() + + // And this one should cross the limit: + // (It's also sent as a CONTINUATION, to verify we still track the decoder context, + // even if we're rejecting it) + rejectID := streamID() + headerBlock := st.encodeHeader(":path", testPath) + frag1, frag2 := headerBlock[:3], headerBlock[3:] + st.writeHeaders(HeadersFrameParam{ + StreamID: rejectID, + BlockFragment: frag1, + EndStream: true, + EndHeaders: false, // CONTINUATION coming + }) + if err := st.fr.WriteContinuation(rejectID, true, frag2); err != nil { + t.Fatal(err) + } + st.wantRSTStream(rejectID, ErrCodeProtocol) + + // But let a handler finish: + leaveHandler <- true + st.wantHeaders() + + // And now another stream should be able to start: + goodID := streamID() + sendReq(goodID, ":path", testPath) + select { + case got := <-inHandler: + if got != goodID { + t.Errorf("Got stream %d; want %d", got, goodID) + } + case <-time.After(3 * time.Second): + t.Error("timeout waiting for handler") + } +} + +// So many response headers that the server needs to use CONTINUATION frames: +func TestServer_Response_ManyHeaders_With_Continuation(t *testing.T) { + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + h := w.Header() + for i := 0; i < 5000; i++ { + h.Set(fmt.Sprintf("x-header-%d", i), fmt.Sprintf("x-value-%d", i)) + } + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.HeadersEnded() { + t.Fatal("got unwanted END_HEADERS flag") + } + n := 0 + for { + n++ + cf := st.wantContinuation() + if cf.HeadersEnded() { + break + } + } + if n < 5 { + t.Errorf("Only got %d CONTINUATION frames; expected 5+ (currently 6)", n) + } + }) +} + +// This previously crashed (reported by Mathieu Lonjaret as observed +// while using Camlistore) because we got a DATA frame from the client +// after the handler exited and our logic at the time was wrong, +// keeping a stream in the map in stateClosed, which tickled an +// invariant check later when we tried to remove that stream (via +// defer sc.closeAllStreamsOnConnClose) when the serverConn serve loop +// ended. +func TestServer_NoCrash_HandlerClose_Then_ClientClose(t *testing.T) { + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + // nothing + return nil + }, func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: false, // DATA is coming + EndHeaders: true, + }) + hf := st.wantHeaders() + if !hf.HeadersEnded() || !hf.StreamEnded() { + t.Fatalf("want END_HEADERS+END_STREAM, got %v", hf) + } + + // Sent when the a Handler closes while a client has + // indicated it's still sending DATA: + st.wantRSTStream(1, ErrCodeCancel) + + // Now the handler has ended, so it's ended its + // stream, but the client hasn't closed its side + // (stateClosedLocal). So send more data and verify + // it doesn't crash with an internal invariant panic, like + // it did before. + st.writeData(1, true, []byte("foo")) + + // Sent after a peer sends data anyway (admittedly the + // previous RST_STREAM might've still been in-flight), + // but they'll get the more friendly 'cancel' code + // first. + st.wantRSTStream(1, ErrCodeStreamClosed) + + // Set up a bunch of machinery to record the panic we saw + // previously. + var ( + panMu sync.Mutex + panicVal interface{} + ) + + testHookOnPanicMu.Lock() + testHookOnPanic = func(sc *serverConn, pv interface{}) bool { + panMu.Lock() + panicVal = pv + panMu.Unlock() + return true + } + testHookOnPanicMu.Unlock() + + // Now force the serve loop to end, via closing the connection. + st.cc.Close() + select { + case <-st.sc.doneServing: + // Loop has exited. + panMu.Lock() + got := panicVal + panMu.Unlock() + if got != nil { + t.Errorf("Got panic: %v", got) + } + case <-time.After(5 * time.Second): + t.Error("timeout") + } + }) +} + +func TestServer_Rejects_TLS10(t *testing.T) { testRejectTLS(t, tls.VersionTLS10) } +func TestServer_Rejects_TLS11(t *testing.T) { testRejectTLS(t, tls.VersionTLS11) } + +func testRejectTLS(t *testing.T, max uint16) { + st := newServerTester(t, nil, func(c *tls.Config) { + c.MaxVersion = max + }) + defer st.Close() + gf := st.wantGoAway() + if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want { + t.Errorf("Got error code %v; want %v", got, want) + } +} + +func TestServer_Rejects_TLSBadCipher(t *testing.T) { + st := newServerTester(t, nil, func(c *tls.Config) { + // Only list bad ones: + c.CipherSuites = []uint16{ + tls.TLS_RSA_WITH_RC4_128_SHA, + tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA, + tls.TLS_RSA_WITH_AES_128_CBC_SHA, + tls.TLS_RSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA, + tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + } + }) + defer st.Close() + gf := st.wantGoAway() + if got, want := gf.ErrCode, ErrCodeInadequateSecurity; got != want { + t.Errorf("Got error code %v; want %v", got, want) + } +} + +func TestServer_Advertises_Common_Cipher(t *testing.T) { + const requiredSuite = tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + st := newServerTester(t, nil, func(c *tls.Config) { + // Have the client only support the one required by the spec. + c.CipherSuites = []uint16{requiredSuite} + }, func(ts *httptest.Server) { + var srv *http.Server = ts.Config + // Have the server configured with no specific cipher suites. + // This tests that Go's defaults include the required one. + srv.TLSConfig = nil + }) + defer st.Close() + st.greet() +} + +func (st *serverTester) onHeaderField(f hpack.HeaderField) { + if f.Name == "date" { + return + } + st.decodedHeaders = append(st.decodedHeaders, [2]string{f.Name, f.Value}) +} + +func (st *serverTester) decodeHeader(headerBlock []byte) (pairs [][2]string) { + st.decodedHeaders = nil + if _, err := st.hpackDec.Write(headerBlock); err != nil { + st.t.Fatalf("hpack decoding error: %v", err) + } + if err := st.hpackDec.Close(); err != nil { + st.t.Fatalf("hpack decoding error: %v", err) + } + return st.decodedHeaders +} + +// testServerResponse sets up an idle HTTP/2 connection and lets you +// write a single request with writeReq, and then reply to it in some way with the provided handler, +// and then verify the output with the serverTester again (assuming the handler returns nil) +func testServerResponse(t testing.TB, + handler func(http.ResponseWriter, *http.Request) error, + client func(*serverTester), +) { + errc := make(chan error, 1) + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + if r.Body == nil { + t.Fatal("nil Body") + } + errc <- handler(w, r) + }) + defer st.Close() + + donec := make(chan bool) + go func() { + defer close(donec) + st.greet() + client(st) + }() + + select { + case <-donec: + return + case <-time.After(5 * time.Second): + t.Fatal("timeout") + } + + select { + case err := <-errc: + if err != nil { + t.Fatalf("Error in handler: %v", err) + } + case <-time.After(2 * time.Second): + t.Error("timeout waiting for handler to finish") + } +} + +// readBodyHandler returns an http Handler func that reads len(want) +// bytes from r.Body and fails t if the contents read were not +// the value of want. +func readBodyHandler(t *testing.T, want string) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { + buf := make([]byte, len(want)) + _, err := io.ReadFull(r.Body, buf) + if err != nil { + t.Error(err) + return + } + if string(buf) != want { + t.Errorf("read %q; want %q", buf, want) + } + } +} + +// TestServerWithCurl currently fails, hence the LenientCipherSuites test. See: +// https://github.com/tatsuhiro-t/nghttp2/issues/140 & +// http://sourceforge.net/p/curl/bugs/1472/ +func TestServerWithCurl(t *testing.T) { testServerWithCurl(t, false) } +func TestServerWithCurl_LenientCipherSuites(t *testing.T) { testServerWithCurl(t, true) } + +func testServerWithCurl(t *testing.T, permitProhibitedCipherSuites bool) { + if runtime.GOOS != "linux" { + t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway") + } + if testing.Short() { + t.Skip("skipping curl test in short mode") + } + requireCurl(t) + var gotConn int32 + testHookOnConn = func() { atomic.StoreInt32(&gotConn, 1) } + + const msg = "Hello from curl!\n" + ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Foo", "Bar") + w.Header().Set("Client-Proto", r.Proto) + io.WriteString(w, msg) + })) + ConfigureServer(ts.Config, &Server{ + PermitProhibitedCipherSuites: permitProhibitedCipherSuites, + }) + ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config + ts.StartTLS() + defer ts.Close() + + t.Logf("Running test server for curl to hit at: %s", ts.URL) + container := curl(t, "--silent", "--http2", "--insecure", "-v", ts.URL) + defer kill(container) + resc := make(chan interface{}, 1) + go func() { + res, err := dockerLogs(container) + if err != nil { + resc <- err + } else { + resc <- res + } + }() + select { + case res := <-resc: + if err, ok := res.(error); ok { + t.Fatal(err) + } + body := string(res.([]byte)) + // Search for both "key: value" and "key:value", since curl changed their format + // Our Dockerfile contains the latest version (no space), but just in case people + // didn't rebuild, check both. + if !strings.Contains(body, "foo: Bar") && !strings.Contains(body, "foo:Bar") { + t.Errorf("didn't see foo: Bar header") + t.Logf("Got: %s", body) + } + if !strings.Contains(body, "client-proto: HTTP/2") && !strings.Contains(body, "client-proto:HTTP/2") { + t.Errorf("didn't see client-proto: HTTP/2 header") + t.Logf("Got: %s", res) + } + if !strings.Contains(string(res.([]byte)), msg) { + t.Errorf("didn't see %q content", msg) + t.Logf("Got: %s", res) + } + case <-time.After(3 * time.Second): + t.Errorf("timeout waiting for curl") + } + + if atomic.LoadInt32(&gotConn) == 0 { + t.Error("never saw an http2 connection") + } +} + +var doh2load = flag.Bool("h2load", false, "Run h2load test") + +func TestServerWithH2Load(t *testing.T) { + if !*doh2load { + t.Skip("Skipping without --h2load flag.") + } + if runtime.GOOS != "linux" { + t.Skip("skipping Docker test when not on Linux; requires --net which won't work with boot2docker anyway") + } + requireH2load(t) + + msg := strings.Repeat("Hello, h2load!\n", 5000) + ts := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, msg) + w.(http.Flusher).Flush() + io.WriteString(w, msg) + })) + ts.StartTLS() + defer ts.Close() + + cmd := exec.Command("docker", "run", "--net=host", "--entrypoint=/usr/local/bin/h2load", "gohttp2/curl", + "-n100000", "-c100", "-m100", ts.URL) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + t.Fatal(err) + } +} + +// Issue 12843 +func TestServerDoS_MaxHeaderListSize(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {}) + defer st.Close() + + // shake hands + st.writePreface() + st.writeInitialSettings() + frameSize := defaultMaxReadFrameSize + var advHeaderListSize *uint32 + st.wantSettings().ForeachSetting(func(s Setting) error { + switch s.ID { + case SettingMaxFrameSize: + if s.Val < minMaxFrameSize { + frameSize = minMaxFrameSize + } else if s.Val > maxFrameSize { + frameSize = maxFrameSize + } else { + frameSize = int(s.Val) + } + case SettingMaxHeaderListSize: + advHeaderListSize = &s.Val + } + return nil + }) + st.writeSettingsAck() + st.wantSettingsAck() + + if advHeaderListSize == nil { + t.Errorf("server didn't advertise a max header list size") + } else if *advHeaderListSize == 0 { + t.Errorf("server advertised a max header list size of 0") + } + + st.encodeHeaderField(":method", "GET") + st.encodeHeaderField(":path", "/") + st.encodeHeaderField(":scheme", "https") + cookie := strings.Repeat("*", 4058) + st.encodeHeaderField("cookie", cookie) + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.headerBuf.Bytes(), + EndStream: true, + EndHeaders: false, + }) + + // Capture the short encoding of a duplicate ~4K cookie, now + // that we've already sent it once. + st.headerBuf.Reset() + st.encodeHeaderField("cookie", cookie) + + // Now send 1MB of it. + const size = 1 << 20 + b := bytes.Repeat(st.headerBuf.Bytes(), size/st.headerBuf.Len()) + for len(b) > 0 { + chunk := b + if len(chunk) > frameSize { + chunk = chunk[:frameSize] + } + b = b[len(chunk):] + st.fr.WriteContinuation(1, len(b) == 0, chunk) + } + + h := st.wantHeaders() + if !h.HeadersEnded() { + t.Fatalf("Got HEADERS without END_HEADERS set: %v", h) + } + headers := st.decodeHeader(h.HeaderBlockFragment()) + want := [][2]string{ + {":status", "431"}, + {"content-type", "text/html; charset=utf-8"}, + {"content-length", "63"}, + } + if !reflect.DeepEqual(headers, want) { + t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want) + } +} + +func TestCompressionErrorOnWrite(t *testing.T) { + const maxStrLen = 8 << 10 + var serverConfig *http.Server + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + // No response body. + }, func(ts *httptest.Server) { + serverConfig = ts.Config + serverConfig.MaxHeaderBytes = maxStrLen + }) + st.addLogFilter("connection error: COMPRESSION_ERROR") + defer st.Close() + st.greet() + + maxAllowed := st.sc.maxHeaderStringLen() + + // Crank this up, now that we have a conn connected with the + // hpack.Decoder's max string length set has been initialized + // from the earlier low ~8K value. We want this higher so don't + // hit the max header list size. We only want to test hitting + // the max string size. + serverConfig.MaxHeaderBytes = 1 << 20 + + // First a request with a header that's exactly the max allowed size. + hbf := st.encodeHeader("foo", strings.Repeat("a", maxAllowed)) + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: hbf, + EndStream: true, + EndHeaders: true, + }) + h := st.wantHeaders() + if !h.HeadersEnded() || !h.StreamEnded() { + t.Errorf("Unexpected HEADER frame %v", h) + } + + // And now send one that's just one byte too big. + hbf = st.encodeHeader("bar", strings.Repeat("b", maxAllowed+1)) + st.writeHeaders(HeadersFrameParam{ + StreamID: 3, + BlockFragment: hbf, + EndStream: true, + EndHeaders: true, + }) + ga := st.wantGoAway() + if ga.ErrCode != ErrCodeCompression { + t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode) + } +} + +func TestCompressionErrorOnClose(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + // No response body. + }) + st.addLogFilter("connection error: COMPRESSION_ERROR") + defer st.Close() + st.greet() + + hbf := st.encodeHeader("foo", "bar") + hbf = hbf[:len(hbf)-1] // truncate one byte from the end, so hpack.Decoder.Close fails. + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: hbf, + EndStream: true, + EndHeaders: true, + }) + ga := st.wantGoAway() + if ga.ErrCode != ErrCodeCompression { + t.Errorf("GOAWAY err = %v; want ErrCodeCompression", ga.ErrCode) + } +} + +// test that a server handler can read trailers from a client +func TestServerReadsTrailers(t *testing.T) { + const testBody = "some test body" + writeReq := func(st *serverTester) { + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader("trailer", "Foo, Bar", "trailer", "Baz"), + EndStream: false, + EndHeaders: true, + }) + st.writeData(1, false, []byte(testBody)) + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeaderRaw( + "foo", "foov", + "bar", "barv", + "baz", "bazv", + "surprise", "wasn't declared; shouldn't show up", + ), + EndStream: true, + EndHeaders: true, + }) + } + checkReq := func(r *http.Request) { + wantTrailer := http.Header{ + "Foo": nil, + "Bar": nil, + "Baz": nil, + } + if !reflect.DeepEqual(r.Trailer, wantTrailer) { + t.Errorf("initial Trailer = %v; want %v", r.Trailer, wantTrailer) + } + slurp, err := ioutil.ReadAll(r.Body) + if string(slurp) != testBody { + t.Errorf("read body %q; want %q", slurp, testBody) + } + if err != nil { + t.Fatalf("Body slurp: %v", err) + } + wantTrailerAfter := http.Header{ + "Foo": {"foov"}, + "Bar": {"barv"}, + "Baz": {"bazv"}, + } + if !reflect.DeepEqual(r.Trailer, wantTrailerAfter) { + t.Errorf("final Trailer = %v; want %v", r.Trailer, wantTrailerAfter) + } + } + testServerRequest(t, writeReq, checkReq) +} + +// test that a server handler can send trailers +func TestServerWritesTrailers_WithFlush(t *testing.T) { testServerWritesTrailers(t, true) } +func TestServerWritesTrailers_WithoutFlush(t *testing.T) { testServerWritesTrailers(t, false) } + +func testServerWritesTrailers(t *testing.T, withFlush bool) { + // See https://httpwg.github.io/specs/rfc7540.html#rfc.section.8.1.3 + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Set("Trailer", "Server-Trailer-A, Server-Trailer-B") + w.Header().Add("Trailer", "Server-Trailer-C") + + // TODO: decide if the server should filter these while + // writing the Trailer header in the response. Currently it + // appears net/http doesn't do this for http/1.1 + w.Header().Add("Trailer", "Transfer-Encoding, Content-Length, Trailer") // filtered + w.Header().Set("Foo", "Bar") + w.Header().Set("Content-Length", "5") + + io.WriteString(w, "Hello") + if withFlush { + w.(http.Flusher).Flush() + } + w.Header().Set("Server-Trailer-A", "valuea") + w.Header().Set("Server-Trailer-C", "valuec") // skipping B + // After a flush, random keys like Server-Surprise shouldn't show up: + w.Header().Set("Server-Surpise", "surprise! this isn't predeclared!") + // But we do permit promoting keys to trailers after a + // flush if they start with the magic + // otherwise-invalid "Trailer:" prefix: + w.Header().Set("Trailer:Post-Header-Trailer", "hi1") + w.Header().Set("Trailer:post-header-trailer2", "hi2") + w.Header().Set("Transfer-Encoding", "should not be included; Forbidden by RFC 2616 14.40") + w.Header().Set("Content-Length", "should not be included; Forbidden by RFC 2616 14.40") + w.Header().Set("Trailer", "should not be included; Forbidden by RFC 2616 14.40") + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if hf.StreamEnded() { + t.Fatal("response HEADERS had END_STREAM") + } + if !hf.HeadersEnded() { + t.Fatal("response HEADERS didn't have END_HEADERS") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"foo", "Bar"}, + {"trailer", "Server-Trailer-A, Server-Trailer-B"}, + {"trailer", "Server-Trailer-C"}, + {"trailer", "Transfer-Encoding, Content-Length, Trailer"}, + {"content-type", "text/plain; charset=utf-8"}, + {"content-length", "5"}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth) + } + df := st.wantData() + if string(df.Data()) != "Hello" { + t.Fatalf("Client read %q; want Hello", df.Data()) + } + if df.StreamEnded() { + t.Fatalf("data frame had STREAM_ENDED") + } + tf := st.wantHeaders() // for the trailers + if !tf.StreamEnded() { + t.Fatalf("trailers HEADERS lacked END_STREAM") + } + if !tf.HeadersEnded() { + t.Fatalf("trailers HEADERS lacked END_HEADERS") + } + wanth = [][2]string{ + {"post-header-trailer", "hi1"}, + {"post-header-trailer2", "hi2"}, + {"server-trailer-a", "valuea"}, + {"server-trailer-c", "valuec"}, + } + goth = st.decodeHeader(tf.HeaderBlockFragment()) + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth) + } + }) +} + +// validate transmitted header field names & values +// golang.org/issue/14048 +func TestServerDoesntWriteInvalidHeaders(t *testing.T) { + testServerResponse(t, func(w http.ResponseWriter, r *http.Request) error { + w.Header().Add("OK1", "x") + w.Header().Add("Bad:Colon", "x") // colon (non-token byte) in key + w.Header().Add("Bad1\x00", "x") // null in key + w.Header().Add("Bad2", "x\x00y") // null in value + return nil + }, func(st *serverTester) { + getSlash(st) + hf := st.wantHeaders() + if !hf.StreamEnded() { + t.Error("response HEADERS lacked END_STREAM") + } + if !hf.HeadersEnded() { + t.Fatal("response HEADERS didn't have END_HEADERS") + } + goth := st.decodeHeader(hf.HeaderBlockFragment()) + wanth := [][2]string{ + {":status", "200"}, + {"ok1", "x"}, + {"content-type", "text/plain; charset=utf-8"}, + {"content-length", "0"}, + } + if !reflect.DeepEqual(goth, wanth) { + t.Errorf("Header mismatch.\n got: %v\nwant: %v", goth, wanth) + } + }) +} + +func BenchmarkServerGets(b *testing.B) { + b.ReportAllocs() + + const msg = "Hello, world" + st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, msg) + }) + defer st.Close() + st.greet() + + // Give the server quota to reply. (plus it has the the 64KB) + if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil { + b.Fatal(err) + } + + for i := 0; i < b.N; i++ { + id := 1 + uint32(i)*2 + st.writeHeaders(HeadersFrameParam{ + StreamID: id, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: true, + }) + st.wantHeaders() + df := st.wantData() + if !df.StreamEnded() { + b.Fatalf("DATA didn't have END_STREAM; got %v", df) + } + } +} + +func BenchmarkServerPosts(b *testing.B) { + b.ReportAllocs() + + const msg = "Hello, world" + st := newServerTester(b, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, msg) + }) + defer st.Close() + st.greet() + + // Give the server quota to reply. (plus it has the the 64KB) + if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil { + b.Fatal(err) + } + + for i := 0; i < b.N; i++ { + id := 1 + uint32(i)*2 + st.writeHeaders(HeadersFrameParam{ + StreamID: id, + BlockFragment: st.encodeHeader(":method", "POST"), + EndStream: false, + EndHeaders: true, + }) + st.writeData(id, true, nil) + st.wantHeaders() + df := st.wantData() + if !df.StreamEnded() { + b.Fatalf("DATA didn't have END_STREAM; got %v", df) + } + } +} + +// go-fuzz bug, originally reported at https://github.com/bradfitz/http2/issues/53 +// Verify we don't hang. +func TestIssue53(t *testing.T) { + const data = "PRI * HTTP/2.0\r\n\r\nSM" + + "\r\n\r\n\x00\x00\x00\x01\ainfinfin\ad" + s := &http.Server{ + ErrorLog: log.New(io.MultiWriter(stderrv(), twriter{t: t}), "", log.LstdFlags), + Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + w.Write([]byte("hello")) + }), + } + s2 := &Server{ + MaxReadFrameSize: 1 << 16, + PermitProhibitedCipherSuites: true, + } + c := &issue53Conn{[]byte(data), false, false} + s2.ServeConn(c, &ServeConnOpts{BaseConfig: s}) + if !c.closed { + t.Fatal("connection is not closed") + } +} + +type issue53Conn struct { + data []byte + closed bool + written bool +} + +func (c *issue53Conn) Read(b []byte) (n int, err error) { + if len(c.data) == 0 { + return 0, io.EOF + } + n = copy(b, c.data) + c.data = c.data[n:] + return +} + +func (c *issue53Conn) Write(b []byte) (n int, err error) { + c.written = true + return len(b), nil +} + +func (c *issue53Conn) Close() error { + c.closed = true + return nil +} + +func (c *issue53Conn) LocalAddr() net.Addr { return &net.TCPAddr{net.IP{127, 0, 0, 1}, 49706, ""} } +func (c *issue53Conn) RemoteAddr() net.Addr { return &net.TCPAddr{net.IP{127, 0, 0, 1}, 49706, ""} } +func (c *issue53Conn) SetDeadline(t time.Time) error { return nil } +func (c *issue53Conn) SetReadDeadline(t time.Time) error { return nil } +func (c *issue53Conn) SetWriteDeadline(t time.Time) error { return nil } + +// golang.org/issue/12895 +func TestConfigureServer(t *testing.T) { + tests := []struct { + name string + in http.Server + wantErr string + }{ + { + name: "empty server", + in: http.Server{}, + }, + { + name: "just the required cipher suite", + in: http.Server{ + TLSConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + }, + }, + }, + { + name: "missing required cipher suite", + in: http.Server{ + TLSConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384}, + }, + }, + wantErr: "is missing HTTP/2-required TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + }, + { + name: "required after bad", + in: http.Server{ + TLSConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_RSA_WITH_RC4_128_SHA, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256}, + }, + }, + wantErr: "contains an HTTP/2-approved cipher suite (0xc02f), but it comes after", + }, + { + name: "bad after required", + in: http.Server{ + TLSConfig: &tls.Config{ + CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_RSA_WITH_RC4_128_SHA}, + }, + }, + }, + } + for _, tt := range tests { + err := ConfigureServer(&tt.in, nil) + if (err != nil) != (tt.wantErr != "") { + if tt.wantErr != "" { + t.Errorf("%s: success, but want error", tt.name) + } else { + t.Errorf("%s: unexpected error: %v", tt.name, err) + } + } + if err != nil && tt.wantErr != "" && !strings.Contains(err.Error(), tt.wantErr) { + t.Errorf("%s: err = %v; want substring %q", tt.name, err, tt.wantErr) + } + if err == nil && !tt.in.TLSConfig.PreferServerCipherSuites { + t.Errorf("%s: PreferServerCipherSuite is false; want true", tt.name) + } + } +} + +func TestServerRejectHeadWithBody(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + // No response body. + }) + defer st.Close() + st.greet() + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "HEAD"), + EndStream: false, // what we're testing, a bogus HEAD request with body + EndHeaders: true, + }) + st.wantRSTStream(1, ErrCodeProtocol) +} + +func TestServerNoAutoContentLengthOnHead(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + // No response body. (or smaller than one frame) + }) + defer st.Close() + st.greet() + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, // clients send odd numbers + BlockFragment: st.encodeHeader(":method", "HEAD"), + EndStream: true, + EndHeaders: true, + }) + h := st.wantHeaders() + headers := st.decodeHeader(h.HeaderBlockFragment()) + want := [][2]string{ + {":status", "200"}, + {"content-type", "text/plain; charset=utf-8"}, + } + if !reflect.DeepEqual(headers, want) { + t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want) + } +} + +// golang.org/issue/13495 +func TestServerNoDuplicateContentType(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + w.Header()["Content-Type"] = []string{""} + fmt.Fprintf(w, "hi") + }) + defer st.Close() + st.greet() + st.writeHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: st.encodeHeader(), + EndStream: true, + EndHeaders: true, + }) + h := st.wantHeaders() + headers := st.decodeHeader(h.HeaderBlockFragment()) + want := [][2]string{ + {":status", "200"}, + {"content-type", ""}, + {"content-length", "41"}, + } + if !reflect.DeepEqual(headers, want) { + t.Errorf("Headers mismatch.\n got: %q\nwant: %q\n", headers, want) + } +} + +type connStateConn struct { + net.Conn + cs tls.ConnectionState +} + +func (c connStateConn) ConnectionState() tls.ConnectionState { return c.cs } + +// golang.org/issue/12737 -- handle any net.Conn, not just +// *tls.Conn. +func TestServerHandleCustomConn(t *testing.T) { + var s Server + c1, c2 := net.Pipe() + clientDone := make(chan struct{}) + handlerDone := make(chan struct{}) + var req *http.Request + go func() { + defer close(clientDone) + defer c2.Close() + fr := NewFramer(c2, c2) + io.WriteString(c2, ClientPreface) + fr.WriteSettings() + fr.WriteSettingsAck() + f, err := fr.ReadFrame() + if err != nil { + t.Error(err) + return + } + if sf, ok := f.(*SettingsFrame); !ok || sf.IsAck() { + t.Errorf("Got %v; want non-ACK SettingsFrame", summarizeFrame(f)) + return + } + f, err = fr.ReadFrame() + if err != nil { + t.Error(err) + return + } + if sf, ok := f.(*SettingsFrame); !ok || !sf.IsAck() { + t.Errorf("Got %v; want ACK SettingsFrame", summarizeFrame(f)) + return + } + var henc hpackEncoder + fr.WriteHeaders(HeadersFrameParam{ + StreamID: 1, + BlockFragment: henc.encodeHeaderRaw(t, ":method", "GET", ":path", "/", ":scheme", "https", ":authority", "foo.com"), + EndStream: true, + EndHeaders: true, + }) + go io.Copy(ioutil.Discard, c2) + <-handlerDone + }() + const testString = "my custom ConnectionState" + fakeConnState := tls.ConnectionState{ + ServerName: testString, + Version: tls.VersionTLS12, + } + go s.ServeConn(connStateConn{c1, fakeConnState}, &ServeConnOpts{ + BaseConfig: &http.Server{ + Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + defer close(handlerDone) + req = r + }), + }}) + select { + case <-clientDone: + case <-time.After(5 * time.Second): + t.Fatal("timeout waiting for handler") + } + if req.TLS == nil { + t.Fatalf("Request.TLS is nil. Got: %#v", req) + } + if req.TLS.ServerName != testString { + t.Fatalf("Request.TLS = %+v; want ServerName of %q", req.TLS, testString) + } +} + +type hpackEncoder struct { + enc *hpack.Encoder + buf bytes.Buffer +} + +func (he *hpackEncoder) encodeHeaderRaw(t *testing.T, headers ...string) []byte { + if len(headers)%2 == 1 { + panic("odd number of kv args") + } + he.buf.Reset() + if he.enc == nil { + he.enc = hpack.NewEncoder(&he.buf) + } + for len(headers) > 0 { + k, v := headers[0], headers[1] + err := he.enc.WriteField(hpack.HeaderField{Name: k, Value: v}) + if err != nil { + t.Fatalf("HPACK encoding error for %q/%q: %v", k, v, err) + } + headers = headers[2:] + } + return he.buf.Bytes() +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/testdata/draft-ietf-httpbis-http2.xml b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/testdata/draft-ietf-httpbis-http2.xml new file mode 100644 index 00000000..31a84bed --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/testdata/draft-ietf-httpbis-http2.xml @@ -0,0 +1,5021 @@ + + + + + + + + + + + + + + + + + + + Hypertext Transfer Protocol version 2 + + + Twist +
    + mbelshe@chromium.org +
    +
    + + + Google, Inc +
    + fenix@google.com +
    +
    + + + Mozilla +
    + + 331 E Evelyn Street + Mountain View + CA + 94041 + US + + martin.thomson@gmail.com +
    +
    + + + Applications + HTTPbis + HTTP + SPDY + Web + + + + This specification describes an optimized expression of the semantics of the Hypertext + Transfer Protocol (HTTP). HTTP/2 enables a more efficient use of network resources and a + reduced perception of latency by introducing header field compression and allowing multiple + concurrent messages on the same connection. It also introduces unsolicited push of + representations from servers to clients. + + + This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. + HTTP's existing semantics remain unchanged. + + + + + + Discussion of this draft takes place on the HTTPBIS working group mailing list + (ietf-http-wg@w3.org), which is archived at . + + + Working Group information can be found at ; that specific to HTTP/2 are at . + + + The changes in this draft are summarized in . + + + +
    + + +
    + + + The Hypertext Transfer Protocol (HTTP) is a wildly successful protocol. However, the + HTTP/1.1 message format () has + several characteristics that have a negative overall effect on application performance + today. + + + In particular, HTTP/1.0 allowed only one request to be outstanding at a time on a given + TCP connection. HTTP/1.1 added request pipelining, but this only partially addressed + request concurrency and still suffers from head-of-line blocking. Therefore, HTTP/1.1 + clients that need to make many requests typically use multiple connections to a server in + order to achieve concurrency and thereby reduce latency. + + + Furthermore, HTTP header fields are often repetitive and verbose, causing unnecessary + network traffic, as well as causing the initial TCP congestion + window to quickly fill. This can result in excessive latency when multiple requests are + made on a new TCP connection. + + + HTTP/2 addresses these issues by defining an optimized mapping of HTTP's semantics to an + underlying connection. Specifically, it allows interleaving of request and response + messages on the same connection and uses an efficient coding for HTTP header fields. It + also allows prioritization of requests, letting more important requests complete more + quickly, further improving performance. + + + The resulting protocol is more friendly to the network, because fewer TCP connections can + be used in comparison to HTTP/1.x. This means less competition with other flows, and + longer-lived connections, which in turn leads to better utilization of available network + capacity. + + + Finally, HTTP/2 also enables more efficient processing of messages through use of binary + message framing. + +
    + +
    + + HTTP/2 provides an optimized transport for HTTP semantics. HTTP/2 supports all of the core + features of HTTP/1.1, but aims to be more efficient in several ways. + + + The basic protocol unit in HTTP/2 is a frame. Each frame + type serves a different purpose. For example, HEADERS and + DATA frames form the basis of HTTP requests and + responses; other frame types like SETTINGS, + WINDOW_UPDATE, and PUSH_PROMISE are used in support of other + HTTP/2 features. + + + Multiplexing of requests is achieved by having each HTTP request-response exchange + associated with its own stream. Streams are largely + independent of each other, so a blocked or stalled request or response does not prevent + progress on other streams. + + + Flow control and prioritization ensure that it is possible to efficiently use multiplexed + streams. Flow control helps to ensure that only data that + can be used by a receiver is transmitted. Prioritization ensures that limited resources can be directed + to the most important streams first. + + + HTTP/2 adds a new interaction mode, whereby a server can push + responses to a client. Server push allows a server to speculatively send a client + data that the server anticipates the client will need, trading off some network usage + against a potential latency gain. The server does this by synthesizing a request, which it + sends as a PUSH_PROMISE frame. The server is then able to send a response to + the synthetic request on a separate stream. + + + Frames that contain HTTP header fields are compressed. + HTTP requests can be highly redundant, so compression can reduce the size of requests and + responses significantly. + + +
    + + The HTTP/2 specification is split into four parts: + + + Starting HTTP/2 covers how an HTTP/2 connection is + initiated. + + + The framing and streams layers describe the way HTTP/2 frames are + structured and formed into multiplexed streams. + + + Frame and error + definitions include details of the frame and error types used in HTTP/2. + + + HTTP mappings and additional + requirements describe how HTTP semantics are expressed using frames and + streams. + + + + + While some of the frame and stream layer concepts are isolated from HTTP, this + specification does not define a completely generic framing layer. The framing and streams + layers are tailored to the needs of the HTTP protocol and server push. + +
    + +
    + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD + NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as + described in RFC 2119. + + + All numeric values are in network byte order. Values are unsigned unless otherwise + indicated. Literal values are provided in decimal or hexadecimal as appropriate. + Hexadecimal literals are prefixed with 0x to distinguish them + from decimal literals. + + + The following terms are used: + + + The endpoint initiating the HTTP/2 connection. + + + A transport-layer connection between two endpoints. + + + An error that affects the entire HTTP/2 connection. + + + Either the client or server of the connection. + + + The smallest unit of communication within an HTTP/2 connection, consisting of a header + and a variable-length sequence of octets structured according to the frame type. + + + An endpoint. When discussing a particular endpoint, "peer" refers to the endpoint + that is remote to the primary subject of discussion. + + + An endpoint that is receiving frames. + + + An endpoint that is transmitting frames. + + + The endpoint which did not initiate the HTTP/2 connection. + + + A bi-directional flow of frames across a virtual channel within the HTTP/2 connection. + + + An error on the individual HTTP/2 stream. + + + + + Finally, the terms "gateway", "intermediary", "proxy", and "tunnel" are defined + in . + +
    +
    + +
    + + An HTTP/2 connection is an application layer protocol running on top of a TCP connection + (). The client is the TCP connection initiator. + + + HTTP/2 uses the same "http" and "https" URI schemes used by HTTP/1.1. HTTP/2 shares the same + default port numbers: 80 for "http" URIs and 443 for "https" URIs. As a result, + implementations processing requests for target resource URIs like http://example.org/foo or https://example.com/bar are required to first discover whether the + upstream server (the immediate peer to which the client wishes to establish a connection) + supports HTTP/2. + + + + The means by which support for HTTP/2 is determined is different for "http" and "https" + URIs. Discovery for "http" URIs is described in . Discovery + for "https" URIs is described in . + + +
    + + The protocol defined in this document has two identifiers. + + + + The string "h2" identifies the protocol where HTTP/2 uses TLS. This identifier is used in the TLS application layer protocol negotiation extension (ALPN) + field and any place that HTTP/2 over TLS is identified. + + + The "h2" string is serialized into an ALPN protocol identifier as the two octet + sequence: 0x68, 0x32. + + + + + The string "h2c" identifies the protocol where HTTP/2 is run over cleartext TCP. + This identifier is used in the HTTP/1.1 Upgrade header field and any place that + HTTP/2 over TCP is identified. + + + + + + Negotiating "h2" or "h2c" implies the use of the transport, security, framing and message + semantics described in this document. + + + RFC Editor's Note: please remove the remainder of this section prior to the + publication of a final version of this document. + + + Only implementations of the final, published RFC can identify themselves as "h2" or "h2c". + Until such an RFC exists, implementations MUST NOT identify themselves using these + strings. + + + Examples and text throughout the rest of this document use "h2" as a matter of + editorial convenience only. Implementations of draft versions MUST NOT identify using + this string. + + + Implementations of draft versions of the protocol MUST add the string "-" and the + corresponding draft number to the identifier. For example, draft-ietf-httpbis-http2-11 + over TLS is identified using the string "h2-11". + + + Non-compatible experiments that are based on these draft versions MUST append the string + "-" and an experiment name to the identifier. For example, an experimental implementation + of packet mood-based encoding based on draft-ietf-httpbis-http2-09 might identify itself + as "h2-09-emo". Note that any label MUST conform to the "token" syntax defined in + . Experimenters are + encouraged to coordinate their experiments on the ietf-http-wg@w3.org mailing list. + +
    + +
    + + A client that makes a request for an "http" URI without prior knowledge about support for + HTTP/2 uses the HTTP Upgrade mechanism (). The client makes an HTTP/1.1 request that includes an Upgrade + header field identifying HTTP/2 with the "h2c" token. The HTTP/1.1 request MUST include + exactly one HTTP2-Settings header field. + +
    + For example: + + +]]> +
    + + Requests that contain an entity body MUST be sent in their entirety before the client can + send HTTP/2 frames. This means that a large request entity can block the use of the + connection until it is completely sent. + + + If concurrency of an initial request with subsequent requests is important, an OPTIONS + request can be used to perform the upgrade to HTTP/2, at the cost of an additional + round-trip. + + + A server that does not support HTTP/2 can respond to the request as though the Upgrade + header field were absent: + +
    + +HTTP/1.1 200 OK +Content-Length: 243 +Content-Type: text/html + +... + +
    + + A server MUST ignore a "h2" token in an Upgrade header field. Presence of a token with + "h2" implies HTTP/2 over TLS, which is instead negotiated as described in . + + + A server that supports HTTP/2 can accept the upgrade with a 101 (Switching Protocols) + response. After the empty line that terminates the 101 response, the server can begin + sending HTTP/2 frames. These frames MUST include a response to the request that initiated + the Upgrade. + + +
    + + For example: + + +HTTP/1.1 101 Switching Protocols +Connection: Upgrade +Upgrade: h2c + +[ HTTP/2 connection ... + +
    + + The first HTTP/2 frame sent by the server is a SETTINGS frame () as the server connection preface (). Upon receiving the 101 response, the client sends a connection preface, which includes a + SETTINGS frame. + + + The HTTP/1.1 request that is sent prior to upgrade is assigned stream identifier 1 and is + assigned default priority values. Stream 1 is + implicitly half closed from the client toward the server, since the request is completed + as an HTTP/1.1 request. After commencing the HTTP/2 connection, stream 1 is used for the + response. + + +
    + + A request that upgrades from HTTP/1.1 to HTTP/2 MUST include exactly one HTTP2-Settings header field. The HTTP2-Settings header field is a connection-specific header field + that includes parameters that govern the HTTP/2 connection, provided in anticipation of + the server accepting the request to upgrade. + +
    + +
    + + A server MUST NOT upgrade the connection to HTTP/2 if this header field is not present, + or if more than one is present. A server MUST NOT send this header field. + + + + The content of the HTTP2-Settings header field is the + payload of a SETTINGS frame (), encoded as a + base64url string (that is, the URL- and filename-safe Base64 encoding described in , with any trailing '=' characters omitted). The + ABNF production for token68 is + defined in . + + + Since the upgrade is only intended to apply to the immediate connection, a client + sending HTTP2-Settings MUST also send HTTP2-Settings as a connection option in the Connection header field to prevent it from being forwarded + downstream. + + + A server decodes and interprets these values as it would any other + SETTINGS frame. Acknowledgement of the + SETTINGS parameters is not necessary, since a 101 response serves as implicit + acknowledgment. Providing these values in the Upgrade request gives a client an + opportunity to provide parameters prior to receiving any frames from the server. + +
    +
    + +
    + + A client that makes a request to an "https" URI uses TLS + with the application layer protocol negotiation extension. + + + HTTP/2 over TLS uses the "h2" application token. The "h2c" token MUST NOT be sent by a + client or selected by a server. + + + Once TLS negotiation is complete, both the client and the server send a connection preface. + +
    + +
    + + A client can learn that a particular server supports HTTP/2 by other means. For example, + describes a mechanism for advertising this capability. + + + A client MAY immediately send HTTP/2 frames to a server that is known to support HTTP/2, + after the connection preface; a server can + identify such a connection by the presence of the connection preface. This only affects + the establishment of HTTP/2 connections over cleartext TCP; implementations that support + HTTP/2 over TLS MUST use protocol negotiation in TLS. + + + Without additional information, prior support for HTTP/2 is not a strong signal that a + given server will support HTTP/2 for future connections. For example, it is possible for + server configurations to change, for configurations to differ between instances in + clustered servers, or for network conditions to change. + +
    + +
    + + Upon establishment of a TCP connection and determination that HTTP/2 will be used by both + peers, each endpoint MUST send a connection preface as a final confirmation and to + establish the initial SETTINGS parameters for the HTTP/2 connection. The client and + server each send a different connection preface. + + + The client connection preface starts with a sequence of 24 octets, which in hex notation + are: + +
    + +
    + + (the string PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n). This sequence + is followed by a SETTINGS frame (). The + SETTINGS frame MAY be empty. The client sends the client connection + preface immediately upon receipt of a 101 Switching Protocols response (indicating a + successful upgrade), or as the first application data octets of a TLS connection. If + starting an HTTP/2 connection with prior knowledge of server support for the protocol, the + client connection preface is sent upon connection establishment. + + + + + The client connection preface is selected so that a large proportion of HTTP/1.1 or + HTTP/1.0 servers and intermediaries do not attempt to process further frames. Note + that this does not address the concerns raised in . + + + + + The server connection preface consists of a potentially empty SETTINGS + frame () that MUST be the first frame the server sends in the + HTTP/2 connection. + + + The SETTINGS frames received from a peer as part of the connection preface + MUST be acknowledged (see ) after sending the connection + preface. + + + To avoid unnecessary latency, clients are permitted to send additional frames to the + server immediately after sending the client connection preface, without waiting to receive + the server connection preface. It is important to note, however, that the server + connection preface SETTINGS frame might include parameters that necessarily + alter how a client is expected to communicate with the server. Upon receiving the + SETTINGS frame, the client is expected to honor any parameters established. + In some configurations, it is possible for the server to transmit SETTINGS + before the client sends additional frames, providing an opportunity to avoid this issue. + + + Clients and servers MUST treat an invalid connection preface as a connection error of type + PROTOCOL_ERROR. A GOAWAY frame () + MAY be omitted in this case, since an invalid preface indicates that the peer is not using + HTTP/2. + +
    +
    + +
    + + Once the HTTP/2 connection is established, endpoints can begin exchanging frames. + + +
    + + All frames begin with a fixed 9-octet header followed by a variable-length payload. + +
    + +
    + + The fields of the frame header are defined as: + + + + The length of the frame payload expressed as an unsigned 24-bit integer. Values + greater than 214 (16,384) MUST NOT be sent unless the receiver has + set a larger value for SETTINGS_MAX_FRAME_SIZE. + + + The 9 octets of the frame header are not included in this value. + + + + + The 8-bit type of the frame. The frame type determines the format and semantics of + the frame. Implementations MUST ignore and discard any frame that has a type that + is unknown. + + + + + An 8-bit field reserved for frame-type specific boolean flags. + + + Flags are assigned semantics specific to the indicated frame type. Flags that have + no defined semantics for a particular frame type MUST be ignored, and MUST be left + unset (0) when sending. + + + + + A reserved 1-bit field. The semantics of this bit are undefined and the bit MUST + remain unset (0) when sending and MUST be ignored when receiving. + + + + + A 31-bit stream identifier (see ). The value 0 is + reserved for frames that are associated with the connection as a whole as opposed to + an individual stream. + + + + + + The structure and content of the frame payload is dependent entirely on the frame type. + +
    + +
    + + The size of a frame payload is limited by the maximum size that a receiver advertises in + the SETTINGS_MAX_FRAME_SIZE setting. This setting can have any value + between 214 (16,384) and 224-1 (16,777,215) octets, + inclusive. + + + All implementations MUST be capable of receiving and minimally processing frames up to + 214 octets in length, plus the 9 octet frame + header. The size of the frame header is not included when describing frame sizes. + + + Certain frame types, such as PING, impose additional limits + on the amount of payload data allowed. + + + + + If a frame size exceeds any defined limit, or is too small to contain mandatory frame + data, the endpoint MUST send a FRAME_SIZE_ERROR error. A frame size error + in a frame that could alter the state of the entire connection MUST be treated as a connection error; this includes any frame carrying + a header block (that is, HEADERS, + PUSH_PROMISE, and CONTINUATION), SETTINGS, + and any WINDOW_UPDATE frame with a stream identifier of 0. + + + Endpoints are not obligated to use all available space in a frame. Responsiveness can be + improved by using frames that are smaller than the permitted maximum size. Sending large + frames can result in delays in sending time-sensitive frames (such + RST_STREAM, WINDOW_UPDATE, or PRIORITY) + which if blocked by the transmission of a large frame, could affect performance. + +
    + +
    + + Just as in HTTP/1, a header field in HTTP/2 is a name with one or more associated values. + They are used within HTTP request and response messages as well as server push operations + (see ). + + + Header lists are collections of zero or more header fields. When transmitted over a + connection, a header list is serialized into a header block using HTTP Header Compression. The serialized header block is then + divided into one or more octet sequences, called header block fragments, and transmitted + within the payload of HEADERS, PUSH_PROMISE or CONTINUATION frames. + + + The Cookie header field is treated specially by the HTTP + mapping (see ). + + + A receiving endpoint reassembles the header block by concatenating its fragments, then + decompresses the block to reconstruct the header list. + + + A complete header block consists of either: + + + a single HEADERS or PUSH_PROMISE frame, + with the END_HEADERS flag set, or + + + a HEADERS or PUSH_PROMISE frame with the END_HEADERS + flag cleared and one or more CONTINUATION frames, + where the last CONTINUATION frame has the END_HEADERS flag set. + + + + + Header compression is stateful. One compression context and one decompression context is + used for the entire connection. Each header block is processed as a discrete unit. + Header blocks MUST be transmitted as a contiguous sequence of frames, with no interleaved + frames of any other type or from any other stream. The last frame in a sequence of + HEADERS or CONTINUATION frames MUST have the END_HEADERS + flag set. The last frame in a sequence of PUSH_PROMISE or + CONTINUATION frames MUST have the END_HEADERS flag set. This allows a + header block to be logically equivalent to a single frame. + + + Header block fragments can only be sent as the payload of HEADERS, + PUSH_PROMISE or CONTINUATION frames, because these frames + carry data that can modify the compression context maintained by a receiver. An endpoint + receiving HEADERS, PUSH_PROMISE or + CONTINUATION frames MUST reassemble header blocks and perform decompression + even if the frames are to be discarded. A receiver MUST terminate the connection with a + connection error of type + COMPRESSION_ERROR if it does not decompress a header block. + +
    +
    + +
    + + A "stream" is an independent, bi-directional sequence of frames exchanged between the client + and server within an HTTP/2 connection. Streams have several important characteristics: + + + A single HTTP/2 connection can contain multiple concurrently open streams, with either + endpoint interleaving frames from multiple streams. + + + Streams can be established and used unilaterally or shared by either the client or + server. + + + Streams can be closed by either endpoint. + + + The order in which frames are sent on a stream is significant. Recipients process frames + in the order they are received. In particular, the order of HEADERS, + and DATA frames is semantically significant. + + + Streams are identified by an integer. Stream identifiers are assigned to streams by the + endpoint initiating the stream. + + + + +
    + + The lifecycle of a stream is shown in . + + +
    + + | |<-----------' | + | R | closed | R | + `-------------------->| |<--------------------' + +--------+ + + H: HEADERS frame (with implied CONTINUATIONs) + PP: PUSH_PROMISE frame (with implied CONTINUATIONs) + ES: END_STREAM flag + R: RST_STREAM frame +]]> + +
    + + + Note that this diagram shows stream state transitions and the frames and flags that affect + those transitions only. In this regard, CONTINUATION frames do not result + in state transitions; they are effectively part of the HEADERS or + PUSH_PROMISE that they follow. For this purpose, the END_STREAM flag is + processed as a separate event to the frame that bears it; a HEADERS frame + with the END_STREAM flag set can cause two state transitions. + + + Both endpoints have a subjective view of the state of a stream that could be different + when frames are in transit. Endpoints do not coordinate the creation of streams; they are + created unilaterally by either endpoint. The negative consequences of a mismatch in + states are limited to the "closed" state after sending RST_STREAM, where + frames might be received for some time after closing. + + + Streams have the following states: + + + + + + All streams start in the "idle" state. In this state, no frames have been + exchanged. + + + The following transitions are valid from this state: + + + Sending or receiving a HEADERS frame causes the stream to become + "open". The stream identifier is selected as described in . The same HEADERS frame can also + cause a stream to immediately become "half closed". + + + Sending a PUSH_PROMISE frame marks the associated stream for + later use. The stream state for the reserved stream transitions to "reserved + (local)". + + + Receiving a PUSH_PROMISE frame marks the associated stream as + reserved by the remote peer. The state of the stream becomes "reserved + (remote)". + + + + + Receiving any frames other than HEADERS or + PUSH_PROMISE on a stream in this state MUST be treated as a connection error of type + PROTOCOL_ERROR. + + + + + + + A stream in the "reserved (local)" state is one that has been promised by sending a + PUSH_PROMISE frame. A PUSH_PROMISE frame reserves an + idle stream by associating the stream with an open stream that was initiated by the + remote peer (see ). + + + In this state, only the following transitions are possible: + + + The endpoint can send a HEADERS frame. This causes the stream to + open in a "half closed (remote)" state. + + + Either endpoint can send a RST_STREAM frame to cause the stream + to become "closed". This releases the stream reservation. + + + + + An endpoint MUST NOT send any type of frame other than HEADERS or + RST_STREAM in this state. + + + A PRIORITY frame MAY be received in this state. Receiving any type + of frame other than RST_STREAM or PRIORITY on a stream + in this state MUST be treated as a connection + error of type PROTOCOL_ERROR. + + + + + + + A stream in the "reserved (remote)" state has been reserved by a remote peer. + + + In this state, only the following transitions are possible: + + + Receiving a HEADERS frame causes the stream to transition to + "half closed (local)". + + + Either endpoint can send a RST_STREAM frame to cause the stream + to become "closed". This releases the stream reservation. + + + + + An endpoint MAY send a PRIORITY frame in this state to reprioritize + the reserved stream. An endpoint MUST NOT send any type of frame other than + RST_STREAM, WINDOW_UPDATE, or PRIORITY + in this state. + + + Receiving any type of frame other than HEADERS or + RST_STREAM on a stream in this state MUST be treated as a connection error of type + PROTOCOL_ERROR. + + + + + + + A stream in the "open" state may be used by both peers to send frames of any type. + In this state, sending peers observe advertised stream + level flow control limits. + + + From this state either endpoint can send a frame with an END_STREAM flag set, which + causes the stream to transition into one of the "half closed" states: an endpoint + sending an END_STREAM flag causes the stream state to become "half closed (local)"; + an endpoint receiving an END_STREAM flag causes the stream state to become "half + closed (remote)". + + + Either endpoint can send a RST_STREAM frame from this state, causing + it to transition immediately to "closed". + + + + + + + A stream that is in the "half closed (local)" state cannot be used for sending + frames. Only WINDOW_UPDATE, PRIORITY and + RST_STREAM frames can be sent in this state. + + + A stream transitions from this state to "closed" when a frame that contains an + END_STREAM flag is received, or when either peer sends a RST_STREAM + frame. + + + A receiver can ignore WINDOW_UPDATE frames in this state, which might + arrive for a short period after a frame bearing the END_STREAM flag is sent. + + + PRIORITY frames received in this state are used to reprioritize + streams that depend on the current stream. + + + + + + + A stream that is "half closed (remote)" is no longer being used by the peer to send + frames. In this state, an endpoint is no longer obligated to maintain a receiver + flow control window if it performs flow control. + + + If an endpoint receives additional frames for a stream that is in this state, other + than WINDOW_UPDATE, PRIORITY or + RST_STREAM, it MUST respond with a stream error of type + STREAM_CLOSED. + + + A stream that is "half closed (remote)" can be used by the endpoint to send frames + of any type. In this state, the endpoint continues to observe advertised stream level flow control limits. + + + A stream can transition from this state to "closed" by sending a frame that contains + an END_STREAM flag, or when either peer sends a RST_STREAM frame. + + + + + + + The "closed" state is the terminal state. + + + An endpoint MUST NOT send frames other than PRIORITY on a closed + stream. An endpoint that receives any frame other than PRIORITY + after receiving a RST_STREAM MUST treat that as a stream error of type + STREAM_CLOSED. Similarly, an endpoint that receives any frames after + receiving a frame with the END_STREAM flag set MUST treat that as a connection error of type + STREAM_CLOSED, unless the frame is permitted as described below. + + + WINDOW_UPDATE or RST_STREAM frames can be received in + this state for a short period after a DATA or HEADERS + frame containing an END_STREAM flag is sent. Until the remote peer receives and + processes RST_STREAM or the frame bearing the END_STREAM flag, it + might send frames of these types. Endpoints MUST ignore + WINDOW_UPDATE or RST_STREAM frames received in this + state, though endpoints MAY choose to treat frames that arrive a significant time + after sending END_STREAM as a connection + error of type PROTOCOL_ERROR. + + + PRIORITY frames can be sent on closed streams to prioritize streams + that are dependent on the closed stream. Endpoints SHOULD process + PRIORITY frame, though they can be ignored if the stream has been + removed from the dependency tree (see ). + + + If this state is reached as a result of sending a RST_STREAM frame, + the peer that receives the RST_STREAM might have already sent - or + enqueued for sending - frames on the stream that cannot be withdrawn. An endpoint + MUST ignore frames that it receives on closed streams after it has sent a + RST_STREAM frame. An endpoint MAY choose to limit the period over + which it ignores frames and treat frames that arrive after this time as being in + error. + + + Flow controlled frames (i.e., DATA) received after sending + RST_STREAM are counted toward the connection flow control window. + Even though these frames might be ignored, because they are sent before the sender + receives the RST_STREAM, the sender will consider the frames to count + against the flow control window. + + + An endpoint might receive a PUSH_PROMISE frame after it sends + RST_STREAM. PUSH_PROMISE causes a stream to become + "reserved" even if the associated stream has been reset. Therefore, a + RST_STREAM is needed to close an unwanted promised stream. + + + + + + In the absence of more specific guidance elsewhere in this document, implementations + SHOULD treat the receipt of a frame that is not expressly permitted in the description of + a state as a connection error of type + PROTOCOL_ERROR. Frame of unknown types are ignored. + + + An example of the state transitions for an HTTP request/response exchange can be found in + . An example of the state transitions for server push can be + found in and . + + +
    + + Streams are identified with an unsigned 31-bit integer. Streams initiated by a client + MUST use odd-numbered stream identifiers; those initiated by the server MUST use + even-numbered stream identifiers. A stream identifier of zero (0x0) is used for + connection control messages; the stream identifier zero cannot be used to establish a + new stream. + + + HTTP/1.1 requests that are upgraded to HTTP/2 (see ) are + responded to with a stream identifier of one (0x1). After the upgrade + completes, stream 0x1 is "half closed (local)" to the client. Therefore, stream 0x1 + cannot be selected as a new stream identifier by a client that upgrades from HTTP/1.1. + + + The identifier of a newly established stream MUST be numerically greater than all + streams that the initiating endpoint has opened or reserved. This governs streams that + are opened using a HEADERS frame and streams that are reserved using + PUSH_PROMISE. An endpoint that receives an unexpected stream identifier + MUST respond with a connection error of + type PROTOCOL_ERROR. + + + The first use of a new stream identifier implicitly closes all streams in the "idle" + state that might have been initiated by that peer with a lower-valued stream identifier. + For example, if a client sends a HEADERS frame on stream 7 without ever + sending a frame on stream 5, then stream 5 transitions to the "closed" state when the + first frame for stream 7 is sent or received. + + + Stream identifiers cannot be reused. Long-lived connections can result in an endpoint + exhausting the available range of stream identifiers. A client that is unable to + establish a new stream identifier can establish a new connection for new streams. A + server that is unable to establish a new stream identifier can send a + GOAWAY frame so that the client is forced to open a new connection for + new streams. + +
    + +
    + + A peer can limit the number of concurrently active streams using the + SETTINGS_MAX_CONCURRENT_STREAMS parameter (see ) within a SETTINGS frame. The maximum concurrent + streams setting is specific to each endpoint and applies only to the peer that receives + the setting. That is, clients specify the maximum number of concurrent streams the + server can initiate, and servers specify the maximum number of concurrent streams the + client can initiate. + + + Streams that are in the "open" state, or either of the "half closed" states count toward + the maximum number of streams that an endpoint is permitted to open. Streams in any of + these three states count toward the limit advertised in the + SETTINGS_MAX_CONCURRENT_STREAMS setting. Streams in either of the + "reserved" states do not count toward the stream limit. + + + Endpoints MUST NOT exceed the limit set by their peer. An endpoint that receives a + HEADERS frame that causes their advertised concurrent stream limit to be + exceeded MUST treat this as a stream error. An + endpoint that wishes to reduce the value of + SETTINGS_MAX_CONCURRENT_STREAMS to a value that is below the current + number of open streams can either close streams that exceed the new value or allow + streams to complete. + +
    +
    + +
    + + Using streams for multiplexing introduces contention over use of the TCP connection, + resulting in blocked streams. A flow control scheme ensures that streams on the same + connection do not destructively interfere with each other. Flow control is used for both + individual streams and for the connection as a whole. + + + HTTP/2 provides for flow control through use of the WINDOW_UPDATE frame. + + +
    + + HTTP/2 stream flow control aims to allow a variety of flow control algorithms to be + used without requiring protocol changes. Flow control in HTTP/2 has the following + characteristics: + + + Flow control is specific to a connection; i.e., it is "hop-by-hop", not + "end-to-end". + + + Flow control is based on window update frames. Receivers advertise how many octets + they are prepared to receive on a stream and for the entire connection. This is a + credit-based scheme. + + + Flow control is directional with overall control provided by the receiver. A + receiver MAY choose to set any window size that it desires for each stream and for + the entire connection. A sender MUST respect flow control limits imposed by a + receiver. Clients, servers and intermediaries all independently advertise their + flow control window as a receiver and abide by the flow control limits set by + their peer when sending. + + + The initial value for the flow control window is 65,535 octets for both new streams + and the overall connection. + + + The frame type determines whether flow control applies to a frame. Of the frames + specified in this document, only DATA frames are subject to flow + control; all other frame types do not consume space in the advertised flow control + window. This ensures that important control frames are not blocked by flow control. + + + Flow control cannot be disabled. + + + HTTP/2 defines only the format and semantics of the WINDOW_UPDATE + frame (). This document does not stipulate how a + receiver decides when to send this frame or the value that it sends, nor does it + specify how a sender chooses to send packets. Implementations are able to select + any algorithm that suits their needs. + + + + + Implementations are also responsible for managing how requests and responses are sent + based on priority; choosing how to avoid head of line blocking for requests; and + managing the creation of new streams. Algorithm choices for these could interact with + any flow control algorithm. + +
    + +
    + + Flow control is defined to protect endpoints that are operating under resource + constraints. For example, a proxy needs to share memory between many connections, and + also might have a slow upstream connection and a fast downstream one. Flow control + addresses cases where the receiver is unable process data on one stream, yet wants to + continue to process other streams in the same connection. + + + Deployments that do not require this capability can advertise a flow control window of + the maximum size, incrementing the available space when new data is received. This + effectively disables flow control for that receiver. Conversely, a sender is always + subject to the flow control window advertised by the receiver. + + + Deployments with constrained resources (for example, memory) can employ flow control to + limit the amount of memory a peer can consume. Note, however, that this can lead to + suboptimal use of available network resources if flow control is enabled without + knowledge of the bandwidth-delay product (see ). + + + Even with full awareness of the current bandwidth-delay product, implementation of flow + control can be difficult. When using flow control, the receiver MUST read from the TCP + receive buffer in a timely fashion. Failure to do so could lead to a deadlock when + critical frames, such as WINDOW_UPDATE, are not read and acted upon. + +
    +
    + +
    + + A client can assign a priority for a new stream by including prioritization information in + the HEADERS frame that opens the stream. For an existing + stream, the PRIORITY frame can be used to change the + priority. + + + The purpose of prioritization is to allow an endpoint to express how it would prefer its + peer allocate resources when managing concurrent streams. Most importantly, priority can + be used to select streams for transmitting frames when there is limited capacity for + sending. + + + Streams can be prioritized by marking them as dependent on the completion of other streams + (). Each dependency is assigned a relative weight, a number + that is used to determine the relative proportion of available resources that are assigned + to streams dependent on the same stream. + + + + Explicitly setting the priority for a stream is input to a prioritization process. It + does not guarantee any particular processing or transmission order for the stream relative + to any other stream. An endpoint cannot force a peer to process concurrent streams in a + particular order using priority. Expressing priority is therefore only ever a suggestion. + + + Providing prioritization information is optional, so default values are used if no + explicit indicator is provided (). + + +
    + + Each stream can be given an explicit dependency on another stream. Including a + dependency expresses a preference to allocate resources to the identified stream rather + than to the dependent stream. + + + A stream that is not dependent on any other stream is given a stream dependency of 0x0. + In other words, the non-existent stream 0 forms the root of the tree. + + + A stream that depends on another stream is a dependent stream. The stream upon which a + stream is dependent is a parent stream. A dependency on a stream that is not currently + in the tree - such as a stream in the "idle" state - results in that stream being given + a default priority. + + + When assigning a dependency on another stream, the stream is added as a new dependency + of the parent stream. Dependent streams that share the same parent are not ordered with + respect to each other. For example, if streams B and C are dependent on stream A, and + if stream D is created with a dependency on stream A, this results in a dependency order + of A followed by B, C, and D in any order. + +
    + /|\ + B C B D C +]]> +
    + + An exclusive flag allows for the insertion of a new level of dependencies. The + exclusive flag causes the stream to become the sole dependency of its parent stream, + causing other dependencies to become dependent on the exclusive stream. In the + previous example, if stream D is created with an exclusive dependency on stream A, this + results in D becoming the dependency parent of B and C. + +
    + D + B C / \ + B C +]]> +
    + + Inside the dependency tree, a dependent stream SHOULD only be allocated resources if all + of the streams that it depends on (the chain of parent streams up to 0x0) are either + closed, or it is not possible to make progress on them. + + + A stream cannot depend on itself. An endpoint MUST treat this as a stream error of type PROTOCOL_ERROR. + +
    + +
    + + All dependent streams are allocated an integer weight between 1 and 256 (inclusive). + + + Streams with the same parent SHOULD be allocated resources proportionally based on their + weight. Thus, if stream B depends on stream A with weight 4, and C depends on stream A + with weight 12, and if no progress can be made on A, stream B ideally receives one third + of the resources allocated to stream C. + +
    + +
    + + Stream priorities are changed using the PRIORITY frame. Setting a + dependency causes a stream to become dependent on the identified parent stream. + + + Dependent streams move with their parent stream if the parent is reprioritized. Setting + a dependency with the exclusive flag for a reprioritized stream moves all the + dependencies of the new parent stream to become dependent on the reprioritized stream. + + + If a stream is made dependent on one of its own dependencies, the formerly dependent + stream is first moved to be dependent on the reprioritized stream's previous parent. + The moved dependency retains its weight. + +
    + + For example, consider an original dependency tree where B and C depend on A, D and E + depend on C, and F depends on D. If A is made dependent on D, then D takes the place + of A. All other dependency relationships stay the same, except for F, which becomes + dependent on A if the reprioritization is exclusive. + + F B C ==> F A OR A + / \ | / \ /|\ + D E E B C B C F + | | | + F E E + (intermediate) (non-exclusive) (exclusive) +]]> +
    +
    + +
    + + When a stream is removed from the dependency tree, its dependencies can be moved to + become dependent on the parent of the closed stream. The weights of new dependencies + are recalculated by distributing the weight of the dependency of the closed stream + proportionally based on the weights of its dependencies. + + + Streams that are removed from the dependency tree cause some prioritization information + to be lost. Resources are shared between streams with the same parent stream, which + means that if a stream in that set closes or becomes blocked, any spare capacity + allocated to a stream is distributed to the immediate neighbors of the stream. However, + if the common dependency is removed from the tree, those streams share resources with + streams at the next highest level. + + + For example, assume streams A and B share a parent, and streams C and D both depend on + stream A. Prior to the removal of stream A, if streams A and D are unable to proceed, + then stream C receives all the resources dedicated to stream A. If stream A is removed + from the tree, the weight of stream A is divided between streams C and D. If stream D + is still unable to proceed, this results in stream C receiving a reduced proportion of + resources. For equal starting weights, C receives one third, rather than one half, of + available resources. + + + It is possible for a stream to become closed while prioritization information that + creates a dependency on that stream is in transit. If a stream identified in a + dependency has no associated priority information, then the dependent stream is instead + assigned a default priority. This potentially creates + suboptimal prioritization, since the stream could be given a priority that is different + to what is intended. + + + To avoid these problems, an endpoint SHOULD retain stream prioritization state for a + period after streams become closed. The longer state is retained, the lower the chance + that streams are assigned incorrect or default priority values. + + + This could create a large state burden for an endpoint, so this state MAY be limited. + An endpoint MAY apply a fixed upper limit on the number of closed streams for which + prioritization state is tracked to limit state exposure. The amount of additional state + an endpoint maintains could be dependent on load; under high load, prioritization state + can be discarded to limit resource commitments. In extreme cases, an endpoint could + even discard prioritization state for active or reserved streams. If a fixed limit is + applied, endpoints SHOULD maintain state for at least as many streams as allowed by + their setting for SETTINGS_MAX_CONCURRENT_STREAMS. + + + An endpoint receiving a PRIORITY frame that changes the priority of a + closed stream SHOULD alter the dependencies of the streams that depend on it, if it has + retained enough state to do so. + +
    + +
    + + Providing priority information is optional. Streams are assigned a non-exclusive + dependency on stream 0x0 by default. Pushed streams + initially depend on their associated stream. In both cases, streams are assigned a + default weight of 16. + +
    +
    + +
    + + HTTP/2 framing permits two classes of error: + + + An error condition that renders the entire connection unusable is a connection error. + + + An error in an individual stream is a stream error. + + + + + A list of error codes is included in . + + +
    + + A connection error is any error which prevents further processing of the framing layer, + or which corrupts any connection state. + + + An endpoint that encounters a connection error SHOULD first send a GOAWAY + frame () with the stream identifier of the last stream that it + successfully received from its peer. The GOAWAY frame includes an error + code that indicates why the connection is terminating. After sending the + GOAWAY frame, the endpoint MUST close the TCP connection. + + + It is possible that the GOAWAY will not be reliably received by the + receiving endpoint (see ). In the event of a connection error, + GOAWAY only provides a best effort attempt to communicate with the peer + about why the connection is being terminated. + + + An endpoint can end a connection at any time. In particular, an endpoint MAY choose to + treat a stream error as a connection error. Endpoints SHOULD send a + GOAWAY frame when ending a connection, providing that circumstances + permit it. + +
    + +
    + + A stream error is an error related to a specific stream that does not affect processing + of other streams. + + + An endpoint that detects a stream error sends a RST_STREAM frame () that contains the stream identifier of the stream where the error + occurred. The RST_STREAM frame includes an error code that indicates the + type of error. + + + A RST_STREAM is the last frame that an endpoint can send on a stream. + The peer that sends the RST_STREAM frame MUST be prepared to receive any + frames that were sent or enqueued for sending by the remote peer. These frames can be + ignored, except where they modify connection state (such as the state maintained for + header compression, or flow control). + + + Normally, an endpoint SHOULD NOT send more than one RST_STREAM frame for + any stream. However, an endpoint MAY send additional RST_STREAM frames if + it receives frames on a closed stream after more than a round-trip time. This behavior + is permitted to deal with misbehaving implementations. + + + An endpoint MUST NOT send a RST_STREAM in response to an + RST_STREAM frame, to avoid looping. + +
    + +
    + + If the TCP connection is closed or reset while streams remain in open or half closed + states, then the endpoint MUST assume that those streams were abnormally interrupted and + could be incomplete. + +
    +
    + +
    + + HTTP/2 permits extension of the protocol. Protocol extensions can be used to provide + additional services or alter any aspect of the protocol, within the limitations described + in this section. Extensions are effective only within the scope of a single HTTP/2 + connection. + + + Extensions are permitted to use new frame types, new + settings, or new error + codes. Registries are established for managing these extension points: frame types, settings and + error codes. + + + Implementations MUST ignore unknown or unsupported values in all extensible protocol + elements. Implementations MUST discard frames that have unknown or unsupported types. + This means that any of these extension points can be safely used by extensions without + prior arrangement or negotiation. However, extension frames that appear in the middle of + a header block are not permitted; these MUST be treated + as a connection error of type + PROTOCOL_ERROR. + + + However, extensions that could change the semantics of existing protocol components MUST + be negotiated before being used. For example, an extension that changes the layout of the + HEADERS frame cannot be used until the peer has given a positive signal + that this is acceptable. In this case, it could also be necessary to coordinate when the + revised layout comes into effect. Note that treating any frame other than + DATA frames as flow controlled is such a change in semantics, and can only + be done through negotiation. + + + This document doesn't mandate a specific method for negotiating the use of an extension, + but notes that a setting could be used for that + purpose. If both peers set a value that indicates willingness to use the extension, then + the extension can be used. If a setting is used for extension negotiation, the initial + value MUST be defined so that the extension is initially disabled. + +
    +
    + +
    + + This specification defines a number of frame types, each identified by a unique 8-bit type + code. Each frame type serves a distinct purpose either in the establishment and management + of the connection as a whole, or of individual streams. + + + The transmission of specific frame types can alter the state of a connection. If endpoints + fail to maintain a synchronized view of the connection state, successful communication + within the connection will no longer be possible. Therefore, it is important that endpoints + have a shared comprehension of how the state is affected by the use any given frame. + + +
    + + DATA frames (type=0x0) convey arbitrary, variable-length sequences of octets associated + with a stream. One or more DATA frames are used, for instance, to carry HTTP request or + response payloads. + + + DATA frames MAY also contain arbitrary padding. Padding can be added to DATA frames to + obscure the size of messages. + +
    + +
    + + The DATA frame contains the following fields: + + + An 8-bit field containing the length of the frame padding in units of octets. This + field is optional and is only present if the PADDED flag is set. + + + Application data. The amount of data is the remainder of the frame payload after + subtracting the length of the other fields that are present. + + + Padding octets that contain no application semantic value. Padding octets MUST be set + to zero when sending and ignored when receiving. + + + + + + The DATA frame defines the following flags: + + + Bit 1 being set indicates that this frame is the last that the endpoint will send for + the identified stream. Setting this flag causes the stream to enter one of the "half closed" states or the "closed" state. + + + Bit 4 being set indicates that the Pad Length field and any padding that it describes + is present. + + + + + DATA frames MUST be associated with a stream. If a DATA frame is received whose stream + identifier field is 0x0, the recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + DATA frames are subject to flow control and can only be sent when a stream is in the + "open" or "half closed (remote)" states. The entire DATA frame payload is included in flow + control, including Pad Length and Padding fields if present. If a DATA frame is received + whose stream is not in "open" or "half closed (local)" state, the recipient MUST respond + with a stream error of type + STREAM_CLOSED. + + + The total number of padding octets is determined by the value of the Pad Length field. If + the length of the padding is greater than the length of the frame payload, the recipient + MUST treat this as a connection error of + type PROTOCOL_ERROR. + + + A frame can be increased in size by one octet by including a Pad Length field with a + value of zero. + + + + + Padding is a security feature; see . + +
    + +
    + + The HEADERS frame (type=0x1) is used to open a stream, + and additionally carries a header block fragment. HEADERS frames can be sent on a stream + in the "open" or "half closed (remote)" states. + +
    + +
    + + The HEADERS frame payload has the following fields: + + + An 8-bit field containing the length of the frame padding in units of octets. This + field is only present if the PADDED flag is set. + + + A single bit flag indicates that the stream dependency is exclusive, see . This field is only present if the PRIORITY flag is set. + + + A 31-bit stream identifier for the stream that this stream depends on, see . This field is only present if the PRIORITY flag is set. + + + An 8-bit weight for the stream, see . Add one to the + value to obtain a weight between 1 and 256. This field is only present if the + PRIORITY flag is set. + + + A header block fragment. + + + Padding octets that contain no application semantic value. Padding octets MUST be set + to zero when sending and ignored when receiving. + + + + + + The HEADERS frame defines the following flags: + + + + Bit 1 being set indicates that the header block is + the last that the endpoint will send for the identified stream. Setting this flag + causes the stream to enter one of "half closed" + states. + + + A HEADERS frame carries the END_STREAM flag that signals the end of a stream. + However, a HEADERS frame with the END_STREAM flag set can be followed by + CONTINUATION frames on the same stream. Logically, the + CONTINUATION frames are part of the HEADERS frame. + + + + + Bit 3 being set indicates that this frame contains an entire header block and is not followed by any + CONTINUATION frames. + + + A HEADERS frame without the END_HEADERS flag set MUST be followed by a + CONTINUATION frame for the same stream. A receiver MUST treat the + receipt of any other type of frame or a frame on a different stream as a connection error of type + PROTOCOL_ERROR. + + + + + Bit 4 being set indicates that the Pad Length field and any padding that it + describes is present. + + + + + Bit 6 being set indicates that the Exclusive Flag (E), Stream Dependency, and Weight + fields are present; see . + + + + + + + The payload of a HEADERS frame contains a header block + fragment. A header block that does not fit within a HEADERS frame is continued in + a CONTINUATION frame. + + + + HEADERS frames MUST be associated with a stream. If a HEADERS frame is received whose + stream identifier field is 0x0, the recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + + The HEADERS frame changes the connection state as described in . + + + + The HEADERS frame includes optional padding. Padding fields and flags are identical to + those defined for DATA frames. + + + Prioritization information in a HEADERS frame is logically equivalent to a separate + PRIORITY frame, but inclusion in HEADERS avoids the potential for churn in + stream prioritization when new streams are created. Priorization fields in HEADERS frames + subsequent to the first on a stream reprioritize the + stream. + +
    + +
    + + The PRIORITY frame (type=0x2) specifies the sender-advised + priority of a stream. It can be sent at any time for an existing stream, including + closed streams. This enables reprioritization of existing streams. + +
    + +
    + + The payload of a PRIORITY frame contains the following fields: + + + A single bit flag indicates that the stream dependency is exclusive, see . + + + A 31-bit stream identifier for the stream that this stream depends on, see . + + + An 8-bit weight for the identified stream dependency, see . Add one to the value to obtain a weight between 1 and 256. + + + + + + The PRIORITY frame does not define any flags. + + + + The PRIORITY frame is associated with an existing stream. If a PRIORITY frame is received + with a stream identifier of 0x0, the recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + The PRIORITY frame can be sent on a stream in any of the "reserved (remote)", "open", + "half closed (local)", "half closed (remote)", or "closed" states, though it cannot be + sent between consecutive frames that comprise a single header + block. Note that this frame could arrive after processing or frame sending has + completed, which would cause it to have no effect on the current stream. For a stream + that is in the "half closed (remote)" or "closed" - state, this frame can only affect + processing of the current stream and not frame transmission. + + + The PRIORITY frame is the only frame that can be sent for a stream in the "closed" state. + This allows for the reprioritization of a group of dependent streams by altering the + priority of a parent stream, which might be closed. However, a PRIORITY frame sent on a + closed stream risks being ignored due to the peer having discarded priority state + information for that stream. + +
    + +
    + + The RST_STREAM frame (type=0x3) allows for abnormal termination of a stream. When sent by + the initiator of a stream, it indicates that they wish to cancel the stream or that an + error condition has occurred. When sent by the receiver of a stream, it indicates that + either the receiver is rejecting the stream, requesting that the stream be cancelled, or + that an error condition has occurred. + +
    + +
    + + + The RST_STREAM frame contains a single unsigned, 32-bit integer identifying the error code. The error code indicates why the stream is being + terminated. + + + + The RST_STREAM frame does not define any flags. + + + + The RST_STREAM frame fully terminates the referenced stream and causes it to enter the + closed state. After receiving a RST_STREAM on a stream, the receiver MUST NOT send + additional frames for that stream, with the exception of PRIORITY. However, + after sending the RST_STREAM, the sending endpoint MUST be prepared to receive and process + additional frames sent on the stream that might have been sent by the peer prior to the + arrival of the RST_STREAM. + + + + RST_STREAM frames MUST be associated with a stream. If a RST_STREAM frame is received + with a stream identifier of 0x0, the recipient MUST treat this as a connection error of type + PROTOCOL_ERROR. + + + + RST_STREAM frames MUST NOT be sent for a stream in the "idle" state. If a RST_STREAM + frame identifying an idle stream is received, the recipient MUST treat this as a connection error of type + PROTOCOL_ERROR. + + +
    + +
    + + The SETTINGS frame (type=0x4) conveys configuration parameters that affect how endpoints + communicate, such as preferences and constraints on peer behavior. The SETTINGS frame is + also used to acknowledge the receipt of those parameters. Individually, a SETTINGS + parameter can also be referred to as a "setting". + + + SETTINGS parameters are not negotiated; they describe characteristics of the sending peer, + which are used by the receiving peer. Different values for the same parameter can be + advertised by each peer. For example, a client might set a high initial flow control + window, whereas a server might set a lower value to conserve resources. + + + + A SETTINGS frame MUST be sent by both endpoints at the start of a connection, and MAY be + sent at any other time by either endpoint over the lifetime of the connection. + Implementations MUST support all of the parameters defined by this specification. + + + + Each parameter in a SETTINGS frame replaces any existing value for that parameter. + Parameters are processed in the order in which they appear, and a receiver of a SETTINGS + frame does not need to maintain any state other than the current value of its + parameters. Therefore, the value of a SETTINGS parameter is the last value that is seen by + a receiver. + + + SETTINGS parameters are acknowledged by the receiving peer. To enable this, the SETTINGS + frame defines the following flag: + + + Bit 1 being set indicates that this frame acknowledges receipt and application of the + peer's SETTINGS frame. When this bit is set, the payload of the SETTINGS frame MUST + be empty. Receipt of a SETTINGS frame with the ACK flag set and a length field value + other than 0 MUST be treated as a connection + error of type FRAME_SIZE_ERROR. For more info, see Settings Synchronization. + + + + + SETTINGS frames always apply to a connection, never a single stream. The stream + identifier for a SETTINGS frame MUST be zero (0x0). If an endpoint receives a SETTINGS + frame whose stream identifier field is anything other than 0x0, the endpoint MUST respond + with a connection error of type + PROTOCOL_ERROR. + + + The SETTINGS frame affects connection state. A badly formed or incomplete SETTINGS frame + MUST be treated as a connection error of type + PROTOCOL_ERROR. + + +
    + + The payload of a SETTINGS frame consists of zero or more parameters, each consisting of + an unsigned 16-bit setting identifier and an unsigned 32-bit value. + + +
    + +
    +
    + +
    + + The following parameters are defined: + + + + Allows the sender to inform the remote endpoint of the maximum size of the header + compression table used to decode header blocks, in octets. The encoder can select + any size equal to or less than this value by using signaling specific to the + header compression format inside a header block. The initial value is 4,096 + octets. + + + + + This setting can be use to disable server + push. An endpoint MUST NOT send a PUSH_PROMISE frame if it + receives this parameter set to a value of 0. An endpoint that has both set this + parameter to 0 and had it acknowledged MUST treat the receipt of a + PUSH_PROMISE frame as a connection error of type + PROTOCOL_ERROR. + + + The initial value is 1, which indicates that server push is permitted. Any value + other than 0 or 1 MUST be treated as a connection error of type + PROTOCOL_ERROR. + + + + + Indicates the maximum number of concurrent streams that the sender will allow. + This limit is directional: it applies to the number of streams that the sender + permits the receiver to create. Initially there is no limit to this value. It is + recommended that this value be no smaller than 100, so as to not unnecessarily + limit parallelism. + + + A value of 0 for SETTINGS_MAX_CONCURRENT_STREAMS SHOULD NOT be treated as special + by endpoints. A zero value does prevent the creation of new streams, however this + can also happen for any limit that is exhausted with active streams. Servers + SHOULD only set a zero value for short durations; if a server does not wish to + accept requests, closing the connection could be preferable. + + + + + Indicates the sender's initial window size (in octets) for stream level flow + control. The initial value is 216-1 (65,535) octets. + + + This setting affects the window size of all streams, including existing streams, + see . + + + Values above the maximum flow control window size of 231-1 MUST + be treated as a connection error of + type FLOW_CONTROL_ERROR. + + + + + Indicates the size of the largest frame payload that the sender is willing to + receive, in octets. + + + The initial value is 214 (16,384) octets. The value advertised by + an endpoint MUST be between this initial value and the maximum allowed frame size + (224-1 or 16,777,215 octets), inclusive. Values outside this range + MUST be treated as a connection error + of type PROTOCOL_ERROR. + + + + + This advisory setting informs a peer of the maximum size of header list that the + sender is prepared to accept, in octets. The value is based on the uncompressed + size of header fields, including the length of the name and value in octets plus + an overhead of 32 octets for each header field. + + + For any given request, a lower limit than what is advertised MAY be enforced. The + initial value of this setting is unlimited. + + + + + + An endpoint that receives a SETTINGS frame with any unknown or unsupported identifier + MUST ignore that setting. + +
    + +
    + + Most values in SETTINGS benefit from or require an understanding of when the peer has + received and applied the changed parameter values. In order to provide + such synchronization timepoints, the recipient of a SETTINGS frame in which the ACK flag + is not set MUST apply the updated parameters as soon as possible upon receipt. + + + The values in the SETTINGS frame MUST be processed in the order they appear, with no + other frame processing between values. Unsupported parameters MUST be ignored. Once + all values have been processed, the recipient MUST immediately emit a SETTINGS frame + with the ACK flag set. Upon receiving a SETTINGS frame with the ACK flag set, the sender + of the altered parameters can rely on the setting having been applied. + + + If the sender of a SETTINGS frame does not receive an acknowledgement within a + reasonable amount of time, it MAY issue a connection error of type + SETTINGS_TIMEOUT. + +
    +
    + +
    + + The PUSH_PROMISE frame (type=0x5) is used to notify the peer endpoint in advance of + streams the sender intends to initiate. The PUSH_PROMISE frame includes the unsigned + 31-bit identifier of the stream the endpoint plans to create along with a set of headers + that provide additional context for the stream. contains a + thorough description of the use of PUSH_PROMISE frames. + + +
    + +
    + + The PUSH_PROMISE frame payload has the following fields: + + + An 8-bit field containing the length of the frame padding in units of octets. This + field is only present if the PADDED flag is set. + + + A single reserved bit. + + + An unsigned 31-bit integer that identifies the stream that is reserved by the + PUSH_PROMISE. The promised stream identifier MUST be a valid choice for the next + stream sent by the sender (see new stream + identifier). + + + A header block fragment containing request header + fields. + + + Padding octets. + + + + + + The PUSH_PROMISE frame defines the following flags: + + + + Bit 3 being set indicates that this frame contains an entire header block and is not followed by any + CONTINUATION frames. + + + A PUSH_PROMISE frame without the END_HEADERS flag set MUST be followed by a + CONTINUATION frame for the same stream. A receiver MUST treat the receipt of any + other type of frame or a frame on a different stream as a connection error of type + PROTOCOL_ERROR. + + + + + Bit 4 being set indicates that the Pad Length field and any padding that it + describes is present. + + + + + + + PUSH_PROMISE frames MUST be associated with an existing, peer-initiated stream. The stream + identifier of a PUSH_PROMISE frame indicates the stream it is associated with. If the + stream identifier field specifies the value 0x0, a recipient MUST respond with a connection error of type + PROTOCOL_ERROR. + + + + Promised streams are not required to be used in the order they are promised. The + PUSH_PROMISE only reserves stream identifiers for later use. + + + + PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH setting of the + peer endpoint is set to 0. An endpoint that has set this setting and has received + acknowledgement MUST treat the receipt of a PUSH_PROMISE frame as a connection error of type + PROTOCOL_ERROR. + + + Recipients of PUSH_PROMISE frames can choose to reject promised streams by returning a + RST_STREAM referencing the promised stream identifier back to the sender of + the PUSH_PROMISE. + + + + A PUSH_PROMISE frame modifies the connection state in two ways. The inclusion of a header block potentially modifies the state maintained for + header compression. PUSH_PROMISE also reserves a stream for later use, causing the + promised stream to enter the "reserved" state. A sender MUST NOT send a PUSH_PROMISE on a + stream unless that stream is either "open" or "half closed (remote)"; the sender MUST + ensure that the promised stream is a valid choice for a new stream identifier (that is, the promised stream MUST + be in the "idle" state). + + + Since PUSH_PROMISE reserves a stream, ignoring a PUSH_PROMISE frame causes the stream + state to become indeterminate. A receiver MUST treat the receipt of a PUSH_PROMISE on a + stream that is neither "open" nor "half closed (local)" as a connection error of type + PROTOCOL_ERROR. However, an endpoint that has sent + RST_STREAM on the associated stream MUST handle PUSH_PROMISE frames that + might have been created before the RST_STREAM frame is received and + processed. + + + A receiver MUST treat the receipt of a PUSH_PROMISE that promises an illegal stream identifier (that is, an identifier for a + stream that is not currently in the "idle" state) as a connection error of type + PROTOCOL_ERROR. + + + + The PUSH_PROMISE frame includes optional padding. Padding fields and flags are identical + to those defined for DATA frames. + +
    + +
    + + The PING frame (type=0x6) is a mechanism for measuring a minimal round trip time from the + sender, as well as determining whether an idle connection is still functional. PING + frames can be sent from any endpoint. + +
    + +
    + + + In addition to the frame header, PING frames MUST contain 8 octets of data in the payload. + A sender can include any value it chooses and use those bytes in any fashion. + + + Receivers of a PING frame that does not include an ACK flag MUST send a PING frame with + the ACK flag set in response, with an identical payload. PING responses SHOULD be given + higher priority than any other frame. + + + + The PING frame defines the following flags: + + + Bit 1 being set indicates that this PING frame is a PING response. An endpoint MUST + set this flag in PING responses. An endpoint MUST NOT respond to PING frames + containing this flag. + + + + + PING frames are not associated with any individual stream. If a PING frame is received + with a stream identifier field value other than 0x0, the recipient MUST respond with a + connection error of type + PROTOCOL_ERROR. + + + Receipt of a PING frame with a length field value other than 8 MUST be treated as a connection error of type + FRAME_SIZE_ERROR. + + +
    + +
    + + The GOAWAY frame (type=0x7) informs the remote peer to stop creating streams on this + connection. GOAWAY can be sent by either the client or the server. Once sent, the sender + will ignore frames sent on any new streams with identifiers higher than the included last + stream identifier. Receivers of a GOAWAY frame MUST NOT open additional streams on the + connection, although a new connection can be established for new streams. + + + The purpose of this frame is to allow an endpoint to gracefully stop accepting new + streams, while still finishing processing of previously established streams. This enables + administrative actions, like server maintainance. + + + There is an inherent race condition between an endpoint starting new streams and the + remote sending a GOAWAY frame. To deal with this case, the GOAWAY contains the stream + identifier of the last peer-initiated stream which was or might be processed on the + sending endpoint in this connection. For instance, if the server sends a GOAWAY frame, + the identified stream is the highest numbered stream initiated by the client. + + + If the receiver of the GOAWAY has sent data on streams with a higher stream identifier + than what is indicated in the GOAWAY frame, those streams are not or will not be + processed. The receiver of the GOAWAY frame can treat the streams as though they had + never been created at all, thereby allowing those streams to be retried later on a new + connection. + + + Endpoints SHOULD always send a GOAWAY frame before closing a connection so that the remote + can know whether a stream has been partially processed or not. For example, if an HTTP + client sends a POST at the same time that a server closes a connection, the client cannot + know if the server started to process that POST request if the server does not send a + GOAWAY frame to indicate what streams it might have acted on. + + + An endpoint might choose to close a connection without sending GOAWAY for misbehaving + peers. + + +
    + +
    + + The GOAWAY frame does not define any flags. + + + The GOAWAY frame applies to the connection, not a specific stream. An endpoint MUST treat + a GOAWAY frame with a stream identifier other than 0x0 as a connection error of type + PROTOCOL_ERROR. + + + The last stream identifier in the GOAWAY frame contains the highest numbered stream + identifier for which the sender of the GOAWAY frame might have taken some action on, or + might yet take action on. All streams up to and including the identified stream might + have been processed in some way. The last stream identifier can be set to 0 if no streams + were processed. + + + In this context, "processed" means that some data from the stream was passed to some + higher layer of software that might have taken some action as a result. + + + If a connection terminates without a GOAWAY frame, the last stream identifier is + effectively the highest possible stream identifier. + + + On streams with lower or equal numbered identifiers that were not closed completely prior + to the connection being closed, re-attempting requests, transactions, or any protocol + activity is not possible, with the exception of idempotent actions like HTTP GET, PUT, or + DELETE. Any protocol activity that uses higher numbered streams can be safely retried + using a new connection. + + + Activity on streams numbered lower or equal to the last stream identifier might still + complete successfully. The sender of a GOAWAY frame might gracefully shut down a + connection by sending a GOAWAY frame, maintaining the connection in an open state until + all in-progress streams complete. + + + An endpoint MAY send multiple GOAWAY frames if circumstances change. For instance, an + endpoint that sends GOAWAY with NO_ERROR during graceful shutdown could + subsequently encounter an condition that requires immediate termination of the connection. + The last stream identifier from the last GOAWAY frame received indicates which streams + could have been acted upon. Endpoints MUST NOT increase the value they send in the last + stream identifier, since the peers might already have retried unprocessed requests on + another connection. + + + A client that is unable to retry requests loses all requests that are in flight when the + server closes the connection. This is especially true for intermediaries that might + not be serving clients using HTTP/2. A server that is attempting to gracefully shut down + a connection SHOULD send an initial GOAWAY frame with the last stream identifier set to + 231-1 and a NO_ERROR code. This signals to the client that + a shutdown is imminent and that no further requests can be initiated. After waiting at + least one round trip time, the server can send another GOAWAY frame with an updated last + stream identifier. This ensures that a connection can be cleanly shut down without losing + requests. + + + + After sending a GOAWAY frame, the sender can discard frames for streams with identifiers + higher than the identified last stream. However, any frames that alter connection state + cannot be completely ignored. For instance, HEADERS, + PUSH_PROMISE and CONTINUATION frames MUST be minimally + processed to ensure the state maintained for header compression is consistent (see ); similarly DATA frames MUST be counted toward the connection flow + control window. Failure to process these frames can cause flow control or header + compression state to become unsynchronized. + + + + The GOAWAY frame also contains a 32-bit error code that + contains the reason for closing the connection. + + + Endpoints MAY append opaque data to the payload of any GOAWAY frame. Additional debug + data is intended for diagnostic purposes only and carries no semantic value. Debug + information could contain security- or privacy-sensitive data. Logged or otherwise + persistently stored debug data MUST have adequate safeguards to prevent unauthorized + access. + +
    + +
    + + The WINDOW_UPDATE frame (type=0x8) is used to implement flow control; see for an overview. + + + Flow control operates at two levels: on each individual stream and on the entire + connection. + + + Both types of flow control are hop-by-hop; that is, only between the two endpoints. + Intermediaries do not forward WINDOW_UPDATE frames between dependent connections. + However, throttling of data transfer by any receiver can indirectly cause the propagation + of flow control information toward the original sender. + + + Flow control only applies to frames that are identified as being subject to flow control. + Of the frame types defined in this document, this includes only DATA frames. + Frames that are exempt from flow control MUST be accepted and processed, unless the + receiver is unable to assign resources to handling the frame. A receiver MAY respond with + a stream error or connection error of type + FLOW_CONTROL_ERROR if it is unable to accept a frame. + +
    + +
    + + The payload of a WINDOW_UPDATE frame is one reserved bit, plus an unsigned 31-bit integer + indicating the number of octets that the sender can transmit in addition to the existing + flow control window. The legal range for the increment to the flow control window is 1 to + 231-1 (0x7fffffff) octets. + + + The WINDOW_UPDATE frame does not define any flags. + + + The WINDOW_UPDATE frame can be specific to a stream or to the entire connection. In the + former case, the frame's stream identifier indicates the affected stream; in the latter, + the value "0" indicates that the entire connection is the subject of the frame. + + + A receiver MUST treat the receipt of a WINDOW_UPDATE frame with an flow control window + increment of 0 as a stream error of type + PROTOCOL_ERROR; errors on the connection flow control window MUST be + treated as a connection error. + + + WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the END_STREAM flag. + This means that a receiver could receive a WINDOW_UPDATE frame on a "half closed (remote)" + or "closed" stream. A receiver MUST NOT treat this as an error, see . + + + A receiver that receives a flow controlled frame MUST always account for its contribution + against the connection flow control window, unless the receiver treats this as a connection error. This is necessary even if the + frame is in error. Since the sender counts the frame toward the flow control window, if + the receiver does not, the flow control window at sender and receiver can become + different. + + +
    + + Flow control in HTTP/2 is implemented using a window kept by each sender on every + stream. The flow control window is a simple integer value that indicates how many octets + of data the sender is permitted to transmit; as such, its size is a measure of the + buffering capacity of the receiver. + + + Two flow control windows are applicable: the stream flow control window and the + connection flow control window. The sender MUST NOT send a flow controlled frame with a + length that exceeds the space available in either of the flow control windows advertised + by the receiver. Frames with zero length with the END_STREAM flag set (that is, an + empty DATA frame) MAY be sent if there is no available space in either + flow control window. + + + For flow control calculations, the 9 octet frame header is not counted. + + + After sending a flow controlled frame, the sender reduces the space available in both + windows by the length of the transmitted frame. + + + The receiver of a frame sends a WINDOW_UPDATE frame as it consumes data and frees up + space in flow control windows. Separate WINDOW_UPDATE frames are sent for the stream + and connection level flow control windows. + + + A sender that receives a WINDOW_UPDATE frame updates the corresponding window by the + amount specified in the frame. + + + A sender MUST NOT allow a flow control window to exceed 231-1 octets. + If a sender receives a WINDOW_UPDATE that causes a flow control window to exceed this + maximum it MUST terminate either the stream or the connection, as appropriate. For + streams, the sender sends a RST_STREAM with the error code of + FLOW_CONTROL_ERROR code; for the connection, a GOAWAY + frame with a FLOW_CONTROL_ERROR code. + + + Flow controlled frames from the sender and WINDOW_UPDATE frames from the receiver are + completely asynchronous with respect to each other. This property allows a receiver to + aggressively update the window size kept by the sender to prevent streams from stalling. + +
    + +
    + + When an HTTP/2 connection is first established, new streams are created with an initial + flow control window size of 65,535 octets. The connection flow control window is 65,535 + octets. Both endpoints can adjust the initial window size for new streams by including + a value for SETTINGS_INITIAL_WINDOW_SIZE in the SETTINGS + frame that forms part of the connection preface. The connection flow control window can + only be changed using WINDOW_UPDATE frames. + + + Prior to receiving a SETTINGS frame that sets a value for + SETTINGS_INITIAL_WINDOW_SIZE, an endpoint can only use the default + initial window size when sending flow controlled frames. Similarly, the connection flow + control window is set to the default initial window size until a WINDOW_UPDATE frame is + received. + + + A SETTINGS frame can alter the initial flow control window size for all + current streams. When the value of SETTINGS_INITIAL_WINDOW_SIZE changes, + a receiver MUST adjust the size of all stream flow control windows that it maintains by + the difference between the new value and the old value. + + + A change to SETTINGS_INITIAL_WINDOW_SIZE can cause the available space in + a flow control window to become negative. A sender MUST track the negative flow control + window, and MUST NOT send new flow controlled frames until it receives WINDOW_UPDATE + frames that cause the flow control window to become positive. + + + For example, if the client sends 60KB immediately on connection establishment, and the + server sets the initial window size to be 16KB, the client will recalculate the + available flow control window to be -44KB on receipt of the SETTINGS + frame. The client retains a negative flow control window until WINDOW_UPDATE frames + restore the window to being positive, after which the client can resume sending. + + + A SETTINGS frame cannot alter the connection flow control window. + + + An endpoint MUST treat a change to SETTINGS_INITIAL_WINDOW_SIZE that + causes any flow control window to exceed the maximum size as a connection error of type + FLOW_CONTROL_ERROR. + +
    + +
    + + A receiver that wishes to use a smaller flow control window than the current size can + send a new SETTINGS frame. However, the receiver MUST be prepared to + receive data that exceeds this window size, since the sender might send data that + exceeds the lower limit prior to processing the SETTINGS frame. + + + After sending a SETTINGS frame that reduces the initial flow control window size, a + receiver has two options for handling streams that exceed flow control limits: + + + The receiver can immediately send RST_STREAM with + FLOW_CONTROL_ERROR error code for the affected streams. + + + The receiver can accept the streams and tolerate the resulting head of line + blocking, sending WINDOW_UPDATE frames as it consumes data. + + + +
    +
    + +
    + + The CONTINUATION frame (type=0x9) is used to continue a sequence of header block fragments. Any number of CONTINUATION frames can + be sent on an existing stream, as long as the preceding frame is on the same stream and is + a HEADERS, PUSH_PROMISE or CONTINUATION frame without the + END_HEADERS flag set. + + +
    + +
    + + The CONTINUATION frame payload contains a header block + fragment. + + + + The CONTINUATION frame defines the following flag: + + + + Bit 3 being set indicates that this frame ends a header + block. + + + If the END_HEADERS bit is not set, this frame MUST be followed by another + CONTINUATION frame. A receiver MUST treat the receipt of any other type of frame or + a frame on a different stream as a connection + error of type PROTOCOL_ERROR. + + + + + + + The CONTINUATION frame changes the connection state as defined in . + + + + CONTINUATION frames MUST be associated with a stream. If a CONTINUATION frame is received + whose stream identifier field is 0x0, the recipient MUST respond with a connection error of type PROTOCOL_ERROR. + + + + A CONTINUATION frame MUST be preceded by a HEADERS, + PUSH_PROMISE or CONTINUATION frame without the END_HEADERS flag set. A + recipient that observes violation of this rule MUST respond with a connection error of type + PROTOCOL_ERROR. + +
    +
    + +
    + + Error codes are 32-bit fields that are used in RST_STREAM and + GOAWAY frames to convey the reasons for the stream or connection error. + + + + Error codes share a common code space. Some error codes apply only to either streams or the + entire connection and have no defined semantics in the other context. + + + + The following error codes are defined: + + + The associated condition is not as a result of an error. For example, a + GOAWAY might include this code to indicate graceful shutdown of a + connection. + + + The endpoint detected an unspecific protocol error. This error is for use when a more + specific error code is not available. + + + The endpoint encountered an unexpected internal error. + + + The endpoint detected that its peer violated the flow control protocol. + + + The endpoint sent a SETTINGS frame, but did not receive a response in a + timely manner. See Settings Synchronization. + + + The endpoint received a frame after a stream was half closed. + + + The endpoint received a frame with an invalid size. + + + The endpoint refuses the stream prior to performing any application processing, see + for details. + + + Used by the endpoint to indicate that the stream is no longer needed. + + + The endpoint is unable to maintain the header compression context for the connection. + + + The connection established in response to a CONNECT + request was reset or abnormally closed. + + + The endpoint detected that its peer is exhibiting a behavior that might be generating + excessive load. + + + The underlying transport has properties that do not meet minimum security + requirements (see ). + + + + + Unknown or unsupported error codes MUST NOT trigger any special behavior. These MAY be + treated by an implementation as being equivalent to INTERNAL_ERROR. + +
    + +
    + + HTTP/2 is intended to be as compatible as possible with current uses of HTTP. This means + that, from the application perspective, the features of the protocol are largely + unchanged. To achieve this, all request and response semantics are preserved, although the + syntax of conveying those semantics has changed. + + + Thus, the specification and requirements of HTTP/1.1 Semantics and Content , Conditional Requests , Range Requests , Caching and Authentication are applicable to HTTP/2. Selected portions of HTTP/1.1 Message Syntax + and Routing , such as the HTTP and HTTPS URI schemes, are also + applicable in HTTP/2, but the expression of those semantics for this protocol are defined + in the sections below. + + +
    + + A client sends an HTTP request on a new stream, using a previously unused stream identifier. A server sends an HTTP response on + the same stream as the request. + + + An HTTP message (request or response) consists of: + + + for a response only, zero or more HEADERS frames (each followed by zero + or more CONTINUATION frames) containing the message headers of + informational (1xx) HTTP responses (see and ), + and + + + one HEADERS frame (followed by zero or more CONTINUATION + frames) containing the message headers (see ), and + + + zero or more DATA frames containing the message payload (see ), and + + + optionally, one HEADERS frame, followed by zero or more + CONTINUATION frames containing the trailer-part, if present (see ). + + + The last frame in the sequence bears an END_STREAM flag, noting that a + HEADERS frame bearing the END_STREAM flag can be followed by + CONTINUATION frames that carry any remaining portions of the header block. + + + Other frames (from any stream) MUST NOT occur between either HEADERS frame + and any CONTINUATION frames that might follow. + + + + Trailing header fields are carried in a header block that also terminates the stream. + That is, a sequence starting with a HEADERS frame, followed by zero or more + CONTINUATION frames, where the HEADERS frame bears an + END_STREAM flag. Header blocks after the first that do not terminate the stream are not + part of an HTTP request or response. + + + A HEADERS frame (and associated CONTINUATION frames) can + only appear at the start or end of a stream. An endpoint that receives a + HEADERS frame without the END_STREAM flag set after receiving a final + (non-informational) status code MUST treat the corresponding request or response as malformed. + + + + An HTTP request/response exchange fully consumes a single stream. A request starts with + the HEADERS frame that puts the stream into an "open" state. The request + ends with a frame bearing END_STREAM, which causes the stream to become "half closed + (local)" for the client and "half closed (remote)" for the server. A response starts with + a HEADERS frame and ends with a frame bearing END_STREAM, which places the + stream in the "closed" state. + + + +
    + + HTTP/2 removes support for the 101 (Switching Protocols) informational status code + (). + + + The semantics of 101 (Switching Protocols) aren't applicable to a multiplexed protocol. + Alternative protocols are able to use the same mechanisms that HTTP/2 uses to negotiate + their use (see ). + +
    + +
    + + HTTP header fields carry information as a series of key-value pairs. For a listing of + registered HTTP headers, see the Message Header Field Registry maintained at . + + +
    + + While HTTP/1.x used the message start-line (see ) to convey the target URI and method of the request, and the + status code for the response, HTTP/2 uses special pseudo-header fields beginning with + ':' character (ASCII 0x3a) for this purpose. + + + Pseudo-header fields are not HTTP header fields. Endpoints MUST NOT generate + pseudo-header fields other than those defined in this document. + + + Pseudo-header fields are only valid in the context in which they are defined. + Pseudo-header fields defined for requests MUST NOT appear in responses; pseudo-header + fields defined for responses MUST NOT appear in requests. Pseudo-header fields MUST + NOT appear in trailers. Endpoints MUST treat a request or response that contains + undefined or invalid pseudo-header fields as malformed. + + + Just as in HTTP/1.x, header field names are strings of ASCII characters that are + compared in a case-insensitive fashion. However, header field names MUST be converted + to lowercase prior to their encoding in HTTP/2. A request or response containing + uppercase header field names MUST be treated as malformed. + + + All pseudo-header fields MUST appear in the header block before regular header fields. + Any request or response that contains a pseudo-header field that appears in a header + block after a regular header field MUST be treated as malformed. + +
    + +
    + + HTTP/2 does not use the Connection header field to + indicate connection-specific header fields; in this protocol, connection-specific + metadata is conveyed by other means. An endpoint MUST NOT generate a HTTP/2 message + containing connection-specific header fields; any message containing + connection-specific header fields MUST be treated as malformed. + + + This means that an intermediary transforming an HTTP/1.x message to HTTP/2 will need + to remove any header fields nominated by the Connection header field, along with the + Connection header field itself. Such intermediaries SHOULD also remove other + connection-specific header fields, such as Keep-Alive, Proxy-Connection, + Transfer-Encoding and Upgrade, even if they are not nominated by Connection. + + + One exception to this is the TE header field, which MAY be present in an HTTP/2 + request, but when it is MUST NOT contain any value other than "trailers". + + + + + HTTP/2 purposefully does not support upgrade to another protocol. The handshake + methods described in are believed sufficient to + negotiate the use of alternative protocols. + + + +
    + +
    + + The following pseudo-header fields are defined for HTTP/2 requests: + + + + The :method pseudo-header field includes the HTTP + method (). + + + + + The :scheme pseudo-header field includes the scheme + portion of the target URI (). + + + :scheme is not restricted to http and https schemed URIs. A + proxy or gateway can translate requests for non-HTTP schemes, enabling the use + of HTTP to interact with non-HTTP services. + + + + + The :authority pseudo-header field includes the + authority portion of the target URI (). The authority MUST NOT include the deprecated userinfo subcomponent for http + or https schemed URIs. + + + To ensure that the HTTP/1.1 request line can be reproduced accurately, this + pseudo-header field MUST be omitted when translating from an HTTP/1.1 request + that has a request target in origin or asterisk form (see ). Clients that generate + HTTP/2 requests directly SHOULD use the :authority pseudo-header + field instead of the Host header field. An + intermediary that converts an HTTP/2 request to HTTP/1.1 MUST create a Host header field if one is not present in a request by + copying the value of the :authority pseudo-header + field. + + + + + The :path pseudo-header field includes the path and + query parts of the target URI (the path-absolute + production from and optionally a '?' character + followed by the query production, see and ). A request in asterisk form includes the value '*' for the + :path pseudo-header field. + + + This pseudo-header field MUST NOT be empty for http + or https URIs; http or + https URIs that do not contain a path component + MUST include a value of '/'. The exception to this rule is an OPTIONS request + for an http or https + URI that does not include a path component; these MUST include a :path pseudo-header field with a value of '*' (see ). + + + + + + All HTTP/2 requests MUST include exactly one valid value for the :method, :scheme, and :path pseudo-header fields, unless it is a CONNECT request. An HTTP request that omits mandatory + pseudo-header fields is malformed. + + + HTTP/2 does not define a way to carry the version identifier that is included in the + HTTP/1.1 request line. + +
    + +
    + + For HTTP/2 responses, a single :status pseudo-header + field is defined that carries the HTTP status code field (see ). This pseudo-header field MUST be included in all + responses, otherwise the response is malformed. + + + HTTP/2 does not define a way to carry the version or reason phrase that is included in + an HTTP/1.1 status line. + +
    + +
    + + The Cookie header field can carry a significant amount of + redundant data. + + + The Cookie header field uses a semi-colon (";") to delimit cookie-pairs (or "crumbs"). + This header field doesn't follow the list construction rules in HTTP (see ), which prevents cookie-pairs from + being separated into different name-value pairs. This can significantly reduce + compression efficiency as individual cookie-pairs are updated. + + + To allow for better compression efficiency, the Cookie header field MAY be split into + separate header fields, each with one or more cookie-pairs. If there are multiple + Cookie header fields after decompression, these MUST be concatenated into a single + octet string using the two octet delimiter of 0x3B, 0x20 (the ASCII string "; ") + before being passed into a non-HTTP/2 context, such as an HTTP/1.1 connection, or a + generic HTTP server application. + +
    + + Therefore, the following two lists of Cookie header fields are semantically + equivalent. + + +
    +
    + +
    + + A malformed request or response is one that is an otherwise valid sequence of HTTP/2 + frames, but is otherwise invalid due to the presence of extraneous frames, prohibited + header fields, the absence of mandatory header fields, or the inclusion of uppercase + header field names. + + + A request or response that includes an entity body can include a content-length header field. A request or response is also + malformed if the value of a content-length header field + does not equal the sum of the DATA frame payload lengths that form the + body. A response that is defined to have no payload, as described in , can have a non-zero + content-length header field, even though no content is + included in DATA frames. + + + Intermediaries that process HTTP requests or responses (i.e., any intermediary not + acting as a tunnel) MUST NOT forward a malformed request or response. Malformed + requests or responses that are detected MUST be treated as a stream error of type PROTOCOL_ERROR. + + + For malformed requests, a server MAY send an HTTP response prior to closing or + resetting the stream. Clients MUST NOT accept a malformed response. Note that these + requirements are intended to protect against several types of common attacks against + HTTP; they are deliberately strict, because being permissive can expose + implementations to these vulnerabilities. + +
    +
    + +
    + + This section shows HTTP/1.1 requests and responses, with illustrations of equivalent + HTTP/2 requests and responses. + + + An HTTP GET request includes request header fields and no body and is therefore + transmitted as a single HEADERS frame, followed by zero or more + CONTINUATION frames containing the serialized block of request header + fields. The HEADERS frame in the following has both the END_HEADERS and + END_STREAM flags set; no CONTINUATION frames are sent: + + +
    + + END_STREAM + Accept: image/jpeg + END_HEADERS + :method = GET + :scheme = https + :path = /resource + host = example.org + accept = image/jpeg +]]> +
    + + + Similarly, a response that includes only response header fields is transmitted as a + HEADERS frame (again, followed by zero or more + CONTINUATION frames) containing the serialized block of response header + fields. + + +
    + + END_STREAM + Expires: Thu, 23 Jan ... + END_HEADERS + :status = 304 + etag = "xyzzy" + expires = Thu, 23 Jan ... +]]> +
    + + + An HTTP POST request that includes request header fields and payload data is transmitted + as one HEADERS frame, followed by zero or more + CONTINUATION frames containing the request header fields, followed by one + or more DATA frames, with the last CONTINUATION (or + HEADERS) frame having the END_HEADERS flag set and the final + DATA frame having the END_STREAM flag set: + + +
    + - END_STREAM + Content-Type: image/jpeg - END_HEADERS + Content-Length: 123 :method = POST + :path = /resource + {binary data} :scheme = https + + CONTINUATION + + END_HEADERS + content-type = image/jpeg + host = example.org + content-length = 123 + + DATA + + END_STREAM + {binary data} +]]> + + Note that data contributing to any given header field could be spread between header + block fragments. The allocation of header fields to frames in this example is + illustrative only. + +
    + + + A response that includes header fields and payload data is transmitted as a + HEADERS frame, followed by zero or more CONTINUATION + frames, followed by one or more DATA frames, with the last + DATA frame in the sequence having the END_STREAM flag set: + + +
    + - END_STREAM + Content-Length: 123 + END_HEADERS + :status = 200 + {binary data} content-type = image/jpeg + content-length = 123 + + DATA + + END_STREAM + {binary data} +]]> +
    + + + Trailing header fields are sent as a header block after both the request or response + header block and all the DATA frames have been sent. The + HEADERS frame starting the trailers header block has the END_STREAM flag + set. + + +
    + - END_STREAM + Transfer-Encoding: chunked + END_HEADERS + Trailer: Foo :status = 200 + content-length = 123 + 123 content-type = image/jpeg + {binary data} trailer = Foo + 0 + Foo: bar DATA + - END_STREAM + {binary data} + + HEADERS + + END_STREAM + + END_HEADERS + foo = bar +]]> +
    + + +
    + + An informational response using a 1xx status code other than 101 is transmitted as a + HEADERS frame, followed by zero or more CONTINUATION + frames: + + - END_STREAM + + END_HEADERS + :status = 103 + extension-field = bar +]]> +
    +
    + +
    + + In HTTP/1.1, an HTTP client is unable to retry a non-idempotent request when an error + occurs, because there is no means to determine the nature of the error. It is possible + that some server processing occurred prior to the error, which could result in + undesirable effects if the request were reattempted. + + + HTTP/2 provides two mechanisms for providing a guarantee to a client that a request has + not been processed: + + + The GOAWAY frame indicates the highest stream number that might have + been processed. Requests on streams with higher numbers are therefore guaranteed to + be safe to retry. + + + The REFUSED_STREAM error code can be included in a + RST_STREAM frame to indicate that the stream is being closed prior to + any processing having occurred. Any request that was sent on the reset stream can + be safely retried. + + + + + Requests that have not been processed have not failed; clients MAY automatically retry + them, even those with non-idempotent methods. + + + A server MUST NOT indicate that a stream has not been processed unless it can guarantee + that fact. If frames that are on a stream are passed to the application layer for any + stream, then REFUSED_STREAM MUST NOT be used for that stream, and a + GOAWAY frame MUST include a stream identifier that is greater than or + equal to the given stream identifier. + + + In addition to these mechanisms, the PING frame provides a way for a + client to easily test a connection. Connections that remain idle can become broken as + some middleboxes (for instance, network address translators, or load balancers) silently + discard connection bindings. The PING frame allows a client to safely + test whether a connection is still active without sending a request. + +
    +
    + +
    + + HTTP/2 allows a server to pre-emptively send (or "push") responses (along with + corresponding "promised" requests) to a client in association with a previous + client-initiated request. This can be useful when the server knows the client will need + to have those responses available in order to fully process the response to the original + request. + + + + Pushing additional message exchanges in this fashion is optional, and is negotiated + between individual endpoints. The SETTINGS_ENABLE_PUSH setting can be set + to 0 to indicate that server push is disabled. + + + Promised requests MUST be cacheable (see ), MUST be safe (see ) and MUST NOT include a request body. Clients that receive a + promised request that is not cacheable, unsafe or that includes a request body MUST + reset the stream with a stream error of type + PROTOCOL_ERROR. + + + Pushed responses that are cacheable (see ) can be stored by the client, if it implements a HTTP + cache. Pushed responses are considered successfully validated on the origin server (e.g., + if the "no-cache" cache response directive is present) while the stream identified by the + promised stream ID is still open. + + + Pushed responses that are not cacheable MUST NOT be stored by any HTTP cache. They MAY + be made available to the application separately. + + + An intermediary can receive pushes from the server and choose not to forward them on to + the client. In other words, how to make use of the pushed information is up to that + intermediary. Equally, the intermediary might choose to make additional pushes to the + client, without any action taken by the server. + + + A client cannot push. Thus, servers MUST treat the receipt of a + PUSH_PROMISE frame as a connection + error of type PROTOCOL_ERROR. Clients MUST reject any attempt to + change the SETTINGS_ENABLE_PUSH setting to a value other than 0 by treating + the message as a connection error of type + PROTOCOL_ERROR. + + +
    + + Server push is semantically equivalent to a server responding to a request; however, in + this case that request is also sent by the server, as a PUSH_PROMISE + frame. + + + The PUSH_PROMISE frame includes a header block that contains a complete + set of request header fields that the server attributes to the request. It is not + possible to push a response to a request that includes a request body. + + + + Pushed responses are always associated with an explicit request from the client. The + PUSH_PROMISE frames sent by the server are sent on that explicit + request's stream. The PUSH_PROMISE frame also includes a promised stream + identifier, chosen from the stream identifiers available to the server (see ). + + + + The header fields in PUSH_PROMISE and any subsequent + CONTINUATION frames MUST be a valid and complete set of request header fields. The server MUST include a method in + the :method header field that is safe and cacheable. If a + client receives a PUSH_PROMISE that does not include a complete and valid + set of header fields, or the :method header field identifies + a method that is not safe, it MUST respond with a stream error of type PROTOCOL_ERROR. + + + + The server SHOULD send PUSH_PROMISE () + frames prior to sending any frames that reference the promised responses. This avoids a + race where clients issue requests prior to receiving any PUSH_PROMISE + frames. + + + For example, if the server receives a request for a document containing embedded links + to multiple image files, and the server chooses to push those additional images to the + client, sending push promises before the DATA frames that contain the + image links ensures that the client is able to see the promises before discovering + embedded links. Similarly, if the server pushes responses referenced by the header block + (for instance, in Link header fields), sending the push promises before sending the + header block ensures that clients do not request them. + + + + PUSH_PROMISE frames MUST NOT be sent by the client. + + + PUSH_PROMISE frames can be sent by the server in response to any + client-initiated stream, but the stream MUST be in either the "open" or "half closed + (remote)" state with respect to the server. PUSH_PROMISE frames are + interspersed with the frames that comprise a response, though they cannot be + interspersed with HEADERS and CONTINUATION frames that + comprise a single header block. + + + Sending a PUSH_PROMISE frame creates a new stream and puts the stream + into the “reserved (local)” state for the server and the “reserved (remote)” state for + the client. + +
    + +
    + + After sending the PUSH_PROMISE frame, the server can begin delivering the + pushed response as a response on a server-initiated + stream that uses the promised stream identifier. The server uses this stream to + transmit an HTTP response, using the same sequence of frames as defined in . This stream becomes "half closed" + to the client after the initial HEADERS frame is sent. + + + + Once a client receives a PUSH_PROMISE frame and chooses to accept the + pushed response, the client SHOULD NOT issue any requests for the promised response + until after the promised stream has closed. + + + + If the client determines, for any reason, that it does not wish to receive the pushed + response from the server, or if the server takes too long to begin sending the promised + response, the client can send an RST_STREAM frame, using either the + CANCEL or REFUSED_STREAM codes, and referencing the pushed + stream's identifier. + + + A client can use the SETTINGS_MAX_CONCURRENT_STREAMS setting to limit the + number of responses that can be concurrently pushed by a server. Advertising a + SETTINGS_MAX_CONCURRENT_STREAMS value of zero disables server push by + preventing the server from creating the necessary streams. This does not prohibit a + server from sending PUSH_PROMISE frames; clients need to reset any + promised streams that are not wanted. + + + + Clients receiving a pushed response MUST validate that either the server is + authoritative (see ), or the proxy that provided the pushed + response is configured for the corresponding request. For example, a server that offers + a certificate for only the example.com DNS-ID or Common Name + is not permitted to push a response for https://www.example.org/doc. + + + The response for a PUSH_PROMISE stream begins with a + HEADERS frame, which immediately puts the stream into the “half closed + (remote)” state for the server and “half closed (local)” state for the client, and ends + with a frame bearing END_STREAM, which places the stream in the "closed" state. + + + The client never sends a frame with the END_STREAM flag for a server push. + + + +
    + +
    + +
    + + In HTTP/1.x, the pseudo-method CONNECT () is used to convert an HTTP connection into a tunnel to a remote host. + CONNECT is primarily used with HTTP proxies to establish a TLS session with an origin + server for the purposes of interacting with https resources. + + + In HTTP/2, the CONNECT method is used to establish a tunnel over a single HTTP/2 stream to + a remote host, for similar purposes. The HTTP header field mapping works as defined in + Request Header Fields, with a few + differences. Specifically: + + + The :method header field is set to CONNECT. + + + The :scheme and :path header + fields MUST be omitted. + + + The :authority header field contains the host and port to + connect to (equivalent to the authority-form of the request-target of CONNECT + requests, see ). + + + + + A proxy that supports CONNECT establishes a TCP connection to + the server identified in the :authority header field. Once + this connection is successfully established, the proxy sends a HEADERS + frame containing a 2xx series status code to the client, as defined in . + + + After the initial HEADERS frame sent by each peer, all subsequent + DATA frames correspond to data sent on the TCP connection. The payload of + any DATA frames sent by the client is transmitted by the proxy to the TCP + server; data received from the TCP server is assembled into DATA frames by + the proxy. Frame types other than DATA or stream management frames + (RST_STREAM, WINDOW_UPDATE, and PRIORITY) + MUST NOT be sent on a connected stream, and MUST be treated as a stream error if received. + + + The TCP connection can be closed by either peer. The END_STREAM flag on a + DATA frame is treated as being equivalent to the TCP FIN bit. A client is + expected to send a DATA frame with the END_STREAM flag set after receiving + a frame bearing the END_STREAM flag. A proxy that receives a DATA frame + with the END_STREAM flag set sends the attached data with the FIN bit set on the last TCP + segment. A proxy that receives a TCP segment with the FIN bit set sends a + DATA frame with the END_STREAM flag set. Note that the final TCP segment + or DATA frame could be empty. + + + A TCP connection error is signaled with RST_STREAM. A proxy treats any + error in the TCP connection, which includes receiving a TCP segment with the RST bit set, + as a stream error of type + CONNECT_ERROR. Correspondingly, a proxy MUST send a TCP segment with the + RST bit set if it detects an error with the stream or the HTTP/2 connection. + +
    +
    + +
    + + This section outlines attributes of the HTTP protocol that improve interoperability, reduce + exposure to known security vulnerabilities, or reduce the potential for implementation + variation. + + +
    + + HTTP/2 connections are persistent. For best performance, it is expected clients will not + close connections until it is determined that no further communication with a server is + necessary (for example, when a user navigates away from a particular web page), or until + the server closes the connection. + + + Clients SHOULD NOT open more than one HTTP/2 connection to a given host and port pair, + where host is derived from a URI, a selected alternative + service, or a configured proxy. + + + A client can create additional connections as replacements, either to replace connections + that are near to exhausting the available stream + identifier space, to refresh the keying material for a TLS connection, or to + replace connections that have encountered errors. + + + A client MAY open multiple connections to the same IP address and TCP port using different + Server Name Indication values or to provide different TLS + client certificates, but SHOULD avoid creating multiple connections with the same + configuration. + + + Servers are encouraged to maintain open connections for as long as possible, but are + permitted to terminate idle connections if necessary. When either endpoint chooses to + close the transport-layer TCP connection, the terminating endpoint SHOULD first send a + GOAWAY () frame so that both endpoints can reliably + determine whether previously sent frames have been processed and gracefully complete or + terminate any necessary remaining tasks. + + +
    + + Connections that are made to an origin servers, either directly or through a tunnel + created using the CONNECT method MAY be reused for + requests with multiple different URI authority components. A connection can be reused + as long as the origin server is authoritative. For + http resources, this depends on the host having resolved to + the same IP address. + + + For https resources, connection reuse additionally depends + on having a certificate that is valid for the host in the URI. An origin server might + offer a certificate with multiple subjectAltName attributes, + or names with wildcards, one of which is valid for the authority in the URI. For + example, a certificate with a subjectAltName of *.example.com might permit the use of the same connection for + requests to URIs starting with https://a.example.com/ and + https://b.example.com/. + + + In some deployments, reusing a connection for multiple origins can result in requests + being directed to the wrong origin server. For example, TLS termination might be + performed by a middlebox that uses the TLS Server Name Indication + (SNI) extension to select an origin server. This means that it is possible + for clients to send confidential information to servers that might not be the intended + target for the request, even though the server is otherwise authoritative. + + + A server that does not wish clients to reuse connections can indicate that it is not + authoritative for a request by sending a 421 (Misdirected Request) status code in response + to the request (see ). + + + A client that is configured to use a proxy over HTTP/2 directs requests to that proxy + through a single connection. That is, all requests sent via a proxy reuse the + connection to the proxy. + +
    + +
    + + The 421 (Misdirected Request) status code indicates that the request was directed at a + server that is not able to produce a response. This can be sent by a server that is not + configured to produce responses for the combination of scheme and authority that are + included in the request URI. + + + Clients receiving a 421 (Misdirected Request) response from a server MAY retry the + request - whether the request method is idempotent or not - over a different connection. + This is possible if a connection is reused () or if an alternative + service is selected (). + + + This status code MUST NOT be generated by proxies. + + + A 421 response is cacheable by default; i.e., unless otherwise indicated by the method + definition or explicit cache controls (see ). + +
    +
    + +
    + + Implementations of HTTP/2 MUST support TLS 1.2 for HTTP/2 over + TLS. The general TLS usage guidance in SHOULD be followed, with + some additional restrictions that are specific to HTTP/2. + + + + An implementation of HTTP/2 over TLS MUST use TLS 1.2 or higher with the restrictions on + feature set and cipher suite described in this section. Due to implementation + limitations, it might not be possible to fail TLS negotiation. An endpoint MUST + immediately terminate an HTTP/2 connection that does not meet these minimum requirements + with a connection error of type + INADEQUATE_SECURITY. + + +
    + + The TLS implementation MUST support the Server Name Indication + (SNI) extension to TLS. HTTP/2 clients MUST indicate the target domain name when + negotiating TLS. + + + The TLS implementation MUST disable compression. TLS compression can lead to the + exposure of information that would not otherwise be revealed . + Generic compression is unnecessary since HTTP/2 provides compression features that are + more aware of context and therefore likely to be more appropriate for use for + performance, security or other reasons. + + + The TLS implementation MUST disable renegotiation. An endpoint MUST treat a TLS + renegotiation as a connection error of type + PROTOCOL_ERROR. Note that disabling renegotiation can result in + long-lived connections becoming unusable due to limits on the number of messages the + underlying cipher suite can encipher. + + + A client MAY use renegotiation to provide confidentiality protection for client + credentials offered in the handshake, but any renegotiation MUST occur prior to sending + the connection preface. A server SHOULD request a client certificate if it sees a + renegotiation request immediately after establishing a connection. + + + This effectively prevents the use of renegotiation in response to a request for a + specific protected resource. A future specification might provide a way to support this + use case. + +
    + +
    + + The set of TLS cipher suites that are permitted in HTTP/2 is restricted. HTTP/2 MUST + only be used with cipher suites that have ephemeral key exchange, such as the ephemeral Diffie-Hellman (DHE) or the elliptic curve variant (ECDHE). Ephemeral key exchange MUST + have a minimum size of 2048 bits for DHE or security level of 128 bits for ECDHE. + Clients MUST accept DHE sizes of up to 4096 bits. HTTP MUST NOT be used with cipher + suites that use stream or block ciphers. Authenticated Encryption with Additional Data + (AEAD) modes, such as the Galois Counter Model (GCM) mode for + AES are acceptable. + + + The effect of these restrictions is that TLS 1.2 implementations could have + non-intersecting sets of available cipher suites, since these prevent the use of the + cipher suite that TLS 1.2 makes mandatory. To avoid this problem, implementations of + HTTP/2 that use TLS 1.2 MUST support TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 with P256 . + + + Clients MAY advertise support of cipher suites that are prohibited by the above + restrictions in order to allow for connection to servers that do not support HTTP/2. + This enables a fallback to protocols without these constraints without the additional + latency imposed by using a separate connection for fallback. + +
    +
    +
    + +
    +
    + + HTTP/2 relies on the HTTP/1.1 definition of authority for determining whether a server is + authoritative in providing a given response, see . This relies on local name resolution for the "http" + URI scheme, and the authenticated server identity for the "https" scheme (see ). + +
    + +
    + + In a cross-protocol attack, an attacker causes a client to initiate a transaction in one + protocol toward a server that understands a different protocol. An attacker might be able + to cause the transaction to appear as valid transaction in the second protocol. In + combination with the capabilities of the web context, this can be used to interact with + poorly protected servers in private networks. + + + Completing a TLS handshake with an ALPN identifier for HTTP/2 can be considered sufficient + protection against cross protocol attacks. ALPN provides a positive indication that a + server is willing to proceed with HTTP/2, which prevents attacks on other TLS-based + protocols. + + + The encryption in TLS makes it difficult for attackers to control the data which could be + used in a cross-protocol attack on a cleartext protocol. + + + The cleartext version of HTTP/2 has minimal protection against cross-protocol attacks. + The connection preface contains a string that is + designed to confuse HTTP/1.1 servers, but no special protection is offered for other + protocols. A server that is willing to ignore parts of an HTTP/1.1 request containing an + Upgrade header field in addition to the client connection preface could be exposed to a + cross-protocol attack. + +
    + +
    + + HTTP/2 header field names and values are encoded as sequences of octets with a length + prefix. This enables HTTP/2 to carry any string of octets as the name or value of a + header field. An intermediary that translates HTTP/2 requests or responses into HTTP/1.1 + directly could permit the creation of corrupted HTTP/1.1 messages. An attacker might + exploit this behavior to cause the intermediary to create HTTP/1.1 messages with illegal + header fields, extra header fields, or even new messages that are entirely falsified. + + + Header field names or values that contain characters not permitted by HTTP/1.1, including + carriage return (ASCII 0xd) or line feed (ASCII 0xa) MUST NOT be translated verbatim by an + intermediary, as stipulated in . + + + Translation from HTTP/1.x to HTTP/2 does not produce the same opportunity to an attacker. + Intermediaries that perform translation to HTTP/2 MUST remove any instances of the obs-fold production from header field values. + +
    + +
    + + Pushed responses do not have an explicit request from the client; the request + is provided by the server in the PUSH_PROMISE frame. + + + Caching responses that are pushed is possible based on the guidance provided by the origin + server in the Cache-Control header field. However, this can cause issues if a single + server hosts more than one tenant. For example, a server might offer multiple users each + a small portion of its URI space. + + + Where multiple tenants share space on the same server, that server MUST ensure that + tenants are not able to push representations of resources that they do not have authority + over. Failure to enforce this would allow a tenant to provide a representation that would + be served out of cache, overriding the actual representation that the authoritative tenant + provides. + + + Pushed responses for which an origin server is not authoritative (see + ) are never cached or used. + +
    + +
    + + An HTTP/2 connection can demand a greater commitment of resources to operate than a + HTTP/1.1 connection. The use of header compression and flow control depend on a + commitment of resources for storing a greater amount of state. Settings for these + features ensure that memory commitments for these features are strictly bounded. + + + The number of PUSH_PROMISE frames is not constrained in the same fashion. + A client that accepts server push SHOULD limit the number of streams it allows to be in + the "reserved (remote)" state. Excessive number of server push streams can be treated as + a stream error of type + ENHANCE_YOUR_CALM. + + + Processing capacity cannot be guarded as effectively as state capacity. + + + The SETTINGS frame can be abused to cause a peer to expend additional + processing time. This might be done by pointlessly changing SETTINGS parameters, setting + multiple undefined parameters, or changing the same setting multiple times in the same + frame. WINDOW_UPDATE or PRIORITY frames can be abused to + cause an unnecessary waste of resources. + + + Large numbers of small or empty frames can be abused to cause a peer to expend time + processing frame headers. Note however that some uses are entirely legitimate, such as + the sending of an empty DATA frame to end a stream. + + + Header compression also offers some opportunities to waste processing resources; see for more details on potential abuses. + + + Limits in SETTINGS parameters cannot be reduced instantaneously, which + leaves an endpoint exposed to behavior from a peer that could exceed the new limits. In + particular, immediately after establishing a connection, limits set by a server are not + known to clients and could be exceeded without being an obvious protocol violation. + + + All these features - i.e., SETTINGS changes, small frames, header + compression - have legitimate uses. These features become a burden only when they are + used unnecessarily or to excess. + + + An endpoint that doesn't monitor this behavior exposes itself to a risk of denial of + service attack. Implementations SHOULD track the use of these features and set limits on + their use. An endpoint MAY treat activity that is suspicious as a connection error of type + ENHANCE_YOUR_CALM. + + +
    + + A large header block can cause an implementation to + commit a large amount of state. Header fields that are critical for routing can appear + toward the end of a header block, which prevents streaming of header fields to their + ultimate destination. For this an other reasons, such as ensuring cache correctness, + means that an endpoint might need to buffer the entire header block. Since there is no + hard limit to the size of a header block, some endpoints could be forced commit a large + amount of available memory for header fields. + + + An endpoint can use the SETTINGS_MAX_HEADER_LIST_SIZE to advise peers of + limits that might apply on the size of header blocks. This setting is only advisory, so + endpoints MAY choose to send header blocks that exceed this limit and risk having the + request or response being treated as malformed. This setting specific to a connection, + so any request or response could encounter a hop with a lower, unknown limit. An + intermediary can attempt to avoid this problem by passing on values presented by + different peers, but they are not obligated to do so. + + + A server that receives a larger header block than it is willing to handle can send an + HTTP 431 (Request Header Fields Too Large) status code . A + client can discard responses that it cannot process. The header block MUST be processed + to ensure a consistent connection state, unless the connection is closed. + +
    +
    + +
    + + HTTP/2 enables greater use of compression for both header fields () and entity bodies. Compression can allow an attacker to recover + secret data when it is compressed in the same context as data under attacker control. + + + There are demonstrable attacks on compression that exploit the characteristics of the web + (e.g., ). The attacker induces multiple requests containing + varying plaintext, observing the length of the resulting ciphertext in each, which + reveals a shorter length when a guess about the secret is correct. + + + Implementations communicating on a secure channel MUST NOT compress content that includes + both confidential and attacker-controlled data unless separate compression dictionaries + are used for each source of data. Compression MUST NOT be used if the source of data + cannot be reliably determined. Generic stream compression, such as that provided by TLS + MUST NOT be used with HTTP/2 (). + + + Further considerations regarding the compression of header fields are described in . + +
    + +
    + + Padding within HTTP/2 is not intended as a replacement for general purpose padding, such + as might be provided by TLS. Redundant padding could even be + counterproductive. Correct application can depend on having specific knowledge of the + data that is being padded. + + + To mitigate attacks that rely on compression, disabling or limiting compression might be + preferable to padding as a countermeasure. + + + Padding can be used to obscure the exact size of frame content, and is provided to + mitigate specific attacks within HTTP. For example, attacks where compressed content + includes both attacker-controlled plaintext and secret data (see for example, ). + + + Use of padding can result in less protection than might seem immediately obvious. At + best, padding only makes it more difficult for an attacker to infer length information by + increasing the number of frames an attacker has to observe. Incorrectly implemented + padding schemes can be easily defeated. In particular, randomized padding with a + predictable distribution provides very little protection; similarly, padding payloads to a + fixed size exposes information as payload sizes cross the fixed size boundary, which could + be possible if an attacker can control plaintext. + + + Intermediaries SHOULD retain padding for DATA frames, but MAY drop padding + for HEADERS and PUSH_PROMISE frames. A valid reason for an + intermediary to change the amount of padding of frames is to improve the protections that + padding provides. + +
    + +
    + + Several characteristics of HTTP/2 provide an observer an opportunity to correlate actions + of a single client or server over time. This includes the value of settings, the manner + in which flow control windows are managed, the way priorities are allocated to streams, + timing of reactions to stimulus, and handling of any optional features. + + + As far as this creates observable differences in behavior, they could be used as a basis + for fingerprinting a specific client, as defined in . + +
    +
    + +
    + + A string for identifying HTTP/2 is entered into the "Application Layer Protocol Negotiation + (ALPN) Protocol IDs" registry established in . + + + This document establishes a registry for frame types, settings, and error codes. These new + registries are entered into a new "Hypertext Transfer Protocol (HTTP) 2 Parameters" section. + + + This document registers the HTTP2-Settings header field for + use in HTTP; and the 421 (Misdirected Request) status code. + + + This document registers the PRI method for use in HTTP, to avoid + collisions with the connection preface. + + +
    + + This document creates two registrations for the identification of HTTP/2 in the + "Application Layer Protocol Negotiation (ALPN) Protocol IDs" registry established in . + + + The "h2" string identifies HTTP/2 when used over TLS: + + HTTP/2 over TLS + 0x68 0x32 ("h2") + This document + + + + The "h2c" string identifies HTTP/2 when used over cleartext TCP: + + HTTP/2 over TCP + 0x68 0x32 0x63 ("h2c") + This document + + +
    + +
    + + This document establishes a registry for HTTP/2 frame type codes. The "HTTP/2 Frame + Type" registry manages an 8-bit space. The "HTTP/2 Frame Type" registry operates under + either of the "IETF Review" or "IESG Approval" policies for + values between 0x00 and 0xef, with values between 0xf0 and 0xff being reserved for + experimental use. + + + New entries in this registry require the following information: + + + A name or label for the frame type. + + + The 8-bit code assigned to the frame type. + + + A reference to a specification that includes a description of the frame layout, + it's semantics and flags that the frame type uses, including any parts of the frame + that are conditionally present based on the value of flags. + + + + + The entries in the following table are registered by this document. + + + Frame Type + Code + Section + DATA0x0 + HEADERS0x1 + PRIORITY0x2 + RST_STREAM0x3 + SETTINGS0x4 + PUSH_PROMISE0x5 + PING0x6 + GOAWAY0x7 + WINDOW_UPDATE0x8 + CONTINUATION0x9 + +
    + +
    + + This document establishes a registry for HTTP/2 settings. The "HTTP/2 Settings" registry + manages a 16-bit space. The "HTTP/2 Settings" registry operates under the "Expert Review" policy for values in the range from 0x0000 to + 0xefff, with values between and 0xf000 and 0xffff being reserved for experimental use. + + + New registrations are advised to provide the following information: + + + A symbolic name for the setting. Specifying a setting name is optional. + + + The 16-bit code assigned to the setting. + + + An initial value for the setting. + + + An optional reference to a specification that describes the use of the setting. + + + + + An initial set of setting registrations can be found in . + + + Name + Code + Initial Value + Specification + HEADER_TABLE_SIZE + 0x14096 + ENABLE_PUSH + 0x21 + MAX_CONCURRENT_STREAMS + 0x3(infinite) + INITIAL_WINDOW_SIZE + 0x465535 + MAX_FRAME_SIZE + 0x516384 + MAX_HEADER_LIST_SIZE + 0x6(infinite) + + +
    + +
    + + This document establishes a registry for HTTP/2 error codes. The "HTTP/2 Error Code" + registry manages a 32-bit space. The "HTTP/2 Error Code" registry operates under the + "Expert Review" policy. + + + Registrations for error codes are required to include a description of the error code. An + expert reviewer is advised to examine new registrations for possible duplication with + existing error codes. Use of existing registrations is to be encouraged, but not + mandated. + + + New registrations are advised to provide the following information: + + + A name for the error code. Specifying an error code name is optional. + + + The 32-bit error code value. + + + A brief description of the error code semantics, longer if no detailed specification + is provided. + + + An optional reference for a specification that defines the error code. + + + + + The entries in the following table are registered by this document. + + + Name + Code + Description + Specification + NO_ERROR0x0 + Graceful shutdown + + PROTOCOL_ERROR0x1 + Protocol error detected + + INTERNAL_ERROR0x2 + Implementation fault + + FLOW_CONTROL_ERROR0x3 + Flow control limits exceeded + + SETTINGS_TIMEOUT0x4 + Settings not acknowledged + + STREAM_CLOSED0x5 + Frame received for closed stream + + FRAME_SIZE_ERROR0x6 + Frame size incorrect + + REFUSED_STREAM0x7 + Stream not processed + + CANCEL0x8 + Stream cancelled + + COMPRESSION_ERROR0x9 + Compression state not updated + + CONNECT_ERROR0xa + TCP connection error for CONNECT method + + ENHANCE_YOUR_CALM0xb + Processing capacity exceeded + + INADEQUATE_SECURITY0xc + Negotiated TLS parameters not acceptable + + + +
    + +
    + + This section registers the HTTP2-Settings header field in the + Permanent Message Header Field Registry. + + + HTTP2-Settings + + + http + + + standard + + + IETF + + + of this document + + + This header field is only used by an HTTP/2 client for Upgrade-based negotiation. + + + +
    + +
    + + This section registers the PRI method in the HTTP Method + Registry (). + + + PRI + + + No + + + No + + + of this document + + + This method is never used by an actual client. This method will appear to be used + when an HTTP/1.1 server or intermediary attempts to parse an HTTP/2 connection + preface. + + + +
    + +
    + + This document registers the 421 (Misdirected Request) HTTP Status code in the Hypertext + Transfer Protocol (HTTP) Status Code Registry (). + + + + + 421 + + + Misdirected Request + + + of this document + + + +
    + +
    + +
    + + This document includes substantial input from the following individuals: + + + Adam Langley, Wan-Teh Chang, Jim Morrison, Mark Nottingham, Alyssa Wilk, Costin + Manolache, William Chan, Vitaliy Lvin, Joe Chan, Adam Barth, Ryan Hamilton, Gavin + Peters, Kent Alstad, Kevin Lindsay, Paul Amer, Fan Yang, Jonathan Leighton (SPDY + contributors). + + + Gabriel Montenegro and Willy Tarreau (Upgrade mechanism). + + + William Chan, Salvatore Loreto, Osama Mazahir, Gabriel Montenegro, Jitu Padhye, Roberto + Peon, Rob Trace (Flow control). + + + Mike Bishop (Extensibility). + + + Mark Nottingham, Julian Reschke, James Snell, Jeff Pinner, Mike Bishop, Herve Ruellan + (Substantial editorial contributions). + + + Kari Hurtta, Tatsuhiro Tsujikawa, Greg Wilkins, Poul-Henning Kamp. + + + Alexey Melnikov was an editor of this document during 2013. + + + A substantial proportion of Martin's contribution was supported by Microsoft during his + employment there. + + + +
    +
    + + + + + + HPACK - Header Compression for HTTP/2 + + + + + + + + + + + + Transmission Control Protocol + + + University of Southern California (USC)/Information Sciences + Institute + + + + + + + + + + + Key words for use in RFCs to Indicate Requirement Levels + + + Harvard University +
    sob@harvard.edu
    +
    + +
    + + +
    + + + + + HTTP Over TLS + + + + + + + + + + Uniform Resource Identifier (URI): Generic + Syntax + + + + + + + + + + + + The Base16, Base32, and Base64 Data Encodings + + + + + + + + + Guidelines for Writing an IANA Considerations Section in RFCs + + + + + + + + + + + Augmented BNF for Syntax Specifications: ABNF + + + + + + + + + + + The Transport Layer Security (TLS) Protocol Version 1.2 + + + + + + + + + + + Transport Layer Security (TLS) Extensions: Extension Definitions + + + + + + + + + + Transport Layer Security (TLS) Application-Layer Protocol Negotiation Extension + + + + + + + + + + + + + TLS Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois + Counter Mode (GCM) + + + + + + + + + + + Digital Signature Standard (DSS) + + NIST + + + + + + + + + Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing + + Adobe Systems Incorporated +
    fielding@gbiv.com
    +
    + + greenbytes GmbH +
    julian.reschke@greenbytes.de
    +
    + +
    + + +
    + + + + Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content + + Adobe Systems Incorporated +
    fielding@gbiv.com
    +
    + + greenbytes GmbH +
    julian.reschke@greenbytes.de
    +
    + +
    + + +
    + + + Hypertext Transfer Protocol (HTTP/1.1): Conditional Requests + + Adobe Systems Incorporated +
    fielding@gbiv.com
    +
    + + greenbytes GmbH +
    julian.reschke@greenbytes.de
    +
    + +
    + +
    + + + Hypertext Transfer Protocol (HTTP/1.1): Range Requests + + Adobe Systems Incorporated +
    fielding@gbiv.com
    +
    + + World Wide Web Consortium +
    ylafon@w3.org
    +
    + + greenbytes GmbH +
    julian.reschke@greenbytes.de
    +
    + +
    + +
    + + + Hypertext Transfer Protocol (HTTP/1.1): Caching + + Adobe Systems Incorporated +
    fielding@gbiv.com
    +
    + + Akamai +
    mnot@mnot.net
    +
    + + greenbytes GmbH +
    julian.reschke@greenbytes.de
    +
    + +
    + + +
    + + + Hypertext Transfer Protocol (HTTP/1.1): Authentication + + Adobe Systems Incorporated +
    fielding@gbiv.com
    +
    + + greenbytes GmbH +
    julian.reschke@greenbytes.de
    +
    + +
    + + +
    + + + + HTTP State Management Mechanism + + + + + +
    + + + + + + TCP Extensions for High Performance + + + + + + + + + + + + Transport Layer Security Protocol Compression Methods + + + + + + + + + Additional HTTP Status Codes + + + + + + + + + + + Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS) + + + + + + + + + + + + + + + AES Galois Counter Mode (GCM) Cipher Suites for TLS + + + + + + + + + + + + HTML5 + + + + + + + + + + + Latest version available at + . + + + + + + + Talking to Yourself for Fun and Profit + + + + + + + + + + + + + + BREACH: Reviving the CRIME Attack + + + + + + + + + + + Registration Procedures for Message Header Fields + + Nine by Nine +
    GK-IETF@ninebynine.org
    +
    + + BEA Systems +
    mnot@pobox.com
    +
    + + HP Labs +
    JeffMogul@acm.org
    +
    + +
    + + +
    + + + + Recommendations for Secure Use of TLS and DTLS + + + + + + + + + + + + + + + + + + HTTP Alternative Services + + + Akamai + + + Mozilla + + + greenbytes + + + + + + +
    + +
    + + This section is to be removed by RFC Editor before publication. + + +
    + + Renamed Not Authoritative status code to Misdirected Request. + +
    + +
    + + Pseudo-header fields are now required to appear strictly before regular ones. + + + Restored 1xx series status codes, except 101. + + + Changed frame length field 24-bits. Expanded frame header to 9 octets. Added a setting + to limit the damage. + + + Added a setting to advise peers of header set size limits. + + + Removed segments. + + + Made non-semantic-bearing HEADERS frames illegal in the HTTP mapping. + +
    + +
    + + Restored extensibility options. + + + Restricting TLS cipher suites to AEAD only. + + + Removing Content-Encoding requirements. + + + Permitting the use of PRIORITY after stream close. + + + Removed ALTSVC frame. + + + Removed BLOCKED frame. + + + Reducing the maximum padding size to 256 octets; removing padding from + CONTINUATION frames. + + + Removed per-frame GZIP compression. + +
    + +
    + + Added BLOCKED frame (at risk). + + + Simplified priority scheme. + + + Added DATA per-frame GZIP compression. + +
    + +
    + + Changed "connection header" to "connection preface" to avoid confusion. + + + Added dependency-based stream prioritization. + + + Added "h2c" identifier to distinguish between cleartext and secured HTTP/2. + + + Adding missing padding to PUSH_PROMISE. + + + Integrate ALTSVC frame and supporting text. + + + Dropping requirement on "deflate" Content-Encoding. + + + Improving security considerations around use of compression. + +
    + +
    + + Adding padding for data frames. + + + Renumbering frame types, error codes, and settings. + + + Adding INADEQUATE_SECURITY error code. + + + Updating TLS usage requirements to 1.2; forbidding TLS compression. + + + Removing extensibility for frames and settings. + + + Changing setting identifier size. + + + Removing the ability to disable flow control. + + + Changing the protocol identification token to "h2". + + + Changing the use of :authority to make it optional and to allow userinfo in non-HTTP + cases. + + + Allowing split on 0x0 for Cookie. + + + Reserved PRI method in HTTP/1.1 to avoid possible future collisions. + +
    + +
    + + Added cookie crumbling for more efficient header compression. + + + Added header field ordering with the value-concatenation mechanism. + +
    + +
    + + Marked draft for implementation. + +
    + +
    + + Adding definition for CONNECT method. + + + Constraining the use of push to safe, cacheable methods with no request body. + + + Changing from :host to :authority to remove any potential confusion. + + + Adding setting for header compression table size. + + + Adding settings acknowledgement. + + + Removing unnecessary and potentially problematic flags from CONTINUATION. + + + Added denial of service considerations. + +
    +
    + + Marking the draft ready for implementation. + + + Renumbering END_PUSH_PROMISE flag. + + + Editorial clarifications and changes. + +
    + +
    + + Added CONTINUATION frame for HEADERS and PUSH_PROMISE. + + + PUSH_PROMISE is no longer implicitly prohibited if SETTINGS_MAX_CONCURRENT_STREAMS is + zero. + + + Push expanded to allow all safe methods without a request body. + + + Clarified the use of HTTP header fields in requests and responses. Prohibited HTTP/1.1 + hop-by-hop header fields. + + + Requiring that intermediaries not forward requests with missing or illegal routing + :-headers. + + + Clarified requirements around handling different frames after stream close, stream reset + and GOAWAY. + + + Added more specific prohibitions for sending of different frame types in various stream + states. + + + Making the last received setting value the effective value. + + + Clarified requirements on TLS version, extension and ciphers. + +
    + +
    + + Committed major restructuring atrocities. + + + Added reference to first header compression draft. + + + Added more formal description of frame lifecycle. + + + Moved END_STREAM (renamed from FINAL) back to HEADERS/DATA. + + + Removed HEADERS+PRIORITY, added optional priority to HEADERS frame. + + + Added PRIORITY frame. + +
    + +
    + + Added continuations to frames carrying header blocks. + + + Replaced use of "session" with "connection" to avoid confusion with other HTTP stateful + concepts, like cookies. + + + Removed "message". + + + Switched to TLS ALPN from NPN. + + + Editorial changes. + +
    + +
    + + Added IANA considerations section for frame types, error codes and settings. + + + Removed data frame compression. + + + Added PUSH_PROMISE. + + + Added globally applicable flags to framing. + + + Removed zlib-based header compression mechanism. + + + Updated references. + + + Clarified stream identifier reuse. + + + Removed CREDENTIALS frame and associated mechanisms. + + + Added advice against naive implementation of flow control. + + + Added session header section. + + + Restructured frame header. Removed distinction between data and control frames. + + + Altered flow control properties to include session-level limits. + + + Added note on cacheability of pushed resources and multiple tenant servers. + + + Changed protocol label form based on discussions. + +
    + +
    + + Changed title throughout. + + + Removed section on Incompatibilities with SPDY draft#2. + + + Changed INTERNAL_ERROR on GOAWAY to have a value of 2 . + + + Replaced abstract and introduction. + + + Added section on starting HTTP/2.0, including upgrade mechanism. + + + Removed unused references. + + + Added flow control principles based on . + +
    + +
    + + Adopted as base for draft-ietf-httpbis-http2. + + + Updated authors/editors list. + + + Added status note. + +
    +
    + +
    +
    + diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/transport.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/transport.go new file mode 100644 index 00000000..0aaa067f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/transport.go @@ -0,0 +1,1745 @@ +// 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. + +// Transport code. + +package http2 + +import ( + "bufio" + "bytes" + "compress/gzip" + "crypto/tls" + "errors" + "fmt" + "io" + "io/ioutil" + "log" + "net" + "net/http" + "sort" + "strconv" + "strings" + "sync" + "time" + + "golang.org/x/net/http2/hpack" +) + +const ( + // transportDefaultConnFlow is how many connection-level flow control + // tokens we give the server at start-up, past the default 64k. + transportDefaultConnFlow = 1 << 30 + + // transportDefaultStreamFlow is how many stream-level flow + // control tokens we announce to the peer, and how many bytes + // we buffer per stream. + transportDefaultStreamFlow = 4 << 20 + + // transportDefaultStreamMinRefresh is the minimum number of bytes we'll send + // a stream-level WINDOW_UPDATE for at a time. + transportDefaultStreamMinRefresh = 4 << 10 + + defaultUserAgent = "Go-http-client/2.0" +) + +// Transport is an HTTP/2 Transport. +// +// A Transport internally caches connections to servers. It is safe +// for concurrent use by multiple goroutines. +type Transport struct { + // DialTLS specifies an optional dial function for creating + // TLS connections for requests. + // + // If DialTLS is nil, tls.Dial is used. + // + // If the returned net.Conn has a ConnectionState method like tls.Conn, + // it will be used to set http.Response.TLS. + DialTLS func(network, addr string, cfg *tls.Config) (net.Conn, error) + + // TLSClientConfig specifies the TLS configuration to use with + // tls.Client. If nil, the default configuration is used. + TLSClientConfig *tls.Config + + // ConnPool optionally specifies an alternate connection pool to use. + // If nil, the default is used. + ConnPool ClientConnPool + + // DisableCompression, if true, prevents the Transport from + // requesting compression with an "Accept-Encoding: gzip" + // request header when the Request contains no existing + // Accept-Encoding value. If the Transport requests gzip on + // its own and gets a gzipped response, it's transparently + // decoded in the Response.Body. However, if the user + // explicitly requested gzip it is not automatically + // uncompressed. + DisableCompression bool + + // MaxHeaderListSize is the http2 SETTINGS_MAX_HEADER_LIST_SIZE to + // send in the initial settings frame. It is how many bytes + // of response headers are allow. Unlike the http2 spec, zero here + // means to use a default limit (currently 10MB). If you actually + // want to advertise an ulimited value to the peer, Transport + // interprets the highest possible value here (0xffffffff or 1<<32-1) + // to mean no limit. + MaxHeaderListSize uint32 + + // t1, if non-nil, is the standard library Transport using + // this transport. Its settings are used (but not its + // RoundTrip method, etc). + t1 *http.Transport + + connPoolOnce sync.Once + connPoolOrDef ClientConnPool // non-nil version of ConnPool +} + +func (t *Transport) maxHeaderListSize() uint32 { + if t.MaxHeaderListSize == 0 { + return 10 << 20 + } + if t.MaxHeaderListSize == 0xffffffff { + return 0 + } + return t.MaxHeaderListSize +} + +func (t *Transport) disableCompression() bool { + return t.DisableCompression || (t.t1 != nil && t.t1.DisableCompression) +} + +var errTransportVersion = errors.New("http2: ConfigureTransport is only supported starting at Go 1.6") + +// ConfigureTransport configures a net/http HTTP/1 Transport to use HTTP/2. +// It requires Go 1.6 or later and returns an error if the net/http package is too old +// or if t1 has already been HTTP/2-enabled. +func ConfigureTransport(t1 *http.Transport) error { + _, err := configureTransport(t1) // in configure_transport.go (go1.6) or not_go16.go + return err +} + +func (t *Transport) connPool() ClientConnPool { + t.connPoolOnce.Do(t.initConnPool) + return t.connPoolOrDef +} + +func (t *Transport) initConnPool() { + if t.ConnPool != nil { + t.connPoolOrDef = t.ConnPool + } else { + t.connPoolOrDef = &clientConnPool{t: t} + } +} + +// ClientConn is the state of a single HTTP/2 client connection to an +// HTTP/2 server. +type ClientConn struct { + t *Transport + tconn net.Conn // usually *tls.Conn, except specialized impls + tlsState *tls.ConnectionState // nil only for specialized impls + + // readLoop goroutine fields: + readerDone chan struct{} // closed on error + readerErr error // set before readerDone is closed + + mu sync.Mutex // guards following + cond *sync.Cond // hold mu; broadcast on flow/closed changes + flow flow // our conn-level flow control quota (cs.flow is per stream) + inflow flow // peer's conn-level flow control + closed bool + goAway *GoAwayFrame // if non-nil, the GoAwayFrame we received + streams map[uint32]*clientStream // client-initiated + nextStreamID uint32 + bw *bufio.Writer + br *bufio.Reader + fr *Framer + // Settings from peer: + maxFrameSize uint32 + maxConcurrentStreams uint32 + initialWindowSize uint32 + hbuf bytes.Buffer // HPACK encoder writes into this + henc *hpack.Encoder + freeBuf [][]byte + + wmu sync.Mutex // held while writing; acquire AFTER mu if holding both + werr error // first write error that has occurred +} + +// clientStream is the state for a single HTTP/2 stream. One of these +// is created for each Transport.RoundTrip call. +type clientStream struct { + cc *ClientConn + req *http.Request + ID uint32 + resc chan resAndError + bufPipe pipe // buffered pipe with the flow-controlled response payload + requestedGzip bool + + flow flow // guarded by cc.mu + inflow flow // guarded by cc.mu + bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read + readErr error // sticky read error; owned by transportResponseBody.Read + stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu + + peerReset chan struct{} // closed on peer reset + resetErr error // populated before peerReset is closed + + done chan struct{} // closed when stream remove from cc.streams map; close calls guarded by cc.mu + + // owned by clientConnReadLoop: + pastHeaders bool // got HEADERS w/ END_HEADERS + pastTrailers bool // got second HEADERS frame w/ END_HEADERS + + trailer http.Header // accumulated trailers + resTrailer *http.Header // client's Response.Trailer +} + +// awaitRequestCancel runs in its own goroutine and waits for the user +// to either cancel a RoundTrip request (using the provided +// Request.Cancel channel), or for the request to be done (any way it +// might be removed from the cc.streams map: peer reset, successful +// completion, TCP connection breakage, etc) +func (cs *clientStream) awaitRequestCancel(cancel <-chan struct{}) { + if cancel == nil { + return + } + select { + case <-cancel: + cs.bufPipe.CloseWithError(errRequestCanceled) + cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + case <-cs.done: + } +} + +// checkReset reports any error sent in a RST_STREAM frame by the +// server. +func (cs *clientStream) checkReset() error { + select { + case <-cs.peerReset: + return cs.resetErr + default: + return nil + } +} + +func (cs *clientStream) abortRequestBodyWrite(err error) { + if err == nil { + panic("nil error") + } + cc := cs.cc + cc.mu.Lock() + cs.stopReqBody = err + cc.cond.Broadcast() + cc.mu.Unlock() +} + +type stickyErrWriter struct { + w io.Writer + err *error +} + +func (sew stickyErrWriter) Write(p []byte) (n int, err error) { + if *sew.err != nil { + return 0, *sew.err + } + n, err = sew.w.Write(p) + *sew.err = err + return +} + +var ErrNoCachedConn = errors.New("http2: no cached connection was available") + +// RoundTripOpt are options for the Transport.RoundTripOpt method. +type RoundTripOpt struct { + // OnlyCachedConn controls whether RoundTripOpt may + // create a new TCP connection. If set true and + // no cached connection is available, RoundTripOpt + // will return ErrNoCachedConn. + OnlyCachedConn bool +} + +func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) { + return t.RoundTripOpt(req, RoundTripOpt{}) +} + +// authorityAddr returns a given authority (a host/IP, or host:port / ip:port) +// and returns a host:port. The port 443 is added if needed. +func authorityAddr(authority string) (addr string) { + if _, _, err := net.SplitHostPort(authority); err == nil { + return authority + } + return net.JoinHostPort(authority, "443") +} + +// RoundTripOpt is like RoundTrip, but takes options. +func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { + if req.URL.Scheme != "https" { + return nil, errors.New("http2: unsupported scheme") + } + + addr := authorityAddr(req.URL.Host) + for { + cc, err := t.connPool().GetClientConn(req, addr) + if err != nil { + t.vlogf("http2: Transport failed to get client conn for %s: %v", addr, err) + return nil, err + } + res, err := cc.RoundTrip(req) + if shouldRetryRequest(req, err) { + continue + } + if err != nil { + t.vlogf("RoundTrip failure: %v", err) + return nil, err + } + return res, nil + } +} + +// CloseIdleConnections closes any connections which were previously +// connected from previous requests but are now sitting idle. +// It does not interrupt any connections currently in use. +func (t *Transport) CloseIdleConnections() { + if cp, ok := t.connPool().(*clientConnPool); ok { + cp.closeIdleConnections() + } +} + +var ( + errClientConnClosed = errors.New("http2: client conn is closed") + errClientConnUnusable = errors.New("http2: client conn not usable") +) + +func shouldRetryRequest(req *http.Request, err error) bool { + // TODO: retry GET requests (no bodies) more aggressively, if shutdown + // before response. + return err == errClientConnUnusable +} + +func (t *Transport) dialClientConn(addr string) (*ClientConn, error) { + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + tconn, err := t.dialTLS()("tcp", addr, t.newTLSConfig(host)) + if err != nil { + return nil, err + } + return t.NewClientConn(tconn) +} + +func (t *Transport) newTLSConfig(host string) *tls.Config { + cfg := new(tls.Config) + if t.TLSClientConfig != nil { + *cfg = *t.TLSClientConfig + } + cfg.NextProtos = []string{NextProtoTLS} // TODO: don't override if already in list + cfg.ServerName = host + return cfg +} + +func (t *Transport) dialTLS() func(string, string, *tls.Config) (net.Conn, error) { + if t.DialTLS != nil { + return t.DialTLS + } + return t.dialTLSDefault +} + +func (t *Transport) dialTLSDefault(network, addr string, cfg *tls.Config) (net.Conn, error) { + cn, err := tls.Dial(network, addr, cfg) + if err != nil { + return nil, err + } + if err := cn.Handshake(); err != nil { + return nil, err + } + if !cfg.InsecureSkipVerify { + if err := cn.VerifyHostname(cfg.ServerName); err != nil { + return nil, err + } + } + state := cn.ConnectionState() + if p := state.NegotiatedProtocol; p != NextProtoTLS { + return nil, fmt.Errorf("http2: unexpected ALPN protocol %q; want %q", p, NextProtoTLS) + } + if !state.NegotiatedProtocolIsMutual { + return nil, errors.New("http2: could not negotiate protocol mutually") + } + return cn, nil +} + +// disableKeepAlives reports whether connections should be closed as +// soon as possible after handling the first request. +func (t *Transport) disableKeepAlives() bool { + return t.t1 != nil && t.t1.DisableKeepAlives +} + +func (t *Transport) NewClientConn(c net.Conn) (*ClientConn, error) { + if VerboseLogs { + t.vlogf("http2: Transport creating client conn to %v", c.RemoteAddr()) + } + if _, err := c.Write(clientPreface); err != nil { + t.vlogf("client preface write error: %v", err) + return nil, err + } + + cc := &ClientConn{ + t: t, + tconn: c, + readerDone: make(chan struct{}), + nextStreamID: 1, + maxFrameSize: 16 << 10, // spec default + initialWindowSize: 65535, // spec default + maxConcurrentStreams: 1000, // "infinite", per spec. 1000 seems good enough. + streams: make(map[uint32]*clientStream), + } + cc.cond = sync.NewCond(&cc.mu) + cc.flow.add(int32(initialWindowSize)) + + // TODO: adjust this writer size to account for frame size + + // MTU + crypto/tls record padding. + cc.bw = bufio.NewWriter(stickyErrWriter{c, &cc.werr}) + cc.br = bufio.NewReader(c) + cc.fr = NewFramer(cc.bw, cc.br) + + // TODO: SetMaxDynamicTableSize, SetMaxDynamicTableSizeLimit on + // henc in response to SETTINGS frames? + cc.henc = hpack.NewEncoder(&cc.hbuf) + + if cs, ok := c.(connectionStater); ok { + state := cs.ConnectionState() + cc.tlsState = &state + } + + initialSettings := []Setting{ + Setting{ID: SettingEnablePush, Val: 0}, + Setting{ID: SettingInitialWindowSize, Val: transportDefaultStreamFlow}, + } + if max := t.maxHeaderListSize(); max != 0 { + initialSettings = append(initialSettings, Setting{ID: SettingMaxHeaderListSize, Val: max}) + } + cc.fr.WriteSettings(initialSettings...) + cc.fr.WriteWindowUpdate(0, transportDefaultConnFlow) + cc.inflow.add(transportDefaultConnFlow + initialWindowSize) + cc.bw.Flush() + if cc.werr != nil { + return nil, cc.werr + } + + // Read the obligatory SETTINGS frame + f, err := cc.fr.ReadFrame() + if err != nil { + return nil, err + } + sf, ok := f.(*SettingsFrame) + if !ok { + return nil, fmt.Errorf("expected settings frame, got: %T", f) + } + cc.fr.WriteSettingsAck() + cc.bw.Flush() + + sf.ForeachSetting(func(s Setting) error { + switch s.ID { + case SettingMaxFrameSize: + cc.maxFrameSize = s.Val + case SettingMaxConcurrentStreams: + cc.maxConcurrentStreams = s.Val + case SettingInitialWindowSize: + cc.initialWindowSize = s.Val + default: + // TODO(bradfitz): handle more; at least SETTINGS_HEADER_TABLE_SIZE? + t.vlogf("Unhandled Setting: %v", s) + } + return nil + }) + + go cc.readLoop() + return cc, nil +} + +func (cc *ClientConn) setGoAway(f *GoAwayFrame) { + cc.mu.Lock() + defer cc.mu.Unlock() + cc.goAway = f +} + +func (cc *ClientConn) CanTakeNewRequest() bool { + cc.mu.Lock() + defer cc.mu.Unlock() + return cc.canTakeNewRequestLocked() +} + +func (cc *ClientConn) canTakeNewRequestLocked() bool { + return cc.goAway == nil && !cc.closed && + int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) && + cc.nextStreamID < 2147483647 +} + +func (cc *ClientConn) closeIfIdle() { + cc.mu.Lock() + if len(cc.streams) > 0 { + cc.mu.Unlock() + return + } + cc.closed = true + // TODO: do clients send GOAWAY too? maybe? Just Close: + cc.mu.Unlock() + + cc.tconn.Close() +} + +const maxAllocFrameSize = 512 << 10 + +// frameBuffer returns a scratch buffer suitable for writing DATA frames. +// They're capped at the min of the peer's max frame size or 512KB +// (kinda arbitrarily), but definitely capped so we don't allocate 4GB +// bufers. +func (cc *ClientConn) frameScratchBuffer() []byte { + cc.mu.Lock() + size := cc.maxFrameSize + if size > maxAllocFrameSize { + size = maxAllocFrameSize + } + for i, buf := range cc.freeBuf { + if len(buf) >= int(size) { + cc.freeBuf[i] = nil + cc.mu.Unlock() + return buf[:size] + } + } + cc.mu.Unlock() + return make([]byte, size) +} + +func (cc *ClientConn) putFrameScratchBuffer(buf []byte) { + cc.mu.Lock() + defer cc.mu.Unlock() + const maxBufs = 4 // arbitrary; 4 concurrent requests per conn? investigate. + if len(cc.freeBuf) < maxBufs { + cc.freeBuf = append(cc.freeBuf, buf) + return + } + for i, old := range cc.freeBuf { + if old == nil { + cc.freeBuf[i] = buf + return + } + } + // forget about it. +} + +// errRequestCanceled is a copy of net/http's errRequestCanceled because it's not +// exported. At least they'll be DeepEqual for h1-vs-h2 comparisons tests. +var errRequestCanceled = errors.New("net/http: request canceled") + +func commaSeparatedTrailers(req *http.Request) (string, error) { + keys := make([]string, 0, len(req.Trailer)) + for k := range req.Trailer { + k = http.CanonicalHeaderKey(k) + switch k { + case "Transfer-Encoding", "Trailer", "Content-Length": + return "", &badStringError{"invalid Trailer key", k} + } + keys = append(keys, k) + } + if len(keys) > 0 { + sort.Strings(keys) + // TODO: could do better allocation-wise here, but trailers are rare, + // so being lazy for now. + return strings.Join(keys, ","), nil + } + return "", nil +} + +func (cc *ClientConn) responseHeaderTimeout() time.Duration { + if cc.t.t1 != nil { + return cc.t.t1.ResponseHeaderTimeout + } + // No way to do this (yet?) with just an http2.Transport. Probably + // no need. Request.Cancel this is the new way. We only need to support + // this for compatibility with the old http.Transport fields when + // we're doing transparent http2. + return 0 +} + +// checkConnHeaders checks whether req has any invalid connection-level headers. +// per RFC 7540 section 8.1.2.2: Connection-Specific Header Fields. +// Certain headers are special-cased as okay but not transmitted later. +func checkConnHeaders(req *http.Request) error { + if v := req.Header.Get("Upgrade"); v != "" { + return errors.New("http2: invalid Upgrade request header") + } + if v := req.Header.Get("Transfer-Encoding"); (v != "" && v != "chunked") || len(req.Header["Transfer-Encoding"]) > 1 { + return errors.New("http2: invalid Transfer-Encoding request header") + } + if v := req.Header.Get("Connection"); (v != "" && v != "close" && v != "keep-alive") || len(req.Header["Connection"]) > 1 { + return errors.New("http2: invalid Connection request header") + } + return nil +} + +func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) { + if err := checkConnHeaders(req); err != nil { + return nil, err + } + + trailers, err := commaSeparatedTrailers(req) + if err != nil { + return nil, err + } + hasTrailers := trailers != "" + + var body io.Reader = req.Body + contentLen := req.ContentLength + if req.Body != nil && contentLen == 0 { + // Test to see if it's actually zero or just unset. + var buf [1]byte + n, rerr := io.ReadFull(body, buf[:]) + if rerr != nil && rerr != io.EOF { + contentLen = -1 + body = errorReader{rerr} + } else if n == 1 { + // Oh, guess there is data in this Body Reader after all. + // The ContentLength field just wasn't set. + // Stich the Body back together again, re-attaching our + // consumed byte. + contentLen = -1 + body = io.MultiReader(bytes.NewReader(buf[:]), body) + } else { + // Body is actually empty. + body = nil + } + } + + cc.mu.Lock() + if cc.closed || !cc.canTakeNewRequestLocked() { + cc.mu.Unlock() + return nil, errClientConnUnusable + } + + cs := cc.newStream() + cs.req = req + hasBody := body != nil + + // TODO(bradfitz): this is a copy of the logic in net/http. Unify somewhere? + if !cc.t.disableCompression() && + req.Header.Get("Accept-Encoding") == "" && + req.Header.Get("Range") == "" && + req.Method != "HEAD" { + // Request gzip only, not deflate. Deflate is ambiguous and + // not as universally supported anyway. + // See: http://www.gzip.org/zlib/zlib_faq.html#faq38 + // + // Note that we don't request this for HEAD requests, + // due to a bug in nginx: + // http://trac.nginx.org/nginx/ticket/358 + // https://golang.org/issue/5522 + // + // We don't request gzip if the request is for a range, since + // auto-decoding a portion of a gzipped document will just fail + // anyway. See https://golang.org/issue/8923 + cs.requestedGzip = true + } + + // we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is + // sent by writeRequestBody below, along with any Trailers, + // again in form HEADERS{1}, CONTINUATION{0,}) + hdrs := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen) + cc.wmu.Lock() + endStream := !hasBody && !hasTrailers + werr := cc.writeHeaders(cs.ID, endStream, hdrs) + cc.wmu.Unlock() + cc.mu.Unlock() + + if werr != nil { + if hasBody { + req.Body.Close() // per RoundTripper contract + } + cc.forgetStreamID(cs.ID) + // Don't bother sending a RST_STREAM (our write already failed; + // no need to keep writing) + return nil, werr + } + + var respHeaderTimer <-chan time.Time + var bodyCopyErrc chan error // result of body copy + if hasBody { + bodyCopyErrc = make(chan error, 1) + go func() { + bodyCopyErrc <- cs.writeRequestBody(body, req.Body) + }() + } else { + if d := cc.responseHeaderTimeout(); d != 0 { + timer := time.NewTimer(d) + defer timer.Stop() + respHeaderTimer = timer.C + } + } + + readLoopResCh := cs.resc + requestCanceledCh := requestCancel(req) + bodyWritten := false + + for { + select { + case re := <-readLoopResCh: + res := re.res + if re.err != nil || res.StatusCode > 299 { + // On error or status code 3xx, 4xx, 5xx, etc abort any + // ongoing write, assuming that the server doesn't care + // about our request body. If the server replied with 1xx or + // 2xx, however, then assume the server DOES potentially + // want our body (e.g. full-duplex streaming: + // golang.org/issue/13444). If it turns out the server + // doesn't, they'll RST_STREAM us soon enough. This is a + // heuristic to avoid adding knobs to Transport. Hopefully + // we can keep it. + cs.abortRequestBodyWrite(errStopReqBodyWrite) + } + if re.err != nil { + cc.forgetStreamID(cs.ID) + return nil, re.err + } + res.Request = req + res.TLS = cc.tlsState + return res, nil + case <-respHeaderTimer: + cc.forgetStreamID(cs.ID) + if !hasBody || bodyWritten { + cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + } else { + cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel) + } + return nil, errTimeout + case <-requestCanceledCh: + cc.forgetStreamID(cs.ID) + if !hasBody || bodyWritten { + cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + } else { + cs.abortRequestBodyWrite(errStopReqBodyWriteAndCancel) + } + return nil, errRequestCanceled + case <-cs.peerReset: + // processResetStream already removed the + // stream from the streams map; no need for + // forgetStreamID. + return nil, cs.resetErr + case err := <-bodyCopyErrc: + if err != nil { + return nil, err + } + bodyWritten = true + if d := cc.responseHeaderTimeout(); d != 0 { + timer := time.NewTimer(d) + defer timer.Stop() + respHeaderTimer = timer.C + } + } + } +} + +// requires cc.wmu be held +func (cc *ClientConn) writeHeaders(streamID uint32, endStream bool, hdrs []byte) error { + first := true // first frame written (HEADERS is first, then CONTINUATION) + frameSize := int(cc.maxFrameSize) + for len(hdrs) > 0 && cc.werr == nil { + chunk := hdrs + if len(chunk) > frameSize { + chunk = chunk[:frameSize] + } + hdrs = hdrs[len(chunk):] + endHeaders := len(hdrs) == 0 + if first { + cc.fr.WriteHeaders(HeadersFrameParam{ + StreamID: streamID, + BlockFragment: chunk, + EndStream: endStream, + EndHeaders: endHeaders, + }) + first = false + } else { + cc.fr.WriteContinuation(streamID, endHeaders, chunk) + } + } + // TODO(bradfitz): this Flush could potentially block (as + // could the WriteHeaders call(s) above), which means they + // wouldn't respond to Request.Cancel being readable. That's + // rare, but this should probably be in a goroutine. + cc.bw.Flush() + return cc.werr +} + +// internal error values; they don't escape to callers +var ( + // abort request body write; don't send cancel + errStopReqBodyWrite = errors.New("http2: aborting request body write") + + // abort request body write, but send stream reset of cancel. + errStopReqBodyWriteAndCancel = errors.New("http2: canceling request") +) + +func (cs *clientStream) writeRequestBody(body io.Reader, bodyCloser io.Closer) (err error) { + cc := cs.cc + sentEnd := false // whether we sent the final DATA frame w/ END_STREAM + buf := cc.frameScratchBuffer() + defer cc.putFrameScratchBuffer(buf) + + defer func() { + // TODO: write h12Compare test showing whether + // Request.Body is closed by the Transport, + // and in multiple cases: server replies <=299 and >299 + // while still writing request body + cerr := bodyCloser.Close() + if err == nil { + err = cerr + } + }() + + req := cs.req + hasTrailers := req.Trailer != nil + + var sawEOF bool + for !sawEOF { + n, err := body.Read(buf) + if err == io.EOF { + sawEOF = true + err = nil + } else if err != nil { + return err + } + + remain := buf[:n] + for len(remain) > 0 && err == nil { + var allowed int32 + allowed, err = cs.awaitFlowControl(len(remain)) + switch { + case err == errStopReqBodyWrite: + return err + case err == errStopReqBodyWriteAndCancel: + cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + return err + case err != nil: + return err + } + cc.wmu.Lock() + data := remain[:allowed] + remain = remain[allowed:] + sentEnd = sawEOF && len(remain) == 0 && !hasTrailers + err = cc.fr.WriteData(cs.ID, sentEnd, data) + if err == nil { + // TODO(bradfitz): this flush is for latency, not bandwidth. + // Most requests won't need this. Make this opt-in or opt-out? + // Use some heuristic on the body type? Nagel-like timers? + // Based on 'n'? Only last chunk of this for loop, unless flow control + // tokens are low? For now, always: + err = cc.bw.Flush() + } + cc.wmu.Unlock() + } + if err != nil { + return err + } + } + + cc.wmu.Lock() + if !sentEnd { + var trls []byte + if hasTrailers { + cc.mu.Lock() + trls = cc.encodeTrailers(req) + cc.mu.Unlock() + } + + // Avoid forgetting to send an END_STREAM if the encoded + // trailers are 0 bytes. Both results produce and END_STREAM. + if len(trls) > 0 { + err = cc.writeHeaders(cs.ID, true, trls) + } else { + err = cc.fr.WriteData(cs.ID, true, nil) + } + } + if ferr := cc.bw.Flush(); ferr != nil && err == nil { + err = ferr + } + cc.wmu.Unlock() + + return err +} + +// awaitFlowControl waits for [1, min(maxBytes, cc.cs.maxFrameSize)] flow +// control tokens from the server. +// It returns either the non-zero number of tokens taken or an error +// if the stream is dead. +func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) { + cc := cs.cc + cc.mu.Lock() + defer cc.mu.Unlock() + for { + if cc.closed { + return 0, errClientConnClosed + } + if cs.stopReqBody != nil { + return 0, cs.stopReqBody + } + if err := cs.checkReset(); err != nil { + return 0, err + } + if a := cs.flow.available(); a > 0 { + take := a + if int(take) > maxBytes { + + take = int32(maxBytes) // can't truncate int; take is int32 + } + if take > int32(cc.maxFrameSize) { + take = int32(cc.maxFrameSize) + } + cs.flow.take(take) + return take, nil + } + cc.cond.Wait() + } +} + +type badStringError struct { + what string + str string +} + +func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) } + +// requires cc.mu be held. +func (cc *ClientConn) encodeHeaders(req *http.Request, addGzipHeader bool, trailers string, contentLength int64) []byte { + cc.hbuf.Reset() + + host := req.Host + if host == "" { + host = req.URL.Host + } + + // 8.1.2.3 Request Pseudo-Header Fields + // The :path pseudo-header field includes the path and query parts of the + // target URI (the path-absolute production and optionally a '?' character + // followed by the query production (see Sections 3.3 and 3.4 of + // [RFC3986]). + cc.writeHeader(":authority", host) + cc.writeHeader(":method", req.Method) + if req.Method != "CONNECT" { + cc.writeHeader(":path", req.URL.RequestURI()) + cc.writeHeader(":scheme", "https") + } + if trailers != "" { + cc.writeHeader("trailer", trailers) + } + + var didUA bool + for k, vv := range req.Header { + lowKey := strings.ToLower(k) + switch lowKey { + case "host", "content-length": + // Host is :authority, already sent. + // Content-Length is automatic, set below. + continue + case "connection", "proxy-connection", "transfer-encoding", "upgrade": + // Per 8.1.2.2 Connection-Specific Header + // Fields, don't send connection-specific + // fields. We deal with these earlier in + // RoundTrip, deciding whether they're + // error-worthy, but we don't want to mutate + // the user's *Request so at this point, just + // skip over them at this point. + continue + case "user-agent": + // Match Go's http1 behavior: at most one + // User-Agent. If set to nil or empty string, + // then omit it. Otherwise if not mentioned, + // include the default (below). + didUA = true + if len(vv) < 1 { + continue + } + vv = vv[:1] + if vv[0] == "" { + continue + } + } + for _, v := range vv { + cc.writeHeader(lowKey, v) + } + } + if shouldSendReqContentLength(req.Method, contentLength) { + cc.writeHeader("content-length", strconv.FormatInt(contentLength, 10)) + } + if addGzipHeader { + cc.writeHeader("accept-encoding", "gzip") + } + if !didUA { + cc.writeHeader("user-agent", defaultUserAgent) + } + return cc.hbuf.Bytes() +} + +// shouldSendReqContentLength reports whether the http2.Transport should send +// a "content-length" request header. This logic is basically a copy of the net/http +// transferWriter.shouldSendContentLength. +// The contentLength is the corrected contentLength (so 0 means actually 0, not unknown). +// -1 means unknown. +func shouldSendReqContentLength(method string, contentLength int64) bool { + if contentLength > 0 { + return true + } + if contentLength < 0 { + return false + } + // For zero bodies, whether we send a content-length depends on the method. + // It also kinda doesn't matter for http2 either way, with END_STREAM. + switch method { + case "POST", "PUT", "PATCH": + return true + default: + return false + } +} + +// requires cc.mu be held. +func (cc *ClientConn) encodeTrailers(req *http.Request) []byte { + cc.hbuf.Reset() + for k, vv := range req.Trailer { + // Transfer-Encoding, etc.. have already been filter at the + // start of RoundTrip + lowKey := strings.ToLower(k) + for _, v := range vv { + cc.writeHeader(lowKey, v) + } + } + return cc.hbuf.Bytes() +} + +func (cc *ClientConn) writeHeader(name, value string) { + if VerboseLogs { + log.Printf("http2: Transport encoding header %q = %q", name, value) + } + cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value}) +} + +type resAndError struct { + res *http.Response + err error +} + +// requires cc.mu be held. +func (cc *ClientConn) newStream() *clientStream { + cs := &clientStream{ + cc: cc, + ID: cc.nextStreamID, + resc: make(chan resAndError, 1), + peerReset: make(chan struct{}), + done: make(chan struct{}), + } + cs.flow.add(int32(cc.initialWindowSize)) + cs.flow.setConnFlow(&cc.flow) + cs.inflow.add(transportDefaultStreamFlow) + cs.inflow.setConnFlow(&cc.inflow) + cc.nextStreamID += 2 + cc.streams[cs.ID] = cs + return cs +} + +func (cc *ClientConn) forgetStreamID(id uint32) { + cc.streamByID(id, true) +} + +func (cc *ClientConn) streamByID(id uint32, andRemove bool) *clientStream { + cc.mu.Lock() + defer cc.mu.Unlock() + cs := cc.streams[id] + if andRemove && cs != nil && !cc.closed { + delete(cc.streams, id) + close(cs.done) + } + return cs +} + +// clientConnReadLoop is the state owned by the clientConn's frame-reading readLoop. +type clientConnReadLoop struct { + cc *ClientConn + activeRes map[uint32]*clientStream // keyed by streamID + closeWhenIdle bool + + hdec *hpack.Decoder + + // Fields reset on each HEADERS: + nextRes *http.Response + sawRegHeader bool // saw non-pseudo header + reqMalformed error // non-nil once known to be malformed + lastHeaderEndsStream bool + headerListSize int64 // actually uint32, but easier math this way +} + +// readLoop runs in its own goroutine and reads and dispatches frames. +func (cc *ClientConn) readLoop() { + rl := &clientConnReadLoop{ + cc: cc, + activeRes: make(map[uint32]*clientStream), + } + rl.hdec = hpack.NewDecoder(initialHeaderTableSize, rl.onNewHeaderField) + + defer rl.cleanup() + cc.readerErr = rl.run() + if ce, ok := cc.readerErr.(ConnectionError); ok { + cc.wmu.Lock() + cc.fr.WriteGoAway(0, ErrCode(ce), nil) + cc.wmu.Unlock() + } +} + +func (rl *clientConnReadLoop) cleanup() { + cc := rl.cc + defer cc.tconn.Close() + defer cc.t.connPool().MarkDead(cc) + defer close(cc.readerDone) + + // Close any response bodies if the server closes prematurely. + // TODO: also do this if we've written the headers but not + // gotten a response yet. + err := cc.readerErr + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + cc.mu.Lock() + for _, cs := range rl.activeRes { + cs.bufPipe.CloseWithError(err) + } + for _, cs := range cc.streams { + select { + case cs.resc <- resAndError{err: err}: + default: + } + close(cs.done) + } + cc.closed = true + cc.cond.Broadcast() + cc.mu.Unlock() +} + +func (rl *clientConnReadLoop) run() error { + cc := rl.cc + rl.closeWhenIdle = cc.t.disableKeepAlives() + gotReply := false // ever saw a reply + for { + f, err := cc.fr.ReadFrame() + if err != nil { + cc.vlogf("Transport readFrame error: (%T) %v", err, err) + } + if se, ok := err.(StreamError); ok { + // TODO: deal with stream errors from the framer. + return se + } else if err != nil { + return err + } + if VerboseLogs { + cc.vlogf("http2: Transport received %s", summarizeFrame(f)) + } + maybeIdle := false // whether frame might transition us to idle + + switch f := f.(type) { + case *HeadersFrame: + err = rl.processHeaders(f) + maybeIdle = true + gotReply = true + case *ContinuationFrame: + err = rl.processContinuation(f) + maybeIdle = true + case *DataFrame: + err = rl.processData(f) + maybeIdle = true + case *GoAwayFrame: + err = rl.processGoAway(f) + maybeIdle = true + case *RSTStreamFrame: + err = rl.processResetStream(f) + maybeIdle = true + case *SettingsFrame: + err = rl.processSettings(f) + case *PushPromiseFrame: + err = rl.processPushPromise(f) + case *WindowUpdateFrame: + err = rl.processWindowUpdate(f) + case *PingFrame: + err = rl.processPing(f) + default: + cc.logf("Transport: unhandled response frame type %T", f) + } + if err != nil { + return err + } + if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 { + cc.closeIfIdle() + } + } +} + +func (rl *clientConnReadLoop) processHeaders(f *HeadersFrame) error { + rl.sawRegHeader = false + rl.reqMalformed = nil + rl.lastHeaderEndsStream = f.StreamEnded() + rl.headerListSize = 0 + rl.nextRes = &http.Response{ + Proto: "HTTP/2.0", + ProtoMajor: 2, + Header: make(http.Header), + } + rl.hdec.SetEmitEnabled(true) + return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded()) +} + +func (rl *clientConnReadLoop) processContinuation(f *ContinuationFrame) error { + return rl.processHeaderBlockFragment(f.HeaderBlockFragment(), f.StreamID, f.HeadersEnded()) +} + +func (rl *clientConnReadLoop) processHeaderBlockFragment(frag []byte, streamID uint32, finalFrag bool) error { + cc := rl.cc + streamEnded := rl.lastHeaderEndsStream + cs := cc.streamByID(streamID, streamEnded && finalFrag) + if cs == nil { + // We'd get here if we canceled a request while the + // server was mid-way through replying with its + // headers. (The case of a CONTINUATION arriving + // without HEADERS would be rejected earlier by the + // Framer). So if this was just something we canceled, + // ignore it. + return nil + } + if cs.pastHeaders { + rl.hdec.SetEmitFunc(func(f hpack.HeaderField) { rl.onNewTrailerField(cs, f) }) + } else { + rl.hdec.SetEmitFunc(rl.onNewHeaderField) + } + _, err := rl.hdec.Write(frag) + if err != nil { + return ConnectionError(ErrCodeCompression) + } + if finalFrag { + if err := rl.hdec.Close(); err != nil { + return ConnectionError(ErrCodeCompression) + } + } + + if !finalFrag { + return nil + } + + if !cs.pastHeaders { + cs.pastHeaders = true + } else { + // We're dealing with trailers. (and specifically the + // final frame of headers) + if cs.pastTrailers { + // Too many HEADERS frames for this stream. + return ConnectionError(ErrCodeProtocol) + } + cs.pastTrailers = true + if !streamEnded { + // We expect that any header block fragment + // frame for trailers with END_HEADERS also + // has END_STREAM. + return ConnectionError(ErrCodeProtocol) + } + rl.endStream(cs) + return nil + } + + if rl.reqMalformed != nil { + cs.resc <- resAndError{err: rl.reqMalformed} + rl.cc.writeStreamReset(cs.ID, ErrCodeProtocol, rl.reqMalformed) + return nil + } + + res := rl.nextRes + + if res.StatusCode == 100 { + // Just skip 100-continue response headers for now. + // TODO: golang.org/issue/13851 for doing it properly. + cs.pastHeaders = false // do it all again + return nil + } + + if !streamEnded || cs.req.Method == "HEAD" { + res.ContentLength = -1 + if clens := res.Header["Content-Length"]; len(clens) == 1 { + if clen64, err := strconv.ParseInt(clens[0], 10, 64); err == nil { + res.ContentLength = clen64 + } else { + // TODO: care? unlike http/1, it won't mess up our framing, so it's + // more safe smuggling-wise to ignore. + } + } else if len(clens) > 1 { + // TODO: care? unlike http/1, it won't mess up our framing, so it's + // more safe smuggling-wise to ignore. + } + } + + if streamEnded { + res.Body = noBody + } else { + buf := new(bytes.Buffer) // TODO(bradfitz): recycle this garbage + cs.bufPipe = pipe{b: buf} + cs.bytesRemain = res.ContentLength + res.Body = transportResponseBody{cs} + go cs.awaitRequestCancel(requestCancel(cs.req)) + + if cs.requestedGzip && res.Header.Get("Content-Encoding") == "gzip" { + res.Header.Del("Content-Encoding") + res.Header.Del("Content-Length") + res.ContentLength = -1 + res.Body = &gzipReader{body: res.Body} + } + rl.activeRes[cs.ID] = cs + } + + cs.resTrailer = &res.Trailer + cs.resc <- resAndError{res: res} + rl.nextRes = nil // unused now; will be reset next HEADERS frame + return nil +} + +// transportResponseBody is the concrete type of Transport.RoundTrip's +// Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body. +// On Close it sends RST_STREAM if EOF wasn't already seen. +type transportResponseBody struct { + cs *clientStream +} + +func (b transportResponseBody) Read(p []byte) (n int, err error) { + cs := b.cs + cc := cs.cc + + if cs.readErr != nil { + return 0, cs.readErr + } + n, err = b.cs.bufPipe.Read(p) + if cs.bytesRemain != -1 { + if int64(n) > cs.bytesRemain { + n = int(cs.bytesRemain) + if err == nil { + err = errors.New("net/http: server replied with more than declared Content-Length; truncated") + cc.writeStreamReset(cs.ID, ErrCodeProtocol, err) + } + cs.readErr = err + return int(cs.bytesRemain), err + } + cs.bytesRemain -= int64(n) + if err == io.EOF && cs.bytesRemain > 0 { + err = io.ErrUnexpectedEOF + cs.readErr = err + return n, err + } + } + if n == 0 { + // No flow control tokens to send back. + return + } + + cc.mu.Lock() + defer cc.mu.Unlock() + + var connAdd, streamAdd int32 + // Check the conn-level first, before the stream-level. + if v := cc.inflow.available(); v < transportDefaultConnFlow/2 { + connAdd = transportDefaultConnFlow - v + cc.inflow.add(connAdd) + } + if err == nil { // No need to refresh if the stream is over or failed. + if v := cs.inflow.available(); v < transportDefaultStreamFlow-transportDefaultStreamMinRefresh { + streamAdd = transportDefaultStreamFlow - v + cs.inflow.add(streamAdd) + } + } + if connAdd != 0 || streamAdd != 0 { + cc.wmu.Lock() + defer cc.wmu.Unlock() + if connAdd != 0 { + cc.fr.WriteWindowUpdate(0, mustUint31(connAdd)) + } + if streamAdd != 0 { + cc.fr.WriteWindowUpdate(cs.ID, mustUint31(streamAdd)) + } + cc.bw.Flush() + } + return +} + +var errClosedResponseBody = errors.New("http2: response body closed") + +func (b transportResponseBody) Close() error { + cs := b.cs + if cs.bufPipe.Err() != io.EOF { + // TODO: write test for this + cs.cc.writeStreamReset(cs.ID, ErrCodeCancel, nil) + } + cs.bufPipe.BreakWithError(errClosedResponseBody) + return nil +} + +func (rl *clientConnReadLoop) processData(f *DataFrame) error { + cc := rl.cc + cs := cc.streamByID(f.StreamID, f.StreamEnded()) + if cs == nil { + cc.mu.Lock() + neverSent := cc.nextStreamID + cc.mu.Unlock() + if f.StreamID >= neverSent { + // We never asked for this. + cc.logf("http2: Transport received unsolicited DATA frame; closing connection") + return ConnectionError(ErrCodeProtocol) + } + // We probably did ask for this, but canceled. Just ignore it. + // TODO: be stricter here? only silently ignore things which + // we canceled, but not things which were closed normally + // by the peer? Tough without accumulating too much state. + return nil + } + if data := f.Data(); len(data) > 0 { + if cs.bufPipe.b == nil { + // Data frame after it's already closed? + cc.logf("http2: Transport received DATA frame for closed stream; closing connection") + return ConnectionError(ErrCodeProtocol) + } + + // Check connection-level flow control. + cc.mu.Lock() + if cs.inflow.available() >= int32(len(data)) { + cs.inflow.take(int32(len(data))) + } else { + cc.mu.Unlock() + return ConnectionError(ErrCodeFlowControl) + } + cc.mu.Unlock() + + if _, err := cs.bufPipe.Write(data); err != nil { + return err + } + } + + if f.StreamEnded() { + rl.endStream(cs) + } + return nil +} + +var errInvalidTrailers = errors.New("http2: invalid trailers") + +func (rl *clientConnReadLoop) endStream(cs *clientStream) { + // TODO: check that any declared content-length matches, like + // server.go's (*stream).endStream method. + err := io.EOF + code := cs.copyTrailers + if rl.reqMalformed != nil { + err = rl.reqMalformed + code = nil + } + cs.bufPipe.closeWithErrorAndCode(err, code) + delete(rl.activeRes, cs.ID) + if cs.req.Close || cs.req.Header.Get("Connection") == "close" { + rl.closeWhenIdle = true + } +} + +func (cs *clientStream) copyTrailers() { + for k, vv := range cs.trailer { + t := cs.resTrailer + if *t == nil { + *t = make(http.Header) + } + (*t)[k] = vv + } +} + +func (rl *clientConnReadLoop) processGoAway(f *GoAwayFrame) error { + cc := rl.cc + cc.t.connPool().MarkDead(cc) + if f.ErrCode != 0 { + // TODO: deal with GOAWAY more. particularly the error code + cc.vlogf("transport got GOAWAY with error code = %v", f.ErrCode) + } + cc.setGoAway(f) + return nil +} + +func (rl *clientConnReadLoop) processSettings(f *SettingsFrame) error { + cc := rl.cc + cc.mu.Lock() + defer cc.mu.Unlock() + return f.ForeachSetting(func(s Setting) error { + switch s.ID { + case SettingMaxFrameSize: + cc.maxFrameSize = s.Val + case SettingMaxConcurrentStreams: + cc.maxConcurrentStreams = s.Val + case SettingInitialWindowSize: + // TODO: error if this is too large. + + // TODO: adjust flow control of still-open + // frames by the difference of the old initial + // window size and this one. + cc.initialWindowSize = s.Val + default: + // TODO(bradfitz): handle more settings? SETTINGS_HEADER_TABLE_SIZE probably. + cc.vlogf("Unhandled Setting: %v", s) + } + return nil + }) +} + +func (rl *clientConnReadLoop) processWindowUpdate(f *WindowUpdateFrame) error { + cc := rl.cc + cs := cc.streamByID(f.StreamID, false) + if f.StreamID != 0 && cs == nil { + return nil + } + + cc.mu.Lock() + defer cc.mu.Unlock() + + fl := &cc.flow + if cs != nil { + fl = &cs.flow + } + if !fl.add(int32(f.Increment)) { + return ConnectionError(ErrCodeFlowControl) + } + cc.cond.Broadcast() + return nil +} + +func (rl *clientConnReadLoop) processResetStream(f *RSTStreamFrame) error { + cs := rl.cc.streamByID(f.StreamID, true) + if cs == nil { + // TODO: return error if server tries to RST_STEAM an idle stream + return nil + } + select { + case <-cs.peerReset: + // Already reset. + // This is the only goroutine + // which closes this, so there + // isn't a race. + default: + err := StreamError{cs.ID, f.ErrCode} + cs.resetErr = err + close(cs.peerReset) + cs.bufPipe.CloseWithError(err) + cs.cc.cond.Broadcast() // wake up checkReset via clientStream.awaitFlowControl + } + delete(rl.activeRes, cs.ID) + return nil +} + +func (rl *clientConnReadLoop) processPing(f *PingFrame) error { + if f.IsAck() { + // 6.7 PING: " An endpoint MUST NOT respond to PING frames + // containing this flag." + return nil + } + cc := rl.cc + cc.wmu.Lock() + defer cc.wmu.Unlock() + if err := cc.fr.WritePing(true, f.Data); err != nil { + return err + } + return cc.bw.Flush() +} + +func (rl *clientConnReadLoop) processPushPromise(f *PushPromiseFrame) error { + // We told the peer we don't want them. + // Spec says: + // "PUSH_PROMISE MUST NOT be sent if the SETTINGS_ENABLE_PUSH + // setting of the peer endpoint is set to 0. An endpoint that + // has set this setting and has received acknowledgement MUST + // treat the receipt of a PUSH_PROMISE frame as a connection + // error (Section 5.4.1) of type PROTOCOL_ERROR." + return ConnectionError(ErrCodeProtocol) +} + +func (cc *ClientConn) writeStreamReset(streamID uint32, code ErrCode, err error) { + // TODO: do something with err? send it as a debug frame to the peer? + // But that's only in GOAWAY. Invent a new frame type? Is there one already? + cc.wmu.Lock() + cc.fr.WriteRSTStream(streamID, code) + cc.bw.Flush() + cc.wmu.Unlock() +} + +var ( + errResponseHeaderListSize = errors.New("http2: response header list larger than advertised limit") + errPseudoTrailers = errors.New("http2: invalid pseudo header in trailers") +) + +func (rl *clientConnReadLoop) checkHeaderField(f hpack.HeaderField) bool { + if rl.reqMalformed != nil { + return false + } + + const headerFieldOverhead = 32 // per spec + rl.headerListSize += int64(len(f.Name)) + int64(len(f.Value)) + headerFieldOverhead + if max := rl.cc.t.maxHeaderListSize(); max != 0 && rl.headerListSize > int64(max) { + rl.hdec.SetEmitEnabled(false) + rl.reqMalformed = errResponseHeaderListSize + return false + } + + if !validHeaderFieldValue(f.Value) { + rl.reqMalformed = errInvalidHeaderFieldValue + return false + } + + isPseudo := strings.HasPrefix(f.Name, ":") + if isPseudo { + if rl.sawRegHeader { + rl.reqMalformed = errors.New("http2: invalid pseudo header after regular header") + return false + } + } else { + if !validHeaderFieldName(f.Name) { + rl.reqMalformed = errInvalidHeaderFieldName + return false + } + rl.sawRegHeader = true + } + + return true +} + +// onNewHeaderField runs on the readLoop goroutine whenever a new +// hpack header field is decoded. +func (rl *clientConnReadLoop) onNewHeaderField(f hpack.HeaderField) { + cc := rl.cc + if VerboseLogs { + cc.logf("http2: Transport decoded %v", f) + } + + if !rl.checkHeaderField(f) { + return + } + + isPseudo := strings.HasPrefix(f.Name, ":") + if isPseudo { + switch f.Name { + case ":status": + code, err := strconv.Atoi(f.Value) + if err != nil { + rl.reqMalformed = errors.New("http2: invalid :status") + return + } + rl.nextRes.Status = f.Value + " " + http.StatusText(code) + rl.nextRes.StatusCode = code + default: + // "Endpoints MUST NOT generate pseudo-header + // fields other than those defined in this + // document." + rl.reqMalformed = fmt.Errorf("http2: unknown response pseudo header %q", f.Name) + } + return + } + + key := http.CanonicalHeaderKey(f.Name) + if key == "Trailer" { + t := rl.nextRes.Trailer + if t == nil { + t = make(http.Header) + rl.nextRes.Trailer = t + } + foreachHeaderElement(f.Value, func(v string) { + t[http.CanonicalHeaderKey(v)] = nil + }) + } else { + rl.nextRes.Header.Add(key, f.Value) + } +} + +func (rl *clientConnReadLoop) onNewTrailerField(cs *clientStream, f hpack.HeaderField) { + if VerboseLogs { + rl.cc.logf("http2: Transport decoded trailer %v", f) + } + if !rl.checkHeaderField(f) { + return + } + if strings.HasPrefix(f.Name, ":") { + // Pseudo-header fields MUST NOT appear in + // trailers. Endpoints MUST treat a request or + // response that contains undefined or invalid + // pseudo-header fields as malformed. + rl.reqMalformed = errPseudoTrailers + return + } + + key := http.CanonicalHeaderKey(f.Name) + + // The spec says one must predeclare their trailers but in practice + // popular users (which is to say the only user we found) do not so we + // violate the spec and accept all of them. + const acceptAllTrailers = true + if _, ok := (*cs.resTrailer)[key]; ok || acceptAllTrailers { + if cs.trailer == nil { + cs.trailer = make(http.Header) + } + cs.trailer[key] = append(cs.trailer[key], f.Value) + } +} + +func (cc *ClientConn) logf(format string, args ...interface{}) { + cc.t.logf(format, args...) +} + +func (cc *ClientConn) vlogf(format string, args ...interface{}) { + cc.t.vlogf(format, args...) +} + +func (t *Transport) vlogf(format string, args ...interface{}) { + if VerboseLogs { + t.logf(format, args...) + } +} + +func (t *Transport) logf(format string, args ...interface{}) { + log.Printf(format, args...) +} + +var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil)) + +func strSliceContains(ss []string, s string) bool { + for _, v := range ss { + if v == s { + return true + } + } + return false +} + +type erringRoundTripper struct{ err error } + +func (rt erringRoundTripper) RoundTrip(*http.Request) (*http.Response, error) { return nil, rt.err } + +// gzipReader wraps a response body so it can lazily +// call gzip.NewReader on the first call to Read +type gzipReader struct { + body io.ReadCloser // underlying Response.Body + zr io.Reader // lazily-initialized gzip reader +} + +func (gz *gzipReader) Read(p []byte) (n int, err error) { + if gz.zr == nil { + gz.zr, err = gzip.NewReader(gz.body) + if err != nil { + return 0, err + } + } + return gz.zr.Read(p) +} + +func (gz *gzipReader) Close() error { + return gz.body.Close() +} + +type errorReader struct{ err error } + +func (r errorReader) Read(p []byte) (int, error) { return 0, r.err } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/transport_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/transport_test.go new file mode 100644 index 00000000..e9b89f75 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/transport_test.go @@ -0,0 +1,1662 @@ +// 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 http2 + +import ( + "bufio" + "bytes" + "crypto/tls" + "errors" + "flag" + "fmt" + "io" + "io/ioutil" + "log" + "math/rand" + "net" + "net/http" + "net/url" + "os" + "reflect" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + "golang.org/x/net/http2/hpack" +) + +var ( + extNet = flag.Bool("extnet", false, "do external network tests") + transportHost = flag.String("transporthost", "http2.golang.org", "hostname to use for TestTransport") + insecure = flag.Bool("insecure", false, "insecure TLS dials") // TODO: dead code. remove? +) + +var tlsConfigInsecure = &tls.Config{InsecureSkipVerify: true} + +func TestTransportExternal(t *testing.T) { + if !*extNet { + t.Skip("skipping external network test") + } + req, _ := http.NewRequest("GET", "https://"+*transportHost+"/", nil) + rt := &Transport{TLSClientConfig: tlsConfigInsecure} + res, err := rt.RoundTrip(req) + if err != nil { + t.Fatalf("%v", err) + } + res.Write(os.Stdout) +} + +func TestTransport(t *testing.T) { + const body = "sup" + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, body) + }, optOnlyServer) + defer st.Close() + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + + req, err := http.NewRequest("GET", st.ts.URL, nil) + if err != nil { + t.Fatal(err) + } + res, err := tr.RoundTrip(req) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + + t.Logf("Got res: %+v", res) + if g, w := res.StatusCode, 200; g != w { + t.Errorf("StatusCode = %v; want %v", g, w) + } + if g, w := res.Status, "200 OK"; g != w { + t.Errorf("Status = %q; want %q", g, w) + } + wantHeader := http.Header{ + "Content-Length": []string{"3"}, + "Content-Type": []string{"text/plain; charset=utf-8"}, + "Date": []string{"XXX"}, // see cleanDate + } + cleanDate(res) + if !reflect.DeepEqual(res.Header, wantHeader) { + t.Errorf("res Header = %v; want %v", res.Header, wantHeader) + } + if res.Request != req { + t.Errorf("Response.Request = %p; want %p", res.Request, req) + } + if res.TLS == nil { + t.Error("Response.TLS = nil; want non-nil") + } + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Errorf("Body read: %v", err) + } else if string(slurp) != body { + t.Errorf("Body = %q; want %q", slurp, body) + } +} +func onSameConn(t *testing.T, modReq func(*http.Request)) bool { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, r.RemoteAddr) + }, optOnlyServer) + defer st.Close() + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + get := func() string { + req, err := http.NewRequest("GET", st.ts.URL, nil) + if err != nil { + t.Fatal(err) + } + modReq(req) + res, err := tr.RoundTrip(req) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Fatalf("Body read: %v", err) + } + addr := strings.TrimSpace(string(slurp)) + if addr == "" { + t.Fatalf("didn't get an addr in response") + } + return addr + } + first := get() + second := get() + return first == second +} + +func TestTransportReusesConns(t *testing.T) { + if !onSameConn(t, func(*http.Request) {}) { + t.Errorf("first and second responses were on different connections") + } +} + +func TestTransportReusesConn_RequestClose(t *testing.T) { + if onSameConn(t, func(r *http.Request) { r.Close = true }) { + t.Errorf("first and second responses were not on different connections") + } +} + +func TestTransportReusesConn_ConnClose(t *testing.T) { + if onSameConn(t, func(r *http.Request) { r.Header.Set("Connection", "close") }) { + t.Errorf("first and second responses were not on different connections") + } +} + +// Tests that the Transport only keeps one pending dial open per destination address. +// https://golang.org/issue/13397 +func TestTransportGroupsPendingDials(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, r.RemoteAddr) + }, optOnlyServer) + defer st.Close() + tr := &Transport{ + TLSClientConfig: tlsConfigInsecure, + } + defer tr.CloseIdleConnections() + var ( + mu sync.Mutex + dials = map[string]int{} + ) + var wg sync.WaitGroup + for i := 0; i < 10; i++ { + wg.Add(1) + go func() { + defer wg.Done() + req, err := http.NewRequest("GET", st.ts.URL, nil) + if err != nil { + t.Error(err) + return + } + res, err := tr.RoundTrip(req) + if err != nil { + t.Error(err) + return + } + defer res.Body.Close() + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Errorf("Body read: %v", err) + } + addr := strings.TrimSpace(string(slurp)) + if addr == "" { + t.Errorf("didn't get an addr in response") + } + mu.Lock() + dials[addr]++ + mu.Unlock() + }() + } + wg.Wait() + if len(dials) != 1 { + t.Errorf("saw %d dials; want 1: %v", len(dials), dials) + } + tr.CloseIdleConnections() + if err := retry(50, 10*time.Millisecond, func() error { + cp, ok := tr.connPool().(*clientConnPool) + if !ok { + return fmt.Errorf("Conn pool is %T; want *clientConnPool", tr.connPool()) + } + cp.mu.Lock() + defer cp.mu.Unlock() + if len(cp.dialing) != 0 { + return fmt.Errorf("dialing map = %v; want empty", cp.dialing) + } + if len(cp.conns) != 0 { + return fmt.Errorf("conns = %v; want empty", cp.conns) + } + if len(cp.keys) != 0 { + return fmt.Errorf("keys = %v; want empty", cp.keys) + } + return nil + }); err != nil { + t.Errorf("State of pool after CloseIdleConnections: %v", err) + } +} + +func retry(tries int, delay time.Duration, fn func() error) error { + var err error + for i := 0; i < tries; i++ { + err = fn() + if err == nil { + return nil + } + time.Sleep(delay) + } + return err +} + +func TestTransportAbortClosesPipes(t *testing.T) { + shutdown := make(chan struct{}) + st := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + w.(http.Flusher).Flush() + <-shutdown + }, + optOnlyServer, + ) + defer st.Close() + defer close(shutdown) // we must shutdown before st.Close() to avoid hanging + + done := make(chan struct{}) + requestMade := make(chan struct{}) + go func() { + defer close(done) + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + req, err := http.NewRequest("GET", st.ts.URL, nil) + if err != nil { + t.Fatal(err) + } + res, err := tr.RoundTrip(req) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + close(requestMade) + _, err = ioutil.ReadAll(res.Body) + if err == nil { + t.Error("expected error from res.Body.Read") + } + }() + + <-requestMade + // Now force the serve loop to end, via closing the connection. + st.closeConn() + // deadlock? that's a bug. + select { + case <-done: + case <-time.After(3 * time.Second): + t.Fatal("timeout") + } +} + +// TODO: merge this with TestTransportBody to make TestTransportRequest? This +// could be a table-driven test with extra goodies. +func TestTransportPath(t *testing.T) { + gotc := make(chan *url.URL, 1) + st := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + gotc <- r.URL + }, + optOnlyServer, + ) + defer st.Close() + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + const ( + path = "/testpath" + query = "q=1" + ) + surl := st.ts.URL + path + "?" + query + req, err := http.NewRequest("POST", surl, nil) + if err != nil { + t.Fatal(err) + } + c := &http.Client{Transport: tr} + res, err := c.Do(req) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + got := <-gotc + if got.Path != path { + t.Errorf("Read Path = %q; want %q", got.Path, path) + } + if got.RawQuery != query { + t.Errorf("Read RawQuery = %q; want %q", got.RawQuery, query) + } +} + +func randString(n int) string { + rnd := rand.New(rand.NewSource(int64(n))) + b := make([]byte, n) + for i := range b { + b[i] = byte(rnd.Intn(256)) + } + return string(b) +} + +var bodyTests = []struct { + body string + noContentLen bool +}{ + {body: "some message"}, + {body: "some message", noContentLen: true}, + {body: ""}, + {body: "", noContentLen: true}, + {body: strings.Repeat("a", 1<<20), noContentLen: true}, + {body: strings.Repeat("a", 1<<20)}, + {body: randString(16<<10 - 1)}, + {body: randString(16 << 10)}, + {body: randString(16<<10 + 1)}, + {body: randString(512<<10 - 1)}, + {body: randString(512 << 10)}, + {body: randString(512<<10 + 1)}, + {body: randString(1<<20 - 1)}, + {body: randString(1 << 20)}, + {body: randString(1<<20 + 2)}, +} + +func TestTransportBody(t *testing.T) { + type reqInfo struct { + req *http.Request + slurp []byte + err error + } + gotc := make(chan reqInfo, 1) + st := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + slurp, err := ioutil.ReadAll(r.Body) + if err != nil { + gotc <- reqInfo{err: err} + } else { + gotc <- reqInfo{req: r, slurp: slurp} + } + }, + optOnlyServer, + ) + defer st.Close() + + for i, tt := range bodyTests { + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + + var body io.Reader = strings.NewReader(tt.body) + if tt.noContentLen { + body = struct{ io.Reader }{body} // just a Reader, hiding concrete type and other methods + } + req, err := http.NewRequest("POST", st.ts.URL, body) + if err != nil { + t.Fatalf("#%d: %v", i, err) + } + c := &http.Client{Transport: tr} + res, err := c.Do(req) + if err != nil { + t.Fatalf("#%d: %v", i, err) + } + defer res.Body.Close() + ri := <-gotc + if ri.err != nil { + t.Errorf("#%d: read error: %v", i, ri.err) + continue + } + if got := string(ri.slurp); got != tt.body { + t.Errorf("#%d: Read body mismatch.\n got: %q (len %d)\nwant: %q (len %d)", i, shortString(got), len(got), shortString(tt.body), len(tt.body)) + } + wantLen := int64(len(tt.body)) + if tt.noContentLen && tt.body != "" { + wantLen = -1 + } + if ri.req.ContentLength != wantLen { + t.Errorf("#%d. handler got ContentLength = %v; want %v", i, ri.req.ContentLength, wantLen) + } + } +} + +func shortString(v string) string { + const maxLen = 100 + if len(v) <= maxLen { + return v + } + return fmt.Sprintf("%v[...%d bytes omitted...]%v", v[:maxLen/2], len(v)-maxLen, v[len(v)-maxLen/2:]) +} + +func TestTransportDialTLS(t *testing.T) { + var mu sync.Mutex // guards following + var gotReq, didDial bool + + ts := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + mu.Lock() + gotReq = true + mu.Unlock() + }, + optOnlyServer, + ) + defer ts.Close() + tr := &Transport{ + DialTLS: func(netw, addr string, cfg *tls.Config) (net.Conn, error) { + mu.Lock() + didDial = true + mu.Unlock() + cfg.InsecureSkipVerify = true + c, err := tls.Dial(netw, addr, cfg) + if err != nil { + return nil, err + } + return c, c.Handshake() + }, + } + defer tr.CloseIdleConnections() + client := &http.Client{Transport: tr} + res, err := client.Get(ts.ts.URL) + if err != nil { + t.Fatal(err) + } + res.Body.Close() + mu.Lock() + if !gotReq { + t.Error("didn't get request") + } + if !didDial { + t.Error("didn't use dial hook") + } +} + +func TestConfigureTransport(t *testing.T) { + t1 := &http.Transport{} + err := ConfigureTransport(t1) + if err == errTransportVersion { + t.Skip(err) + } + if err != nil { + t.Fatal(err) + } + if got := fmt.Sprintf("%#v", *t1); !strings.Contains(got, `"h2"`) { + // Laziness, to avoid buildtags. + t.Errorf("stringification of HTTP/1 transport didn't contain \"h2\": %v", got) + } + wantNextProtos := []string{"h2", "http/1.1"} + if t1.TLSClientConfig == nil { + t.Errorf("nil t1.TLSClientConfig") + } else if !reflect.DeepEqual(t1.TLSClientConfig.NextProtos, wantNextProtos) { + t.Errorf("TLSClientConfig.NextProtos = %q; want %q", t1.TLSClientConfig.NextProtos, wantNextProtos) + } + if err := ConfigureTransport(t1); err == nil { + t.Error("unexpected success on second call to ConfigureTransport") + } + + // And does it work? + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, r.Proto) + }, optOnlyServer) + defer st.Close() + + t1.TLSClientConfig.InsecureSkipVerify = true + c := &http.Client{Transport: t1} + res, err := c.Get(st.ts.URL) + if err != nil { + t.Fatal(err) + } + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + t.Fatal(err) + } + if got, want := string(slurp), "HTTP/2.0"; got != want { + t.Errorf("body = %q; want %q", got, want) + } +} + +type capitalizeReader struct { + r io.Reader +} + +func (cr capitalizeReader) Read(p []byte) (n int, err error) { + n, err = cr.r.Read(p) + for i, b := range p[:n] { + if b >= 'a' && b <= 'z' { + p[i] = b - ('a' - 'A') + } + } + return +} + +type flushWriter struct { + w io.Writer +} + +func (fw flushWriter) Write(p []byte) (n int, err error) { + n, err = fw.w.Write(p) + if f, ok := fw.w.(http.Flusher); ok { + f.Flush() + } + return +} + +type clientTester struct { + t *testing.T + tr *Transport + sc, cc net.Conn // server and client conn + fr *Framer // server's framer + client func() error + server func() error +} + +func newClientTester(t *testing.T) *clientTester { + var dialOnce struct { + sync.Mutex + dialed bool + } + ct := &clientTester{ + t: t, + } + ct.tr = &Transport{ + TLSClientConfig: tlsConfigInsecure, + DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { + dialOnce.Lock() + defer dialOnce.Unlock() + if dialOnce.dialed { + return nil, errors.New("only one dial allowed in test mode") + } + dialOnce.dialed = true + return ct.cc, nil + }, + } + + ln := newLocalListener(t) + cc, err := net.Dial("tcp", ln.Addr().String()) + if err != nil { + t.Fatal(err) + + } + sc, err := ln.Accept() + if err != nil { + t.Fatal(err) + } + ln.Close() + ct.cc = cc + ct.sc = sc + ct.fr = NewFramer(sc, sc) + return ct +} + +func newLocalListener(t *testing.T) net.Listener { + ln, err := net.Listen("tcp4", "127.0.0.1:0") + if err == nil { + return ln + } + ln, err = net.Listen("tcp6", "[::1]:0") + if err != nil { + t.Fatal(err) + } + return ln +} + +func (ct *clientTester) greet() { + buf := make([]byte, len(ClientPreface)) + _, err := io.ReadFull(ct.sc, buf) + if err != nil { + ct.t.Fatalf("reading client preface: %v", err) + } + f, err := ct.fr.ReadFrame() + if err != nil { + ct.t.Fatalf("Reading client settings frame: %v", err) + } + if sf, ok := f.(*SettingsFrame); !ok { + ct.t.Fatalf("Wanted client settings frame; got %v", f) + _ = sf // stash it away? + } + if err := ct.fr.WriteSettings(); err != nil { + ct.t.Fatal(err) + } + if err := ct.fr.WriteSettingsAck(); err != nil { + ct.t.Fatal(err) + } +} + +func (ct *clientTester) cleanup() { + ct.tr.CloseIdleConnections() +} + +func (ct *clientTester) run() { + errc := make(chan error, 2) + ct.start("client", errc, ct.client) + ct.start("server", errc, ct.server) + defer ct.cleanup() + for i := 0; i < 2; i++ { + if err := <-errc; err != nil { + ct.t.Error(err) + return + } + } +} + +func (ct *clientTester) start(which string, errc chan<- error, fn func() error) { + go func() { + finished := false + var err error + defer func() { + if !finished { + err = fmt.Errorf("%s goroutine didn't finish.", which) + } else if err != nil { + err = fmt.Errorf("%s: %v", which, err) + } + errc <- err + }() + err = fn() + finished = true + }() +} + +type countingReader struct { + n *int64 +} + +func (r countingReader) Read(p []byte) (n int, err error) { + for i := range p { + p[i] = byte(i) + } + atomic.AddInt64(r.n, int64(len(p))) + return len(p), err +} + +func TestTransportReqBodyAfterResponse_200(t *testing.T) { testTransportReqBodyAfterResponse(t, 200) } +func TestTransportReqBodyAfterResponse_403(t *testing.T) { testTransportReqBodyAfterResponse(t, 403) } + +func testTransportReqBodyAfterResponse(t *testing.T, status int) { + const bodySize = 10 << 20 + ct := newClientTester(t) + ct.client = func() error { + var n int64 // atomic + req, err := http.NewRequest("PUT", "https://dummy.tld/", io.LimitReader(countingReader{&n}, bodySize)) + if err != nil { + return err + } + res, err := ct.tr.RoundTrip(req) + if err != nil { + return fmt.Errorf("RoundTrip: %v", err) + } + defer res.Body.Close() + if res.StatusCode != status { + return fmt.Errorf("status code = %v; want %v", res.StatusCode, status) + } + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + return fmt.Errorf("Slurp: %v", err) + } + if len(slurp) > 0 { + return fmt.Errorf("unexpected body: %q", slurp) + } + if status == 200 { + if got := atomic.LoadInt64(&n); got != bodySize { + return fmt.Errorf("For 200 response, Transport wrote %d bytes; want %d", got, bodySize) + } + } else { + if got := atomic.LoadInt64(&n); got == 0 || got >= bodySize { + return fmt.Errorf("For %d response, Transport wrote %d bytes; want (0,%d) exclusive", status, got, bodySize) + } + } + return nil + } + ct.server = func() error { + ct.greet() + var buf bytes.Buffer + enc := hpack.NewEncoder(&buf) + var dataRecv int64 + var closed bool + for { + f, err := ct.fr.ReadFrame() + if err != nil { + return err + } + //println(fmt.Sprintf("server got frame: %v", f)) + switch f := f.(type) { + case *WindowUpdateFrame, *SettingsFrame: + case *HeadersFrame: + if !f.HeadersEnded() { + return fmt.Errorf("headers should have END_HEADERS be ended: %v", f) + } + if f.StreamEnded() { + return fmt.Errorf("headers contains END_STREAM unexpectedly: %v", f) + } + time.Sleep(50 * time.Millisecond) // let client send body + enc.WriteField(hpack.HeaderField{Name: ":status", Value: strconv.Itoa(status)}) + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: f.StreamID, + EndHeaders: true, + EndStream: false, + BlockFragment: buf.Bytes(), + }) + case *DataFrame: + dataLen := len(f.Data()) + dataRecv += int64(dataLen) + if dataLen > 0 { + if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil { + return err + } + if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil { + return err + } + } + if !closed && ((status != 200 && dataRecv > 0) || + (status == 200 && dataRecv == bodySize)) { + closed = true + if err := ct.fr.WriteData(f.StreamID, true, nil); err != nil { + return err + } + return nil + } + default: + return fmt.Errorf("Unexpected client frame %v", f) + } + } + return nil + } + ct.run() +} + +// See golang.org/issue/13444 +func TestTransportFullDuplex(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) // redundant but for clarity + w.(http.Flusher).Flush() + io.Copy(flushWriter{w}, capitalizeReader{r.Body}) + fmt.Fprintf(w, "bye.\n") + }, optOnlyServer) + defer st.Close() + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + c := &http.Client{Transport: tr} + + pr, pw := io.Pipe() + req, err := http.NewRequest("PUT", st.ts.URL, ioutil.NopCloser(pr)) + if err != nil { + log.Fatal(err) + } + req.ContentLength = -1 + res, err := c.Do(req) + if err != nil { + log.Fatal(err) + } + defer res.Body.Close() + if res.StatusCode != 200 { + t.Fatalf("StatusCode = %v; want %v", res.StatusCode, 200) + } + bs := bufio.NewScanner(res.Body) + want := func(v string) { + if !bs.Scan() { + t.Fatalf("wanted to read %q but Scan() = false, err = %v", v, bs.Err()) + } + } + write := func(v string) { + _, err := io.WriteString(pw, v) + if err != nil { + t.Fatalf("pipe write: %v", err) + } + } + write("foo\n") + want("FOO") + write("bar\n") + want("BAR") + pw.Close() + want("bye.") + if err := bs.Err(); err != nil { + t.Fatal(err) + } +} + +func TestTransportConnectRequest(t *testing.T) { + gotc := make(chan *http.Request, 1) + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + gotc <- r + }, optOnlyServer) + defer st.Close() + + u, err := url.Parse(st.ts.URL) + if err != nil { + t.Fatal(err) + } + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + c := &http.Client{Transport: tr} + + tests := []struct { + req *http.Request + want string + }{ + { + req: &http.Request{ + Method: "CONNECT", + Header: http.Header{}, + URL: u, + }, + want: u.Host, + }, + { + req: &http.Request{ + Method: "CONNECT", + Header: http.Header{}, + URL: u, + Host: "example.com:123", + }, + want: "example.com:123", + }, + } + + for i, tt := range tests { + res, err := c.Do(tt.req) + if err != nil { + t.Errorf("%d. RoundTrip = %v", i, err) + continue + } + res.Body.Close() + req := <-gotc + if req.Method != "CONNECT" { + t.Errorf("method = %q; want CONNECT", req.Method) + } + if req.Host != tt.want { + t.Errorf("Host = %q; want %q", req.Host, tt.want) + } + if req.URL.Host != tt.want { + t.Errorf("URL.Host = %q; want %q", req.URL.Host, tt.want) + } + } +} + +type headerType int + +const ( + noHeader headerType = iota // omitted + oneHeader + splitHeader // broken into continuation on purpose +) + +const ( + f0 = noHeader + f1 = oneHeader + f2 = splitHeader + d0 = false + d1 = true +) + +// Test all 36 combinations of response frame orders: +// (3 ways of 100-continue) * (2 ways of headers) * (2 ways of data) * (3 ways of trailers):func TestTransportResponsePattern_00f0(t *testing.T) { testTransportResponsePattern(h0, h1, false, h0) } +// Generated by http://play.golang.org/p/SScqYKJYXd +func TestTransportResPattern_c0h1d0t0(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f0) } +func TestTransportResPattern_c0h1d0t1(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f1) } +func TestTransportResPattern_c0h1d0t2(t *testing.T) { testTransportResPattern(t, f0, f1, d0, f2) } +func TestTransportResPattern_c0h1d1t0(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f0) } +func TestTransportResPattern_c0h1d1t1(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f1) } +func TestTransportResPattern_c0h1d1t2(t *testing.T) { testTransportResPattern(t, f0, f1, d1, f2) } +func TestTransportResPattern_c0h2d0t0(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f0) } +func TestTransportResPattern_c0h2d0t1(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f1) } +func TestTransportResPattern_c0h2d0t2(t *testing.T) { testTransportResPattern(t, f0, f2, d0, f2) } +func TestTransportResPattern_c0h2d1t0(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f0) } +func TestTransportResPattern_c0h2d1t1(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f1) } +func TestTransportResPattern_c0h2d1t2(t *testing.T) { testTransportResPattern(t, f0, f2, d1, f2) } +func TestTransportResPattern_c1h1d0t0(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f0) } +func TestTransportResPattern_c1h1d0t1(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f1) } +func TestTransportResPattern_c1h1d0t2(t *testing.T) { testTransportResPattern(t, f1, f1, d0, f2) } +func TestTransportResPattern_c1h1d1t0(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f0) } +func TestTransportResPattern_c1h1d1t1(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f1) } +func TestTransportResPattern_c1h1d1t2(t *testing.T) { testTransportResPattern(t, f1, f1, d1, f2) } +func TestTransportResPattern_c1h2d0t0(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f0) } +func TestTransportResPattern_c1h2d0t1(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f1) } +func TestTransportResPattern_c1h2d0t2(t *testing.T) { testTransportResPattern(t, f1, f2, d0, f2) } +func TestTransportResPattern_c1h2d1t0(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f0) } +func TestTransportResPattern_c1h2d1t1(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f1) } +func TestTransportResPattern_c1h2d1t2(t *testing.T) { testTransportResPattern(t, f1, f2, d1, f2) } +func TestTransportResPattern_c2h1d0t0(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f0) } +func TestTransportResPattern_c2h1d0t1(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f1) } +func TestTransportResPattern_c2h1d0t2(t *testing.T) { testTransportResPattern(t, f2, f1, d0, f2) } +func TestTransportResPattern_c2h1d1t0(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f0) } +func TestTransportResPattern_c2h1d1t1(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f1) } +func TestTransportResPattern_c2h1d1t2(t *testing.T) { testTransportResPattern(t, f2, f1, d1, f2) } +func TestTransportResPattern_c2h2d0t0(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f0) } +func TestTransportResPattern_c2h2d0t1(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f1) } +func TestTransportResPattern_c2h2d0t2(t *testing.T) { testTransportResPattern(t, f2, f2, d0, f2) } +func TestTransportResPattern_c2h2d1t0(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f0) } +func TestTransportResPattern_c2h2d1t1(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f1) } +func TestTransportResPattern_c2h2d1t2(t *testing.T) { testTransportResPattern(t, f2, f2, d1, f2) } + +func testTransportResPattern(t *testing.T, expect100Continue, resHeader headerType, withData bool, trailers headerType) { + const reqBody = "some request body" + const resBody = "some response body" + + if resHeader == noHeader { + // TODO: test 100-continue followed by immediate + // server stream reset, without headers in the middle? + panic("invalid combination") + } + + ct := newClientTester(t) + ct.client = func() error { + req, _ := http.NewRequest("POST", "https://dummy.tld/", strings.NewReader(reqBody)) + if expect100Continue != noHeader { + req.Header.Set("Expect", "100-continue") + } + res, err := ct.tr.RoundTrip(req) + if err != nil { + return fmt.Errorf("RoundTrip: %v", err) + } + defer res.Body.Close() + if res.StatusCode != 200 { + return fmt.Errorf("status code = %v; want 200", res.StatusCode) + } + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + return fmt.Errorf("Slurp: %v", err) + } + wantBody := resBody + if !withData { + wantBody = "" + } + if string(slurp) != wantBody { + return fmt.Errorf("body = %q; want %q", slurp, wantBody) + } + if trailers == noHeader { + if len(res.Trailer) > 0 { + t.Errorf("Trailer = %v; want none", res.Trailer) + } + } else { + want := http.Header{"Some-Trailer": {"some-value"}} + if !reflect.DeepEqual(res.Trailer, want) { + t.Errorf("Trailer = %v; want %v", res.Trailer, want) + } + } + return nil + } + ct.server = func() error { + ct.greet() + var buf bytes.Buffer + enc := hpack.NewEncoder(&buf) + + for { + f, err := ct.fr.ReadFrame() + if err != nil { + return err + } + switch f := f.(type) { + case *WindowUpdateFrame, *SettingsFrame: + case *DataFrame: + // ignore for now. + case *HeadersFrame: + endStream := false + send := func(mode headerType) { + hbf := buf.Bytes() + switch mode { + case oneHeader: + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: f.StreamID, + EndHeaders: true, + EndStream: endStream, + BlockFragment: hbf, + }) + case splitHeader: + if len(hbf) < 2 { + panic("too small") + } + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: f.StreamID, + EndHeaders: false, + EndStream: endStream, + BlockFragment: hbf[:1], + }) + ct.fr.WriteContinuation(f.StreamID, true, hbf[1:]) + default: + panic("bogus mode") + } + } + if expect100Continue != noHeader { + buf.Reset() + enc.WriteField(hpack.HeaderField{Name: ":status", Value: "100"}) + send(expect100Continue) + } + // Response headers (1+ frames; 1 or 2 in this test, but never 0) + { + buf.Reset() + enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) + enc.WriteField(hpack.HeaderField{Name: "x-foo", Value: "blah"}) + enc.WriteField(hpack.HeaderField{Name: "x-bar", Value: "more"}) + if trailers != noHeader { + enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "some-trailer"}) + } + endStream = withData == false && trailers == noHeader + send(resHeader) + } + if withData { + endStream = trailers == noHeader + ct.fr.WriteData(f.StreamID, endStream, []byte(resBody)) + } + if trailers != noHeader { + endStream = true + buf.Reset() + enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "some-value"}) + send(trailers) + } + return nil + } + } + } + ct.run() +} + +func TestTransportReceiveUndeclaredTrailer(t *testing.T) { + ct := newClientTester(t) + ct.client = func() error { + req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) + res, err := ct.tr.RoundTrip(req) + if err != nil { + return fmt.Errorf("RoundTrip: %v", err) + } + defer res.Body.Close() + if res.StatusCode != 200 { + return fmt.Errorf("status code = %v; want 200", res.StatusCode) + } + slurp, err := ioutil.ReadAll(res.Body) + if err != nil { + return fmt.Errorf("res.Body ReadAll error = %q, %v; want %v", slurp, err, nil) + } + if len(slurp) > 0 { + return fmt.Errorf("body = %q; want nothing", slurp) + } + if _, ok := res.Trailer["Some-Trailer"]; !ok { + return fmt.Errorf("expected Some-Trailer") + } + return nil + } + ct.server = func() error { + ct.greet() + + var n int + var hf *HeadersFrame + for hf == nil && n < 10 { + f, err := ct.fr.ReadFrame() + if err != nil { + return err + } + hf, _ = f.(*HeadersFrame) + n++ + } + + var buf bytes.Buffer + enc := hpack.NewEncoder(&buf) + + // send headers without Trailer header + enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: hf.StreamID, + EndHeaders: true, + EndStream: false, + BlockFragment: buf.Bytes(), + }) + + // send trailers + buf.Reset() + enc.WriteField(hpack.HeaderField{Name: "some-trailer", Value: "I'm an undeclared Trailer!"}) + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: hf.StreamID, + EndHeaders: true, + EndStream: true, + BlockFragment: buf.Bytes(), + }) + return nil + } + ct.run() +} + +func TestTransportInvalidTrailer_Pseudo1(t *testing.T) { + testTransportInvalidTrailer_Pseudo(t, oneHeader) +} +func TestTransportInvalidTrailer_Pseudo2(t *testing.T) { + testTransportInvalidTrailer_Pseudo(t, splitHeader) +} +func testTransportInvalidTrailer_Pseudo(t *testing.T, trailers headerType) { + testInvalidTrailer(t, trailers, errPseudoTrailers, func(enc *hpack.Encoder) { + enc.WriteField(hpack.HeaderField{Name: ":colon", Value: "foo"}) + enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) + }) +} + +func TestTransportInvalidTrailer_Capital1(t *testing.T) { + testTransportInvalidTrailer_Capital(t, oneHeader) +} +func TestTransportInvalidTrailer_Capital2(t *testing.T) { + testTransportInvalidTrailer_Capital(t, splitHeader) +} +func testTransportInvalidTrailer_Capital(t *testing.T, trailers headerType) { + testInvalidTrailer(t, trailers, errInvalidHeaderFieldName, func(enc *hpack.Encoder) { + enc.WriteField(hpack.HeaderField{Name: "foo", Value: "bar"}) + enc.WriteField(hpack.HeaderField{Name: "Capital", Value: "bad"}) + }) +} +func TestTransportInvalidTrailer_EmptyFieldName(t *testing.T) { + testInvalidTrailer(t, oneHeader, errInvalidHeaderFieldName, func(enc *hpack.Encoder) { + enc.WriteField(hpack.HeaderField{Name: "", Value: "bad"}) + }) +} +func TestTransportInvalidTrailer_BinaryFieldValue(t *testing.T) { + testInvalidTrailer(t, oneHeader, errInvalidHeaderFieldValue, func(enc *hpack.Encoder) { + enc.WriteField(hpack.HeaderField{Name: "", Value: "has\nnewline"}) + }) +} + +func testInvalidTrailer(t *testing.T, trailers headerType, wantErr error, writeTrailer func(*hpack.Encoder)) { + ct := newClientTester(t) + ct.client = func() error { + req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) + res, err := ct.tr.RoundTrip(req) + if err != nil { + return fmt.Errorf("RoundTrip: %v", err) + } + defer res.Body.Close() + if res.StatusCode != 200 { + return fmt.Errorf("status code = %v; want 200", res.StatusCode) + } + slurp, err := ioutil.ReadAll(res.Body) + if err != wantErr { + return fmt.Errorf("res.Body ReadAll error = %q, %v; want %v", slurp, err, wantErr) + } + if len(slurp) > 0 { + return fmt.Errorf("body = %q; want nothing", slurp) + } + return nil + } + ct.server = func() error { + ct.greet() + var buf bytes.Buffer + enc := hpack.NewEncoder(&buf) + + for { + f, err := ct.fr.ReadFrame() + if err != nil { + return err + } + switch f := f.(type) { + case *HeadersFrame: + var endStream bool + send := func(mode headerType) { + hbf := buf.Bytes() + switch mode { + case oneHeader: + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: f.StreamID, + EndHeaders: true, + EndStream: endStream, + BlockFragment: hbf, + }) + case splitHeader: + if len(hbf) < 2 { + panic("too small") + } + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: f.StreamID, + EndHeaders: false, + EndStream: endStream, + BlockFragment: hbf[:1], + }) + ct.fr.WriteContinuation(f.StreamID, true, hbf[1:]) + default: + panic("bogus mode") + } + } + // Response headers (1+ frames; 1 or 2 in this test, but never 0) + { + buf.Reset() + enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) + enc.WriteField(hpack.HeaderField{Name: "trailer", Value: "declared"}) + endStream = false + send(oneHeader) + } + // Trailers: + { + endStream = true + buf.Reset() + writeTrailer(enc) + send(trailers) + } + return nil + } + } + } + ct.run() +} + +func TestTransportChecksResponseHeaderListSize(t *testing.T) { + ct := newClientTester(t) + ct.client = func() error { + req, _ := http.NewRequest("GET", "https://dummy.tld/", nil) + res, err := ct.tr.RoundTrip(req) + if err != errResponseHeaderListSize { + if res != nil { + res.Body.Close() + } + size := int64(0) + for k, vv := range res.Header { + for _, v := range vv { + size += int64(len(k)) + int64(len(v)) + 32 + } + } + return fmt.Errorf("RoundTrip Error = %v (and %d bytes of response headers); want errResponseHeaderListSize", err, size) + } + return nil + } + ct.server = func() error { + ct.greet() + var buf bytes.Buffer + enc := hpack.NewEncoder(&buf) + + for { + f, err := ct.fr.ReadFrame() + if err != nil { + return err + } + switch f := f.(type) { + case *HeadersFrame: + enc.WriteField(hpack.HeaderField{Name: ":status", Value: "200"}) + large := strings.Repeat("a", 1<<10) + for i := 0; i < 5042; i++ { + enc.WriteField(hpack.HeaderField{Name: large, Value: large}) + } + if size, want := buf.Len(), 6329; size != want { + // Note: this number might change if + // our hpack implementation + // changes. That's fine. This is + // just a sanity check that our + // response can fit in a single + // header block fragment frame. + return fmt.Errorf("encoding over 10MB of duplicate keypairs took %d bytes; expected %d", size, want) + } + ct.fr.WriteHeaders(HeadersFrameParam{ + StreamID: f.StreamID, + EndHeaders: true, + EndStream: true, + BlockFragment: buf.Bytes(), + }) + return nil + } + } + } + ct.run() +} + +// Test that the the Transport returns a typed error from Response.Body.Read calls +// when the server sends an error. (here we use a panic, since that should generate +// a stream error, but others like cancel should be similar) +func TestTransportBodyReadErrorType(t *testing.T) { + doPanic := make(chan bool, 1) + st := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + w.(http.Flusher).Flush() // force headers out + <-doPanic + panic("boom") + }, + optOnlyServer, + optQuiet, + ) + defer st.Close() + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + c := &http.Client{Transport: tr} + + res, err := c.Get(st.ts.URL) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() + doPanic <- true + buf := make([]byte, 100) + n, err := res.Body.Read(buf) + want := StreamError{StreamID: 0x1, Code: 0x2} + if !reflect.DeepEqual(want, err) { + t.Errorf("Read = %v, %#v; want error %#v", n, err, want) + } +} + +// golang.org/issue/13924 +// This used to fail after many iterations, especially with -race: +// go test -v -run=TestTransportDoubleCloseOnWriteError -count=500 -race +func TestTransportDoubleCloseOnWriteError(t *testing.T) { + var ( + mu sync.Mutex + conn net.Conn // to close if set + ) + + st := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + mu.Lock() + defer mu.Unlock() + if conn != nil { + conn.Close() + } + }, + optOnlyServer, + ) + defer st.Close() + + tr := &Transport{ + TLSClientConfig: tlsConfigInsecure, + DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { + tc, err := tls.Dial(network, addr, cfg) + if err != nil { + return nil, err + } + mu.Lock() + defer mu.Unlock() + conn = tc + return tc, nil + }, + } + defer tr.CloseIdleConnections() + c := &http.Client{Transport: tr} + c.Get(st.ts.URL) +} + +// Test that the http1 Transport.DisableKeepAlives option is respected +// and connections are closed as soon as idle. +// See golang.org/issue/14008 +func TestTransportDisableKeepAlives(t *testing.T) { + st := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + io.WriteString(w, "hi") + }, + optOnlyServer, + ) + defer st.Close() + + connClosed := make(chan struct{}) // closed on tls.Conn.Close + tr := &Transport{ + t1: &http.Transport{ + DisableKeepAlives: true, + }, + TLSClientConfig: tlsConfigInsecure, + DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { + tc, err := tls.Dial(network, addr, cfg) + if err != nil { + return nil, err + } + return ¬eCloseConn{Conn: tc, closefn: func() { close(connClosed) }}, nil + }, + } + c := &http.Client{Transport: tr} + res, err := c.Get(st.ts.URL) + if err != nil { + t.Fatal(err) + } + if _, err := ioutil.ReadAll(res.Body); err != nil { + t.Fatal(err) + } + defer res.Body.Close() + + select { + case <-connClosed: + case <-time.After(1 * time.Second): + t.Errorf("timeout") + } + +} + +// Test concurrent requests with Transport.DisableKeepAlives. We can share connections, +// but when things are totally idle, it still needs to close. +func TestTransportDisableKeepAlives_Concurrency(t *testing.T) { + const D = 25 * time.Millisecond + st := newServerTester(t, + func(w http.ResponseWriter, r *http.Request) { + time.Sleep(D) + io.WriteString(w, "hi") + }, + optOnlyServer, + ) + defer st.Close() + + var dials int32 + var conns sync.WaitGroup + tr := &Transport{ + t1: &http.Transport{ + DisableKeepAlives: true, + }, + TLSClientConfig: tlsConfigInsecure, + DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { + tc, err := tls.Dial(network, addr, cfg) + if err != nil { + return nil, err + } + atomic.AddInt32(&dials, 1) + conns.Add(1) + return ¬eCloseConn{Conn: tc, closefn: func() { conns.Done() }}, nil + }, + } + c := &http.Client{Transport: tr} + var reqs sync.WaitGroup + const N = 20 + for i := 0; i < N; i++ { + reqs.Add(1) + if i == N-1 { + // For the final request, try to make all the + // others close. This isn't verified in the + // count, other than the Log statement, since + // it's so timing dependent. This test is + // really to make sure we don't interrupt a + // valid request. + time.Sleep(D * 2) + } + go func() { + defer reqs.Done() + res, err := c.Get(st.ts.URL) + if err != nil { + t.Error(err) + return + } + if _, err := ioutil.ReadAll(res.Body); err != nil { + t.Error(err) + return + } + res.Body.Close() + }() + } + reqs.Wait() + conns.Wait() + t.Logf("did %d dials, %d requests", atomic.LoadInt32(&dials), N) +} + +type noteCloseConn struct { + net.Conn + onceClose sync.Once + closefn func() +} + +func (c *noteCloseConn) Close() error { + c.onceClose.Do(c.closefn) + return c.Conn.Close() +} + +func isTimeout(err error) bool { + switch err := err.(type) { + case nil: + return false + case *url.Error: + return isTimeout(err.Err) + case net.Error: + return err.Timeout() + } + return false +} + +// Test that the http1 Transport.ResponseHeaderTimeout option and cancel is sent. +func TestTransportResponseHeaderTimeout_NoBody(t *testing.T) { + testTransportResponseHeaderTimeout(t, false) +} +func TestTransportResponseHeaderTimeout_Body(t *testing.T) { + testTransportResponseHeaderTimeout(t, true) +} + +func testTransportResponseHeaderTimeout(t *testing.T, body bool) { + ct := newClientTester(t) + ct.tr.t1 = &http.Transport{ + ResponseHeaderTimeout: 5 * time.Millisecond, + } + ct.client = func() error { + c := &http.Client{Transport: ct.tr} + var err error + var n int64 + const bodySize = 4 << 20 + if body { + _, err = c.Post("https://dummy.tld/", "text/foo", io.LimitReader(countingReader{&n}, bodySize)) + } else { + _, err = c.Get("https://dummy.tld/") + } + if !isTimeout(err) { + t.Errorf("client expected timeout error; got %#v", err) + } + if body && n != bodySize { + t.Errorf("only read %d bytes of body; want %d", n, bodySize) + } + return nil + } + ct.server = func() error { + ct.greet() + for { + f, err := ct.fr.ReadFrame() + if err != nil { + t.Logf("ReadFrame: %v", err) + return nil + } + switch f := f.(type) { + case *DataFrame: + dataLen := len(f.Data()) + if dataLen > 0 { + if err := ct.fr.WriteWindowUpdate(0, uint32(dataLen)); err != nil { + return err + } + if err := ct.fr.WriteWindowUpdate(f.StreamID, uint32(dataLen)); err != nil { + return err + } + } + case *RSTStreamFrame: + if f.StreamID == 1 && f.ErrCode == ErrCodeCancel { + return nil + } + } + } + return nil + } + ct.run() +} + +func TestTransportDisableCompression(t *testing.T) { + const body = "sup" + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + want := http.Header{ + "User-Agent": []string{"Go-http-client/2.0"}, + } + if !reflect.DeepEqual(r.Header, want) { + t.Errorf("request headers = %v; want %v", r.Header, want) + } + }, optOnlyServer) + defer st.Close() + + tr := &Transport{ + TLSClientConfig: tlsConfigInsecure, + t1: &http.Transport{ + DisableCompression: true, + }, + } + defer tr.CloseIdleConnections() + + req, err := http.NewRequest("GET", st.ts.URL, nil) + if err != nil { + t.Fatal(err) + } + res, err := tr.RoundTrip(req) + if err != nil { + t.Fatal(err) + } + defer res.Body.Close() +} + +// RFC 7540 section 8.1.2.2 +func TestTransportRejectsConnHeaders(t *testing.T) { + st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) { + var got []string + for k := range r.Header { + got = append(got, k) + } + sort.Strings(got) + w.Header().Set("Got-Header", strings.Join(got, ",")) + }, optOnlyServer) + defer st.Close() + + tr := &Transport{TLSClientConfig: tlsConfigInsecure} + defer tr.CloseIdleConnections() + + tests := []struct { + key string + value []string + want string + }{ + { + key: "Upgrade", + value: []string{"anything"}, + want: "ERROR: http2: invalid Upgrade request header", + }, + { + key: "Connection", + value: []string{"foo"}, + want: "ERROR: http2: invalid Connection request header", + }, + { + key: "Connection", + value: []string{"close"}, + want: "Accept-Encoding,User-Agent", + }, + { + key: "Connection", + value: []string{"close", "something-else"}, + want: "ERROR: http2: invalid Connection request header", + }, + { + key: "Connection", + value: []string{"keep-alive"}, + want: "Accept-Encoding,User-Agent", + }, + { + key: "Proxy-Connection", // just deleted and ignored + value: []string{"keep-alive"}, + want: "Accept-Encoding,User-Agent", + }, + { + key: "Transfer-Encoding", + value: []string{""}, + want: "Accept-Encoding,User-Agent", + }, + { + key: "Transfer-Encoding", + value: []string{"foo"}, + want: "ERROR: http2: invalid Transfer-Encoding request header", + }, + { + key: "Transfer-Encoding", + value: []string{"chunked"}, + want: "Accept-Encoding,User-Agent", + }, + { + key: "Transfer-Encoding", + value: []string{"chunked", "other"}, + want: "ERROR: http2: invalid Transfer-Encoding request header", + }, + { + key: "Content-Length", + value: []string{"123"}, + want: "Accept-Encoding,User-Agent", + }, + } + + for _, tt := range tests { + req, _ := http.NewRequest("GET", st.ts.URL, nil) + req.Header[tt.key] = tt.value + res, err := tr.RoundTrip(req) + var got string + if err != nil { + got = fmt.Sprintf("ERROR: %v", err) + } else { + got = res.Header.Get("Got-Header") + res.Body.Close() + } + if got != tt.want { + t.Errorf("For key %q, value %q, got = %q; want %q", tt.key, tt.value, got, tt.want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/write.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/write.go new file mode 100644 index 00000000..5297a4bf --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/write.go @@ -0,0 +1,263 @@ +// 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. + +package http2 + +import ( + "bytes" + "fmt" + "log" + "net/http" + "sort" + "time" + + "golang.org/x/net/http2/hpack" +) + +// writeFramer is implemented by any type that is used to write frames. +type writeFramer interface { + writeFrame(writeContext) error +} + +// writeContext is the interface needed by the various frame writer +// types below. All the writeFrame methods below are scheduled via the +// frame writing scheduler (see writeScheduler in writesched.go). +// +// This interface is implemented by *serverConn. +// +// TODO: decide whether to a) use this in the client code (which didn't +// end up using this yet, because it has a simpler design, not +// currently implementing priorities), or b) delete this and +// make the server code a bit more concrete. +type writeContext interface { + Framer() *Framer + Flush() error + CloseConn() error + // HeaderEncoder returns an HPACK encoder that writes to the + // returned buffer. + HeaderEncoder() (*hpack.Encoder, *bytes.Buffer) +} + +// endsStream reports whether the given frame writer w will locally +// close the stream. +func endsStream(w writeFramer) bool { + switch v := w.(type) { + case *writeData: + return v.endStream + case *writeResHeaders: + return v.endStream + case nil: + // This can only happen if the caller reuses w after it's + // been intentionally nil'ed out to prevent use. Keep this + // here to catch future refactoring breaking it. + panic("endsStream called on nil writeFramer") + } + return false +} + +type flushFrameWriter struct{} + +func (flushFrameWriter) writeFrame(ctx writeContext) error { + return ctx.Flush() +} + +type writeSettings []Setting + +func (s writeSettings) writeFrame(ctx writeContext) error { + return ctx.Framer().WriteSettings([]Setting(s)...) +} + +type writeGoAway struct { + maxStreamID uint32 + code ErrCode +} + +func (p *writeGoAway) writeFrame(ctx writeContext) error { + err := ctx.Framer().WriteGoAway(p.maxStreamID, p.code, nil) + if p.code != 0 { + ctx.Flush() // ignore error: we're hanging up on them anyway + time.Sleep(50 * time.Millisecond) + ctx.CloseConn() + } + return err +} + +type writeData struct { + streamID uint32 + p []byte + endStream bool +} + +func (w *writeData) String() string { + return fmt.Sprintf("writeData(stream=%d, p=%d, endStream=%v)", w.streamID, len(w.p), w.endStream) +} + +func (w *writeData) writeFrame(ctx writeContext) error { + return ctx.Framer().WriteData(w.streamID, w.endStream, w.p) +} + +// handlerPanicRST is the message sent from handler goroutines when +// the handler panics. +type handlerPanicRST struct { + StreamID uint32 +} + +func (hp handlerPanicRST) writeFrame(ctx writeContext) error { + return ctx.Framer().WriteRSTStream(hp.StreamID, ErrCodeInternal) +} + +func (se StreamError) writeFrame(ctx writeContext) error { + return ctx.Framer().WriteRSTStream(se.StreamID, se.Code) +} + +type writePingAck struct{ pf *PingFrame } + +func (w writePingAck) writeFrame(ctx writeContext) error { + return ctx.Framer().WritePing(true, w.pf.Data) +} + +type writeSettingsAck struct{} + +func (writeSettingsAck) writeFrame(ctx writeContext) error { + return ctx.Framer().WriteSettingsAck() +} + +// writeResHeaders is a request to write a HEADERS and 0+ CONTINUATION frames +// for HTTP response headers or trailers from a server handler. +type writeResHeaders struct { + streamID uint32 + httpResCode int // 0 means no ":status" line + h http.Header // may be nil + trailers []string // if non-nil, which keys of h to write. nil means all. + endStream bool + + date string + contentType string + contentLength string +} + +func encKV(enc *hpack.Encoder, k, v string) { + if VerboseLogs { + log.Printf("http2: server encoding header %q = %q", k, v) + } + enc.WriteField(hpack.HeaderField{Name: k, Value: v}) +} + +func (w *writeResHeaders) writeFrame(ctx writeContext) error { + enc, buf := ctx.HeaderEncoder() + buf.Reset() + + if w.httpResCode != 0 { + encKV(enc, ":status", httpCodeString(w.httpResCode)) + } + + encodeHeaders(enc, w.h, w.trailers) + + if w.contentType != "" { + encKV(enc, "content-type", w.contentType) + } + if w.contentLength != "" { + encKV(enc, "content-length", w.contentLength) + } + if w.date != "" { + encKV(enc, "date", w.date) + } + + headerBlock := buf.Bytes() + if len(headerBlock) == 0 && w.trailers == nil { + panic("unexpected empty hpack") + } + + // For now we're lazy and just pick the minimum MAX_FRAME_SIZE + // that all peers must support (16KB). Later we could care + // more and send larger frames if the peer advertised it, but + // there's little point. Most headers are small anyway (so we + // generally won't have CONTINUATION frames), and extra frames + // only waste 9 bytes anyway. + const maxFrameSize = 16384 + + first := true + for len(headerBlock) > 0 { + frag := headerBlock + if len(frag) > maxFrameSize { + frag = frag[:maxFrameSize] + } + headerBlock = headerBlock[len(frag):] + endHeaders := len(headerBlock) == 0 + var err error + if first { + first = false + err = ctx.Framer().WriteHeaders(HeadersFrameParam{ + StreamID: w.streamID, + BlockFragment: frag, + EndStream: w.endStream, + EndHeaders: endHeaders, + }) + } else { + err = ctx.Framer().WriteContinuation(w.streamID, endHeaders, frag) + } + if err != nil { + return err + } + } + return nil +} + +type write100ContinueHeadersFrame struct { + streamID uint32 +} + +func (w write100ContinueHeadersFrame) writeFrame(ctx writeContext) error { + enc, buf := ctx.HeaderEncoder() + buf.Reset() + encKV(enc, ":status", "100") + return ctx.Framer().WriteHeaders(HeadersFrameParam{ + StreamID: w.streamID, + BlockFragment: buf.Bytes(), + EndStream: false, + EndHeaders: true, + }) +} + +type writeWindowUpdate struct { + streamID uint32 // or 0 for conn-level + n uint32 +} + +func (wu writeWindowUpdate) writeFrame(ctx writeContext) error { + return ctx.Framer().WriteWindowUpdate(wu.streamID, wu.n) +} + +func encodeHeaders(enc *hpack.Encoder, h http.Header, keys []string) { + // TODO: garbage. pool sorters like http1? hot path for 1 key? + if keys == nil { + keys = make([]string, 0, len(h)) + for k := range h { + keys = append(keys, k) + } + sort.Strings(keys) + } + for _, k := range keys { + vv := h[k] + k = lowerHeader(k) + if !validHeaderFieldName(k) { + // TODO: return an error? golang.org/issue/14048 + // For now just omit it. + continue + } + isTE := k == "transfer-encoding" + for _, v := range vv { + if !validHeaderFieldValue(v) { + // TODO: return an error? golang.org/issue/14048 + // For now just omit it. + continue + } + // TODO: more of "8.1.2.2 Connection-Specific Header Fields" + if isTE && v != "trailers" { + continue + } + encKV(enc, k, v) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/writesched.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/writesched.go new file mode 100644 index 00000000..c24316ce --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/writesched.go @@ -0,0 +1,283 @@ +// 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. + +package http2 + +import "fmt" + +// frameWriteMsg is a request to write a frame. +type frameWriteMsg struct { + // write is the interface value that does the writing, once the + // writeScheduler (below) has decided to select this frame + // to write. The write functions are all defined in write.go. + write writeFramer + + stream *stream // used for prioritization. nil for non-stream frames. + + // done, if non-nil, must be a buffered channel with space for + // 1 message and is sent the return value from write (or an + // earlier error) when the frame has been written. + done chan error +} + +// for debugging only: +func (wm frameWriteMsg) String() string { + var streamID uint32 + if wm.stream != nil { + streamID = wm.stream.id + } + var des string + if s, ok := wm.write.(fmt.Stringer); ok { + des = s.String() + } else { + des = fmt.Sprintf("%T", wm.write) + } + return fmt.Sprintf("[frameWriteMsg stream=%d, ch=%v, type: %v]", streamID, wm.done != nil, des) +} + +// writeScheduler tracks pending frames to write, priorities, and decides +// the next one to use. It is not thread-safe. +type writeScheduler struct { + // zero are frames not associated with a specific stream. + // They're sent before any stream-specific freams. + zero writeQueue + + // maxFrameSize is the maximum size of a DATA frame + // we'll write. Must be non-zero and between 16K-16M. + maxFrameSize uint32 + + // sq contains the stream-specific queues, keyed by stream ID. + // when a stream is idle, it's deleted from the map. + sq map[uint32]*writeQueue + + // canSend is a slice of memory that's reused between frame + // scheduling decisions to hold the list of writeQueues (from sq) + // which have enough flow control data to send. After canSend is + // built, the best is selected. + canSend []*writeQueue + + // pool of empty queues for reuse. + queuePool []*writeQueue +} + +func (ws *writeScheduler) putEmptyQueue(q *writeQueue) { + if len(q.s) != 0 { + panic("queue must be empty") + } + ws.queuePool = append(ws.queuePool, q) +} + +func (ws *writeScheduler) getEmptyQueue() *writeQueue { + ln := len(ws.queuePool) + if ln == 0 { + return new(writeQueue) + } + q := ws.queuePool[ln-1] + ws.queuePool = ws.queuePool[:ln-1] + return q +} + +func (ws *writeScheduler) empty() bool { return ws.zero.empty() && len(ws.sq) == 0 } + +func (ws *writeScheduler) add(wm frameWriteMsg) { + st := wm.stream + if st == nil { + ws.zero.push(wm) + } else { + ws.streamQueue(st.id).push(wm) + } +} + +func (ws *writeScheduler) streamQueue(streamID uint32) *writeQueue { + if q, ok := ws.sq[streamID]; ok { + return q + } + if ws.sq == nil { + ws.sq = make(map[uint32]*writeQueue) + } + q := ws.getEmptyQueue() + ws.sq[streamID] = q + return q +} + +// take returns the most important frame to write and removes it from the scheduler. +// It is illegal to call this if the scheduler is empty or if there are no connection-level +// flow control bytes available. +func (ws *writeScheduler) take() (wm frameWriteMsg, ok bool) { + if ws.maxFrameSize == 0 { + panic("internal error: ws.maxFrameSize not initialized or invalid") + } + + // If there any frames not associated with streams, prefer those first. + // These are usually SETTINGS, etc. + if !ws.zero.empty() { + return ws.zero.shift(), true + } + if len(ws.sq) == 0 { + return + } + + // Next, prioritize frames on streams that aren't DATA frames (no cost). + for id, q := range ws.sq { + if q.firstIsNoCost() { + return ws.takeFrom(id, q) + } + } + + // Now, all that remains are DATA frames with non-zero bytes to + // send. So pick the best one. + if len(ws.canSend) != 0 { + panic("should be empty") + } + for _, q := range ws.sq { + if n := ws.streamWritableBytes(q); n > 0 { + ws.canSend = append(ws.canSend, q) + } + } + if len(ws.canSend) == 0 { + return + } + defer ws.zeroCanSend() + + // TODO: find the best queue + q := ws.canSend[0] + + return ws.takeFrom(q.streamID(), q) +} + +// zeroCanSend is defered from take. +func (ws *writeScheduler) zeroCanSend() { + for i := range ws.canSend { + ws.canSend[i] = nil + } + ws.canSend = ws.canSend[:0] +} + +// streamWritableBytes returns the number of DATA bytes we could write +// from the given queue's stream, if this stream/queue were +// selected. It is an error to call this if q's head isn't a +// *writeData. +func (ws *writeScheduler) streamWritableBytes(q *writeQueue) int32 { + wm := q.head() + ret := wm.stream.flow.available() // max we can write + if ret == 0 { + return 0 + } + if int32(ws.maxFrameSize) < ret { + ret = int32(ws.maxFrameSize) + } + if ret == 0 { + panic("internal error: ws.maxFrameSize not initialized or invalid") + } + wd := wm.write.(*writeData) + if len(wd.p) < int(ret) { + ret = int32(len(wd.p)) + } + return ret +} + +func (ws *writeScheduler) takeFrom(id uint32, q *writeQueue) (wm frameWriteMsg, ok bool) { + wm = q.head() + // If the first item in this queue costs flow control tokens + // and we don't have enough, write as much as we can. + if wd, ok := wm.write.(*writeData); ok && len(wd.p) > 0 { + allowed := wm.stream.flow.available() // max we can write + if allowed == 0 { + // No quota available. Caller can try the next stream. + return frameWriteMsg{}, false + } + if int32(ws.maxFrameSize) < allowed { + allowed = int32(ws.maxFrameSize) + } + // TODO: further restrict the allowed size, because even if + // the peer says it's okay to write 16MB data frames, we might + // want to write smaller ones to properly weight competing + // streams' priorities. + + if len(wd.p) > int(allowed) { + wm.stream.flow.take(allowed) + chunk := wd.p[:allowed] + wd.p = wd.p[allowed:] + // Make up a new write message of a valid size, rather + // than shifting one off the queue. + return frameWriteMsg{ + stream: wm.stream, + write: &writeData{ + streamID: wd.streamID, + p: chunk, + // even if the original had endStream set, there + // arebytes remaining because len(wd.p) > allowed, + // so we know endStream is false: + endStream: false, + }, + // our caller is blocking on the final DATA frame, not + // these intermediates, so no need to wait: + done: nil, + }, true + } + wm.stream.flow.take(int32(len(wd.p))) + } + + q.shift() + if q.empty() { + ws.putEmptyQueue(q) + delete(ws.sq, id) + } + return wm, true +} + +func (ws *writeScheduler) forgetStream(id uint32) { + q, ok := ws.sq[id] + if !ok { + return + } + delete(ws.sq, id) + + // But keep it for others later. + for i := range q.s { + q.s[i] = frameWriteMsg{} + } + q.s = q.s[:0] + ws.putEmptyQueue(q) +} + +type writeQueue struct { + s []frameWriteMsg +} + +// streamID returns the stream ID for a non-empty stream-specific queue. +func (q *writeQueue) streamID() uint32 { return q.s[0].stream.id } + +func (q *writeQueue) empty() bool { return len(q.s) == 0 } + +func (q *writeQueue) push(wm frameWriteMsg) { + q.s = append(q.s, wm) +} + +// head returns the next item that would be removed by shift. +func (q *writeQueue) head() frameWriteMsg { + if len(q.s) == 0 { + panic("invalid use of queue") + } + return q.s[0] +} + +func (q *writeQueue) shift() frameWriteMsg { + if len(q.s) == 0 { + panic("invalid use of queue") + } + wm := q.s[0] + // TODO: less copy-happy queue. + copy(q.s, q.s[1:]) + q.s[len(q.s)-1] = frameWriteMsg{} + q.s = q.s[:len(q.s)-1] + return wm +} + +func (q *writeQueue) firstIsNoCost() bool { + if df, ok := q.s[0].write.(*writeData); ok { + return len(df.p) == 0 + } + return true +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/z_spec_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/z_spec_test.go new file mode 100644 index 00000000..e0f420a1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/http2/z_spec_test.go @@ -0,0 +1,356 @@ +// 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. + +package http2 + +import ( + "bytes" + "encoding/xml" + "flag" + "fmt" + "io" + "os" + "reflect" + "regexp" + "sort" + "strconv" + "strings" + "sync" + "testing" +) + +var coverSpec = flag.Bool("coverspec", false, "Run spec coverage tests") + +// The global map of sentence coverage for the http2 spec. +var defaultSpecCoverage specCoverage + +var loadSpecOnce sync.Once + +func loadSpec() { + if f, err := os.Open("testdata/draft-ietf-httpbis-http2.xml"); err != nil { + panic(err) + } else { + defaultSpecCoverage = readSpecCov(f) + f.Close() + } +} + +// covers marks all sentences for section sec in defaultSpecCoverage. Sentences not +// "covered" will be included in report outputed by TestSpecCoverage. +func covers(sec, sentences string) { + loadSpecOnce.Do(loadSpec) + defaultSpecCoverage.cover(sec, sentences) +} + +type specPart struct { + section string + sentence string +} + +func (ss specPart) Less(oo specPart) bool { + atoi := func(s string) int { + n, err := strconv.Atoi(s) + if err != nil { + panic(err) + } + return n + } + a := strings.Split(ss.section, ".") + b := strings.Split(oo.section, ".") + for len(a) > 0 { + if len(b) == 0 { + return false + } + x, y := atoi(a[0]), atoi(b[0]) + if x == y { + a, b = a[1:], b[1:] + continue + } + return x < y + } + if len(b) > 0 { + return true + } + return false +} + +type bySpecSection []specPart + +func (a bySpecSection) Len() int { return len(a) } +func (a bySpecSection) Less(i, j int) bool { return a[i].Less(a[j]) } +func (a bySpecSection) Swap(i, j int) { a[i], a[j] = a[j], a[i] } + +type specCoverage struct { + coverage map[specPart]bool + d *xml.Decoder +} + +func joinSection(sec []int) string { + s := fmt.Sprintf("%d", sec[0]) + for _, n := range sec[1:] { + s = fmt.Sprintf("%s.%d", s, n) + } + return s +} + +func (sc specCoverage) readSection(sec []int) { + var ( + buf = new(bytes.Buffer) + sub = 0 + ) + for { + tk, err := sc.d.Token() + if err != nil { + if err == io.EOF { + return + } + panic(err) + } + switch v := tk.(type) { + case xml.StartElement: + if skipElement(v) { + if err := sc.d.Skip(); err != nil { + panic(err) + } + if v.Name.Local == "section" { + sub++ + } + break + } + switch v.Name.Local { + case "section": + sub++ + sc.readSection(append(sec, sub)) + case "xref": + buf.Write(sc.readXRef(v)) + } + case xml.CharData: + if len(sec) == 0 { + break + } + buf.Write(v) + case xml.EndElement: + if v.Name.Local == "section" { + sc.addSentences(joinSection(sec), buf.String()) + return + } + } + } +} + +func (sc specCoverage) readXRef(se xml.StartElement) []byte { + var b []byte + for { + tk, err := sc.d.Token() + if err != nil { + panic(err) + } + switch v := tk.(type) { + case xml.CharData: + if b != nil { + panic("unexpected CharData") + } + b = []byte(string(v)) + case xml.EndElement: + if v.Name.Local != "xref" { + panic("expected ") + } + if b != nil { + return b + } + sig := attrSig(se) + switch sig { + case "target": + return []byte(fmt.Sprintf("[%s]", attrValue(se, "target"))) + case "fmt-of,rel,target", "fmt-,,rel,target": + return []byte(fmt.Sprintf("[%s, %s]", attrValue(se, "target"), attrValue(se, "rel"))) + case "fmt-of,sec,target", "fmt-,,sec,target": + return []byte(fmt.Sprintf("[section %s of %s]", attrValue(se, "sec"), attrValue(se, "target"))) + case "fmt-of,rel,sec,target": + return []byte(fmt.Sprintf("[section %s of %s, %s]", attrValue(se, "sec"), attrValue(se, "target"), attrValue(se, "rel"))) + default: + panic(fmt.Sprintf("unknown attribute signature %q in %#v", sig, fmt.Sprintf("%#v", se))) + } + default: + panic(fmt.Sprintf("unexpected tag %q", v)) + } + } +} + +var skipAnchor = map[string]bool{ + "intro": true, + "Overview": true, +} + +var skipTitle = map[string]bool{ + "Acknowledgements": true, + "Change Log": true, + "Document Organization": true, + "Conventions and Terminology": true, +} + +func skipElement(s xml.StartElement) bool { + switch s.Name.Local { + case "artwork": + return true + case "section": + for _, attr := range s.Attr { + switch attr.Name.Local { + case "anchor": + if skipAnchor[attr.Value] || strings.HasPrefix(attr.Value, "changes.since.") { + return true + } + case "title": + if skipTitle[attr.Value] { + return true + } + } + } + } + return false +} + +func readSpecCov(r io.Reader) specCoverage { + sc := specCoverage{ + coverage: map[specPart]bool{}, + d: xml.NewDecoder(r)} + sc.readSection(nil) + return sc +} + +func (sc specCoverage) addSentences(sec string, sentence string) { + for _, s := range parseSentences(sentence) { + sc.coverage[specPart{sec, s}] = false + } +} + +func (sc specCoverage) cover(sec string, sentence string) { + for _, s := range parseSentences(sentence) { + p := specPart{sec, s} + if _, ok := sc.coverage[p]; !ok { + panic(fmt.Sprintf("Not found in spec: %q, %q", sec, s)) + } + sc.coverage[specPart{sec, s}] = true + } + +} + +var whitespaceRx = regexp.MustCompile(`\s+`) + +func parseSentences(sens string) []string { + sens = strings.TrimSpace(sens) + if sens == "" { + return nil + } + ss := strings.Split(whitespaceRx.ReplaceAllString(sens, " "), ". ") + for i, s := range ss { + s = strings.TrimSpace(s) + if !strings.HasSuffix(s, ".") { + s += "." + } + ss[i] = s + } + return ss +} + +func TestSpecParseSentences(t *testing.T) { + tests := []struct { + ss string + want []string + }{ + {"Sentence 1. Sentence 2.", + []string{ + "Sentence 1.", + "Sentence 2.", + }}, + {"Sentence 1. \nSentence 2.\tSentence 3.", + []string{ + "Sentence 1.", + "Sentence 2.", + "Sentence 3.", + }}, + } + + for i, tt := range tests { + got := parseSentences(tt.ss) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("%d: got = %q, want %q", i, got, tt.want) + } + } +} + +func TestSpecCoverage(t *testing.T) { + if !*coverSpec { + t.Skip() + } + + loadSpecOnce.Do(loadSpec) + + var ( + list []specPart + cv = defaultSpecCoverage.coverage + total = len(cv) + complete = 0 + ) + + for sp, touched := range defaultSpecCoverage.coverage { + if touched { + complete++ + } else { + list = append(list, sp) + } + } + sort.Stable(bySpecSection(list)) + + if testing.Short() && len(list) > 5 { + list = list[:5] + } + + for _, p := range list { + t.Errorf("\tSECTION %s: %s", p.section, p.sentence) + } + + t.Logf("%d/%d (%d%%) sentances covered", complete, total, (complete/total)*100) +} + +func attrSig(se xml.StartElement) string { + var names []string + for _, attr := range se.Attr { + if attr.Name.Local == "fmt" { + names = append(names, "fmt-"+attr.Value) + } else { + names = append(names, attr.Name.Local) + } + } + sort.Strings(names) + return strings.Join(names, ",") +} + +func attrValue(se xml.StartElement, attr string) string { + for _, a := range se.Attr { + if a.Name.Local == attr { + return a.Value + } + } + panic("unknown attribute " + attr) +} + +func TestSpecPartLess(t *testing.T) { + tests := []struct { + sec1, sec2 string + want bool + }{ + {"6.2.1", "6.2", false}, + {"6.2", "6.2.1", true}, + {"6.10", "6.10.1", true}, + {"6.10", "6.1.1", false}, // 10, not 1 + {"6.1", "6.1", false}, // equal, so not less + } + for _, tt := range tests { + got := (specPart{tt.sec1, "foo"}).Less(specPart{tt.sec2, "foo"}) + if got != tt.want { + t.Errorf("Less(%q, %q) = %v; want %v", tt.sec1, tt.sec2, got, tt.want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/dstunreach.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/dstunreach.go new file mode 100644 index 00000000..75db991d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/dstunreach.go @@ -0,0 +1,41 @@ +// 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. + +package icmp + +// A DstUnreach represents an ICMP destination unreachable message +// body. +type DstUnreach struct { + Data []byte // data, known as original datagram field + Extensions []Extension // extensions +} + +// Len implements the Len method of MessageBody interface. +func (p *DstUnreach) Len(proto int) int { + if p == nil { + return 0 + } + l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions) + return 4 + l +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *DstUnreach) Marshal(proto int) ([]byte, error) { + return marshalMultipartMessageBody(proto, p.Data, p.Extensions) +} + +// parseDstUnreach parses b as an ICMP destination unreachable message +// body. +func parseDstUnreach(proto int, b []byte) (MessageBody, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + p := &DstUnreach{} + var err error + p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b) + if err != nil { + return nil, err + } + return p, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/echo.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/echo.go new file mode 100644 index 00000000..8943eab3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/echo.go @@ -0,0 +1,43 @@ +// 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 icmp + +// An Echo represents an ICMP echo request or reply message body. +type Echo struct { + ID int // identifier + Seq int // sequence number + Data []byte // data +} + +// Len implements the Len method of MessageBody interface. +func (p *Echo) Len(proto int) int { + if p == nil { + return 0 + } + return 4 + len(p.Data) +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *Echo) Marshal(proto int) ([]byte, error) { + b := make([]byte, 4+len(p.Data)) + b[0], b[1] = byte(p.ID>>8), byte(p.ID) + b[2], b[3] = byte(p.Seq>>8), byte(p.Seq) + copy(b[4:], p.Data) + return b, nil +} + +// parseEcho parses b as an ICMP echo request or reply message body. +func parseEcho(proto int, b []byte) (MessageBody, error) { + bodyLen := len(b) + if bodyLen < 4 { + return nil, errMessageTooShort + } + p := &Echo{ID: int(b[0])<<8 | int(b[1]), Seq: int(b[2])<<8 | int(b[3])} + if bodyLen > 4 { + p.Data = make([]byte, bodyLen-4) + copy(p.Data, b[4:]) + } + return p, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/endpoint.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/endpoint.go new file mode 100644 index 00000000..0213d1a1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/endpoint.go @@ -0,0 +1,113 @@ +// 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. + +package icmp + +import ( + "net" + "runtime" + "syscall" + "time" + + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +var _ net.PacketConn = &PacketConn{} + +// A PacketConn represents a packet network endpoint that uses either +// ICMPv4 or ICMPv6. +type PacketConn struct { + c net.PacketConn + p4 *ipv4.PacketConn + p6 *ipv6.PacketConn +} + +func (c *PacketConn) ok() bool { return c != nil && c.c != nil } + +// IPv4PacketConn returns the ipv4.PacketConn of c. +// It returns nil when c is not created as the endpoint for ICMPv4. +func (c *PacketConn) IPv4PacketConn() *ipv4.PacketConn { + if !c.ok() { + return nil + } + return c.p4 +} + +// IPv6PacketConn returns the ipv6.PacketConn of c. +// It returns nil when c is not created as the endpoint for ICMPv6. +func (c *PacketConn) IPv6PacketConn() *ipv6.PacketConn { + if !c.ok() { + return nil + } + return c.p6 +} + +// ReadFrom reads an ICMP message from the connection. +func (c *PacketConn) ReadFrom(b []byte) (int, net.Addr, error) { + if !c.ok() { + return 0, nil, syscall.EINVAL + } + // Please be informed that ipv4.NewPacketConn enables + // IP_STRIPHDR option by default on Darwin. + // See golang.org/issue/9395 for futher information. + if runtime.GOOS == "darwin" && c.p4 != nil { + n, _, peer, err := c.p4.ReadFrom(b) + return n, peer, err + } + return c.c.ReadFrom(b) +} + +// WriteTo writes the ICMP message b to dst. +// Dst must be net.UDPAddr when c is a non-privileged +// datagram-oriented ICMP endpoint. Otherwise it must be net.IPAddr. +func (c *PacketConn) WriteTo(b []byte, dst net.Addr) (int, error) { + if !c.ok() { + return 0, syscall.EINVAL + } + return c.c.WriteTo(b, dst) +} + +// Close closes the endpoint. +func (c *PacketConn) Close() error { + if !c.ok() { + return syscall.EINVAL + } + return c.c.Close() +} + +// LocalAddr returns the local network address. +func (c *PacketConn) LocalAddr() net.Addr { + if !c.ok() { + return nil + } + return c.c.LocalAddr() +} + +// SetDeadline sets the read and write deadlines associated with the +// endpoint. +func (c *PacketConn) SetDeadline(t time.Time) error { + if !c.ok() { + return syscall.EINVAL + } + return c.c.SetDeadline(t) +} + +// SetReadDeadline sets the read deadline associated with the +// endpoint. +func (c *PacketConn) SetReadDeadline(t time.Time) error { + if !c.ok() { + return syscall.EINVAL + } + return c.c.SetReadDeadline(t) +} + +// SetWriteDeadline sets the write deadline associated with the +// endpoint. +func (c *PacketConn) SetWriteDeadline(t time.Time) error { + if !c.ok() { + return syscall.EINVAL + } + return c.c.SetWriteDeadline(t) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/example_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/example_test.go new file mode 100644 index 00000000..1df4cecc --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/example_test.go @@ -0,0 +1,63 @@ +// 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. + +package icmp_test + +import ( + "log" + "net" + "os" + "runtime" + + "golang.org/x/net/icmp" + "golang.org/x/net/ipv6" +) + +func ExamplePacketConn_nonPrivilegedPing() { + switch runtime.GOOS { + case "darwin": + case "linux": + log.Println("you may need to adjust the net.ipv4.ping_group_range kernel state") + default: + log.Println("not supported on", runtime.GOOS) + return + } + + c, err := icmp.ListenPacket("udp6", "fe80::1%en0") + if err != nil { + log.Fatal(err) + } + defer c.Close() + + wm := icmp.Message{ + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: 1, + Data: []byte("HELLO-R-U-THERE"), + }, + } + wb, err := wm.Marshal(nil) + if err != nil { + log.Fatal(err) + } + if _, err := c.WriteTo(wb, &net.UDPAddr{IP: net.ParseIP("ff02::1"), Zone: "en0"}); err != nil { + log.Fatal(err) + } + + rb := make([]byte, 1500) + n, peer, err := c.ReadFrom(rb) + if err != nil { + log.Fatal(err) + } + rm, err := icmp.ParseMessage(58, rb[:n]) + if err != nil { + log.Fatal(err) + } + switch rm.Type { + case ipv6.ICMPTypeEchoReply: + log.Printf("got reflection from %v", peer) + default: + log.Printf("got %+v; want echo reply", rm) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/extension.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/extension.go new file mode 100644 index 00000000..b47529b1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/extension.go @@ -0,0 +1,87 @@ +// 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 icmp + +// An Extension represents an ICMP extension. +type Extension interface { + // Len returns the length of ICMP extension. + // Proto must be either the ICMPv4 or ICMPv6 protocol number. + Len(proto int) int + + // Marshal returns the binary encoding of ICMP extension. + // Proto must be either the ICMPv4 or ICMPv6 protocol number. + Marshal(proto int) ([]byte, error) +} + +const extensionVersion = 2 + +func validExtensionHeader(b []byte) bool { + v := int(b[0]&0xf0) >> 4 + s := uint16(b[2])<<8 | uint16(b[3]) + if s != 0 { + s = checksum(b) + } + if v != extensionVersion || s != 0 { + return false + } + return true +} + +// parseExtensions parses b as a list of ICMP extensions. +// The length attribute l must be the length attribute field in +// received icmp messages. +// +// It will return a list of ICMP extensions and an adjusted length +// attribute that represents the length of the padded original +// datagram field. Otherwise, it returns an error. +func parseExtensions(b []byte, l int) ([]Extension, int, error) { + // Still a lot of non-RFC 4884 compliant implementations are + // out there. Set the length attribute l to 128 when it looks + // inappropriate for backwards compatibility. + // + // A minimal extension at least requires 8 octets; 4 octets + // for an extension header, and 4 octets for a single object + // header. + // + // See RFC 4884 for further information. + if 128 > l || l+8 > len(b) { + l = 128 + } + if l+8 > len(b) { + return nil, -1, errNoExtension + } + if !validExtensionHeader(b[l:]) { + if l == 128 { + return nil, -1, errNoExtension + } + l = 128 + if !validExtensionHeader(b[l:]) { + return nil, -1, errNoExtension + } + } + var exts []Extension + for b = b[l+4:]; len(b) >= 4; { + ol := int(b[0])<<8 | int(b[1]) + if 4 > ol || ol > len(b) { + break + } + switch b[2] { + case classMPLSLabelStack: + ext, err := parseMPLSLabelStack(b[:ol]) + if err != nil { + return nil, -1, err + } + exts = append(exts, ext) + case classInterfaceInfo: + ext, err := parseInterfaceInfo(b[:ol]) + if err != nil { + return nil, -1, err + } + exts = append(exts, ext) + } + b = b[ol:] + } + return exts, l, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/extension_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/extension_test.go new file mode 100644 index 00000000..0b3f7b9e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/extension_test.go @@ -0,0 +1,259 @@ +// 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 icmp + +import ( + "net" + "reflect" + "testing" + + "golang.org/x/net/internal/iana" +) + +var marshalAndParseExtensionTests = []struct { + proto int + hdr []byte + obj []byte + exts []Extension +}{ + // MPLS label stack with no label + { + proto: iana.ProtocolICMP, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x04, 0x01, 0x01, + }, + exts: []Extension{ + &MPLSLabelStack{ + Class: classMPLSLabelStack, + Type: typeIncomingMPLSLabelStack, + }, + }, + }, + // MPLS label stack with a single label + { + proto: iana.ProtocolIPv6ICMP, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x08, 0x01, 0x01, + 0x03, 0xe8, 0xe9, 0xff, + }, + exts: []Extension{ + &MPLSLabelStack{ + Class: classMPLSLabelStack, + Type: typeIncomingMPLSLabelStack, + Labels: []MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + }, + }, + // MPLS label stack with multiple labels + { + proto: iana.ProtocolICMP, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x0c, 0x01, 0x01, + 0x03, 0xe8, 0xde, 0xfe, + 0x03, 0xe8, 0xe1, 0xff, + }, + exts: []Extension{ + &MPLSLabelStack{ + Class: classMPLSLabelStack, + Type: typeIncomingMPLSLabelStack, + Labels: []MPLSLabel{ + { + Label: 16013, + TC: 0x7, + S: false, + TTL: 254, + }, + { + Label: 16014, + TC: 0, + S: true, + TTL: 255, + }, + }, + }, + }, + }, + // Interface information with no attribute + { + proto: iana.ProtocolICMP, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x04, 0x02, 0x00, + }, + exts: []Extension{ + &InterfaceInfo{ + Class: classInterfaceInfo, + }, + }, + }, + // Interface information with ifIndex and name + { + proto: iana.ProtocolICMP, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x10, 0x02, 0x0a, + 0x00, 0x00, 0x00, 0x10, + 0x08, byte('e'), byte('n'), byte('1'), + byte('0'), byte('1'), 0x00, 0x00, + }, + exts: []Extension{ + &InterfaceInfo{ + Class: classInterfaceInfo, + Type: 0x0a, + Interface: &net.Interface{ + Index: 16, + Name: "en101", + }, + }, + }, + }, + // Interface information with ifIndex, IPAddr, name and MTU + { + proto: iana.ProtocolIPv6ICMP, + hdr: []byte{ + 0x20, 0x00, 0x00, 0x00, + }, + obj: []byte{ + 0x00, 0x28, 0x02, 0x0f, + 0x00, 0x00, 0x00, 0x0f, + 0x00, 0x02, 0x00, 0x00, + 0xfe, 0x80, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x08, byte('e'), byte('n'), byte('1'), + byte('0'), byte('1'), 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, + }, + exts: []Extension{ + &InterfaceInfo{ + Class: classInterfaceInfo, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en101", + }, + }, + }, + }, +} + +func TestMarshalAndParseExtension(t *testing.T) { + for i, tt := range marshalAndParseExtensionTests { + for j, ext := range tt.exts { + var err error + var b []byte + switch ext := ext.(type) { + case *MPLSLabelStack: + b, err = ext.Marshal(tt.proto) + if err != nil { + t.Errorf("#%v/%v: %v", i, j, err) + continue + } + case *InterfaceInfo: + b, err = ext.Marshal(tt.proto) + if err != nil { + t.Errorf("#%v/%v: %v", i, j, err) + continue + } + } + if !reflect.DeepEqual(b, tt.obj) { + t.Errorf("#%v/%v: got %#v; want %#v", i, j, b, tt.obj) + continue + } + } + + for j, wire := range []struct { + data []byte // original datagram + inlattr int // length of padded original datagram, a hint + outlattr int // length of padded original datagram, a want + err error + }{ + {nil, 0, -1, errNoExtension}, + {make([]byte, 127), 128, -1, errNoExtension}, + + {make([]byte, 128), 127, -1, errNoExtension}, + {make([]byte, 128), 128, -1, errNoExtension}, + {make([]byte, 128), 129, -1, errNoExtension}, + + {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 127, 128, nil}, + {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 128, 128, nil}, + {append(make([]byte, 128), append(tt.hdr, tt.obj...)...), 129, 128, nil}, + + {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 511, -1, errNoExtension}, + {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 512, 512, nil}, + {append(make([]byte, 512), append(tt.hdr, tt.obj...)...), 513, -1, errNoExtension}, + } { + exts, l, err := parseExtensions(wire.data, wire.inlattr) + if err != wire.err { + t.Errorf("#%v/%v: got %v; want %v", i, j, err, wire.err) + continue + } + if wire.err != nil { + continue + } + if l != wire.outlattr { + t.Errorf("#%v/%v: got %v; want %v", i, j, l, wire.outlattr) + } + if !reflect.DeepEqual(exts, tt.exts) { + for j, ext := range exts { + switch ext := ext.(type) { + case *MPLSLabelStack: + want := tt.exts[j].(*MPLSLabelStack) + t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want) + case *InterfaceInfo: + want := tt.exts[j].(*InterfaceInfo) + t.Errorf("#%v/%v: got %#v; want %#v", i, j, ext, want) + } + } + continue + } + } + } +} + +var parseInterfaceNameTests = []struct { + b []byte + error +}{ + {[]byte{0, 'e', 'n', '0'}, errInvalidExtension}, + {[]byte{4, 'e', 'n', '0'}, nil}, + {[]byte{7, 'e', 'n', '0', 0xff, 0xff, 0xff, 0xff}, errInvalidExtension}, + {[]byte{8, 'e', 'n', '0', 0xff, 0xff, 0xff}, errMessageTooShort}, +} + +func TestParseInterfaceName(t *testing.T) { + ifi := InterfaceInfo{Interface: &net.Interface{}} + for i, tt := range parseInterfaceNameTests { + if _, err := ifi.parseName(tt.b); err != tt.error { + t.Errorf("#%d: got %v; want %v", i, err, tt.error) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/helper_posix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/helper_posix.go new file mode 100644 index 00000000..398fd388 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/helper_posix.go @@ -0,0 +1,75 @@ +// 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. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows + +package icmp + +import ( + "net" + "strconv" + "syscall" +) + +func sockaddr(family int, address string) (syscall.Sockaddr, error) { + switch family { + case syscall.AF_INET: + a, err := net.ResolveIPAddr("ip4", address) + if err != nil { + return nil, err + } + if len(a.IP) == 0 { + a.IP = net.IPv4zero + } + if a.IP = a.IP.To4(); a.IP == nil { + return nil, net.InvalidAddrError("non-ipv4 address") + } + sa := &syscall.SockaddrInet4{} + copy(sa.Addr[:], a.IP) + return sa, nil + case syscall.AF_INET6: + a, err := net.ResolveIPAddr("ip6", address) + if err != nil { + return nil, err + } + if len(a.IP) == 0 { + a.IP = net.IPv6unspecified + } + if a.IP.Equal(net.IPv4zero) { + a.IP = net.IPv6unspecified + } + if a.IP = a.IP.To16(); a.IP == nil || a.IP.To4() != nil { + return nil, net.InvalidAddrError("non-ipv6 address") + } + sa := &syscall.SockaddrInet6{ZoneId: zoneToUint32(a.Zone)} + copy(sa.Addr[:], a.IP) + return sa, nil + default: + return nil, net.InvalidAddrError("unexpected family") + } +} + +func zoneToUint32(zone string) uint32 { + if zone == "" { + return 0 + } + if ifi, err := net.InterfaceByName(zone); err == nil { + return uint32(ifi.Index) + } + n, err := strconv.Atoi(zone) + if err != nil { + return 0 + } + return uint32(n) +} + +func last(s string, b byte) int { + i := len(s) + for i--; i >= 0; i-- { + if s[i] == b { + break + } + } + return i +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/interface.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/interface.go new file mode 100644 index 00000000..c7bf8dd1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/interface.go @@ -0,0 +1,235 @@ +// 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 icmp + +import ( + "net" + "strings" + + "golang.org/x/net/internal/iana" +) + +const ( + classInterfaceInfo = 2 + + afiIPv4 = 1 + afiIPv6 = 2 +) + +const ( + attrMTU = 1 << iota + attrName + attrIPAddr + attrIfIndex +) + +// An InterfaceInfo represents interface and next-hop identification. +type InterfaceInfo struct { + Class int // extension object class number + Type int // extension object sub-type + Interface *net.Interface + Addr *net.IPAddr +} + +func (ifi *InterfaceInfo) nameLen() int { + if len(ifi.Interface.Name) > 63 { + return 64 + } + l := 1 + len(ifi.Interface.Name) + return (l + 3) &^ 3 +} + +func (ifi *InterfaceInfo) attrsAndLen(proto int) (attrs, l int) { + l = 4 + if ifi.Interface != nil && ifi.Interface.Index > 0 { + attrs |= attrIfIndex + l += 4 + if len(ifi.Interface.Name) > 0 { + attrs |= attrName + l += ifi.nameLen() + } + if ifi.Interface.MTU > 0 { + attrs |= attrMTU + l += 4 + } + } + if ifi.Addr != nil { + switch proto { + case iana.ProtocolICMP: + if ifi.Addr.IP.To4() != nil { + attrs |= attrIPAddr + l += 4 + net.IPv4len + } + case iana.ProtocolIPv6ICMP: + if ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil { + attrs |= attrIPAddr + l += 4 + net.IPv6len + } + } + } + return +} + +// Len implements the Len method of Extension interface. +func (ifi *InterfaceInfo) Len(proto int) int { + _, l := ifi.attrsAndLen(proto) + return l +} + +// Marshal implements the Marshal method of Extension interface. +func (ifi *InterfaceInfo) Marshal(proto int) ([]byte, error) { + attrs, l := ifi.attrsAndLen(proto) + b := make([]byte, l) + if err := ifi.marshal(proto, b, attrs, l); err != nil { + return nil, err + } + return b, nil +} + +func (ifi *InterfaceInfo) marshal(proto int, b []byte, attrs, l int) error { + b[0], b[1] = byte(l>>8), byte(l) + b[2], b[3] = classInterfaceInfo, byte(ifi.Type) + for b = b[4:]; len(b) > 0 && attrs != 0; { + switch { + case attrs&attrIfIndex != 0: + b = ifi.marshalIfIndex(proto, b) + attrs &^= attrIfIndex + case attrs&attrIPAddr != 0: + b = ifi.marshalIPAddr(proto, b) + attrs &^= attrIPAddr + case attrs&attrName != 0: + b = ifi.marshalName(proto, b) + attrs &^= attrName + case attrs&attrMTU != 0: + b = ifi.marshalMTU(proto, b) + attrs &^= attrMTU + } + } + return nil +} + +func (ifi *InterfaceInfo) marshalIfIndex(proto int, b []byte) []byte { + b[0], b[1], b[2], b[3] = byte(ifi.Interface.Index>>24), byte(ifi.Interface.Index>>16), byte(ifi.Interface.Index>>8), byte(ifi.Interface.Index) + return b[4:] +} + +func (ifi *InterfaceInfo) parseIfIndex(b []byte) ([]byte, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + ifi.Interface.Index = int(b[0])<<24 | int(b[1])<<16 | int(b[2])<<8 | int(b[3]) + return b[4:], nil +} + +func (ifi *InterfaceInfo) marshalIPAddr(proto int, b []byte) []byte { + switch proto { + case iana.ProtocolICMP: + b[0], b[1] = byte(afiIPv4>>8), byte(afiIPv4) + copy(b[4:4+net.IPv4len], ifi.Addr.IP.To4()) + b = b[4+net.IPv4len:] + case iana.ProtocolIPv6ICMP: + b[0], b[1] = byte(afiIPv6>>8), byte(afiIPv6) + copy(b[4:4+net.IPv6len], ifi.Addr.IP.To16()) + b = b[4+net.IPv6len:] + } + return b +} + +func (ifi *InterfaceInfo) parseIPAddr(b []byte) ([]byte, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + afi := int(b[0])<<8 | int(b[1]) + b = b[4:] + switch afi { + case afiIPv4: + if len(b) < net.IPv4len { + return nil, errMessageTooShort + } + ifi.Addr.IP = make(net.IP, net.IPv4len) + copy(ifi.Addr.IP, b[:net.IPv4len]) + b = b[net.IPv4len:] + case afiIPv6: + if len(b) < net.IPv6len { + return nil, errMessageTooShort + } + ifi.Addr.IP = make(net.IP, net.IPv6len) + copy(ifi.Addr.IP, b[:net.IPv6len]) + b = b[net.IPv6len:] + } + return b, nil +} + +func (ifi *InterfaceInfo) marshalName(proto int, b []byte) []byte { + l := byte(ifi.nameLen()) + b[0] = l + copy(b[1:], []byte(ifi.Interface.Name)) + return b[l:] +} + +func (ifi *InterfaceInfo) parseName(b []byte) ([]byte, error) { + if 4 > len(b) || len(b) < int(b[0]) { + return nil, errMessageTooShort + } + l := int(b[0]) + if l%4 != 0 || 4 > l || l > 64 { + return nil, errInvalidExtension + } + var name [63]byte + copy(name[:], b[1:l]) + ifi.Interface.Name = strings.Trim(string(name[:]), "\000") + return b[l:], nil +} + +func (ifi *InterfaceInfo) marshalMTU(proto int, b []byte) []byte { + b[0], b[1], b[2], b[3] = byte(ifi.Interface.MTU>>24), byte(ifi.Interface.MTU>>16), byte(ifi.Interface.MTU>>8), byte(ifi.Interface.MTU) + return b[4:] +} + +func (ifi *InterfaceInfo) parseMTU(b []byte) ([]byte, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + ifi.Interface.MTU = int(b[0])<<24 | int(b[1])<<16 | int(b[2])<<8 | int(b[3]) + return b[4:], nil +} + +func parseInterfaceInfo(b []byte) (Extension, error) { + ifi := &InterfaceInfo{ + Class: int(b[2]), + Type: int(b[3]), + } + if ifi.Type&(attrIfIndex|attrName|attrMTU) != 0 { + ifi.Interface = &net.Interface{} + } + if ifi.Type&attrIPAddr != 0 { + ifi.Addr = &net.IPAddr{} + } + attrs := ifi.Type & (attrIfIndex | attrIPAddr | attrName | attrMTU) + for b = b[4:]; len(b) > 0 && attrs != 0; { + var err error + switch { + case attrs&attrIfIndex != 0: + b, err = ifi.parseIfIndex(b) + attrs &^= attrIfIndex + case attrs&attrIPAddr != 0: + b, err = ifi.parseIPAddr(b) + attrs &^= attrIPAddr + case attrs&attrName != 0: + b, err = ifi.parseName(b) + attrs &^= attrName + case attrs&attrMTU != 0: + b, err = ifi.parseMTU(b) + attrs &^= attrMTU + } + if err != nil { + return nil, err + } + } + if ifi.Interface != nil && ifi.Interface.Name != "" && ifi.Addr != nil && ifi.Addr.IP.To16() != nil && ifi.Addr.IP.To4() == nil { + ifi.Addr.Zone = ifi.Interface.Name + } + return ifi, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv4.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv4.go new file mode 100644 index 00000000..a252d730 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv4.go @@ -0,0 +1,61 @@ +// 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. + +package icmp + +import ( + "net" + "runtime" + "unsafe" + + "golang.org/x/net/ipv4" +) + +// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html. +var freebsdVersion uint32 + +// ParseIPv4Header parses b as an IPv4 header of ICMP error message +// invoking packet, which is contained in ICMP error message. +func ParseIPv4Header(b []byte) (*ipv4.Header, error) { + if len(b) < ipv4.HeaderLen { + return nil, errHeaderTooShort + } + hdrlen := int(b[0]&0x0f) << 2 + if hdrlen > len(b) { + return nil, errBufferTooShort + } + h := &ipv4.Header{ + Version: int(b[0] >> 4), + Len: hdrlen, + TOS: int(b[1]), + ID: int(b[4])<<8 | int(b[5]), + FragOff: int(b[6])<<8 | int(b[7]), + TTL: int(b[8]), + Protocol: int(b[9]), + Checksum: int(b[10])<<8 | int(b[11]), + Src: net.IPv4(b[12], b[13], b[14], b[15]), + Dst: net.IPv4(b[16], b[17], b[18], b[19]), + } + switch runtime.GOOS { + case "darwin": + // TODO(mikio): fix potential misaligned memory access + h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0]))) + case "freebsd": + if freebsdVersion >= 1000000 { + h.TotalLen = int(b[2])<<8 | int(b[3]) + } else { + // TODO(mikio): fix potential misaligned memory access + h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0]))) + } + default: + h.TotalLen = int(b[2])<<8 | int(b[3]) + } + h.Flags = ipv4.HeaderFlags(h.FragOff&0xe000) >> 13 + h.FragOff = h.FragOff & 0x1fff + if hdrlen-ipv4.HeaderLen > 0 { + h.Options = make([]byte, hdrlen-ipv4.HeaderLen) + copy(h.Options, b[ipv4.HeaderLen:]) + } + return h, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv4_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv4_test.go new file mode 100644 index 00000000..b05c6973 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv4_test.go @@ -0,0 +1,71 @@ +// 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. + +package icmp + +import ( + "net" + "reflect" + "runtime" + "testing" + + "golang.org/x/net/ipv4" +) + +var ( + wireHeaderFromKernel = [ipv4.HeaderLen]byte{ + 0x45, 0x01, 0xbe, 0xef, + 0xca, 0xfe, 0x45, 0xdc, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + wireHeaderFromTradBSDKernel = [ipv4.HeaderLen]byte{ + 0x45, 0x01, 0xef, 0xbe, + 0xca, 0xfe, 0x45, 0xdc, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + // TODO(mikio): Add platform dependent wire header formats when + // we support new platforms. + + testHeader = &ipv4.Header{ + Version: ipv4.Version, + Len: ipv4.HeaderLen, + TOS: 1, + TotalLen: 0xbeef, + ID: 0xcafe, + Flags: ipv4.DontFragment, + FragOff: 1500, + TTL: 255, + Protocol: 1, + Checksum: 0xdead, + Src: net.IPv4(172, 16, 254, 254), + Dst: net.IPv4(192, 168, 0, 1), + } +) + +func TestParseIPv4Header(t *testing.T) { + var wh []byte + switch runtime.GOOS { + case "darwin": + wh = wireHeaderFromTradBSDKernel[:] + case "freebsd": + if freebsdVersion >= 1000000 { + wh = wireHeaderFromKernel[:] + } else { + wh = wireHeaderFromTradBSDKernel[:] + } + default: + wh = wireHeaderFromKernel[:] + } + h, err := ParseIPv4Header(wh) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(h, testHeader) { + t.Fatalf("got %#v; want %#v", h, testHeader) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv6.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv6.go new file mode 100644 index 00000000..58eaa77d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ipv6.go @@ -0,0 +1,23 @@ +// 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 icmp + +import ( + "net" + + "golang.org/x/net/internal/iana" +) + +const ipv6PseudoHeaderLen = 2*net.IPv6len + 8 + +// IPv6PseudoHeader returns an IPv6 pseudo header for checksum +// calculation. +func IPv6PseudoHeader(src, dst net.IP) []byte { + b := make([]byte, ipv6PseudoHeaderLen) + copy(b, src.To16()) + copy(b[net.IPv6len:], dst.To16()) + b[len(b)-1] = byte(iana.ProtocolIPv6ICMP) + return b +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/listen_posix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/listen_posix.go new file mode 100644 index 00000000..b9f26079 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/listen_posix.go @@ -0,0 +1,98 @@ +// 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. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows + +package icmp + +import ( + "net" + "os" + "runtime" + "syscall" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +const sysIP_STRIPHDR = 0x17 // for now only darwin supports this option + +// ListenPacket listens for incoming ICMP packets addressed to +// address. See net.Dial for the syntax of address. +// +// For non-privileged datagram-oriented ICMP endpoints, network must +// be "udp4" or "udp6". The endpoint allows to read, write a few +// limited ICMP messages such as echo request and echo reply. +// Currently only Darwin and Linux support this. +// +// Examples: +// ListenPacket("udp4", "192.168.0.1") +// ListenPacket("udp4", "0.0.0.0") +// ListenPacket("udp6", "fe80::1%en0") +// ListenPacket("udp6", "::") +// +// For privileged raw ICMP endpoints, network must be "ip4" or "ip6" +// followed by a colon and an ICMP protocol number or name. +// +// Examples: +// ListenPacket("ip4:icmp", "192.168.0.1") +// ListenPacket("ip4:1", "0.0.0.0") +// ListenPacket("ip6:ipv6-icmp", "fe80::1%en0") +// ListenPacket("ip6:58", "::") +func ListenPacket(network, address string) (*PacketConn, error) { + var family, proto int + switch network { + case "udp4": + family, proto = syscall.AF_INET, iana.ProtocolICMP + case "udp6": + family, proto = syscall.AF_INET6, iana.ProtocolIPv6ICMP + default: + i := last(network, ':') + switch network[:i] { + case "ip4": + proto = iana.ProtocolICMP + case "ip6": + proto = iana.ProtocolIPv6ICMP + } + } + var cerr error + var c net.PacketConn + switch family { + case syscall.AF_INET, syscall.AF_INET6: + s, err := syscall.Socket(family, syscall.SOCK_DGRAM, proto) + if err != nil { + return nil, os.NewSyscallError("socket", err) + } + defer syscall.Close(s) + if runtime.GOOS == "darwin" && family == syscall.AF_INET { + if err := syscall.SetsockoptInt(s, iana.ProtocolIP, sysIP_STRIPHDR, 1); err != nil { + return nil, os.NewSyscallError("setsockopt", err) + } + } + sa, err := sockaddr(family, address) + if err != nil { + return nil, err + } + if err := syscall.Bind(s, sa); err != nil { + return nil, os.NewSyscallError("bind", err) + } + f := os.NewFile(uintptr(s), "datagram-oriented icmp") + defer f.Close() + c, cerr = net.FilePacketConn(f) + default: + c, cerr = net.ListenPacket(network, address) + } + if cerr != nil { + return nil, cerr + } + switch proto { + case iana.ProtocolICMP: + return &PacketConn{c: c, p4: ipv4.NewPacketConn(c)}, nil + case iana.ProtocolIPv6ICMP: + return &PacketConn{c: c, p6: ipv6.NewPacketConn(c)}, nil + default: + return &PacketConn{c: c}, nil + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/listen_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/listen_stub.go new file mode 100644 index 00000000..668728d1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/listen_stub.go @@ -0,0 +1,33 @@ +// 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. + +// +build nacl plan9 + +package icmp + +// ListenPacket listens for incoming ICMP packets addressed to +// address. See net.Dial for the syntax of address. +// +// For non-privileged datagram-oriented ICMP endpoints, network must +// be "udp4" or "udp6". The endpoint allows to read, write a few +// limited ICMP messages such as echo request and echo reply. +// Currently only Darwin and Linux support this. +// +// Examples: +// ListenPacket("udp4", "192.168.0.1") +// ListenPacket("udp4", "0.0.0.0") +// ListenPacket("udp6", "fe80::1%en0") +// ListenPacket("udp6", "::") +// +// For privileged raw ICMP endpoints, network must be "ip4" or "ip6" +// followed by a colon and an ICMP protocol number or name. +// +// Examples: +// ListenPacket("ip4:icmp", "192.168.0.1") +// ListenPacket("ip4:1", "0.0.0.0") +// ListenPacket("ip6:ipv6-icmp", "fe80::1%en0") +// ListenPacket("ip6:58", "::") +func ListenPacket(network, address string) (*PacketConn, error) { + return nil, errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/message.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/message.go new file mode 100644 index 00000000..a20adacd --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/message.go @@ -0,0 +1,149 @@ +// 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 icmp provides basic functions for the manipulation of +// messages used in the Internet Control Message Protocols, +// ICMPv4 and ICMPv6. +// +// ICMPv4 and ICMPv6 are defined in RFC 792 and RFC 4443. +// Multi-part message support for ICMP is defined in RFC 4884. +// ICMP extensions for MPLS are defined in RFC 4950. +// ICMP extensions for interface and next-hop identification are +// defined in RFC 5837. +package icmp // import "golang.org/x/net/icmp" + +import ( + "errors" + "net" + "syscall" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +var ( + errMessageTooShort = errors.New("message too short") + errHeaderTooShort = errors.New("header too short") + errBufferTooShort = errors.New("buffer too short") + errOpNoSupport = errors.New("operation not supported") + errNoExtension = errors.New("no extension") + errInvalidExtension = errors.New("invalid extension") +) + +func checksum(b []byte) uint16 { + csumcv := len(b) - 1 // checksum coverage + s := uint32(0) + for i := 0; i < csumcv; i += 2 { + s += uint32(b[i+1])<<8 | uint32(b[i]) + } + if csumcv&1 == 0 { + s += uint32(b[csumcv]) + } + s = s>>16 + s&0xffff + s = s + s>>16 + return ^uint16(s) +} + +// A Type represents an ICMP message type. +type Type interface { + Protocol() int +} + +// A Message represents an ICMP message. +type Message struct { + Type Type // type, either ipv4.ICMPType or ipv6.ICMPType + Code int // code + Checksum int // checksum + Body MessageBody // body +} + +// Marshal returns the binary encoding of the ICMP message m. +// +// For an ICMPv4 message, the returned message always contains the +// calculated checksum field. +// +// For an ICMPv6 message, the returned message contains the calculated +// checksum field when psh is not nil, otherwise the kernel will +// compute the checksum field during the message transmission. +// When psh is not nil, it must be the pseudo header for IPv6. +func (m *Message) Marshal(psh []byte) ([]byte, error) { + var mtype int + switch typ := m.Type.(type) { + case ipv4.ICMPType: + mtype = int(typ) + case ipv6.ICMPType: + mtype = int(typ) + default: + return nil, syscall.EINVAL + } + b := []byte{byte(mtype), byte(m.Code), 0, 0} + if m.Type.Protocol() == iana.ProtocolIPv6ICMP && psh != nil { + b = append(psh, b...) + } + if m.Body != nil && m.Body.Len(m.Type.Protocol()) != 0 { + mb, err := m.Body.Marshal(m.Type.Protocol()) + if err != nil { + return nil, err + } + b = append(b, mb...) + } + if m.Type.Protocol() == iana.ProtocolIPv6ICMP { + if psh == nil { // cannot calculate checksum here + return b, nil + } + off, l := 2*net.IPv6len, len(b)-len(psh) + b[off], b[off+1], b[off+2], b[off+3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l) + } + s := checksum(b) + // Place checksum back in header; using ^= avoids the + // assumption the checksum bytes are zero. + b[len(psh)+2] ^= byte(s) + b[len(psh)+3] ^= byte(s >> 8) + return b[len(psh):], nil +} + +var parseFns = map[Type]func(int, []byte) (MessageBody, error){ + ipv4.ICMPTypeDestinationUnreachable: parseDstUnreach, + ipv4.ICMPTypeTimeExceeded: parseTimeExceeded, + ipv4.ICMPTypeParameterProblem: parseParamProb, + + ipv4.ICMPTypeEcho: parseEcho, + ipv4.ICMPTypeEchoReply: parseEcho, + + ipv6.ICMPTypeDestinationUnreachable: parseDstUnreach, + ipv6.ICMPTypePacketTooBig: parsePacketTooBig, + ipv6.ICMPTypeTimeExceeded: parseTimeExceeded, + ipv6.ICMPTypeParameterProblem: parseParamProb, + + ipv6.ICMPTypeEchoRequest: parseEcho, + ipv6.ICMPTypeEchoReply: parseEcho, +} + +// ParseMessage parses b as an ICMP message. +// Proto must be either the ICMPv4 or ICMPv6 protocol number. +func ParseMessage(proto int, b []byte) (*Message, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + var err error + m := &Message{Code: int(b[1]), Checksum: int(b[2])<<8 | int(b[3])} + switch proto { + case iana.ProtocolICMP: + m.Type = ipv4.ICMPType(b[0]) + case iana.ProtocolIPv6ICMP: + m.Type = ipv6.ICMPType(b[0]) + default: + return nil, syscall.EINVAL + } + if fn, ok := parseFns[m.Type]; !ok { + m.Body, err = parseDefaultMessageBody(proto, b[4:]) + } else { + m.Body, err = fn(proto, b[4:]) + } + if err != nil { + return nil, err + } + return m, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/message_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/message_test.go new file mode 100644 index 00000000..5d2605f8 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/message_test.go @@ -0,0 +1,134 @@ +// 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. + +package icmp_test + +import ( + "net" + "reflect" + "testing" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +var marshalAndParseMessageForIPv4Tests = []icmp.Message{ + { + Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv4.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv4.ICMPTypeParameterProblem, Code: 2, + Body: &icmp.ParamProb{ + Pointer: 8, + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: 1, Seq: 2, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + { + Type: ipv4.ICMPTypePhoturis, + Body: &icmp.DefaultMessageBody{ + Data: []byte{0x80, 0x40, 0x20, 0x10}, + }, + }, +} + +func TestMarshalAndParseMessageForIPv4(t *testing.T) { + for i, tt := range marshalAndParseMessageForIPv4Tests { + b, err := tt.Marshal(nil) + if err != nil { + t.Fatal(err) + } + m, err := icmp.ParseMessage(iana.ProtocolICMP, b) + if err != nil { + t.Fatal(err) + } + if m.Type != tt.Type || m.Code != tt.Code { + t.Errorf("#%v: got %v; want %v", i, m, &tt) + } + if !reflect.DeepEqual(m.Body, tt.Body) { + t.Errorf("#%v: got %v; want %v", i, m.Body, tt.Body) + } + } +} + +var marshalAndParseMessageForIPv6Tests = []icmp.Message{ + { + Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypePacketTooBig, Code: 0, + Body: &icmp.PacketTooBig{ + MTU: 1<<16 - 1, + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypeParameterProblem, Code: 2, + Body: &icmp.ParamProb{ + Pointer: 8, + Data: []byte("ERROR-INVOKING-PACKET"), + }, + }, + { + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: 1, Seq: 2, + Data: []byte("HELLO-R-U-THERE"), + }, + }, + { + Type: ipv6.ICMPTypeDuplicateAddressConfirmation, + Body: &icmp.DefaultMessageBody{ + Data: []byte{0x80, 0x40, 0x20, 0x10}, + }, + }, +} + +func TestMarshalAndParseMessageForIPv6(t *testing.T) { + pshicmp := icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")) + for i, tt := range marshalAndParseMessageForIPv6Tests { + for _, psh := range [][]byte{pshicmp, nil} { + b, err := tt.Marshal(psh) + if err != nil { + t.Fatal(err) + } + m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b) + if err != nil { + t.Fatal(err) + } + if m.Type != tt.Type || m.Code != tt.Code { + t.Errorf("#%v: got %v; want %v", i, m, &tt) + } + if !reflect.DeepEqual(m.Body, tt.Body) { + t.Errorf("#%v: got %v; want %v", i, m.Body, tt.Body) + } + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/messagebody.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/messagebody.go new file mode 100644 index 00000000..2121a17b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/messagebody.go @@ -0,0 +1,41 @@ +// 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 icmp + +// A MessageBody represents an ICMP message body. +type MessageBody interface { + // Len returns the length of ICMP message body. + // Proto must be either the ICMPv4 or ICMPv6 protocol number. + Len(proto int) int + + // Marshal returns the binary encoding of ICMP message body. + // Proto must be either the ICMPv4 or ICMPv6 protocol number. + Marshal(proto int) ([]byte, error) +} + +// A DefaultMessageBody represents the default message body. +type DefaultMessageBody struct { + Data []byte // data +} + +// Len implements the Len method of MessageBody interface. +func (p *DefaultMessageBody) Len(proto int) int { + if p == nil { + return 0 + } + return len(p.Data) +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *DefaultMessageBody) Marshal(proto int) ([]byte, error) { + return p.Data, nil +} + +// parseDefaultMessageBody parses b as an ICMP message body. +func parseDefaultMessageBody(proto int, b []byte) (MessageBody, error) { + p := &DefaultMessageBody{Data: make([]byte, len(b))} + copy(p.Data, b) + return p, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/mpls.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/mpls.go new file mode 100644 index 00000000..31bcfe8d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/mpls.go @@ -0,0 +1,75 @@ +// 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 icmp + +// A MPLSLabel represents a MPLS label stack entry. +type MPLSLabel struct { + Label int // label value + TC int // traffic class; formerly experimental use + S bool // bottom of stack + TTL int // time to live +} + +const ( + classMPLSLabelStack = 1 + typeIncomingMPLSLabelStack = 1 +) + +// A MPLSLabelStack represents a MPLS label stack. +type MPLSLabelStack struct { + Class int // extension object class number + Type int // extension object sub-type + Labels []MPLSLabel +} + +// Len implements the Len method of Extension interface. +func (ls *MPLSLabelStack) Len(proto int) int { + return 4 + (4 * len(ls.Labels)) +} + +// Marshal implements the Marshal method of Extension interface. +func (ls *MPLSLabelStack) Marshal(proto int) ([]byte, error) { + b := make([]byte, ls.Len(proto)) + if err := ls.marshal(proto, b); err != nil { + return nil, err + } + return b, nil +} + +func (ls *MPLSLabelStack) marshal(proto int, b []byte) error { + l := ls.Len(proto) + b[0], b[1] = byte(l>>8), byte(l) + b[2], b[3] = classMPLSLabelStack, typeIncomingMPLSLabelStack + off := 4 + for _, ll := range ls.Labels { + b[off], b[off+1], b[off+2] = byte(ll.Label>>12), byte(ll.Label>>4&0xff), byte(ll.Label<<4&0xf0) + b[off+2] |= byte(ll.TC << 1 & 0x0e) + if ll.S { + b[off+2] |= 0x1 + } + b[off+3] = byte(ll.TTL) + off += 4 + } + return nil +} + +func parseMPLSLabelStack(b []byte) (Extension, error) { + ls := &MPLSLabelStack{ + Class: int(b[2]), + Type: int(b[3]), + } + for b = b[4:]; len(b) >= 4; b = b[4:] { + ll := MPLSLabel{ + Label: int(b[0])<<12 | int(b[1])<<4 | int(b[2])>>4, + TC: int(b[2]&0x0e) >> 1, + TTL: int(b[3]), + } + if b[2]&0x1 != 0 { + ll.S = true + } + ls.Labels = append(ls.Labels, ll) + } + return ls, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/multipart.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/multipart.go new file mode 100644 index 00000000..f2713566 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/multipart.go @@ -0,0 +1,109 @@ +// 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 icmp + +import "golang.org/x/net/internal/iana" + +// multipartMessageBodyDataLen takes b as an original datagram and +// exts as extensions, and returns a required length for message body +// and a required length for a padded original datagram in wire +// format. +func multipartMessageBodyDataLen(proto int, b []byte, exts []Extension) (bodyLen, dataLen int) { + for _, ext := range exts { + bodyLen += ext.Len(proto) + } + if bodyLen > 0 { + dataLen = multipartMessageOrigDatagramLen(proto, b) + bodyLen += 4 // length of extension header + } else { + dataLen = len(b) + } + bodyLen += dataLen + return bodyLen, dataLen +} + +// multipartMessageOrigDatagramLen takes b as an original datagram, +// and returns a required length for a padded orignal datagram in wire +// format. +func multipartMessageOrigDatagramLen(proto int, b []byte) int { + roundup := func(b []byte, align int) int { + // According to RFC 4884, the padded original datagram + // field must contain at least 128 octets. + if len(b) < 128 { + return 128 + } + r := len(b) + return (r + align - 1) & ^(align - 1) + } + switch proto { + case iana.ProtocolICMP: + return roundup(b, 4) + case iana.ProtocolIPv6ICMP: + return roundup(b, 8) + default: + return len(b) + } +} + +// marshalMultipartMessageBody takes data as an original datagram and +// exts as extesnsions, and returns a binary encoding of message body. +// It can be used for non-multipart message bodies when exts is nil. +func marshalMultipartMessageBody(proto int, data []byte, exts []Extension) ([]byte, error) { + bodyLen, dataLen := multipartMessageBodyDataLen(proto, data, exts) + b := make([]byte, 4+bodyLen) + copy(b[4:], data) + off := dataLen + 4 + if len(exts) > 0 { + b[dataLen+4] = byte(extensionVersion << 4) + off += 4 // length of object header + for _, ext := range exts { + switch ext := ext.(type) { + case *MPLSLabelStack: + if err := ext.marshal(proto, b[off:]); err != nil { + return nil, err + } + off += ext.Len(proto) + case *InterfaceInfo: + attrs, l := ext.attrsAndLen(proto) + if err := ext.marshal(proto, b[off:], attrs, l); err != nil { + return nil, err + } + off += ext.Len(proto) + } + } + s := checksum(b[dataLen+4:]) + b[dataLen+4+2] ^= byte(s) + b[dataLen+4+3] ^= byte(s >> 8) + switch proto { + case iana.ProtocolICMP: + b[1] = byte(dataLen / 4) + case iana.ProtocolIPv6ICMP: + b[0] = byte(dataLen / 8) + } + } + return b, nil +} + +// parseMultipartMessageBody parses b as either a non-multipart +// message body or a multipart message body. +func parseMultipartMessageBody(proto int, b []byte) ([]byte, []Extension, error) { + var l int + switch proto { + case iana.ProtocolICMP: + l = 4 * int(b[1]) + case iana.ProtocolIPv6ICMP: + l = 8 * int(b[0]) + } + if len(b) == 4 { + return nil, nil, nil + } + exts, l, err := parseExtensions(b[4:], l) + if err != nil { + l = len(b) - 4 + } + data := make([]byte, l) + copy(data, b[4:]) + return data, exts, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/multipart_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/multipart_test.go new file mode 100644 index 00000000..966ccb8d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/multipart_test.go @@ -0,0 +1,442 @@ +// 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 icmp_test + +import ( + "fmt" + "net" + "reflect" + "testing" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +var marshalAndParseMultipartMessageForIPv4Tests = []icmp.Message{ + { + Type: ipv4.ICMPTypeDestinationUnreachable, Code: 15, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 1).To4(), + }, + }, + }, + }, + }, + { + Type: ipv4.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 1).To4(), + }, + }, + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + }, + }, + }, + { + Type: ipv4.ICMPTypeParameterProblem, Code: 2, + Body: &icmp.ParamProb{ + Pointer: 8, + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 1).To4(), + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x2f, + Interface: &net.Interface{ + Index: 16, + Name: "en102", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.IPv4(192, 168, 0, 2).To4(), + }, + }, + }, + }, + }, +} + +func TestMarshalAndParseMultipartMessageForIPv4(t *testing.T) { + for i, tt := range marshalAndParseMultipartMessageForIPv4Tests { + b, err := tt.Marshal(nil) + if err != nil { + t.Fatal(err) + } + if b[5] != 32 { + t.Errorf("#%v: got %v; want 32", i, b[5]) + } + m, err := icmp.ParseMessage(iana.ProtocolICMP, b) + if err != nil { + t.Fatal(err) + } + if m.Type != tt.Type || m.Code != tt.Code { + t.Errorf("#%v: got %v; want %v", i, m, &tt) + } + switch m.Type { + case ipv4.ICMPTypeDestinationUnreachable: + got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + } + if len(got.Data) != 128 { + t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + } + case ipv4.ICMPTypeTimeExceeded: + got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + } + if len(got.Data) != 128 { + t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + } + case ipv4.ICMPTypeParameterProblem: + got, want := m.Body.(*icmp.ParamProb), tt.Body.(*icmp.ParamProb) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + } + if len(got.Data) != 128 { + t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + } + } + } +} + +var marshalAndParseMultipartMessageForIPv6Tests = []icmp.Message{ + { + Type: ipv6.ICMPTypeDestinationUnreachable, Code: 6, + Body: &icmp.DstUnreach{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en101", + }, + }, + }, + }, + }, + { + Type: ipv6.ICMPTypeTimeExceeded, Code: 1, + Body: &icmp.TimeExceeded{ + Data: []byte("ERROR-INVOKING-PACKET"), + Extensions: []icmp.Extension{ + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x0f, + Interface: &net.Interface{ + Index: 15, + Name: "en101", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en101", + }, + }, + &icmp.MPLSLabelStack{ + Class: 1, + Type: 1, + Labels: []icmp.MPLSLabel{ + { + Label: 16014, + TC: 0x4, + S: true, + TTL: 255, + }, + }, + }, + &icmp.InterfaceInfo{ + Class: 2, + Type: 0x2f, + Interface: &net.Interface{ + Index: 16, + Name: "en102", + MTU: 8192, + }, + Addr: &net.IPAddr{ + IP: net.ParseIP("fe80::1"), + Zone: "en102", + }, + }, + }, + }, + }, +} + +func TestMarshalAndParseMultipartMessageForIPv6(t *testing.T) { + pshicmp := icmp.IPv6PseudoHeader(net.ParseIP("fe80::1"), net.ParseIP("ff02::1")) + for i, tt := range marshalAndParseMultipartMessageForIPv6Tests { + for _, psh := range [][]byte{pshicmp, nil} { + b, err := tt.Marshal(psh) + if err != nil { + t.Fatal(err) + } + if b[4] != 16 { + t.Errorf("#%v: got %v; want 16", i, b[4]) + } + m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, b) + if err != nil { + t.Fatal(err) + } + if m.Type != tt.Type || m.Code != tt.Code { + t.Errorf("#%v: got %v; want %v", i, m, &tt) + } + switch m.Type { + case ipv6.ICMPTypeDestinationUnreachable: + got, want := m.Body.(*icmp.DstUnreach), tt.Body.(*icmp.DstUnreach) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + } + if len(got.Data) != 128 { + t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + } + case ipv6.ICMPTypeTimeExceeded: + got, want := m.Body.(*icmp.TimeExceeded), tt.Body.(*icmp.TimeExceeded) + if !reflect.DeepEqual(got.Extensions, want.Extensions) { + t.Error(dumpExtensions(i, got.Extensions, want.Extensions)) + } + if len(got.Data) != 128 { + t.Errorf("#%v: got %v; want 128", i, len(got.Data)) + } + } + } + } +} + +func dumpExtensions(i int, gotExts, wantExts []icmp.Extension) string { + var s string + for j, got := range gotExts { + switch got := got.(type) { + case *icmp.MPLSLabelStack: + want := wantExts[j].(*icmp.MPLSLabelStack) + if !reflect.DeepEqual(got, want) { + s += fmt.Sprintf("#%v/%v: got %#v; want %#v\n", i, j, got, want) + } + case *icmp.InterfaceInfo: + want := wantExts[j].(*icmp.InterfaceInfo) + if !reflect.DeepEqual(got, want) { + s += fmt.Sprintf("#%v/%v: got %#v, %#v, %#v; want %#v, %#v, %#v\n", i, j, got, got.Interface, got.Addr, want, want.Interface, want.Addr) + } + } + } + return s[:len(s)-1] +} + +var multipartMessageBodyLenTests = []struct { + proto int + in icmp.MessageBody + out int +}{ + { + iana.ProtocolICMP, + &icmp.DstUnreach{ + Data: make([]byte, ipv4.HeaderLen), + }, + 4 + ipv4.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolICMP, + &icmp.TimeExceeded{ + Data: make([]byte, ipv4.HeaderLen), + }, + 4 + ipv4.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, ipv4.HeaderLen), + }, + 4 + ipv4.HeaderLen, // [pointer, unused] and original datagram + }, + + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, ipv4.HeaderLen), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload, original datagram + }, + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, 128), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [pointer, length, unused], extension header, object header, object payload and original datagram + }, + { + iana.ProtocolICMP, + &icmp.ParamProb{ + Data: make([]byte, 129), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 132, // [pointer, length, unused], extension header, object header, object payload and original datagram + }, + + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.PacketTooBig{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // mtu and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.TimeExceeded{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // unused and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.ParamProb{ + Data: make([]byte, ipv6.HeaderLen), + }, + 4 + ipv6.HeaderLen, // pointer and original datagram + }, + + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, 127), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, 128), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 128, // [length, unused], extension header, object header, object payload and original datagram + }, + { + iana.ProtocolIPv6ICMP, + &icmp.DstUnreach{ + Data: make([]byte, 129), + Extensions: []icmp.Extension{ + &icmp.MPLSLabelStack{}, + }, + }, + 4 + 4 + 4 + 0 + 136, // [length, unused], extension header, object header, object payload and original datagram + }, +} + +func TestMultipartMessageBodyLen(t *testing.T) { + for i, tt := range multipartMessageBodyLenTests { + if out := tt.in.Len(tt.proto); out != tt.out { + t.Errorf("#%d: got %d; want %d", i, out, tt.out) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/packettoobig.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/packettoobig.go new file mode 100644 index 00000000..91d289b2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/packettoobig.go @@ -0,0 +1,41 @@ +// 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. + +package icmp + +// A PacketTooBig represents an ICMP packet too big message body. +type PacketTooBig struct { + MTU int // maximum transmission unit of the nexthop link + Data []byte // data, known as original datagram field +} + +// Len implements the Len method of MessageBody interface. +func (p *PacketTooBig) Len(proto int) int { + if p == nil { + return 0 + } + return 4 + len(p.Data) +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *PacketTooBig) Marshal(proto int) ([]byte, error) { + b := make([]byte, 4+len(p.Data)) + b[0], b[1], b[2], b[3] = byte(p.MTU>>24), byte(p.MTU>>16), byte(p.MTU>>8), byte(p.MTU) + copy(b[4:], p.Data) + return b, nil +} + +// parsePacketTooBig parses b as an ICMP packet too big message body. +func parsePacketTooBig(proto int, b []byte) (MessageBody, error) { + bodyLen := len(b) + if bodyLen < 4 { + return nil, errMessageTooShort + } + p := &PacketTooBig{MTU: int(b[0])<<24 | int(b[1])<<16 | int(b[2])<<8 | int(b[3])} + if bodyLen > 4 { + p.Data = make([]byte, bodyLen-4) + copy(p.Data, b[4:]) + } + return p, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/paramprob.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/paramprob.go new file mode 100644 index 00000000..05cc311e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/paramprob.go @@ -0,0 +1,60 @@ +// 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. + +package icmp + +import "golang.org/x/net/internal/iana" + +// A ParamProb represents an ICMP parameter problem message body. +type ParamProb struct { + Pointer uintptr // offset within the data where the error was detected + Data []byte // data, known as original datagram field + Extensions []Extension // extensions +} + +// Len implements the Len method of MessageBody interface. +func (p *ParamProb) Len(proto int) int { + if p == nil { + return 0 + } + l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions) + return 4 + l +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *ParamProb) Marshal(proto int) ([]byte, error) { + if proto == iana.ProtocolIPv6ICMP { + b := make([]byte, p.Len(proto)) + b[0], b[1], b[2], b[3] = byte(p.Pointer>>24), byte(p.Pointer>>16), byte(p.Pointer>>8), byte(p.Pointer) + copy(b[4:], p.Data) + return b, nil + } + b, err := marshalMultipartMessageBody(proto, p.Data, p.Extensions) + if err != nil { + return nil, err + } + b[0] = byte(p.Pointer) + return b, nil +} + +// parseParamProb parses b as an ICMP parameter problem message body. +func parseParamProb(proto int, b []byte) (MessageBody, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + p := &ParamProb{} + if proto == iana.ProtocolIPv6ICMP { + p.Pointer = uintptr(b[0])<<24 | uintptr(b[1])<<16 | uintptr(b[2])<<8 | uintptr(b[3]) + p.Data = make([]byte, len(b)-4) + copy(p.Data, b[4:]) + return p, nil + } + p.Pointer = uintptr(b[0]) + var err error + p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b) + if err != nil { + return nil, err + } + return p, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ping_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ping_test.go new file mode 100644 index 00000000..4ec26928 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/ping_test.go @@ -0,0 +1,166 @@ +// 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. + +package icmp_test + +import ( + "errors" + "fmt" + "net" + "os" + "runtime" + "testing" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" + "golang.org/x/net/ipv6" +) + +func googleAddr(c *icmp.PacketConn, protocol int) (net.Addr, error) { + const host = "www.google.com" + ips, err := net.LookupIP(host) + if err != nil { + return nil, err + } + netaddr := func(ip net.IP) (net.Addr, error) { + switch c.LocalAddr().(type) { + case *net.UDPAddr: + return &net.UDPAddr{IP: ip}, nil + case *net.IPAddr: + return &net.IPAddr{IP: ip}, nil + default: + return nil, errors.New("neither UDPAddr nor IPAddr") + } + } + for _, ip := range ips { + switch protocol { + case iana.ProtocolICMP: + if ip.To4() != nil { + return netaddr(ip) + } + case iana.ProtocolIPv6ICMP: + if ip.To16() != nil && ip.To4() == nil { + return netaddr(ip) + } + } + } + return nil, errors.New("no A or AAAA record") +} + +type pingTest struct { + network, address string + protocol int + mtype icmp.Type +} + +var nonPrivilegedPingTests = []pingTest{ + {"udp4", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho}, + + {"udp6", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest}, +} + +func TestNonPrivilegedPing(t *testing.T) { + if testing.Short() { + t.Skip("avoid external network") + } + switch runtime.GOOS { + case "darwin": + case "linux": + t.Log("you may need to adjust the net.ipv4.ping_group_range kernel state") + default: + t.Skipf("not supported on %s", runtime.GOOS) + } + + for i, tt := range nonPrivilegedPingTests { + if err := doPing(tt, i); err != nil { + t.Error(err) + } + } +} + +var privilegedPingTests = []pingTest{ + {"ip4:icmp", "0.0.0.0", iana.ProtocolICMP, ipv4.ICMPTypeEcho}, + + {"ip6:ipv6-icmp", "::", iana.ProtocolIPv6ICMP, ipv6.ICMPTypeEchoRequest}, +} + +func TestPrivilegedPing(t *testing.T) { + if testing.Short() { + t.Skip("avoid external network") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + for i, tt := range privilegedPingTests { + if err := doPing(tt, i); err != nil { + t.Error(err) + } + } +} + +func doPing(tt pingTest, seq int) error { + c, err := icmp.ListenPacket(tt.network, tt.address) + if err != nil { + return err + } + defer c.Close() + + dst, err := googleAddr(c, tt.protocol) + if err != nil { + return err + } + + if tt.network != "udp6" && tt.protocol == iana.ProtocolIPv6ICMP { + var f ipv6.ICMPFilter + f.SetAll(true) + f.Accept(ipv6.ICMPTypeDestinationUnreachable) + f.Accept(ipv6.ICMPTypePacketTooBig) + f.Accept(ipv6.ICMPTypeTimeExceeded) + f.Accept(ipv6.ICMPTypeParameterProblem) + f.Accept(ipv6.ICMPTypeEchoReply) + if err := c.IPv6PacketConn().SetICMPFilter(&f); err != nil { + return err + } + } + + wm := icmp.Message{ + Type: tt.mtype, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: 1 << uint(seq), + Data: []byte("HELLO-R-U-THERE"), + }, + } + wb, err := wm.Marshal(nil) + if err != nil { + return err + } + if n, err := c.WriteTo(wb, dst); err != nil { + return err + } else if n != len(wb) { + return fmt.Errorf("got %v; want %v", n, len(wb)) + } + + rb := make([]byte, 1500) + if err := c.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil { + return err + } + n, peer, err := c.ReadFrom(rb) + if err != nil { + return err + } + rm, err := icmp.ParseMessage(tt.protocol, rb[:n]) + if err != nil { + return err + } + switch rm.Type { + case ipv4.ICMPTypeEchoReply, ipv6.ICMPTypeEchoReply: + return nil + default: + return fmt.Errorf("got %+v from %v; want echo reply", rm, peer) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/sys_freebsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/sys_freebsd.go new file mode 100644 index 00000000..c75f3dda --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/sys_freebsd.go @@ -0,0 +1,11 @@ +// 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. + +package icmp + +import "syscall" + +func init() { + freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate") +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/timeexceeded.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/timeexceeded.go new file mode 100644 index 00000000..344e1584 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/icmp/timeexceeded.go @@ -0,0 +1,39 @@ +// 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. + +package icmp + +// A TimeExceeded represents an ICMP time exceeded message body. +type TimeExceeded struct { + Data []byte // data, known as original datagram field + Extensions []Extension // extensions +} + +// Len implements the Len method of MessageBody interface. +func (p *TimeExceeded) Len(proto int) int { + if p == nil { + return 0 + } + l, _ := multipartMessageBodyDataLen(proto, p.Data, p.Extensions) + return 4 + l +} + +// Marshal implements the Marshal method of MessageBody interface. +func (p *TimeExceeded) Marshal(proto int) ([]byte, error) { + return marshalMultipartMessageBody(proto, p.Data, p.Extensions) +} + +// parseTimeExceeded parses b as an ICMP time exceeded message body. +func parseTimeExceeded(proto int, b []byte) (MessageBody, error) { + if len(b) < 4 { + return nil, errMessageTooShort + } + p := &TimeExceeded{} + var err error + p.Data, p.Extensions, err = parseMultipartMessageBody(proto, b) + if err != nil { + return nil, err + } + return p, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/idna.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/idna.go new file mode 100644 index 00000000..3daa8979 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/idna.go @@ -0,0 +1,68 @@ +// 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 idna implements IDNA2008 (Internationalized Domain Names for +// Applications), defined in RFC 5890, RFC 5891, RFC 5892, RFC 5893 and +// RFC 5894. +package idna // import "golang.org/x/net/idna" + +import ( + "strings" + "unicode/utf8" +) + +// TODO(nigeltao): specify when errors occur. For example, is ToASCII(".") or +// ToASCII("foo\x00") an error? See also http://www.unicode.org/faq/idn.html#11 + +// acePrefix is the ASCII Compatible Encoding prefix. +const acePrefix = "xn--" + +// ToASCII converts a domain or domain label to its ASCII form. For example, +// ToASCII("bücher.example.com") is "xn--bcher-kva.example.com", and +// ToASCII("golang") is "golang". +func ToASCII(s string) (string, error) { + if ascii(s) { + return s, nil + } + labels := strings.Split(s, ".") + for i, label := range labels { + if !ascii(label) { + a, err := encode(acePrefix, label) + if err != nil { + return "", err + } + labels[i] = a + } + } + return strings.Join(labels, "."), nil +} + +// ToUnicode converts a domain or domain label to its Unicode form. For example, +// ToUnicode("xn--bcher-kva.example.com") is "bücher.example.com", and +// ToUnicode("golang") is "golang". +func ToUnicode(s string) (string, error) { + if !strings.Contains(s, acePrefix) { + return s, nil + } + labels := strings.Split(s, ".") + for i, label := range labels { + if strings.HasPrefix(label, acePrefix) { + u, err := decode(label[len(acePrefix):]) + if err != nil { + return "", err + } + labels[i] = u + } + } + return strings.Join(labels, "."), nil +} + +func ascii(s string) bool { + for i := 0; i < len(s); i++ { + if s[i] >= utf8.RuneSelf { + return false + } + } + return true +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/idna_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/idna_test.go new file mode 100644 index 00000000..b1bc6fa2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/idna_test.go @@ -0,0 +1,43 @@ +// 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 idna + +import ( + "testing" +) + +var idnaTestCases = [...]struct { + ascii, unicode string +}{ + // Labels. + {"books", "books"}, + {"xn--bcher-kva", "bücher"}, + + // Domains. + {"foo--xn--bar.org", "foo--xn--bar.org"}, + {"golang.org", "golang.org"}, + {"example.xn--p1ai", "example.рф"}, + {"xn--czrw28b.tw", "商業.tw"}, + {"www.xn--mller-kva.de", "www.müller.de"}, +} + +func TestIDNA(t *testing.T) { + for _, tc := range idnaTestCases { + if a, err := ToASCII(tc.unicode); err != nil { + t.Errorf("ToASCII(%q): %v", tc.unicode, err) + } else if a != tc.ascii { + t.Errorf("ToASCII(%q): got %q, want %q", tc.unicode, a, tc.ascii) + } + + if u, err := ToUnicode(tc.ascii); err != nil { + t.Errorf("ToUnicode(%q): %v", tc.ascii, err) + } else if u != tc.unicode { + t.Errorf("ToUnicode(%q): got %q, want %q", tc.ascii, u, tc.unicode) + } + } +} + +// TODO(nigeltao): test errors, once we've specified when ToASCII and ToUnicode +// return errors. diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/punycode.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/punycode.go new file mode 100644 index 00000000..92e733f6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/punycode.go @@ -0,0 +1,200 @@ +// 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 idna + +// This file implements the Punycode algorithm from RFC 3492. + +import ( + "fmt" + "math" + "strings" + "unicode/utf8" +) + +// These parameter values are specified in section 5. +// +// All computation is done with int32s, so that overflow behavior is identical +// regardless of whether int is 32-bit or 64-bit. +const ( + base int32 = 36 + damp int32 = 700 + initialBias int32 = 72 + initialN int32 = 128 + skew int32 = 38 + tmax int32 = 26 + tmin int32 = 1 +) + +// decode decodes a string as specified in section 6.2. +func decode(encoded string) (string, error) { + if encoded == "" { + return "", nil + } + pos := 1 + strings.LastIndex(encoded, "-") + if pos == 1 { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + if pos == len(encoded) { + return encoded[:len(encoded)-1], nil + } + output := make([]rune, 0, len(encoded)) + if pos != 0 { + for _, r := range encoded[:pos-1] { + output = append(output, r) + } + } + i, n, bias := int32(0), initialN, initialBias + for pos < len(encoded) { + oldI, w := i, int32(1) + for k := base; ; k += base { + if pos == len(encoded) { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + digit, ok := decodeDigit(encoded[pos]) + if !ok { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + pos++ + i += digit * w + if i < 0 { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + t := k - bias + if t < tmin { + t = tmin + } else if t > tmax { + t = tmax + } + if digit < t { + break + } + w *= base - t + if w >= math.MaxInt32/base { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + } + x := int32(len(output) + 1) + bias = adapt(i-oldI, x, oldI == 0) + n += i / x + i %= x + if n > utf8.MaxRune || len(output) >= 1024 { + return "", fmt.Errorf("idna: invalid label %q", encoded) + } + output = append(output, 0) + copy(output[i+1:], output[i:]) + output[i] = n + i++ + } + return string(output), nil +} + +// encode encodes a string as specified in section 6.3 and prepends prefix to +// the result. +// +// The "while h < length(input)" line in the specification becomes "for +// remaining != 0" in the Go code, because len(s) in Go is in bytes, not runes. +func encode(prefix, s string) (string, error) { + output := make([]byte, len(prefix), len(prefix)+1+2*len(s)) + copy(output, prefix) + delta, n, bias := int32(0), initialN, initialBias + b, remaining := int32(0), int32(0) + for _, r := range s { + if r < 0x80 { + b++ + output = append(output, byte(r)) + } else { + remaining++ + } + } + h := b + if b > 0 { + output = append(output, '-') + } + for remaining != 0 { + m := int32(0x7fffffff) + for _, r := range s { + if m > r && r >= n { + m = r + } + } + delta += (m - n) * (h + 1) + if delta < 0 { + return "", fmt.Errorf("idna: invalid label %q", s) + } + n = m + for _, r := range s { + if r < n { + delta++ + if delta < 0 { + return "", fmt.Errorf("idna: invalid label %q", s) + } + continue + } + if r > n { + continue + } + q := delta + for k := base; ; k += base { + t := k - bias + if t < tmin { + t = tmin + } else if t > tmax { + t = tmax + } + if q < t { + break + } + output = append(output, encodeDigit(t+(q-t)%(base-t))) + q = (q - t) / (base - t) + } + output = append(output, encodeDigit(q)) + bias = adapt(delta, h+1, h == b) + delta = 0 + h++ + remaining-- + } + delta++ + n++ + } + return string(output), nil +} + +func decodeDigit(x byte) (digit int32, ok bool) { + switch { + case '0' <= x && x <= '9': + return int32(x - ('0' - 26)), true + case 'A' <= x && x <= 'Z': + return int32(x - 'A'), true + case 'a' <= x && x <= 'z': + return int32(x - 'a'), true + } + return 0, false +} + +func encodeDigit(digit int32) byte { + switch { + case 0 <= digit && digit < 26: + return byte(digit + 'a') + case 26 <= digit && digit < 36: + return byte(digit + ('0' - 26)) + } + panic("idna: internal error in punycode encoding") +} + +// adapt is the bias adaptation function specified in section 6.1. +func adapt(delta, numPoints int32, firstTime bool) int32 { + if firstTime { + delta /= damp + } else { + delta /= 2 + } + delta += delta / numPoints + k := int32(0) + for delta > ((base-tmin)*tmax)/2 { + delta /= base - tmin + k += base + } + return k + (base-tmin+1)*delta/(delta+skew) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/punycode_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/punycode_test.go new file mode 100644 index 00000000..bfec81de --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/idna/punycode_test.go @@ -0,0 +1,198 @@ +// 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 idna + +import ( + "strings" + "testing" +) + +var punycodeTestCases = [...]struct { + s, encoded string +}{ + {"", ""}, + {"-", "--"}, + {"-a", "-a-"}, + {"-a-", "-a--"}, + {"a", "a-"}, + {"a-", "a--"}, + {"a-b", "a-b-"}, + {"books", "books-"}, + {"bücher", "bcher-kva"}, + {"Hello世界", "Hello-ck1hg65u"}, + {"ü", "tda"}, + {"üý", "tdac"}, + + // The test cases below come from RFC 3492 section 7.1 with Errata 3026. + { + // (A) Arabic (Egyptian). + "\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644" + + "\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F", + "egbpdaj6bu4bxfgehfvwxn", + }, + { + // (B) Chinese (simplified). + "\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2D\u6587", + "ihqwcrb4cv8a8dqg056pqjye", + }, + { + // (C) Chinese (traditional). + "\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587", + "ihqwctvzc91f659drss3x8bo0yb", + }, + { + // (D) Czech. + "\u0050\u0072\u006F\u010D\u0070\u0072\u006F\u0073\u0074" + + "\u011B\u006E\u0065\u006D\u006C\u0075\u0076\u00ED\u010D" + + "\u0065\u0073\u006B\u0079", + "Proprostnemluvesky-uyb24dma41a", + }, + { + // (E) Hebrew. + "\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8" + + "\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2" + + "\u05D1\u05E8\u05D9\u05EA", + "4dbcagdahymbxekheh6e0a7fei0b", + }, + { + // (F) Hindi (Devanagari). + "\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D" + + "\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939" + + "\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947" + + "\u0939\u0948\u0902", + "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd", + }, + { + // (G) Japanese (kanji and hiragana). + "\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092" + + "\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B", + "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa", + }, + { + // (H) Korean (Hangul syllables). + "\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774" + + "\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74" + + "\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C", + "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5j" + + "psd879ccm6fea98c", + }, + { + // (I) Russian (Cyrillic). + "\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E" + + "\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440" + + "\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A" + + "\u0438", + "b1abfaaepdrnnbgefbadotcwatmq2g4l", + }, + { + // (J) Spanish. + "\u0050\u006F\u0072\u0071\u0075\u00E9\u006E\u006F\u0070" + + "\u0075\u0065\u0064\u0065\u006E\u0073\u0069\u006D\u0070" + + "\u006C\u0065\u006D\u0065\u006E\u0074\u0065\u0068\u0061" + + "\u0062\u006C\u0061\u0072\u0065\u006E\u0045\u0073\u0070" + + "\u0061\u00F1\u006F\u006C", + "PorqunopuedensimplementehablarenEspaol-fmd56a", + }, + { + // (K) Vietnamese. + "\u0054\u1EA1\u0069\u0073\u0061\u006F\u0068\u1ECD\u006B" + + "\u0068\u00F4\u006E\u0067\u0074\u0068\u1EC3\u0063\u0068" + + "\u1EC9\u006E\u00F3\u0069\u0074\u0069\u1EBF\u006E\u0067" + + "\u0056\u0069\u1EC7\u0074", + "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g", + }, + { + // (L) 3B. + "\u0033\u5E74\u0042\u7D44\u91D1\u516B\u5148\u751F", + "3B-ww4c5e180e575a65lsy2b", + }, + { + // (M) -with-SUPER-MONKEYS. + "\u5B89\u5BA4\u5948\u7F8E\u6075\u002D\u0077\u0069\u0074" + + "\u0068\u002D\u0053\u0055\u0050\u0045\u0052\u002D\u004D" + + "\u004F\u004E\u004B\u0045\u0059\u0053", + "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n", + }, + { + // (N) Hello-Another-Way-. + "\u0048\u0065\u006C\u006C\u006F\u002D\u0041\u006E\u006F" + + "\u0074\u0068\u0065\u0072\u002D\u0057\u0061\u0079\u002D" + + "\u305D\u308C\u305E\u308C\u306E\u5834\u6240", + "Hello-Another-Way--fc4qua05auwb3674vfr0b", + }, + { + // (O) 2. + "\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B\u0032", + "2-u9tlzr9756bt3uc0v", + }, + { + // (P) MajiKoi5 + "\u004D\u0061\u006A\u0069\u3067\u004B\u006F\u0069\u3059" + + "\u308B\u0035\u79D2\u524D", + "MajiKoi5-783gue6qz075azm5e", + }, + { + // (Q) de + "\u30D1\u30D5\u30A3\u30FC\u0064\u0065\u30EB\u30F3\u30D0", + "de-jg4avhby1noc0d", + }, + { + // (R) + "\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067", + "d9juau41awczczp", + }, + { + // (S) -> $1.00 <- + "\u002D\u003E\u0020\u0024\u0031\u002E\u0030\u0030\u0020" + + "\u003C\u002D", + "-> $1.00 <--", + }, +} + +func TestPunycode(t *testing.T) { + for _, tc := range punycodeTestCases { + if got, err := decode(tc.encoded); err != nil { + t.Errorf("decode(%q): %v", tc.encoded, err) + } else if got != tc.s { + t.Errorf("decode(%q): got %q, want %q", tc.encoded, got, tc.s) + } + + if got, err := encode("", tc.s); err != nil { + t.Errorf(`encode("", %q): %v`, tc.s, err) + } else if got != tc.encoded { + t.Errorf(`encode("", %q): got %q, want %q`, tc.s, got, tc.encoded) + } + } +} + +var punycodeErrorTestCases = [...]string{ + "decode -", // A sole '-' is invalid. + "decode foo\x00bar", // '\x00' is not in [0-9A-Za-z]. + "decode foo#bar", // '#' is not in [0-9A-Za-z]. + "decode foo\u00A3bar", // '\u00A3' is not in [0-9A-Za-z]. + "decode 9", // "9a" decodes to codepoint \u00A3; "9" is truncated. + "decode 99999a", // "99999a" decodes to codepoint \U0048A3C1, which is > \U0010FFFF. + "decode 9999999999a", // "9999999999a" overflows the int32 calculation. + + "encode " + strings.Repeat("x", 65536) + "\uff00", // int32 overflow. +} + +func TestPunycodeErrors(t *testing.T) { + for _, tc := range punycodeErrorTestCases { + var err error + switch { + case strings.HasPrefix(tc, "decode "): + _, err = decode(tc[7:]) + case strings.HasPrefix(tc, "encode "): + _, err = encode("", tc[7:]) + } + if err == nil { + if len(tc) > 256 { + tc = tc[:100] + "..." + tc[len(tc)-100:] + } + t.Errorf("no error for %s", tc) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/iana/const.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/iana/const.go new file mode 100644 index 00000000..7fe88225 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/iana/const.go @@ -0,0 +1,181 @@ +// go generate gen.go +// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA). +package iana // import "golang.org/x/net/internal/iana" + +// Differentiated Services Field Codepoints (DSCP), Updated: 2013-06-25 +const ( + DiffServCS0 = 0x0 // CS0 + DiffServCS1 = 0x20 // CS1 + DiffServCS2 = 0x40 // CS2 + DiffServCS3 = 0x60 // CS3 + DiffServCS4 = 0x80 // CS4 + DiffServCS5 = 0xa0 // CS5 + DiffServCS6 = 0xc0 // CS6 + DiffServCS7 = 0xe0 // CS7 + DiffServAF11 = 0x28 // AF11 + DiffServAF12 = 0x30 // AF12 + DiffServAF13 = 0x38 // AF13 + DiffServAF21 = 0x48 // AF21 + DiffServAF22 = 0x50 // AF22 + DiffServAF23 = 0x58 // AF23 + DiffServAF31 = 0x68 // AF31 + DiffServAF32 = 0x70 // AF32 + DiffServAF33 = 0x78 // AF33 + DiffServAF41 = 0x88 // AF41 + DiffServAF42 = 0x90 // AF42 + DiffServAF43 = 0x98 // AF43 + DiffServEFPHB = 0xb8 // EF PHB + DiffServVOICEADMIT = 0xb0 // VOICE-ADMIT +) + +// IPv4 TOS Byte and IPv6 Traffic Class Octet, Updated: 2001-09-06 +const ( + NotECNTransport = 0x0 // Not-ECT (Not ECN-Capable Transport) + ECNTransport1 = 0x1 // ECT(1) (ECN-Capable Transport(1)) + ECNTransport0 = 0x2 // ECT(0) (ECN-Capable Transport(0)) + CongestionExperienced = 0x3 // CE (Congestion Experienced) +) + +// Protocol Numbers, Updated: 2015-06-23 +const ( + ProtocolIP = 0 // IPv4 encapsulation, pseudo protocol number + ProtocolHOPOPT = 0 // IPv6 Hop-by-Hop Option + ProtocolICMP = 1 // Internet Control Message + ProtocolIGMP = 2 // Internet Group Management + ProtocolGGP = 3 // Gateway-to-Gateway + ProtocolIPv4 = 4 // IPv4 encapsulation + ProtocolST = 5 // Stream + ProtocolTCP = 6 // Transmission Control + ProtocolCBT = 7 // CBT + ProtocolEGP = 8 // Exterior Gateway Protocol + ProtocolIGP = 9 // any private interior gateway (used by Cisco for their IGRP) + ProtocolBBNRCCMON = 10 // BBN RCC Monitoring + ProtocolNVPII = 11 // Network Voice Protocol + ProtocolPUP = 12 // PUP + ProtocolARGUS = 13 // ARGUS + ProtocolEMCON = 14 // EMCON + ProtocolXNET = 15 // Cross Net Debugger + ProtocolCHAOS = 16 // Chaos + ProtocolUDP = 17 // User Datagram + ProtocolMUX = 18 // Multiplexing + ProtocolDCNMEAS = 19 // DCN Measurement Subsystems + ProtocolHMP = 20 // Host Monitoring + ProtocolPRM = 21 // Packet Radio Measurement + ProtocolXNSIDP = 22 // XEROX NS IDP + ProtocolTRUNK1 = 23 // Trunk-1 + ProtocolTRUNK2 = 24 // Trunk-2 + ProtocolLEAF1 = 25 // Leaf-1 + ProtocolLEAF2 = 26 // Leaf-2 + ProtocolRDP = 27 // Reliable Data Protocol + ProtocolIRTP = 28 // Internet Reliable Transaction + ProtocolISOTP4 = 29 // ISO Transport Protocol Class 4 + ProtocolNETBLT = 30 // Bulk Data Transfer Protocol + ProtocolMFENSP = 31 // MFE Network Services Protocol + ProtocolMERITINP = 32 // MERIT Internodal Protocol + ProtocolDCCP = 33 // Datagram Congestion Control Protocol + Protocol3PC = 34 // Third Party Connect Protocol + ProtocolIDPR = 35 // Inter-Domain Policy Routing Protocol + ProtocolXTP = 36 // XTP + ProtocolDDP = 37 // Datagram Delivery Protocol + ProtocolIDPRCMTP = 38 // IDPR Control Message Transport Proto + ProtocolTPPP = 39 // TP++ Transport Protocol + ProtocolIL = 40 // IL Transport Protocol + ProtocolIPv6 = 41 // IPv6 encapsulation + ProtocolSDRP = 42 // Source Demand Routing Protocol + ProtocolIPv6Route = 43 // Routing Header for IPv6 + ProtocolIPv6Frag = 44 // Fragment Header for IPv6 + ProtocolIDRP = 45 // Inter-Domain Routing Protocol + ProtocolRSVP = 46 // Reservation Protocol + ProtocolGRE = 47 // Generic Routing Encapsulation + ProtocolDSR = 48 // Dynamic Source Routing Protocol + ProtocolBNA = 49 // BNA + ProtocolESP = 50 // Encap Security Payload + ProtocolAH = 51 // Authentication Header + ProtocolINLSP = 52 // Integrated Net Layer Security TUBA + ProtocolNARP = 54 // NBMA Address Resolution Protocol + ProtocolMOBILE = 55 // IP Mobility + ProtocolTLSP = 56 // Transport Layer Security Protocol using Kryptonet key management + ProtocolSKIP = 57 // SKIP + ProtocolIPv6ICMP = 58 // ICMP for IPv6 + ProtocolIPv6NoNxt = 59 // No Next Header for IPv6 + ProtocolIPv6Opts = 60 // Destination Options for IPv6 + ProtocolCFTP = 62 // CFTP + ProtocolSATEXPAK = 64 // SATNET and Backroom EXPAK + ProtocolKRYPTOLAN = 65 // Kryptolan + ProtocolRVD = 66 // MIT Remote Virtual Disk Protocol + ProtocolIPPC = 67 // Internet Pluribus Packet Core + ProtocolSATMON = 69 // SATNET Monitoring + ProtocolVISA = 70 // VISA Protocol + ProtocolIPCV = 71 // Internet Packet Core Utility + ProtocolCPNX = 72 // Computer Protocol Network Executive + ProtocolCPHB = 73 // Computer Protocol Heart Beat + ProtocolWSN = 74 // Wang Span Network + ProtocolPVP = 75 // Packet Video Protocol + ProtocolBRSATMON = 76 // Backroom SATNET Monitoring + ProtocolSUNND = 77 // SUN ND PROTOCOL-Temporary + ProtocolWBMON = 78 // WIDEBAND Monitoring + ProtocolWBEXPAK = 79 // WIDEBAND EXPAK + ProtocolISOIP = 80 // ISO Internet Protocol + ProtocolVMTP = 81 // VMTP + ProtocolSECUREVMTP = 82 // SECURE-VMTP + ProtocolVINES = 83 // VINES + ProtocolTTP = 84 // Transaction Transport Protocol + ProtocolIPTM = 84 // Internet Protocol Traffic Manager + ProtocolNSFNETIGP = 85 // NSFNET-IGP + ProtocolDGP = 86 // Dissimilar Gateway Protocol + ProtocolTCF = 87 // TCF + ProtocolEIGRP = 88 // EIGRP + ProtocolOSPFIGP = 89 // OSPFIGP + ProtocolSpriteRPC = 90 // Sprite RPC Protocol + ProtocolLARP = 91 // Locus Address Resolution Protocol + ProtocolMTP = 92 // Multicast Transport Protocol + ProtocolAX25 = 93 // AX.25 Frames + ProtocolIPIP = 94 // IP-within-IP Encapsulation Protocol + ProtocolSCCSP = 96 // Semaphore Communications Sec. Pro. + ProtocolETHERIP = 97 // Ethernet-within-IP Encapsulation + ProtocolENCAP = 98 // Encapsulation Header + ProtocolGMTP = 100 // GMTP + ProtocolIFMP = 101 // Ipsilon Flow Management Protocol + ProtocolPNNI = 102 // PNNI over IP + ProtocolPIM = 103 // Protocol Independent Multicast + ProtocolARIS = 104 // ARIS + ProtocolSCPS = 105 // SCPS + ProtocolQNX = 106 // QNX + ProtocolAN = 107 // Active Networks + ProtocolIPComp = 108 // IP Payload Compression Protocol + ProtocolSNP = 109 // Sitara Networks Protocol + ProtocolCompaqPeer = 110 // Compaq Peer Protocol + ProtocolIPXinIP = 111 // IPX in IP + ProtocolVRRP = 112 // Virtual Router Redundancy Protocol + ProtocolPGM = 113 // PGM Reliable Transport Protocol + ProtocolL2TP = 115 // Layer Two Tunneling Protocol + ProtocolDDX = 116 // D-II Data Exchange (DDX) + ProtocolIATP = 117 // Interactive Agent Transfer Protocol + ProtocolSTP = 118 // Schedule Transfer Protocol + ProtocolSRP = 119 // SpectraLink Radio Protocol + ProtocolUTI = 120 // UTI + ProtocolSMP = 121 // Simple Message Protocol + ProtocolPTP = 123 // Performance Transparency Protocol + ProtocolISIS = 124 // ISIS over IPv4 + ProtocolFIRE = 125 // FIRE + ProtocolCRTP = 126 // Combat Radio Transport Protocol + ProtocolCRUDP = 127 // Combat Radio User Datagram + ProtocolSSCOPMCE = 128 // SSCOPMCE + ProtocolIPLT = 129 // IPLT + ProtocolSPS = 130 // Secure Packet Shield + ProtocolPIPE = 131 // Private IP Encapsulation within IP + ProtocolSCTP = 132 // Stream Control Transmission Protocol + ProtocolFC = 133 // Fibre Channel + ProtocolRSVPE2EIGNORE = 134 // RSVP-E2E-IGNORE + ProtocolMobilityHeader = 135 // Mobility Header + ProtocolUDPLite = 136 // UDPLite + ProtocolMPLSinIP = 137 // MPLS-in-IP + ProtocolMANET = 138 // MANET Protocols + ProtocolHIP = 139 // Host Identity Protocol + ProtocolShim6 = 140 // Shim6 Protocol + ProtocolWESP = 141 // Wrapped Encapsulating Security Payload + ProtocolROHC = 142 // Robust Header Compression + ProtocolReserved = 255 // Reserved +) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/iana/gen.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/iana/gen.go new file mode 100644 index 00000000..2d8c07ca --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/iana/gen.go @@ -0,0 +1,293 @@ +// 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 ignore + +//go:generate go run gen.go + +// This program generates internet protocol constants and tables by +// reading IANA protocol registries. +package main + +import ( + "bytes" + "encoding/xml" + "fmt" + "go/format" + "io" + "io/ioutil" + "net/http" + "os" + "strconv" + "strings" +) + +var registries = []struct { + url string + parse func(io.Writer, io.Reader) error +}{ + { + "http://www.iana.org/assignments/dscp-registry/dscp-registry.xml", + parseDSCPRegistry, + }, + { + "http://www.iana.org/assignments/ipv4-tos-byte/ipv4-tos-byte.xml", + parseTOSTCByte, + }, + { + "http://www.iana.org/assignments/protocol-numbers/protocol-numbers.xml", + parseProtocolNumbers, + }, +} + +func main() { + var bb bytes.Buffer + fmt.Fprintf(&bb, "// go generate gen.go\n") + fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") + fmt.Fprintf(&bb, "// Package iana provides protocol number resources managed by the Internet Assigned Numbers Authority (IANA).\n") + fmt.Fprintf(&bb, `package iana // import "golang.org/x/net/internal/iana"`+"\n\n") + for _, r := range registries { + resp, err := http.Get(r.url) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + fmt.Fprintf(os.Stderr, "got HTTP status code %v for %v\n", resp.StatusCode, r.url) + os.Exit(1) + } + if err := r.parse(&bb, resp.Body); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + fmt.Fprintf(&bb, "\n") + } + b, err := format.Source(bb.Bytes()) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := ioutil.WriteFile("const.go", b, 0644); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func parseDSCPRegistry(w io.Writer, r io.Reader) error { + dec := xml.NewDecoder(r) + var dr dscpRegistry + if err := dec.Decode(&dr); err != nil { + return err + } + drs := dr.escape() + fmt.Fprintf(w, "// %s, Updated: %s\n", dr.Title, dr.Updated) + fmt.Fprintf(w, "const (\n") + for _, dr := range drs { + fmt.Fprintf(w, "DiffServ%s = %#x", dr.Name, dr.Value) + fmt.Fprintf(w, "// %s\n", dr.OrigName) + } + fmt.Fprintf(w, ")\n") + return nil +} + +type dscpRegistry struct { + XMLName xml.Name `xml:"registry"` + Title string `xml:"title"` + Updated string `xml:"updated"` + Note string `xml:"note"` + RegTitle string `xml:"registry>title"` + PoolRecords []struct { + Name string `xml:"name"` + Space string `xml:"space"` + } `xml:"registry>record"` + Records []struct { + Name string `xml:"name"` + Space string `xml:"space"` + } `xml:"registry>registry>record"` +} + +type canonDSCPRecord struct { + OrigName string + Name string + Value int +} + +func (drr *dscpRegistry) escape() []canonDSCPRecord { + drs := make([]canonDSCPRecord, len(drr.Records)) + sr := strings.NewReplacer( + "+", "", + "-", "", + "/", "", + ".", "", + " ", "", + ) + for i, dr := range drr.Records { + s := strings.TrimSpace(dr.Name) + drs[i].OrigName = s + drs[i].Name = sr.Replace(s) + n, err := strconv.ParseUint(dr.Space, 2, 8) + if err != nil { + continue + } + drs[i].Value = int(n) << 2 + } + return drs +} + +func parseTOSTCByte(w io.Writer, r io.Reader) error { + dec := xml.NewDecoder(r) + var ttb tosTCByte + if err := dec.Decode(&ttb); err != nil { + return err + } + trs := ttb.escape() + fmt.Fprintf(w, "// %s, Updated: %s\n", ttb.Title, ttb.Updated) + fmt.Fprintf(w, "const (\n") + for _, tr := range trs { + fmt.Fprintf(w, "%s = %#x", tr.Keyword, tr.Value) + fmt.Fprintf(w, "// %s\n", tr.OrigKeyword) + } + fmt.Fprintf(w, ")\n") + return nil +} + +type tosTCByte struct { + XMLName xml.Name `xml:"registry"` + Title string `xml:"title"` + Updated string `xml:"updated"` + Note string `xml:"note"` + RegTitle string `xml:"registry>title"` + Records []struct { + Binary string `xml:"binary"` + Keyword string `xml:"keyword"` + } `xml:"registry>record"` +} + +type canonTOSTCByteRecord struct { + OrigKeyword string + Keyword string + Value int +} + +func (ttb *tosTCByte) escape() []canonTOSTCByteRecord { + trs := make([]canonTOSTCByteRecord, len(ttb.Records)) + sr := strings.NewReplacer( + "Capable", "", + "(", "", + ")", "", + "+", "", + "-", "", + "/", "", + ".", "", + " ", "", + ) + for i, tr := range ttb.Records { + s := strings.TrimSpace(tr.Keyword) + trs[i].OrigKeyword = s + ss := strings.Split(s, " ") + if len(ss) > 1 { + trs[i].Keyword = strings.Join(ss[1:], " ") + } else { + trs[i].Keyword = ss[0] + } + trs[i].Keyword = sr.Replace(trs[i].Keyword) + n, err := strconv.ParseUint(tr.Binary, 2, 8) + if err != nil { + continue + } + trs[i].Value = int(n) + } + return trs +} + +func parseProtocolNumbers(w io.Writer, r io.Reader) error { + dec := xml.NewDecoder(r) + var pn protocolNumbers + if err := dec.Decode(&pn); err != nil { + return err + } + prs := pn.escape() + prs = append([]canonProtocolRecord{{ + Name: "IP", + Descr: "IPv4 encapsulation, pseudo protocol number", + Value: 0, + }}, prs...) + fmt.Fprintf(w, "// %s, Updated: %s\n", pn.Title, pn.Updated) + fmt.Fprintf(w, "const (\n") + for _, pr := range prs { + if pr.Name == "" { + continue + } + fmt.Fprintf(w, "Protocol%s = %d", pr.Name, pr.Value) + s := pr.Descr + if s == "" { + s = pr.OrigName + } + fmt.Fprintf(w, "// %s\n", s) + } + fmt.Fprintf(w, ")\n") + return nil +} + +type protocolNumbers struct { + XMLName xml.Name `xml:"registry"` + Title string `xml:"title"` + Updated string `xml:"updated"` + RegTitle string `xml:"registry>title"` + Note string `xml:"registry>note"` + Records []struct { + Value string `xml:"value"` + Name string `xml:"name"` + Descr string `xml:"description"` + } `xml:"registry>record"` +} + +type canonProtocolRecord struct { + OrigName string + Name string + Descr string + Value int +} + +func (pn *protocolNumbers) escape() []canonProtocolRecord { + prs := make([]canonProtocolRecord, len(pn.Records)) + sr := strings.NewReplacer( + "-in-", "in", + "-within-", "within", + "-over-", "over", + "+", "P", + "-", "", + "/", "", + ".", "", + " ", "", + ) + for i, pr := range pn.Records { + if strings.Contains(pr.Name, "Deprecated") || + strings.Contains(pr.Name, "deprecated") { + continue + } + prs[i].OrigName = pr.Name + s := strings.TrimSpace(pr.Name) + switch pr.Name { + case "ISIS over IPv4": + prs[i].Name = "ISIS" + case "manet": + prs[i].Name = "MANET" + default: + prs[i].Name = sr.Replace(s) + } + ss := strings.Split(pr.Descr, "\n") + for i := range ss { + ss[i] = strings.TrimSpace(ss[i]) + } + if len(ss) > 1 { + prs[i].Descr = strings.Join(ss, " ") + } else { + prs[i].Descr = ss[0] + } + prs[i].Value, _ = strconv.Atoi(pr.Value) + } + return prs +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/error_posix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/error_posix.go new file mode 100644 index 00000000..963ed996 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/error_posix.go @@ -0,0 +1,31 @@ +// 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. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris windows + +package nettest + +import ( + "os" + "syscall" +) + +func protocolNotSupported(err error) bool { + switch err := err.(type) { + case syscall.Errno: + switch err { + case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT: + return true + } + case *os.SyscallError: + switch err := err.Err.(type) { + case syscall.Errno: + switch err { + case syscall.EPROTONOSUPPORT, syscall.ENOPROTOOPT: + return true + } + } + } + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/error_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/error_stub.go new file mode 100644 index 00000000..3c74d812 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/error_stub.go @@ -0,0 +1,11 @@ +// 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. + +// +build nacl plan9 + +package nettest + +func protocolNotSupported(err error) bool { + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/interface.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/interface.go new file mode 100644 index 00000000..53ae13a9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/interface.go @@ -0,0 +1,94 @@ +// 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 nettest + +import "net" + +// IsMulticastCapable reports whether ifi is an IP multicast-capable +// network interface. Network must be "ip", "ip4" or "ip6". +func IsMulticastCapable(network string, ifi *net.Interface) (net.IP, bool) { + switch network { + case "ip", "ip4", "ip6": + default: + return nil, false + } + if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 { + return nil, false + } + return hasRoutableIP(network, ifi) +} + +// RoutedInterface returns a network interface that can route IP +// traffic and satisfies flags. It returns nil when an appropriate +// network interface is not found. Network must be "ip", "ip4" or +// "ip6". +func RoutedInterface(network string, flags net.Flags) *net.Interface { + switch network { + case "ip", "ip4", "ip6": + default: + return nil + } + ift, err := net.Interfaces() + if err != nil { + return nil + } + for _, ifi := range ift { + if ifi.Flags&flags != flags { + continue + } + if _, ok := hasRoutableIP(network, &ifi); !ok { + continue + } + return &ifi + } + return nil +} + +func hasRoutableIP(network string, ifi *net.Interface) (net.IP, bool) { + ifat, err := ifi.Addrs() + if err != nil { + return nil, false + } + for _, ifa := range ifat { + switch ifa := ifa.(type) { + case *net.IPAddr: + if ip := routableIP(network, ifa.IP); ip != nil { + return ip, true + } + case *net.IPNet: + if ip := routableIP(network, ifa.IP); ip != nil { + return ip, true + } + } + } + return nil, false +} + +func routableIP(network string, ip net.IP) net.IP { + if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsGlobalUnicast() { + return nil + } + switch network { + case "ip4": + if ip := ip.To4(); ip != nil { + return ip + } + case "ip6": + if ip.IsLoopback() { // addressing scope of the loopback address depends on each implementation + return nil + } + if ip := ip.To16(); ip != nil && ip.To4() == nil { + return ip + } + default: + if ip := ip.To4(); ip != nil { + return ip + } + if ip := ip.To16(); ip != nil { + return ip + } + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit.go new file mode 100644 index 00000000..bb34aec0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit.go @@ -0,0 +1,11 @@ +// 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 nettest + +const defaultMaxOpenFiles = 256 + +// MaxOpenFiles returns the maximum number of open files for the +// caller's process. +func MaxOpenFiles() int { return maxOpenFiles() } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_stub.go new file mode 100644 index 00000000..102bef93 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_stub.go @@ -0,0 +1,9 @@ +// 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 nacl plan9 + +package nettest + +func maxOpenFiles() int { return defaultMaxOpenFiles } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_unix.go new file mode 100644 index 00000000..eb4312ce --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_unix.go @@ -0,0 +1,17 @@ +// 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 darwin dragonfly freebsd linux netbsd openbsd solaris + +package nettest + +import "syscall" + +func maxOpenFiles() int { + var rlim syscall.Rlimit + if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rlim); err != nil { + return defaultMaxOpenFiles + } + return int(rlim.Cur) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_windows.go new file mode 100644 index 00000000..de927b56 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/rlimit_windows.go @@ -0,0 +1,7 @@ +// 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 nettest + +func maxOpenFiles() int { return 4 * defaultMaxOpenFiles /* actually it's 16581375 */ } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack.go new file mode 100644 index 00000000..e07c015f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack.go @@ -0,0 +1,36 @@ +// 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. + +// Package nettest provides utilities for IP testing. +package nettest // import "golang.org/x/net/internal/nettest" + +import "net" + +// SupportsIPv4 reports whether the platform supports IPv4 networking +// functionality. +func SupportsIPv4() bool { + ln, err := net.Listen("tcp4", "127.0.0.1:0") + if err != nil { + return false + } + ln.Close() + return true +} + +// SupportsIPv6 reports whether the platform supports IPv6 networking +// functionality. +func SupportsIPv6() bool { + ln, err := net.Listen("tcp6", "[::1]:0") + if err != nil { + return false + } + ln.Close() + return true +} + +// ProtocolNotSupported reports whether err is a protocol not +// supported error. +func ProtocolNotSupported(err error) bool { + return protocolNotSupported(err) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_stub.go new file mode 100644 index 00000000..1b5fde1a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_stub.go @@ -0,0 +1,18 @@ +// 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 nacl plan9 + +package nettest + +import ( + "fmt" + "runtime" +) + +// SupportsRawIPSocket reports whether the platform supports raw IP +// sockets. +func SupportsRawIPSocket() (string, bool) { + return fmt.Sprintf("not supported on %s", runtime.GOOS), false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_unix.go new file mode 100644 index 00000000..af89229f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_unix.go @@ -0,0 +1,22 @@ +// 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 darwin dragonfly freebsd linux netbsd openbsd solaris + +package nettest + +import ( + "fmt" + "os" + "runtime" +) + +// SupportsRawIPSocket reports whether the platform supports raw IP +// sockets. +func SupportsRawIPSocket() (string, bool) { + if os.Getuid() != 0 { + return fmt.Sprintf("must be root on %s", runtime.GOOS), false + } + return "", true +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_windows.go new file mode 100644 index 00000000..a21f4993 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/nettest/stack_windows.go @@ -0,0 +1,32 @@ +// 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 nettest + +import ( + "fmt" + "runtime" + "syscall" +) + +// SupportsRawIPSocket reports whether the platform supports raw IP +// sockets. +func SupportsRawIPSocket() (string, bool) { + // From http://msdn.microsoft.com/en-us/library/windows/desktop/ms740548.aspx: + // Note: To use a socket of type SOCK_RAW requires administrative privileges. + // Users running Winsock applications that use raw sockets must be a member of + // the Administrators group on the local computer, otherwise raw socket calls + // will fail with an error code of WSAEACCES. On Windows Vista and later, access + // for raw sockets is enforced at socket creation. In earlier versions of Windows, + // access for raw sockets is enforced during other socket operations. + s, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, 0) + if err == syscall.WSAEACCES { + return fmt.Sprintf("no access to raw socket allowed on %s", runtime.GOOS), false + } + if err != nil { + return err.Error(), false + } + syscall.Closesocket(s) + return "", true +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/timeseries/timeseries.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/timeseries/timeseries.go new file mode 100644 index 00000000..1119f344 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/timeseries/timeseries.go @@ -0,0 +1,525 @@ +// 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 timeseries implements a time series structure for stats collection. +package timeseries // import "golang.org/x/net/internal/timeseries" + +import ( + "fmt" + "log" + "time" +) + +const ( + timeSeriesNumBuckets = 64 + minuteHourSeriesNumBuckets = 60 +) + +var timeSeriesResolutions = []time.Duration{ + 1 * time.Second, + 10 * time.Second, + 1 * time.Minute, + 10 * time.Minute, + 1 * time.Hour, + 6 * time.Hour, + 24 * time.Hour, // 1 day + 7 * 24 * time.Hour, // 1 week + 4 * 7 * 24 * time.Hour, // 4 weeks + 16 * 7 * 24 * time.Hour, // 16 weeks +} + +var minuteHourSeriesResolutions = []time.Duration{ + 1 * time.Second, + 1 * time.Minute, +} + +// An Observable is a kind of data that can be aggregated in a time series. +type Observable interface { + Multiply(ratio float64) // Multiplies the data in self by a given ratio + Add(other Observable) // Adds the data from a different observation to self + Clear() // Clears the observation so it can be reused. + CopyFrom(other Observable) // Copies the contents of a given observation to self +} + +// Float attaches the methods of Observable to a float64. +type Float float64 + +// NewFloat returns a Float. +func NewFloat() Observable { + f := Float(0) + return &f +} + +// String returns the float as a string. +func (f *Float) String() string { return fmt.Sprintf("%g", f.Value()) } + +// Value returns the float's value. +func (f *Float) Value() float64 { return float64(*f) } + +func (f *Float) Multiply(ratio float64) { *f *= Float(ratio) } + +func (f *Float) Add(other Observable) { + o := other.(*Float) + *f += *o +} + +func (f *Float) Clear() { *f = 0 } + +func (f *Float) CopyFrom(other Observable) { + o := other.(*Float) + *f = *o +} + +// A Clock tells the current time. +type Clock interface { + Time() time.Time +} + +type defaultClock int + +var defaultClockInstance defaultClock + +func (defaultClock) Time() time.Time { return time.Now() } + +// Information kept per level. Each level consists of a circular list of +// observations. The start of the level may be derived from end and the +// len(buckets) * sizeInMillis. +type tsLevel struct { + oldest int // index to oldest bucketed Observable + newest int // index to newest bucketed Observable + end time.Time // end timestamp for this level + size time.Duration // duration of the bucketed Observable + buckets []Observable // collections of observations + provider func() Observable // used for creating new Observable +} + +func (l *tsLevel) Clear() { + l.oldest = 0 + l.newest = len(l.buckets) - 1 + l.end = time.Time{} + for i := range l.buckets { + if l.buckets[i] != nil { + l.buckets[i].Clear() + l.buckets[i] = nil + } + } +} + +func (l *tsLevel) InitLevel(size time.Duration, numBuckets int, f func() Observable) { + l.size = size + l.provider = f + l.buckets = make([]Observable, numBuckets) +} + +// Keeps a sequence of levels. Each level is responsible for storing data at +// a given resolution. For example, the first level stores data at a one +// minute resolution while the second level stores data at a one hour +// resolution. + +// Each level is represented by a sequence of buckets. Each bucket spans an +// interval equal to the resolution of the level. New observations are added +// to the last bucket. +type timeSeries struct { + provider func() Observable // make more Observable + numBuckets int // number of buckets in each level + levels []*tsLevel // levels of bucketed Observable + lastAdd time.Time // time of last Observable tracked + total Observable // convenient aggregation of all Observable + clock Clock // Clock for getting current time + pending Observable // observations not yet bucketed + pendingTime time.Time // what time are we keeping in pending + dirty bool // if there are pending observations +} + +// init initializes a level according to the supplied criteria. +func (ts *timeSeries) init(resolutions []time.Duration, f func() Observable, numBuckets int, clock Clock) { + ts.provider = f + ts.numBuckets = numBuckets + ts.clock = clock + ts.levels = make([]*tsLevel, len(resolutions)) + + for i := range resolutions { + if i > 0 && resolutions[i-1] >= resolutions[i] { + log.Print("timeseries: resolutions must be monotonically increasing") + break + } + newLevel := new(tsLevel) + newLevel.InitLevel(resolutions[i], ts.numBuckets, ts.provider) + ts.levels[i] = newLevel + } + + ts.Clear() +} + +// Clear removes all observations from the time series. +func (ts *timeSeries) Clear() { + ts.lastAdd = time.Time{} + ts.total = ts.resetObservation(ts.total) + ts.pending = ts.resetObservation(ts.pending) + ts.pendingTime = time.Time{} + ts.dirty = false + + for i := range ts.levels { + ts.levels[i].Clear() + } +} + +// Add records an observation at the current time. +func (ts *timeSeries) Add(observation Observable) { + ts.AddWithTime(observation, ts.clock.Time()) +} + +// AddWithTime records an observation at the specified time. +func (ts *timeSeries) AddWithTime(observation Observable, t time.Time) { + + smallBucketDuration := ts.levels[0].size + + if t.After(ts.lastAdd) { + ts.lastAdd = t + } + + if t.After(ts.pendingTime) { + ts.advance(t) + ts.mergePendingUpdates() + ts.pendingTime = ts.levels[0].end + ts.pending.CopyFrom(observation) + ts.dirty = true + } else if t.After(ts.pendingTime.Add(-1 * smallBucketDuration)) { + // The observation is close enough to go into the pending bucket. + // This compensates for clock skewing and small scheduling delays + // by letting the update stay in the fast path. + ts.pending.Add(observation) + ts.dirty = true + } else { + ts.mergeValue(observation, t) + } +} + +// mergeValue inserts the observation at the specified time in the past into all levels. +func (ts *timeSeries) mergeValue(observation Observable, t time.Time) { + for _, level := range ts.levels { + index := (ts.numBuckets - 1) - int(level.end.Sub(t)/level.size) + if 0 <= index && index < ts.numBuckets { + bucketNumber := (level.oldest + index) % ts.numBuckets + if level.buckets[bucketNumber] == nil { + level.buckets[bucketNumber] = level.provider() + } + level.buckets[bucketNumber].Add(observation) + } + } + ts.total.Add(observation) +} + +// mergePendingUpdates applies the pending updates into all levels. +func (ts *timeSeries) mergePendingUpdates() { + if ts.dirty { + ts.mergeValue(ts.pending, ts.pendingTime) + ts.pending = ts.resetObservation(ts.pending) + ts.dirty = false + } +} + +// advance cycles the buckets at each level until the latest bucket in +// each level can hold the time specified. +func (ts *timeSeries) advance(t time.Time) { + if !t.After(ts.levels[0].end) { + return + } + for i := 0; i < len(ts.levels); i++ { + level := ts.levels[i] + if !level.end.Before(t) { + break + } + + // If the time is sufficiently far, just clear the level and advance + // directly. + if !t.Before(level.end.Add(level.size * time.Duration(ts.numBuckets))) { + for _, b := range level.buckets { + ts.resetObservation(b) + } + level.end = time.Unix(0, (t.UnixNano()/level.size.Nanoseconds())*level.size.Nanoseconds()) + } + + for t.After(level.end) { + level.end = level.end.Add(level.size) + level.newest = level.oldest + level.oldest = (level.oldest + 1) % ts.numBuckets + ts.resetObservation(level.buckets[level.newest]) + } + + t = level.end + } +} + +// Latest returns the sum of the num latest buckets from the level. +func (ts *timeSeries) Latest(level, num int) Observable { + now := ts.clock.Time() + if ts.levels[0].end.Before(now) { + ts.advance(now) + } + + ts.mergePendingUpdates() + + result := ts.provider() + l := ts.levels[level] + index := l.newest + + for i := 0; i < num; i++ { + if l.buckets[index] != nil { + result.Add(l.buckets[index]) + } + if index == 0 { + index = ts.numBuckets + } + index-- + } + + return result +} + +// LatestBuckets returns a copy of the num latest buckets from level. +func (ts *timeSeries) LatestBuckets(level, num int) []Observable { + if level < 0 || level > len(ts.levels) { + log.Print("timeseries: bad level argument: ", level) + return nil + } + if num < 0 || num >= ts.numBuckets { + log.Print("timeseries: bad num argument: ", num) + return nil + } + + results := make([]Observable, num) + now := ts.clock.Time() + if ts.levels[0].end.Before(now) { + ts.advance(now) + } + + ts.mergePendingUpdates() + + l := ts.levels[level] + index := l.newest + + for i := 0; i < num; i++ { + result := ts.provider() + results[i] = result + if l.buckets[index] != nil { + result.CopyFrom(l.buckets[index]) + } + + if index == 0 { + index = ts.numBuckets + } + index -= 1 + } + return results +} + +// ScaleBy updates observations by scaling by factor. +func (ts *timeSeries) ScaleBy(factor float64) { + for _, l := range ts.levels { + for i := 0; i < ts.numBuckets; i++ { + l.buckets[i].Multiply(factor) + } + } + + ts.total.Multiply(factor) + ts.pending.Multiply(factor) +} + +// Range returns the sum of observations added over the specified time range. +// If start or finish times don't fall on bucket boundaries of the same +// level, then return values are approximate answers. +func (ts *timeSeries) Range(start, finish time.Time) Observable { + return ts.ComputeRange(start, finish, 1)[0] +} + +// Recent returns the sum of observations from the last delta. +func (ts *timeSeries) Recent(delta time.Duration) Observable { + now := ts.clock.Time() + return ts.Range(now.Add(-delta), now) +} + +// Total returns the total of all observations. +func (ts *timeSeries) Total() Observable { + ts.mergePendingUpdates() + return ts.total +} + +// ComputeRange computes a specified number of values into a slice using +// the observations recorded over the specified time period. The return +// values are approximate if the start or finish times don't fall on the +// bucket boundaries at the same level or if the number of buckets spanning +// the range is not an integral multiple of num. +func (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observable { + if start.After(finish) { + log.Printf("timeseries: start > finish, %v>%v", start, finish) + return nil + } + + if num < 0 { + log.Printf("timeseries: num < 0, %v", num) + return nil + } + + results := make([]Observable, num) + + for _, l := range ts.levels { + if !start.Before(l.end.Add(-l.size * time.Duration(ts.numBuckets))) { + ts.extract(l, start, finish, num, results) + return results + } + } + + // Failed to find a level that covers the desired range. So just + // extract from the last level, even if it doesn't cover the entire + // desired range. + ts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results) + + return results +} + +// RecentList returns the specified number of values in slice over the most +// recent time period of the specified range. +func (ts *timeSeries) RecentList(delta time.Duration, num int) []Observable { + if delta < 0 { + return nil + } + now := ts.clock.Time() + return ts.ComputeRange(now.Add(-delta), now, num) +} + +// extract returns a slice of specified number of observations from a given +// level over a given range. +func (ts *timeSeries) extract(l *tsLevel, start, finish time.Time, num int, results []Observable) { + ts.mergePendingUpdates() + + srcInterval := l.size + dstInterval := finish.Sub(start) / time.Duration(num) + dstStart := start + srcStart := l.end.Add(-srcInterval * time.Duration(ts.numBuckets)) + + srcIndex := 0 + + // Where should scanning start? + if dstStart.After(srcStart) { + advance := dstStart.Sub(srcStart) / srcInterval + srcIndex += int(advance) + srcStart = srcStart.Add(advance * srcInterval) + } + + // The i'th value is computed as show below. + // interval = (finish/start)/num + // i'th value = sum of observation in range + // [ start + i * interval, + // start + (i + 1) * interval ) + for i := 0; i < num; i++ { + results[i] = ts.resetObservation(results[i]) + dstEnd := dstStart.Add(dstInterval) + for srcIndex < ts.numBuckets && srcStart.Before(dstEnd) { + srcEnd := srcStart.Add(srcInterval) + if srcEnd.After(ts.lastAdd) { + srcEnd = ts.lastAdd + } + + if !srcEnd.Before(dstStart) { + srcValue := l.buckets[(srcIndex+l.oldest)%ts.numBuckets] + if !srcStart.Before(dstStart) && !srcEnd.After(dstEnd) { + // dst completely contains src. + if srcValue != nil { + results[i].Add(srcValue) + } + } else { + // dst partially overlaps src. + overlapStart := maxTime(srcStart, dstStart) + overlapEnd := minTime(srcEnd, dstEnd) + base := srcEnd.Sub(srcStart) + fraction := overlapEnd.Sub(overlapStart).Seconds() / base.Seconds() + + used := ts.provider() + if srcValue != nil { + used.CopyFrom(srcValue) + } + used.Multiply(fraction) + results[i].Add(used) + } + + if srcEnd.After(dstEnd) { + break + } + } + srcIndex++ + srcStart = srcStart.Add(srcInterval) + } + dstStart = dstStart.Add(dstInterval) + } +} + +// resetObservation clears the content so the struct may be reused. +func (ts *timeSeries) resetObservation(observation Observable) Observable { + if observation == nil { + observation = ts.provider() + } else { + observation.Clear() + } + return observation +} + +// TimeSeries tracks data at granularities from 1 second to 16 weeks. +type TimeSeries struct { + timeSeries +} + +// NewTimeSeries creates a new TimeSeries using the function provided for creating new Observable. +func NewTimeSeries(f func() Observable) *TimeSeries { + return NewTimeSeriesWithClock(f, defaultClockInstance) +} + +// NewTimeSeriesWithClock creates a new TimeSeries using the function provided for creating new Observable and the clock for +// assigning timestamps. +func NewTimeSeriesWithClock(f func() Observable, clock Clock) *TimeSeries { + ts := new(TimeSeries) + ts.timeSeries.init(timeSeriesResolutions, f, timeSeriesNumBuckets, clock) + return ts +} + +// MinuteHourSeries tracks data at granularities of 1 minute and 1 hour. +type MinuteHourSeries struct { + timeSeries +} + +// NewMinuteHourSeries creates a new MinuteHourSeries using the function provided for creating new Observable. +func NewMinuteHourSeries(f func() Observable) *MinuteHourSeries { + return NewMinuteHourSeriesWithClock(f, defaultClockInstance) +} + +// NewMinuteHourSeriesWithClock creates a new MinuteHourSeries using the function provided for creating new Observable and the clock for +// assigning timestamps. +func NewMinuteHourSeriesWithClock(f func() Observable, clock Clock) *MinuteHourSeries { + ts := new(MinuteHourSeries) + ts.timeSeries.init(minuteHourSeriesResolutions, f, + minuteHourSeriesNumBuckets, clock) + return ts +} + +func (ts *MinuteHourSeries) Minute() Observable { + return ts.timeSeries.Latest(0, 60) +} + +func (ts *MinuteHourSeries) Hour() Observable { + return ts.timeSeries.Latest(1, 60) +} + +func minTime(a, b time.Time) time.Time { + if a.Before(b) { + return a + } + return b +} + +func maxTime(a, b time.Time) time.Time { + if a.After(b) { + return a + } + return b +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/timeseries/timeseries_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/timeseries/timeseries_test.go new file mode 100644 index 00000000..66325a91 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/internal/timeseries/timeseries_test.go @@ -0,0 +1,170 @@ +// 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 timeseries + +import ( + "math" + "testing" + "time" +) + +func isNear(x *Float, y float64, tolerance float64) bool { + return math.Abs(x.Value()-y) < tolerance +} + +func isApproximate(x *Float, y float64) bool { + return isNear(x, y, 1e-2) +} + +func checkApproximate(t *testing.T, o Observable, y float64) { + x := o.(*Float) + if !isApproximate(x, y) { + t.Errorf("Wanted %g, got %g", y, x.Value()) + } +} + +func checkNear(t *testing.T, o Observable, y, tolerance float64) { + x := o.(*Float) + if !isNear(x, y, tolerance) { + t.Errorf("Wanted %g +- %g, got %g", y, tolerance, x.Value()) + } +} + +var baseTime = time.Date(2013, 1, 1, 0, 0, 0, 0, time.UTC) + +func tu(s int64) time.Time { + return baseTime.Add(time.Duration(s) * time.Second) +} + +func tu2(s int64, ns int64) time.Time { + return baseTime.Add(time.Duration(s)*time.Second + time.Duration(ns)*time.Nanosecond) +} + +func TestBasicTimeSeries(t *testing.T) { + ts := NewTimeSeries(NewFloat) + fo := new(Float) + *fo = Float(10) + ts.AddWithTime(fo, tu(1)) + ts.AddWithTime(fo, tu(1)) + ts.AddWithTime(fo, tu(1)) + ts.AddWithTime(fo, tu(1)) + checkApproximate(t, ts.Range(tu(0), tu(1)), 40) + checkApproximate(t, ts.Total(), 40) + ts.AddWithTime(fo, tu(3)) + ts.AddWithTime(fo, tu(3)) + ts.AddWithTime(fo, tu(3)) + checkApproximate(t, ts.Range(tu(0), tu(2)), 40) + checkApproximate(t, ts.Range(tu(2), tu(4)), 30) + checkApproximate(t, ts.Total(), 70) + ts.AddWithTime(fo, tu(1)) + ts.AddWithTime(fo, tu(1)) + checkApproximate(t, ts.Range(tu(0), tu(2)), 60) + checkApproximate(t, ts.Range(tu(2), tu(4)), 30) + checkApproximate(t, ts.Total(), 90) + *fo = Float(100) + ts.AddWithTime(fo, tu(100)) + checkApproximate(t, ts.Range(tu(99), tu(100)), 100) + checkApproximate(t, ts.Range(tu(0), tu(4)), 36) + checkApproximate(t, ts.Total(), 190) + *fo = Float(10) + ts.AddWithTime(fo, tu(1)) + ts.AddWithTime(fo, tu(1)) + checkApproximate(t, ts.Range(tu(0), tu(4)), 44) + checkApproximate(t, ts.Range(tu(37), tu2(100, 100e6)), 100) + checkApproximate(t, ts.Range(tu(50), tu2(100, 100e6)), 100) + checkApproximate(t, ts.Range(tu(99), tu2(100, 100e6)), 100) + checkApproximate(t, ts.Total(), 210) + + for i, l := range ts.ComputeRange(tu(36), tu(100), 64) { + if i == 63 { + checkApproximate(t, l, 100) + } else { + checkApproximate(t, l, 0) + } + } + + checkApproximate(t, ts.Range(tu(0), tu(100)), 210) + checkApproximate(t, ts.Range(tu(10), tu(100)), 100) + + for i, l := range ts.ComputeRange(tu(0), tu(100), 100) { + if i < 10 { + checkApproximate(t, l, 11) + } else if i >= 90 { + checkApproximate(t, l, 10) + } else { + checkApproximate(t, l, 0) + } + } +} + +func TestFloat(t *testing.T) { + f := Float(1) + if g, w := f.String(), "1"; g != w { + t.Errorf("Float(1).String = %q; want %q", g, w) + } + f2 := Float(2) + var o Observable = &f2 + f.Add(o) + if g, w := f.Value(), 3.0; g != w { + t.Errorf("Float post-add = %v; want %v", g, w) + } + f.Multiply(2) + if g, w := f.Value(), 6.0; g != w { + t.Errorf("Float post-multiply = %v; want %v", g, w) + } + f.Clear() + if g, w := f.Value(), 0.0; g != w { + t.Errorf("Float post-clear = %v; want %v", g, w) + } + f.CopyFrom(&f2) + if g, w := f.Value(), 2.0; g != w { + t.Errorf("Float post-CopyFrom = %v; want %v", g, w) + } +} + +type mockClock struct { + time time.Time +} + +func (m *mockClock) Time() time.Time { return m.time } +func (m *mockClock) Set(t time.Time) { m.time = t } + +const buckets = 6 + +var testResolutions = []time.Duration{ + 10 * time.Second, // level holds one minute of observations + 100 * time.Second, // level holds ten minutes of observations + 10 * time.Minute, // level holds one hour of observations +} + +// TestTimeSeries uses a small number of buckets to force a higher +// error rate on approximations from the timeseries. +type TestTimeSeries struct { + timeSeries +} + +func TestExpectedErrorRate(t *testing.T) { + ts := new(TestTimeSeries) + fake := new(mockClock) + fake.Set(time.Now()) + ts.timeSeries.init(testResolutions, NewFloat, buckets, fake) + for i := 1; i <= 61*61; i++ { + fake.Set(fake.Time().Add(1 * time.Second)) + ob := Float(1) + ts.AddWithTime(&ob, fake.Time()) + + // The results should be accurate within one missing bucket (1/6) of the observations recorded. + checkNear(t, ts.Latest(0, buckets), min(float64(i), 60), 10) + checkNear(t, ts.Latest(1, buckets), min(float64(i), 600), 100) + checkNear(t, ts.Latest(2, buckets), min(float64(i), 3600), 600) + } +} + +func min(a, b float64) float64 { + if a < b { + return a + } + return b +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control.go new file mode 100644 index 00000000..8cadfd7f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control.go @@ -0,0 +1,70 @@ +// 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 ipv4 + +import ( + "fmt" + "net" + "sync" +) + +type rawOpt struct { + sync.RWMutex + cflags ControlFlags +} + +func (c *rawOpt) set(f ControlFlags) { c.cflags |= f } +func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f } +func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 } + +type ControlFlags uint + +const ( + FlagTTL ControlFlags = 1 << iota // pass the TTL on the received packet + FlagSrc // pass the source address on the received packet + FlagDst // pass the destination address on the received packet + FlagInterface // pass the interface index on the received packet +) + +// A ControlMessage represents per packet basis IP-level socket options. +type ControlMessage struct { + // Receiving socket options: SetControlMessage allows to + // receive the options from the protocol stack using ReadFrom + // method of PacketConn or RawConn. + // + // Specifying socket options: ControlMessage for WriteTo + // method of PacketConn or RawConn allows to send the options + // to the protocol stack. + // + TTL int // time-to-live, receiving only + Src net.IP // source address, specifying only + Dst net.IP // destination address, receiving only + IfIndex int // interface index, must be 1 <= value when specifying +} + +func (cm *ControlMessage) String() string { + if cm == nil { + return "" + } + return fmt.Sprintf("ttl=%d src=%v dst=%v ifindex=%d", cm.TTL, cm.Src, cm.Dst, cm.IfIndex) +} + +// Ancillary data socket options +const ( + ctlTTL = iota // header field + ctlSrc // header field + ctlDst // header field + ctlInterface // inbound or outbound interface + ctlPacketInfo // inbound or outbound packet path + ctlMax +) + +// A ctlOpt represents a binding for ancillary data socket option. +type ctlOpt struct { + name int // option name, must be equal or greater than 1 + length int // option length + marshal func([]byte, *ControlMessage) []byte + parse func(*ControlMessage, []byte) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_bsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_bsd.go new file mode 100644 index 00000000..33d8bc8b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_bsd.go @@ -0,0 +1,40 @@ +// 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 darwin dragonfly freebsd netbsd openbsd + +package ipv4 + +import ( + "net" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func marshalDst(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIP + m.Type = sysIP_RECVDSTADDR + m.SetLen(syscall.CmsgLen(net.IPv4len)) + return b[syscall.CmsgSpace(net.IPv4len):] +} + +func parseDst(cm *ControlMessage, b []byte) { + cm.Dst = b[:net.IPv4len] +} + +func marshalInterface(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIP + m.Type = sysIP_RECVIF + m.SetLen(syscall.CmsgLen(syscall.SizeofSockaddrDatalink)) + return b[syscall.CmsgSpace(syscall.SizeofSockaddrDatalink):] +} + +func parseInterface(cm *ControlMessage, b []byte) { + sadl := (*syscall.SockaddrDatalink)(unsafe.Pointer(&b[0])) + cm.IfIndex = int(sadl.Index) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_pktinfo.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_pktinfo.go new file mode 100644 index 00000000..444782f3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_pktinfo.go @@ -0,0 +1,37 @@ +// 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. + +// +build darwin linux + +package ipv4 + +import ( + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func marshalPacketInfo(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIP + m.Type = sysIP_PKTINFO + m.SetLen(syscall.CmsgLen(sysSizeofInetPktinfo)) + if cm != nil { + pi := (*sysInetPktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)])) + if ip := cm.Src.To4(); ip != nil { + copy(pi.Spec_dst[:], ip) + } + if cm.IfIndex > 0 { + pi.setIfindex(cm.IfIndex) + } + } + return b[syscall.CmsgSpace(sysSizeofInetPktinfo):] +} + +func parsePacketInfo(cm *ControlMessage, b []byte) { + pi := (*sysInetPktinfo)(unsafe.Pointer(&b[0])) + cm.IfIndex = int(pi.Ifindex) + cm.Dst = pi.Addr[:] +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_stub.go new file mode 100644 index 00000000..4d850719 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_stub.go @@ -0,0 +1,23 @@ +// 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 nacl plan9 solaris + +package ipv4 + +func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error { + return errOpNoSupport +} + +func newControlMessage(opt *rawOpt) []byte { + return nil +} + +func parseControlMessage(b []byte) (*ControlMessage, error) { + return nil, errOpNoSupport +} + +func marshalControlMessage(cm *ControlMessage) []byte { + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_unix.go new file mode 100644 index 00000000..3000c52e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_unix.go @@ -0,0 +1,164 @@ +// 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 darwin dragonfly freebsd linux netbsd openbsd + +package ipv4 + +import ( + "os" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error { + opt.Lock() + defer opt.Unlock() + if cf&FlagTTL != 0 && sockOpts[ssoReceiveTTL].name > 0 { + if err := setInt(fd, &sockOpts[ssoReceiveTTL], boolint(on)); err != nil { + return err + } + if on { + opt.set(FlagTTL) + } else { + opt.clear(FlagTTL) + } + } + if sockOpts[ssoPacketInfo].name > 0 { + if cf&(FlagSrc|FlagDst|FlagInterface) != 0 { + if err := setInt(fd, &sockOpts[ssoPacketInfo], boolint(on)); err != nil { + return err + } + if on { + opt.set(cf & (FlagSrc | FlagDst | FlagInterface)) + } else { + opt.clear(cf & (FlagSrc | FlagDst | FlagInterface)) + } + } + } else { + if cf&FlagDst != 0 && sockOpts[ssoReceiveDst].name > 0 { + if err := setInt(fd, &sockOpts[ssoReceiveDst], boolint(on)); err != nil { + return err + } + if on { + opt.set(FlagDst) + } else { + opt.clear(FlagDst) + } + } + if cf&FlagInterface != 0 && sockOpts[ssoReceiveInterface].name > 0 { + if err := setInt(fd, &sockOpts[ssoReceiveInterface], boolint(on)); err != nil { + return err + } + if on { + opt.set(FlagInterface) + } else { + opt.clear(FlagInterface) + } + } + } + return nil +} + +func newControlMessage(opt *rawOpt) (oob []byte) { + opt.RLock() + var l int + if opt.isset(FlagTTL) && ctlOpts[ctlTTL].name > 0 { + l += syscall.CmsgSpace(ctlOpts[ctlTTL].length) + } + if ctlOpts[ctlPacketInfo].name > 0 { + if opt.isset(FlagSrc | FlagDst | FlagInterface) { + l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length) + } + } else { + if opt.isset(FlagDst) && ctlOpts[ctlDst].name > 0 { + l += syscall.CmsgSpace(ctlOpts[ctlDst].length) + } + if opt.isset(FlagInterface) && ctlOpts[ctlInterface].name > 0 { + l += syscall.CmsgSpace(ctlOpts[ctlInterface].length) + } + } + if l > 0 { + oob = make([]byte, l) + b := oob + if opt.isset(FlagTTL) && ctlOpts[ctlTTL].name > 0 { + b = ctlOpts[ctlTTL].marshal(b, nil) + } + if ctlOpts[ctlPacketInfo].name > 0 { + if opt.isset(FlagSrc | FlagDst | FlagInterface) { + b = ctlOpts[ctlPacketInfo].marshal(b, nil) + } + } else { + if opt.isset(FlagDst) && ctlOpts[ctlDst].name > 0 { + b = ctlOpts[ctlDst].marshal(b, nil) + } + if opt.isset(FlagInterface) && ctlOpts[ctlInterface].name > 0 { + b = ctlOpts[ctlInterface].marshal(b, nil) + } + } + } + opt.RUnlock() + return +} + +func parseControlMessage(b []byte) (*ControlMessage, error) { + if len(b) == 0 { + return nil, nil + } + cmsgs, err := syscall.ParseSocketControlMessage(b) + if err != nil { + return nil, os.NewSyscallError("parse socket control message", err) + } + cm := &ControlMessage{} + for _, m := range cmsgs { + if m.Header.Level != iana.ProtocolIP { + continue + } + switch int(m.Header.Type) { + case ctlOpts[ctlTTL].name: + ctlOpts[ctlTTL].parse(cm, m.Data[:]) + case ctlOpts[ctlDst].name: + ctlOpts[ctlDst].parse(cm, m.Data[:]) + case ctlOpts[ctlInterface].name: + ctlOpts[ctlInterface].parse(cm, m.Data[:]) + case ctlOpts[ctlPacketInfo].name: + ctlOpts[ctlPacketInfo].parse(cm, m.Data[:]) + } + } + return cm, nil +} + +func marshalControlMessage(cm *ControlMessage) (oob []byte) { + if cm == nil { + return nil + } + var l int + pktinfo := false + if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To4() != nil || cm.IfIndex > 0) { + pktinfo = true + l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length) + } + if l > 0 { + oob = make([]byte, l) + b := oob + if pktinfo { + b = ctlOpts[ctlPacketInfo].marshal(b, cm) + } + } + return +} + +func marshalTTL(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIP + m.Type = sysIP_RECVTTL + m.SetLen(syscall.CmsgLen(1)) + return b[syscall.CmsgSpace(1):] +} + +func parseTTL(cm *ControlMessage, b []byte) { + cm.TTL = int(*(*byte)(unsafe.Pointer(&b[:1][0]))) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_windows.go new file mode 100644 index 00000000..800f6377 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/control_windows.go @@ -0,0 +1,27 @@ +// 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 ipv4 + +import "syscall" + +func setControlMessage(fd syscall.Handle, opt *rawOpt, cf ControlFlags, on bool) error { + // TODO(mikio): implement this + return syscall.EWINDOWS +} + +func newControlMessage(opt *rawOpt) []byte { + // TODO(mikio): implement this + return nil +} + +func parseControlMessage(b []byte) (*ControlMessage, error) { + // TODO(mikio): implement this + return nil, syscall.EWINDOWS +} + +func marshalControlMessage(cm *ControlMessage) []byte { + // TODO(mikio): implement this + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_darwin.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_darwin.go new file mode 100644 index 00000000..731d56a7 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_darwin.go @@ -0,0 +1,77 @@ +// 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. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include + +#include +*/ +import "C" + +const ( + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_RECVDSTADDR = C.IP_RECVDSTADDR + sysIP_RETOPTS = C.IP_RETOPTS + sysIP_RECVIF = C.IP_RECVIF + sysIP_STRIPHDR = C.IP_STRIPHDR + sysIP_RECVTTL = C.IP_RECVTTL + sysIP_BOUND_IF = C.IP_BOUND_IF + sysIP_PKTINFO = C.IP_PKTINFO + sysIP_RECVPKTINFO = C.IP_RECVPKTINFO + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + sysIP_MULTICAST_VIF = C.IP_MULTICAST_VIF + sysIP_MULTICAST_IFINDEX = C.IP_MULTICAST_IFINDEX + sysIP_ADD_SOURCE_MEMBERSHIP = C.IP_ADD_SOURCE_MEMBERSHIP + sysIP_DROP_SOURCE_MEMBERSHIP = C.IP_DROP_SOURCE_MEMBERSHIP + sysIP_BLOCK_SOURCE = C.IP_BLOCK_SOURCE + sysIP_UNBLOCK_SOURCE = C.IP_UNBLOCK_SOURCE + sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP + sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP + sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP + sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP + sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE + sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE + + sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage + sysSizeofSockaddrInet = C.sizeof_struct_sockaddr_in + sysSizeofInetPktinfo = C.sizeof_struct_in_pktinfo + + sysSizeofIPMreq = C.sizeof_struct_ip_mreq + sysSizeofIPMreqn = C.sizeof_struct_ip_mreqn + sysSizeofIPMreqSource = C.sizeof_struct_ip_mreq_source + sysSizeofGroupReq = C.sizeof_struct_group_req + sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req +) + +type sysSockaddrStorage C.struct_sockaddr_storage + +type sysSockaddrInet C.struct_sockaddr_in + +type sysInetPktinfo C.struct_in_pktinfo + +type sysIPMreq C.struct_ip_mreq + +type sysIPMreqn C.struct_ip_mreqn + +type sysIPMreqSource C.struct_ip_mreq_source + +type sysGroupReq C.struct_group_req + +type sysGroupSourceReq C.struct_group_source_req diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_dragonfly.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_dragonfly.go new file mode 100644 index 00000000..08e3b855 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_dragonfly.go @@ -0,0 +1,38 @@ +// 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. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include +*/ +import "C" + +const ( + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_RECVDSTADDR = C.IP_RECVDSTADDR + sysIP_RETOPTS = C.IP_RETOPTS + sysIP_RECVIF = C.IP_RECVIF + sysIP_RECVTTL = C.IP_RECVTTL + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_MULTICAST_VIF = C.IP_MULTICAST_VIF + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + + sysSizeofIPMreq = C.sizeof_struct_ip_mreq +) + +type sysIPMreq C.struct_ip_mreq diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_freebsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_freebsd.go new file mode 100644 index 00000000..f12ca327 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_freebsd.go @@ -0,0 +1,75 @@ +// 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. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include + +#include +*/ +import "C" + +const ( + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_RECVDSTADDR = C.IP_RECVDSTADDR + sysIP_SENDSRCADDR = C.IP_SENDSRCADDR + sysIP_RETOPTS = C.IP_RETOPTS + sysIP_RECVIF = C.IP_RECVIF + sysIP_ONESBCAST = C.IP_ONESBCAST + sysIP_BINDANY = C.IP_BINDANY + sysIP_RECVTTL = C.IP_RECVTTL + sysIP_MINTTL = C.IP_MINTTL + sysIP_DONTFRAG = C.IP_DONTFRAG + sysIP_RECVTOS = C.IP_RECVTOS + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + sysIP_MULTICAST_VIF = C.IP_MULTICAST_VIF + sysIP_ADD_SOURCE_MEMBERSHIP = C.IP_ADD_SOURCE_MEMBERSHIP + sysIP_DROP_SOURCE_MEMBERSHIP = C.IP_DROP_SOURCE_MEMBERSHIP + sysIP_BLOCK_SOURCE = C.IP_BLOCK_SOURCE + sysIP_UNBLOCK_SOURCE = C.IP_UNBLOCK_SOURCE + sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP + sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP + sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP + sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP + sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE + sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE + + sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage + sysSizeofSockaddrInet = C.sizeof_struct_sockaddr_in + + sysSizeofIPMreq = C.sizeof_struct_ip_mreq + sysSizeofIPMreqn = C.sizeof_struct_ip_mreqn + sysSizeofIPMreqSource = C.sizeof_struct_ip_mreq_source + sysSizeofGroupReq = C.sizeof_struct_group_req + sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req +) + +type sysSockaddrStorage C.struct_sockaddr_storage + +type sysSockaddrInet C.struct_sockaddr_in + +type sysIPMreq C.struct_ip_mreq + +type sysIPMreqn C.struct_ip_mreqn + +type sysIPMreqSource C.struct_ip_mreq_source + +type sysGroupReq C.struct_group_req + +type sysGroupSourceReq C.struct_group_source_req diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_linux.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_linux.go new file mode 100644 index 00000000..fdba148a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_linux.go @@ -0,0 +1,111 @@ +// 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. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include + +#include +#include +#include +*/ +import "C" + +const ( + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_ROUTER_ALERT = C.IP_ROUTER_ALERT + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RETOPTS = C.IP_RETOPTS + sysIP_PKTINFO = C.IP_PKTINFO + sysIP_PKTOPTIONS = C.IP_PKTOPTIONS + sysIP_MTU_DISCOVER = C.IP_MTU_DISCOVER + sysIP_RECVERR = C.IP_RECVERR + sysIP_RECVTTL = C.IP_RECVTTL + sysIP_RECVTOS = C.IP_RECVTOS + sysIP_MTU = C.IP_MTU + sysIP_FREEBIND = C.IP_FREEBIND + sysIP_TRANSPARENT = C.IP_TRANSPARENT + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_ORIGDSTADDR = C.IP_ORIGDSTADDR + sysIP_RECVORIGDSTADDR = C.IP_RECVORIGDSTADDR + sysIP_MINTTL = C.IP_MINTTL + sysIP_NODEFRAG = C.IP_NODEFRAG + sysIP_UNICAST_IF = C.IP_UNICAST_IF + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + sysIP_UNBLOCK_SOURCE = C.IP_UNBLOCK_SOURCE + sysIP_BLOCK_SOURCE = C.IP_BLOCK_SOURCE + sysIP_ADD_SOURCE_MEMBERSHIP = C.IP_ADD_SOURCE_MEMBERSHIP + sysIP_DROP_SOURCE_MEMBERSHIP = C.IP_DROP_SOURCE_MEMBERSHIP + sysIP_MSFILTER = C.IP_MSFILTER + sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP + sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP + sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP + sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP + sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE + sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE + sysMCAST_MSFILTER = C.MCAST_MSFILTER + sysIP_MULTICAST_ALL = C.IP_MULTICAST_ALL + + //sysIP_PMTUDISC_DONT = C.IP_PMTUDISC_DONT + //sysIP_PMTUDISC_WANT = C.IP_PMTUDISC_WANT + //sysIP_PMTUDISC_DO = C.IP_PMTUDISC_DO + //sysIP_PMTUDISC_PROBE = C.IP_PMTUDISC_PROBE + //sysIP_PMTUDISC_INTERFACE = C.IP_PMTUDISC_INTERFACE + //sysIP_PMTUDISC_OMIT = C.IP_PMTUDISC_OMIT + + sysICMP_FILTER = C.ICMP_FILTER + + sysSO_EE_ORIGIN_NONE = C.SO_EE_ORIGIN_NONE + sysSO_EE_ORIGIN_LOCAL = C.SO_EE_ORIGIN_LOCAL + sysSO_EE_ORIGIN_ICMP = C.SO_EE_ORIGIN_ICMP + sysSO_EE_ORIGIN_ICMP6 = C.SO_EE_ORIGIN_ICMP6 + sysSO_EE_ORIGIN_TXSTATUS = C.SO_EE_ORIGIN_TXSTATUS + sysSO_EE_ORIGIN_TIMESTAMPING = C.SO_EE_ORIGIN_TIMESTAMPING + + sysSizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage + sysSizeofSockaddrInet = C.sizeof_struct_sockaddr_in + sysSizeofInetPktinfo = C.sizeof_struct_in_pktinfo + sysSizeofSockExtendedErr = C.sizeof_struct_sock_extended_err + + sysSizeofIPMreq = C.sizeof_struct_ip_mreq + sysSizeofIPMreqn = C.sizeof_struct_ip_mreqn + sysSizeofIPMreqSource = C.sizeof_struct_ip_mreq_source + sysSizeofGroupReq = C.sizeof_struct_group_req + sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req + + sysSizeofICMPFilter = C.sizeof_struct_icmp_filter +) + +type sysKernelSockaddrStorage C.struct___kernel_sockaddr_storage + +type sysSockaddrInet C.struct_sockaddr_in + +type sysInetPktinfo C.struct_in_pktinfo + +type sysSockExtendedErr C.struct_sock_extended_err + +type sysIPMreq C.struct_ip_mreq + +type sysIPMreqn C.struct_ip_mreqn + +type sysIPMreqSource C.struct_ip_mreq_source + +type sysGroupReq C.struct_group_req + +type sysGroupSourceReq C.struct_group_source_req + +type sysICMPFilter C.struct_icmp_filter diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_netbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_netbsd.go new file mode 100644 index 00000000..8642354f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_netbsd.go @@ -0,0 +1,37 @@ +// 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. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include +*/ +import "C" + +const ( + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_RECVDSTADDR = C.IP_RECVDSTADDR + sysIP_RETOPTS = C.IP_RETOPTS + sysIP_RECVIF = C.IP_RECVIF + sysIP_RECVTTL = C.IP_RECVTTL + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + + sysSizeofIPMreq = C.sizeof_struct_ip_mreq +) + +type sysIPMreq C.struct_ip_mreq diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_openbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_openbsd.go new file mode 100644 index 00000000..8642354f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_openbsd.go @@ -0,0 +1,37 @@ +// 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. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include +*/ +import "C" + +const ( + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_RECVDSTADDR = C.IP_RECVDSTADDR + sysIP_RETOPTS = C.IP_RETOPTS + sysIP_RECVIF = C.IP_RECVIF + sysIP_RECVTTL = C.IP_RECVTTL + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + + sysSizeofIPMreq = C.sizeof_struct_ip_mreq +) + +type sysIPMreq C.struct_ip_mreq diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_solaris.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_solaris.go new file mode 100644 index 00000000..bb74afa4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/defs_solaris.go @@ -0,0 +1,57 @@ +// 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. + +// +build ignore + +// +godefs map struct_in_addr [4]byte /* in_addr */ + +package ipv4 + +/* +#include +*/ +import "C" + +const ( + sysIP_OPTIONS = C.IP_OPTIONS + sysIP_HDRINCL = C.IP_HDRINCL + sysIP_TOS = C.IP_TOS + sysIP_TTL = C.IP_TTL + sysIP_RECVOPTS = C.IP_RECVOPTS + sysIP_RECVRETOPTS = C.IP_RECVRETOPTS + sysIP_RECVDSTADDR = C.IP_RECVDSTADDR + sysIP_RETOPTS = C.IP_RETOPTS + sysIP_RECVIF = C.IP_RECVIF + sysIP_RECVSLLA = C.IP_RECVSLLA + sysIP_RECVTTL = C.IP_RECVTTL + sysIP_NEXTHOP = C.IP_NEXTHOP + sysIP_PKTINFO = C.IP_PKTINFO + sysIP_RECVPKTINFO = C.IP_RECVPKTINFO + sysIP_DONTFRAG = C.IP_DONTFRAG + sysIP_BOUND_IF = C.IP_BOUND_IF + sysIP_UNSPEC_SRC = C.IP_UNSPEC_SRC + sysIP_BROADCAST_TTL = C.IP_BROADCAST_TTL + sysIP_DHCPINIT_IF = C.IP_DHCPINIT_IF + + sysIP_MULTICAST_IF = C.IP_MULTICAST_IF + sysIP_MULTICAST_TTL = C.IP_MULTICAST_TTL + sysIP_MULTICAST_LOOP = C.IP_MULTICAST_LOOP + sysIP_ADD_MEMBERSHIP = C.IP_ADD_MEMBERSHIP + sysIP_DROP_MEMBERSHIP = C.IP_DROP_MEMBERSHIP + sysIP_BLOCK_SOURCE = C.IP_BLOCK_SOURCE + sysIP_UNBLOCK_SOURCE = C.IP_UNBLOCK_SOURCE + sysIP_ADD_SOURCE_MEMBERSHIP = C.IP_ADD_SOURCE_MEMBERSHIP + sysIP_DROP_SOURCE_MEMBERSHIP = C.IP_DROP_SOURCE_MEMBERSHIP + + sysSizeofInetPktinfo = C.sizeof_struct_in_pktinfo + + sysSizeofIPMreq = C.sizeof_struct_ip_mreq + sysSizeofIPMreqSource = C.sizeof_struct_ip_mreq_source +) + +type sysInetPktinfo C.struct_in_pktinfo + +type sysIPMreq C.struct_ip_mreq + +type sysIPMreqSource C.struct_ip_mreq_source diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/dgramopt_posix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/dgramopt_posix.go new file mode 100644 index 00000000..103c4f6d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/dgramopt_posix.go @@ -0,0 +1,251 @@ +// 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 darwin dragonfly freebsd linux netbsd openbsd windows + +package ipv4 + +import ( + "net" + "syscall" +) + +// MulticastTTL returns the time-to-live field value for outgoing +// multicast packets. +func (c *dgramOpt) MulticastTTL() (int, error) { + if !c.ok() { + return 0, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return 0, err + } + return getInt(fd, &sockOpts[ssoMulticastTTL]) +} + +// SetMulticastTTL sets the time-to-live field value for future +// outgoing multicast packets. +func (c *dgramOpt) SetMulticastTTL(ttl int) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoMulticastTTL], ttl) +} + +// MulticastInterface returns the default interface for multicast +// packet transmissions. +func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { + if !c.ok() { + return nil, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return nil, err + } + return getInterface(fd, &sockOpts[ssoMulticastInterface]) +} + +// SetMulticastInterface sets the default interface for future +// multicast packet transmissions. +func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInterface(fd, &sockOpts[ssoMulticastInterface], ifi) +} + +// MulticastLoopback reports whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) MulticastLoopback() (bool, error) { + if !c.ok() { + return false, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return false, err + } + on, err := getInt(fd, &sockOpts[ssoMulticastLoopback]) + if err != nil { + return false, err + } + return on == 1, nil +} + +// SetMulticastLoopback sets whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) SetMulticastLoopback(on bool) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on)) +} + +// JoinGroup joins the group address group on the interface ifi. +// By default all sources that can cast data to group are accepted. +// It's possible to mute and unmute data transmission from a specific +// source by using ExcludeSourceSpecificGroup and +// IncludeSourceSpecificGroup. +// JoinGroup uses the system assigned multicast interface when ifi is +// nil, although this is not recommended because the assignment +// depends on platforms and sometimes it might require routing +// configuration. +func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP4(group) + if grp == nil { + return errMissingAddress + } + return setGroup(fd, &sockOpts[ssoJoinGroup], ifi, grp) +} + +// LeaveGroup leaves the group address group on the interface ifi +// regardless of whether the group is any-source group or +// source-specific group. +func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP4(group) + if grp == nil { + return errMissingAddress + } + return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp) +} + +// JoinSourceSpecificGroup joins the source-specific group comprising +// group and source on the interface ifi. +// JoinSourceSpecificGroup uses the system assigned multicast +// interface when ifi is nil, although this is not recommended because +// the assignment depends on platforms and sometimes it might require +// routing configuration. +func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP4(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP4(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoJoinSourceGroup], ifi, grp, src) +} + +// LeaveSourceSpecificGroup leaves the source-specific group on the +// interface ifi. +func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP4(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP4(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src) +} + +// ExcludeSourceSpecificGroup excludes the source-specific group from +// the already joined any-source groups by JoinGroup on the interface +// ifi. +func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP4(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP4(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoBlockSourceGroup], ifi, grp, src) +} + +// IncludeSourceSpecificGroup includes the excluded source-specific +// group by ExcludeSourceSpecificGroup again on the interface ifi. +func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP4(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP4(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src) +} + +// ICMPFilter returns an ICMP filter. +// Currently only Linux supports this. +func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { + if !c.ok() { + return nil, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return nil, err + } + return getICMPFilter(fd, &sockOpts[ssoICMPFilter]) +} + +// SetICMPFilter deploys the ICMP filter. +// Currently only Linux supports this. +func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setICMPFilter(fd, &sockOpts[ssoICMPFilter], f) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/dgramopt_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/dgramopt_stub.go new file mode 100644 index 00000000..b74df693 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/dgramopt_stub.go @@ -0,0 +1,106 @@ +// 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 nacl plan9 solaris + +package ipv4 + +import "net" + +// MulticastTTL returns the time-to-live field value for outgoing +// multicast packets. +func (c *dgramOpt) MulticastTTL() (int, error) { + return 0, errOpNoSupport +} + +// SetMulticastTTL sets the time-to-live field value for future +// outgoing multicast packets. +func (c *dgramOpt) SetMulticastTTL(ttl int) error { + return errOpNoSupport +} + +// MulticastInterface returns the default interface for multicast +// packet transmissions. +func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { + return nil, errOpNoSupport +} + +// SetMulticastInterface sets the default interface for future +// multicast packet transmissions. +func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { + return errOpNoSupport +} + +// MulticastLoopback reports whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) MulticastLoopback() (bool, error) { + return false, errOpNoSupport +} + +// SetMulticastLoopback sets whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) SetMulticastLoopback(on bool) error { + return errOpNoSupport +} + +// JoinGroup joins the group address group on the interface ifi. +// By default all sources that can cast data to group are accepted. +// It's possible to mute and unmute data transmission from a specific +// source by using ExcludeSourceSpecificGroup and +// IncludeSourceSpecificGroup. +// JoinGroup uses the system assigned multicast interface when ifi is +// nil, although this is not recommended because the assignment +// depends on platforms and sometimes it might require routing +// configuration. +func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { + return errOpNoSupport +} + +// LeaveGroup leaves the group address group on the interface ifi +// regardless of whether the group is any-source group or +// source-specific group. +func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { + return errOpNoSupport +} + +// JoinSourceSpecificGroup joins the source-specific group comprising +// group and source on the interface ifi. +// JoinSourceSpecificGroup uses the system assigned multicast +// interface when ifi is nil, although this is not recommended because +// the assignment depends on platforms and sometimes it might require +// routing configuration. +func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// LeaveSourceSpecificGroup leaves the source-specific group on the +// interface ifi. +func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// ExcludeSourceSpecificGroup excludes the source-specific group from +// the already joined any-source groups by JoinGroup on the interface +// ifi. +func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// IncludeSourceSpecificGroup includes the excluded source-specific +// group by ExcludeSourceSpecificGroup again on the interface ifi. +func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// ICMPFilter returns an ICMP filter. +// Currently only Linux supports this. +func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { + return nil, errOpNoSupport +} + +// SetICMPFilter deploys the ICMP filter. +// Currently only Linux supports this. +func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/doc.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/doc.go new file mode 100644 index 00000000..9a79badf --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/doc.go @@ -0,0 +1,242 @@ +// 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 ipv4 implements IP-level socket options for the Internet +// Protocol version 4. +// +// The package provides IP-level socket options that allow +// manipulation of IPv4 facilities. +// +// The IPv4 protocol and basic host requirements for IPv4 are defined +// in RFC 791 and RFC 1122. +// Host extensions for multicasting and socket interface extensions +// for multicast source filters are defined in RFC 1112 and RFC 3678. +// IGMPv1, IGMPv2 and IGMPv3 are defined in RFC 1112, RFC 2236 and RFC +// 3376. +// Source-specific multicast is defined in RFC 4607. +// +// +// Unicasting +// +// The options for unicasting are available for net.TCPConn, +// net.UDPConn and net.IPConn which are created as network connections +// that use the IPv4 transport. When a single TCP connection carrying +// a data flow of multiple packets needs to indicate the flow is +// important, ipv4.Conn is used to set the type-of-service field on +// the IPv4 header for each packet. +// +// ln, err := net.Listen("tcp4", "0.0.0.0:1024") +// if err != nil { +// // error handling +// } +// defer ln.Close() +// for { +// c, err := ln.Accept() +// if err != nil { +// // error handling +// } +// go func(c net.Conn) { +// defer c.Close() +// +// The outgoing packets will be labeled DiffServ assured forwarding +// class 1 low drop precedence, known as AF11 packets. +// +// if err := ipv4.NewConn(c).SetTOS(0x28); err != nil { +// // error handling +// } +// if _, err := c.Write(data); err != nil { +// // error handling +// } +// }(c) +// } +// +// +// Multicasting +// +// The options for multicasting are available for net.UDPConn and +// net.IPconn which are created as network connections that use the +// IPv4 transport. A few network facilities must be prepared before +// you begin multicasting, at a minimum joining network interfaces and +// multicast groups. +// +// en0, err := net.InterfaceByName("en0") +// if err != nil { +// // error handling +// } +// en1, err := net.InterfaceByIndex(911) +// if err != nil { +// // error handling +// } +// group := net.IPv4(224, 0, 0, 250) +// +// First, an application listens to an appropriate address with an +// appropriate service port. +// +// c, err := net.ListenPacket("udp4", "0.0.0.0:1024") +// if err != nil { +// // error handling +// } +// defer c.Close() +// +// Second, the application joins multicast groups, starts listening to +// the groups on the specified network interfaces. Note that the +// service port for transport layer protocol does not matter with this +// operation as joining groups affects only network and link layer +// protocols, such as IPv4 and Ethernet. +// +// p := ipv4.NewPacketConn(c) +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil { +// // error handling +// } +// +// The application might set per packet control message transmissions +// between the protocol stack within the kernel. When the application +// needs a destination address on an incoming packet, +// SetControlMessage of ipv4.PacketConn is used to enable control +// message transmissons. +// +// if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil { +// // error handling +// } +// +// The application could identify whether the received packets are +// of interest by using the control message that contains the +// destination address of the received packet. +// +// b := make([]byte, 1500) +// for { +// n, cm, src, err := p.ReadFrom(b) +// if err != nil { +// // error handling +// } +// if cm.Dst.IsMulticast() { +// if cm.Dst.Equal(group) { +// // joined group, do something +// } else { +// // unknown group, discard +// continue +// } +// } +// +// The application can also send both unicast and multicast packets. +// +// p.SetTOS(0x0) +// p.SetTTL(16) +// if _, err := p.WriteTo(data, nil, src); err != nil { +// // error handling +// } +// dst := &net.UDPAddr{IP: group, Port: 1024} +// for _, ifi := range []*net.Interface{en0, en1} { +// if err := p.SetMulticastInterface(ifi); err != nil { +// // error handling +// } +// p.SetMulticastTTL(2) +// if _, err := p.WriteTo(data, nil, dst); err != nil { +// // error handling +// } +// } +// } +// +// +// More multicasting +// +// An application that uses PacketConn or RawConn may join multiple +// multicast groups. For example, a UDP listener with port 1024 might +// join two different groups across over two different network +// interfaces by using: +// +// c, err := net.ListenPacket("udp4", "0.0.0.0:1024") +// if err != nil { +// // error handling +// } +// defer c.Close() +// p := ipv4.NewPacketConn(c) +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}); err != nil { +// // error handling +// } +// +// It is possible for multiple UDP listeners that listen on the same +// UDP port to join the same multicast group. The net package will +// provide a socket that listens to a wildcard address with reusable +// UDP port when an appropriate multicast address prefix is passed to +// the net.ListenPacket or net.ListenUDP. +// +// c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") +// if err != nil { +// // error handling +// } +// defer c1.Close() +// c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") +// if err != nil { +// // error handling +// } +// defer c2.Close() +// p1 := ipv4.NewPacketConn(c1) +// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { +// // error handling +// } +// p2 := ipv4.NewPacketConn(c2) +// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { +// // error handling +// } +// +// Also it is possible for the application to leave or rejoin a +// multicast group on the network interface. +// +// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 248)}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)}); err != nil { +// // error handling +// } +// +// +// Source-specific multicasting +// +// An application that uses PacketConn or RawConn on IGMPv3 supported +// platform is able to join source-specific multicast groups. +// The application may use JoinSourceSpecificGroup and +// LeaveSourceSpecificGroup for the operation known as "include" mode, +// +// ssmgroup := net.UDPAddr{IP: net.IPv4(232, 7, 8, 9)} +// ssmsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 1)}) +// if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { +// // error handling +// } +// if err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { +// // error handling +// } +// +// or JoinGroup, ExcludeSourceSpecificGroup, +// IncludeSourceSpecificGroup and LeaveGroup for the operation known +// as "exclude" mode. +// +// exclsource := net.UDPAddr{IP: net.IPv4(192, 168, 0, 254)} +// if err := p.JoinGroup(en0, &ssmgroup); err != nil { +// // error handling +// } +// if err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil { +// // error handling +// } +// if err := p.LeaveGroup(en0, &ssmgroup); err != nil { +// // error handling +// } +// +// Note that it depends on each platform implementation what happens +// when an application which runs on IGMPv3 unsupported platform uses +// JoinSourceSpecificGroup and LeaveSourceSpecificGroup. +// In general the platform tries to fall back to conversations using +// IGMPv1 or IGMPv2 and starts to listen to multicast traffic. +// In the fallback case, ExcludeSourceSpecificGroup and +// IncludeSourceSpecificGroup may return an error. +package ipv4 // import "golang.org/x/net/ipv4" diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/endpoint.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/endpoint.go new file mode 100644 index 00000000..bc45bf05 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/endpoint.go @@ -0,0 +1,187 @@ +// 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 ipv4 + +import ( + "net" + "syscall" + "time" +) + +// A Conn represents a network endpoint that uses the IPv4 transport. +// It is used to control basic IP-level socket options such as TOS and +// TTL. +type Conn struct { + genericOpt +} + +type genericOpt struct { + net.Conn +} + +func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil } + +// NewConn returns a new Conn. +func NewConn(c net.Conn) *Conn { + return &Conn{ + genericOpt: genericOpt{Conn: c}, + } +} + +// A PacketConn represents a packet network endpoint that uses the +// IPv4 transport. It is used to control several IP-level socket +// options including multicasting. It also provides datagram based +// network I/O methods specific to the IPv4 and higher layer protocols +// such as UDP. +type PacketConn struct { + genericOpt + dgramOpt + payloadHandler +} + +type dgramOpt struct { + net.PacketConn +} + +func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil } + +// SetControlMessage sets the per packet IP-level socket options. +func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + fd, err := c.payloadHandler.sysfd() + if err != nil { + return err + } + return setControlMessage(fd, &c.payloadHandler.rawOpt, cf, on) +} + +// SetDeadline sets the read and write deadlines associated with the +// endpoint. +func (c *PacketConn) SetDeadline(t time.Time) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.PacketConn.SetDeadline(t) +} + +// SetReadDeadline sets the read deadline associated with the +// endpoint. +func (c *PacketConn) SetReadDeadline(t time.Time) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.PacketConn.SetReadDeadline(t) +} + +// SetWriteDeadline sets the write deadline associated with the +// endpoint. +func (c *PacketConn) SetWriteDeadline(t time.Time) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.PacketConn.SetWriteDeadline(t) +} + +// Close closes the endpoint. +func (c *PacketConn) Close() error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.PacketConn.Close() +} + +// NewPacketConn returns a new PacketConn using c as its underlying +// transport. +func NewPacketConn(c net.PacketConn) *PacketConn { + p := &PacketConn{ + genericOpt: genericOpt{Conn: c.(net.Conn)}, + dgramOpt: dgramOpt{PacketConn: c}, + payloadHandler: payloadHandler{PacketConn: c}, + } + if _, ok := c.(*net.IPConn); ok && sockOpts[ssoStripHeader].name > 0 { + if fd, err := p.payloadHandler.sysfd(); err == nil { + setInt(fd, &sockOpts[ssoStripHeader], boolint(true)) + } + } + return p +} + +// A RawConn represents a packet network endpoint that uses the IPv4 +// transport. It is used to control several IP-level socket options +// including IPv4 header manipulation. It also provides datagram +// based network I/O methods specific to the IPv4 and higher layer +// protocols that handle IPv4 datagram directly such as OSPF, GRE. +type RawConn struct { + genericOpt + dgramOpt + packetHandler +} + +// SetControlMessage sets the per packet IP-level socket options. +func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error { + if !c.packetHandler.ok() { + return syscall.EINVAL + } + fd, err := c.packetHandler.sysfd() + if err != nil { + return err + } + return setControlMessage(fd, &c.packetHandler.rawOpt, cf, on) +} + +// SetDeadline sets the read and write deadlines associated with the +// endpoint. +func (c *RawConn) SetDeadline(t time.Time) error { + if !c.packetHandler.ok() { + return syscall.EINVAL + } + return c.packetHandler.c.SetDeadline(t) +} + +// SetReadDeadline sets the read deadline associated with the +// endpoint. +func (c *RawConn) SetReadDeadline(t time.Time) error { + if !c.packetHandler.ok() { + return syscall.EINVAL + } + return c.packetHandler.c.SetReadDeadline(t) +} + +// SetWriteDeadline sets the write deadline associated with the +// endpoint. +func (c *RawConn) SetWriteDeadline(t time.Time) error { + if !c.packetHandler.ok() { + return syscall.EINVAL + } + return c.packetHandler.c.SetWriteDeadline(t) +} + +// Close closes the endpoint. +func (c *RawConn) Close() error { + if !c.packetHandler.ok() { + return syscall.EINVAL + } + return c.packetHandler.c.Close() +} + +// NewRawConn returns a new RawConn using c as its underlying +// transport. +func NewRawConn(c net.PacketConn) (*RawConn, error) { + r := &RawConn{ + genericOpt: genericOpt{Conn: c.(net.Conn)}, + dgramOpt: dgramOpt{PacketConn: c}, + packetHandler: packetHandler{c: c.(*net.IPConn)}, + } + fd, err := r.packetHandler.sysfd() + if err != nil { + return nil, err + } + if err := setInt(fd, &sockOpts[ssoHeaderPrepend], boolint(true)); err != nil { + return nil, err + } + return r, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/example_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/example_test.go new file mode 100644 index 00000000..4f5e2f31 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/example_test.go @@ -0,0 +1,224 @@ +// 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 ipv4_test + +import ( + "fmt" + "log" + "net" + "os" + "runtime" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/ipv4" +) + +func ExampleConn_markingTCP() { + ln, err := net.Listen("tcp", "0.0.0.0:1024") + if err != nil { + log.Fatal(err) + } + defer ln.Close() + + for { + c, err := ln.Accept() + if err != nil { + log.Fatal(err) + } + go func(c net.Conn) { + defer c.Close() + if c.RemoteAddr().(*net.TCPAddr).IP.To4() != nil { + p := ipv4.NewConn(c) + if err := p.SetTOS(0x28); err != nil { // DSCP AF11 + log.Fatal(err) + } + if err := p.SetTTL(128); err != nil { + log.Fatal(err) + } + } + if _, err := c.Write([]byte("HELLO-R-U-THERE-ACK")); err != nil { + log.Fatal(err) + } + }(c) + } +} + +func ExamplePacketConn_servingOneShotMulticastDNS() { + c, err := net.ListenPacket("udp4", "0.0.0.0:5353") // mDNS over UDP + if err != nil { + log.Fatal(err) + } + defer c.Close() + p := ipv4.NewPacketConn(c) + + en0, err := net.InterfaceByName("en0") + if err != nil { + log.Fatal(err) + } + mDNSLinkLocal := net.UDPAddr{IP: net.IPv4(224, 0, 0, 251)} + if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil { + log.Fatal(err) + } + defer p.LeaveGroup(en0, &mDNSLinkLocal) + if err := p.SetControlMessage(ipv4.FlagDst, true); err != nil { + log.Fatal(err) + } + + b := make([]byte, 1500) + for { + _, cm, peer, err := p.ReadFrom(b) + if err != nil { + log.Fatal(err) + } + if !cm.Dst.IsMulticast() || !cm.Dst.Equal(mDNSLinkLocal.IP) { + continue + } + answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this + if _, err := p.WriteTo(answers, nil, peer); err != nil { + log.Fatal(err) + } + } +} + +func ExamplePacketConn_tracingIPPacketRoute() { + // Tracing an IP packet route to www.google.com. + + const host = "www.google.com" + ips, err := net.LookupIP(host) + if err != nil { + log.Fatal(err) + } + var dst net.IPAddr + for _, ip := range ips { + if ip.To4() != nil { + dst.IP = ip + fmt.Printf("using %v for tracing an IP packet route to %s\n", dst.IP, host) + break + } + } + if dst.IP == nil { + log.Fatal("no A record found") + } + + c, err := net.ListenPacket("ip4:1", "0.0.0.0") // ICMP for IPv4 + if err != nil { + log.Fatal(err) + } + defer c.Close() + p := ipv4.NewPacketConn(c) + + if err := p.SetControlMessage(ipv4.FlagTTL|ipv4.FlagSrc|ipv4.FlagDst|ipv4.FlagInterface, true); err != nil { + log.Fatal(err) + } + wm := icmp.Message{ + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, + Data: []byte("HELLO-R-U-THERE"), + }, + } + + rb := make([]byte, 1500) + for i := 1; i <= 64; i++ { // up to 64 hops + wm.Body.(*icmp.Echo).Seq = i + wb, err := wm.Marshal(nil) + if err != nil { + log.Fatal(err) + } + if err := p.SetTTL(i); err != nil { + log.Fatal(err) + } + + // In the real world usually there are several + // multiple traffic-engineered paths for each hop. + // You may need to probe a few times to each hop. + begin := time.Now() + if _, err := p.WriteTo(wb, nil, &dst); err != nil { + log.Fatal(err) + } + if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil { + log.Fatal(err) + } + n, cm, peer, err := p.ReadFrom(rb) + if err != nil { + if err, ok := err.(net.Error); ok && err.Timeout() { + fmt.Printf("%v\t*\n", i) + continue + } + log.Fatal(err) + } + rm, err := icmp.ParseMessage(1, rb[:n]) + if err != nil { + log.Fatal(err) + } + rtt := time.Since(begin) + + // In the real world you need to determine whether the + // received message is yours using ControlMessage.Src, + // ControlMessage.Dst, icmp.Echo.ID and icmp.Echo.Seq. + switch rm.Type { + case ipv4.ICMPTypeTimeExceeded: + names, _ := net.LookupAddr(peer.String()) + fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm) + case ipv4.ICMPTypeEchoReply: + names, _ := net.LookupAddr(peer.String()) + fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, cm) + return + default: + log.Printf("unknown ICMP message: %+v\n", rm) + } + } +} + +func ExampleRawConn_advertisingOSPFHello() { + c, err := net.ListenPacket("ip4:89", "0.0.0.0") // OSPF for IPv4 + if err != nil { + log.Fatal(err) + } + defer c.Close() + r, err := ipv4.NewRawConn(c) + if err != nil { + log.Fatal(err) + } + + en0, err := net.InterfaceByName("en0") + if err != nil { + log.Fatal(err) + } + allSPFRouters := net.IPAddr{IP: net.IPv4(224, 0, 0, 5)} + if err := r.JoinGroup(en0, &allSPFRouters); err != nil { + log.Fatal(err) + } + defer r.LeaveGroup(en0, &allSPFRouters) + + hello := make([]byte, 24) // fake hello data, you need to implement this + ospf := make([]byte, 24) // fake ospf header, you need to implement this + ospf[0] = 2 // version 2 + ospf[1] = 1 // hello packet + ospf = append(ospf, hello...) + iph := &ipv4.Header{ + Version: ipv4.Version, + Len: ipv4.HeaderLen, + TOS: 0xc0, // DSCP CS6 + TotalLen: ipv4.HeaderLen + len(ospf), + TTL: 1, + Protocol: 89, + Dst: allSPFRouters.IP.To4(), + } + + var cm *ipv4.ControlMessage + switch runtime.GOOS { + case "darwin", "linux": + cm = &ipv4.ControlMessage{IfIndex: en0.Index} + default: + if err := r.SetMulticastInterface(en0); err != nil { + log.Fatal(err) + } + } + if err := r.WriteTo(iph, ospf, cm); err != nil { + log.Fatal(err) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/gen.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/gen.go new file mode 100644 index 00000000..4785212a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/gen.go @@ -0,0 +1,208 @@ +// 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 ignore + +//go:generate go run gen.go + +// This program generates system adaptation constants and types, +// internet protocol constants and tables by reading template files +// and IANA protocol registries. +package main + +import ( + "bytes" + "encoding/xml" + "fmt" + "go/format" + "io" + "io/ioutil" + "net/http" + "os" + "os/exec" + "runtime" + "strconv" + "strings" +) + +func main() { + if err := genzsys(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := geniana(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func genzsys() error { + defs := "defs_" + runtime.GOOS + ".go" + f, err := os.Open(defs) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + f.Close() + cmd := exec.Command("go", "tool", "cgo", "-godefs", defs) + b, err := cmd.Output() + if err != nil { + return err + } + // The ipv4 pacakge still supports go1.2, and so we need to + // take care of additional platforms in go1.3 and above for + // working with go1.2. + switch { + case runtime.GOOS == "dragonfly" || runtime.GOOS == "solaris": + b = bytes.Replace(b, []byte("package ipv4\n"), []byte("// +build "+runtime.GOOS+"\n\npackage ipv4\n"), 1) + case runtime.GOOS == "linux" && (runtime.GOARCH == "arm64" || runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"): + b = bytes.Replace(b, []byte("package ipv4\n"), []byte("// +build "+runtime.GOOS+","+runtime.GOARCH+"\n\npackage ipv4\n"), 1) + } + b, err = format.Source(b) + if err != nil { + return err + } + zsys := "zsys_" + runtime.GOOS + ".go" + switch runtime.GOOS { + case "freebsd", "linux": + zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go" + } + if err := ioutil.WriteFile(zsys, b, 0644); err != nil { + return err + } + return nil +} + +var registries = []struct { + url string + parse func(io.Writer, io.Reader) error +}{ + { + "http://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml", + parseICMPv4Parameters, + }, +} + +func geniana() error { + var bb bytes.Buffer + fmt.Fprintf(&bb, "// go generate gen.go\n") + fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") + fmt.Fprintf(&bb, "package ipv4\n\n") + for _, r := range registries { + resp, err := http.Get(r.url) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("got HTTP status code %v for %v\n", resp.StatusCode, r.url) + } + if err := r.parse(&bb, resp.Body); err != nil { + return err + } + fmt.Fprintf(&bb, "\n") + } + b, err := format.Source(bb.Bytes()) + if err != nil { + return err + } + if err := ioutil.WriteFile("iana.go", b, 0644); err != nil { + return err + } + return nil +} + +func parseICMPv4Parameters(w io.Writer, r io.Reader) error { + dec := xml.NewDecoder(r) + var icp icmpv4Parameters + if err := dec.Decode(&icp); err != nil { + return err + } + prs := icp.escape() + fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) + fmt.Fprintf(w, "const (\n") + for _, pr := range prs { + if pr.Descr == "" { + continue + } + fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Descr, pr.Value) + fmt.Fprintf(w, "// %s\n", pr.OrigDescr) + } + fmt.Fprintf(w, ")\n\n") + fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) + fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n") + for _, pr := range prs { + if pr.Descr == "" { + continue + } + fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigDescr)) + } + fmt.Fprintf(w, "}\n") + return nil +} + +type icmpv4Parameters struct { + XMLName xml.Name `xml:"registry"` + Title string `xml:"title"` + Updated string `xml:"updated"` + Registries []struct { + Title string `xml:"title"` + Records []struct { + Value string `xml:"value"` + Descr string `xml:"description"` + } `xml:"record"` + } `xml:"registry"` +} + +type canonICMPv4ParamRecord struct { + OrigDescr string + Descr string + Value int +} + +func (icp *icmpv4Parameters) escape() []canonICMPv4ParamRecord { + id := -1 + for i, r := range icp.Registries { + if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") { + id = i + break + } + } + if id < 0 { + return nil + } + prs := make([]canonICMPv4ParamRecord, len(icp.Registries[id].Records)) + sr := strings.NewReplacer( + "Messages", "", + "Message", "", + "ICMP", "", + "+", "P", + "-", "", + "/", "", + ".", "", + " ", "", + ) + for i, pr := range icp.Registries[id].Records { + if strings.Contains(pr.Descr, "Reserved") || + strings.Contains(pr.Descr, "Unassigned") || + strings.Contains(pr.Descr, "Deprecated") || + strings.Contains(pr.Descr, "Experiment") || + strings.Contains(pr.Descr, "experiment") { + continue + } + ss := strings.Split(pr.Descr, "\n") + if len(ss) > 1 { + prs[i].Descr = strings.Join(ss, " ") + } else { + prs[i].Descr = ss[0] + } + s := strings.TrimSpace(prs[i].Descr) + prs[i].OrigDescr = s + prs[i].Descr = sr.Replace(s) + prs[i].Value, _ = strconv.Atoi(pr.Value) + } + return prs +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/genericopt_posix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/genericopt_posix.go new file mode 100644 index 00000000..fefa0be3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/genericopt_posix.go @@ -0,0 +1,59 @@ +// 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 darwin dragonfly freebsd linux netbsd openbsd windows + +package ipv4 + +import "syscall" + +// TOS returns the type-of-service field value for outgoing packets. +func (c *genericOpt) TOS() (int, error) { + if !c.ok() { + return 0, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return 0, err + } + return getInt(fd, &sockOpts[ssoTOS]) +} + +// SetTOS sets the type-of-service field value for future outgoing +// packets. +func (c *genericOpt) SetTOS(tos int) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoTOS], tos) +} + +// TTL returns the time-to-live field value for outgoing packets. +func (c *genericOpt) TTL() (int, error) { + if !c.ok() { + return 0, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return 0, err + } + return getInt(fd, &sockOpts[ssoTTL]) +} + +// SetTTL sets the time-to-live field value for future outgoing +// packets. +func (c *genericOpt) SetTTL(ttl int) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoTTL], ttl) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/genericopt_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/genericopt_stub.go new file mode 100644 index 00000000..1817badb --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/genericopt_stub.go @@ -0,0 +1,29 @@ +// 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 nacl plan9 solaris + +package ipv4 + +// TOS returns the type-of-service field value for outgoing packets. +func (c *genericOpt) TOS() (int, error) { + return 0, errOpNoSupport +} + +// SetTOS sets the type-of-service field value for future outgoing +// packets. +func (c *genericOpt) SetTOS(tos int) error { + return errOpNoSupport +} + +// TTL returns the time-to-live field value for outgoing packets. +func (c *genericOpt) TTL() (int, error) { + return 0, errOpNoSupport +} + +// SetTTL sets the time-to-live field value for future outgoing +// packets. +func (c *genericOpt) SetTTL(ttl int) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/header.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/header.go new file mode 100644 index 00000000..d1081764 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/header.go @@ -0,0 +1,140 @@ +// 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 ipv4 + +import ( + "fmt" + "net" + "runtime" + "syscall" + "unsafe" +) + +const ( + Version = 4 // protocol version + HeaderLen = 20 // header length without extension headers + maxHeaderLen = 60 // sensible default, revisit if later RFCs define new usage of version and header length fields +) + +type HeaderFlags int + +const ( + MoreFragments HeaderFlags = 1 << iota // more fragments flag + DontFragment // don't fragment flag +) + +// A Header represents an IPv4 header. +type Header struct { + Version int // protocol version + Len int // header length + TOS int // type-of-service + TotalLen int // packet total length + ID int // identification + Flags HeaderFlags // flags + FragOff int // fragment offset + TTL int // time-to-live + Protocol int // next protocol + Checksum int // checksum + Src net.IP // source address + Dst net.IP // destination address + Options []byte // options, extension headers +} + +func (h *Header) String() string { + if h == nil { + return "" + } + return fmt.Sprintf("ver=%d hdrlen=%d tos=%#x totallen=%d id=%#x flags=%#x fragoff=%#x ttl=%d proto=%d cksum=%#x src=%v dst=%v", h.Version, h.Len, h.TOS, h.TotalLen, h.ID, h.Flags, h.FragOff, h.TTL, h.Protocol, h.Checksum, h.Src, h.Dst) +} + +// Marshal returns the binary encoding of the IPv4 header h. +func (h *Header) Marshal() ([]byte, error) { + if h == nil { + return nil, syscall.EINVAL + } + if h.Len < HeaderLen { + return nil, errHeaderTooShort + } + hdrlen := HeaderLen + len(h.Options) + b := make([]byte, hdrlen) + b[0] = byte(Version<<4 | (hdrlen >> 2 & 0x0f)) + b[1] = byte(h.TOS) + flagsAndFragOff := (h.FragOff & 0x1fff) | int(h.Flags<<13) + switch runtime.GOOS { + case "darwin", "dragonfly", "freebsd", "netbsd": + // TODO(mikio): fix potential misaligned memory access + *(*uint16)(unsafe.Pointer(&b[2:3][0])) = uint16(h.TotalLen) + *(*uint16)(unsafe.Pointer(&b[6:7][0])) = uint16(flagsAndFragOff) + default: + b[2], b[3] = byte(h.TotalLen>>8), byte(h.TotalLen) + b[6], b[7] = byte(flagsAndFragOff>>8), byte(flagsAndFragOff) + } + b[4], b[5] = byte(h.ID>>8), byte(h.ID) + b[8] = byte(h.TTL) + b[9] = byte(h.Protocol) + b[10], b[11] = byte(h.Checksum>>8), byte(h.Checksum) + if ip := h.Src.To4(); ip != nil { + copy(b[12:16], ip[:net.IPv4len]) + } + if ip := h.Dst.To4(); ip != nil { + copy(b[16:20], ip[:net.IPv4len]) + } else { + return nil, errMissingAddress + } + if len(h.Options) > 0 { + copy(b[HeaderLen:], h.Options) + } + return b, nil +} + +// See http://www.freebsd.org/doc/en/books/porters-handbook/freebsd-versions.html. +var freebsdVersion uint32 + +// ParseHeader parses b as an IPv4 header. +func ParseHeader(b []byte) (*Header, error) { + if len(b) < HeaderLen { + return nil, errHeaderTooShort + } + hdrlen := int(b[0]&0x0f) << 2 + if hdrlen > len(b) { + return nil, errBufferTooShort + } + h := &Header{ + Version: int(b[0] >> 4), + Len: hdrlen, + TOS: int(b[1]), + ID: int(b[4])<<8 | int(b[5]), + TTL: int(b[8]), + Protocol: int(b[9]), + Checksum: int(b[10])<<8 | int(b[11]), + Src: net.IPv4(b[12], b[13], b[14], b[15]), + Dst: net.IPv4(b[16], b[17], b[18], b[19]), + } + switch runtime.GOOS { + case "darwin", "dragonfly", "netbsd": + // TODO(mikio): fix potential misaligned memory access + h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0]))) + hdrlen + // TODO(mikio): fix potential misaligned memory access + h.FragOff = int(*(*uint16)(unsafe.Pointer(&b[6:7][0]))) + case "freebsd": + // TODO(mikio): fix potential misaligned memory access + h.TotalLen = int(*(*uint16)(unsafe.Pointer(&b[2:3][0]))) + if freebsdVersion < 1000000 { + h.TotalLen += hdrlen + } + // TODO(mikio): fix potential misaligned memory access + h.FragOff = int(*(*uint16)(unsafe.Pointer(&b[6:7][0]))) + default: + h.TotalLen = int(b[2])<<8 | int(b[3]) + h.FragOff = int(b[6])<<8 | int(b[7]) + } + h.Flags = HeaderFlags(h.FragOff&0xe000) >> 13 + h.FragOff = h.FragOff & 0x1fff + if hdrlen-HeaderLen > 0 { + h.Options = make([]byte, hdrlen-HeaderLen) + copy(h.Options, b[HeaderLen:]) + } + return h, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/header_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/header_test.go new file mode 100644 index 00000000..ac89358c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/header_test.go @@ -0,0 +1,119 @@ +// 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 ipv4 + +import ( + "bytes" + "net" + "reflect" + "runtime" + "strings" + "testing" +) + +var ( + wireHeaderFromKernel = [HeaderLen]byte{ + 0x45, 0x01, 0xbe, 0xef, + 0xca, 0xfe, 0x45, 0xdc, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + wireHeaderToKernel = [HeaderLen]byte{ + 0x45, 0x01, 0xbe, 0xef, + 0xca, 0xfe, 0x45, 0xdc, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + wireHeaderFromTradBSDKernel = [HeaderLen]byte{ + 0x45, 0x01, 0xdb, 0xbe, + 0xca, 0xfe, 0xdc, 0x45, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + wireHeaderFromFreeBSD10Kernel = [HeaderLen]byte{ + 0x45, 0x01, 0xef, 0xbe, + 0xca, 0xfe, 0xdc, 0x45, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + wireHeaderToTradBSDKernel = [HeaderLen]byte{ + 0x45, 0x01, 0xef, 0xbe, + 0xca, 0xfe, 0xdc, 0x45, + 0xff, 0x01, 0xde, 0xad, + 172, 16, 254, 254, + 192, 168, 0, 1, + } + // TODO(mikio): Add platform dependent wire header formats when + // we support new platforms. + + testHeader = &Header{ + Version: Version, + Len: HeaderLen, + TOS: 1, + TotalLen: 0xbeef, + ID: 0xcafe, + Flags: DontFragment, + FragOff: 1500, + TTL: 255, + Protocol: 1, + Checksum: 0xdead, + Src: net.IPv4(172, 16, 254, 254), + Dst: net.IPv4(192, 168, 0, 1), + } +) + +func TestMarshalHeader(t *testing.T) { + b, err := testHeader.Marshal() + if err != nil { + t.Fatal(err) + } + var wh []byte + switch runtime.GOOS { + case "darwin", "dragonfly", "netbsd": + wh = wireHeaderToTradBSDKernel[:] + case "freebsd": + if freebsdVersion < 1000000 { + wh = wireHeaderToTradBSDKernel[:] + } else { + wh = wireHeaderFromFreeBSD10Kernel[:] + } + default: + wh = wireHeaderToKernel[:] + } + if !bytes.Equal(b, wh) { + t.Fatalf("got %#v; want %#v", b, wh) + } +} + +func TestParseHeader(t *testing.T) { + var wh []byte + switch runtime.GOOS { + case "darwin", "dragonfly", "netbsd": + wh = wireHeaderFromTradBSDKernel[:] + case "freebsd": + if freebsdVersion < 1000000 { + wh = wireHeaderFromTradBSDKernel[:] + } else { + wh = wireHeaderFromFreeBSD10Kernel[:] + } + default: + wh = wireHeaderFromKernel[:] + } + h, err := ParseHeader(wh) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(h, testHeader) { + t.Fatalf("got %#v; want %#v", h, testHeader) + } + s := h.String() + if strings.Contains(s, ",") { + t.Fatalf("should be space-separated values: %s", s) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper.go new file mode 100644 index 00000000..8a7ee900 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper.go @@ -0,0 +1,42 @@ +// 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 ipv4 + +import ( + "errors" + "net" +) + +var ( + errMissingAddress = errors.New("missing address") + errMissingHeader = errors.New("missing header") + errHeaderTooShort = errors.New("header too short") + errBufferTooShort = errors.New("buffer too short") + errInvalidConnType = errors.New("invalid conn type") + errOpNoSupport = errors.New("operation not supported") + errNoSuchInterface = errors.New("no such interface") + errNoSuchMulticastInterface = errors.New("no such multicast interface") +) + +func boolint(b bool) int { + if b { + return 1 + } + return 0 +} + +func netAddrToIP4(a net.Addr) net.IP { + switch v := a.(type) { + case *net.UDPAddr: + if ip := v.IP.To4(); ip != nil { + return ip + } + case *net.IPAddr: + if ip := v.IP.To4(); ip != nil { + return ip + } + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_stub.go new file mode 100644 index 00000000..dc2120cf --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_stub.go @@ -0,0 +1,23 @@ +// 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 nacl plan9 solaris + +package ipv4 + +func (c *genericOpt) sysfd() (int, error) { + return 0, errOpNoSupport +} + +func (c *dgramOpt) sysfd() (int, error) { + return 0, errOpNoSupport +} + +func (c *payloadHandler) sysfd() (int, error) { + return 0, errOpNoSupport +} + +func (c *packetHandler) sysfd() (int, error) { + return 0, errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_unix.go new file mode 100644 index 00000000..345ca7dc --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_unix.go @@ -0,0 +1,50 @@ +// 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 darwin dragonfly freebsd linux netbsd openbsd + +package ipv4 + +import ( + "net" + "reflect" +) + +func (c *genericOpt) sysfd() (int, error) { + switch p := c.Conn.(type) { + case *net.TCPConn, *net.UDPConn, *net.IPConn: + return sysfd(p) + } + return 0, errInvalidConnType +} + +func (c *dgramOpt) sysfd() (int, error) { + switch p := c.PacketConn.(type) { + case *net.UDPConn, *net.IPConn: + return sysfd(p.(net.Conn)) + } + return 0, errInvalidConnType +} + +func (c *payloadHandler) sysfd() (int, error) { + return sysfd(c.PacketConn.(net.Conn)) +} + +func (c *packetHandler) sysfd() (int, error) { + return sysfd(c.c) +} + +func sysfd(c net.Conn) (int, error) { + cv := reflect.ValueOf(c) + switch ce := cv.Elem(); ce.Kind() { + case reflect.Struct: + netfd := ce.FieldByName("conn").FieldByName("fd") + switch fe := netfd.Elem(); fe.Kind() { + case reflect.Struct: + fd := fe.FieldByName("sysfd") + return int(fd.Int()), nil + } + } + return 0, errInvalidConnType +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_windows.go new file mode 100644 index 00000000..322b2a5e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/helper_windows.go @@ -0,0 +1,49 @@ +// 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 ipv4 + +import ( + "net" + "reflect" + "syscall" +) + +func (c *genericOpt) sysfd() (syscall.Handle, error) { + switch p := c.Conn.(type) { + case *net.TCPConn, *net.UDPConn, *net.IPConn: + return sysfd(p) + } + return syscall.InvalidHandle, errInvalidConnType +} + +func (c *dgramOpt) sysfd() (syscall.Handle, error) { + switch p := c.PacketConn.(type) { + case *net.UDPConn, *net.IPConn: + return sysfd(p.(net.Conn)) + } + return syscall.InvalidHandle, errInvalidConnType +} + +func (c *payloadHandler) sysfd() (syscall.Handle, error) { + return sysfd(c.PacketConn.(net.Conn)) +} + +func (c *packetHandler) sysfd() (syscall.Handle, error) { + return sysfd(c.c) +} + +func sysfd(c net.Conn) (syscall.Handle, error) { + cv := reflect.ValueOf(c) + switch ce := cv.Elem(); ce.Kind() { + case reflect.Struct: + netfd := ce.FieldByName("conn").FieldByName("fd") + switch fe := netfd.Elem(); fe.Kind() { + case reflect.Struct: + fd := fe.FieldByName("sysfd") + return syscall.Handle(fd.Uint()), nil + } + } + return syscall.InvalidHandle, errInvalidConnType +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/iana.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/iana.go new file mode 100644 index 00000000..be10c948 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/iana.go @@ -0,0 +1,34 @@ +// go generate gen.go +// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +package ipv4 + +// Internet Control Message Protocol (ICMP) Parameters, Updated: 2013-04-19 +const ( + ICMPTypeEchoReply ICMPType = 0 // Echo Reply + ICMPTypeDestinationUnreachable ICMPType = 3 // Destination Unreachable + ICMPTypeRedirect ICMPType = 5 // Redirect + ICMPTypeEcho ICMPType = 8 // Echo + ICMPTypeRouterAdvertisement ICMPType = 9 // Router Advertisement + ICMPTypeRouterSolicitation ICMPType = 10 // Router Solicitation + ICMPTypeTimeExceeded ICMPType = 11 // Time Exceeded + ICMPTypeParameterProblem ICMPType = 12 // Parameter Problem + ICMPTypeTimestamp ICMPType = 13 // Timestamp + ICMPTypeTimestampReply ICMPType = 14 // Timestamp Reply + ICMPTypePhoturis ICMPType = 40 // Photuris +) + +// Internet Control Message Protocol (ICMP) Parameters, Updated: 2013-04-19 +var icmpTypes = map[ICMPType]string{ + 0: "echo reply", + 3: "destination unreachable", + 5: "redirect", + 8: "echo", + 9: "router advertisement", + 10: "router solicitation", + 11: "time exceeded", + 12: "parameter problem", + 13: "timestamp", + 14: "timestamp reply", + 40: "photuris", +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp.go new file mode 100644 index 00000000..dbd05cff --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp.go @@ -0,0 +1,57 @@ +// 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 ipv4 + +import "golang.org/x/net/internal/iana" + +// An ICMPType represents a type of ICMP message. +type ICMPType int + +func (typ ICMPType) String() string { + s, ok := icmpTypes[typ] + if !ok { + return "" + } + return s +} + +// Protocol returns the ICMPv4 protocol number. +func (typ ICMPType) Protocol() int { + return iana.ProtocolICMP +} + +// An ICMPFilter represents an ICMP message filter for incoming +// packets. The filter belongs to a packet delivery path on a host and +// it cannot interact with forwarding packets or tunnel-outer packets. +// +// Note: RFC 2460 defines a reasonable role model and it works not +// only for IPv6 but IPv4. A node means a device that implements IP. +// A router means a node that forwards IP packets not explicitly +// addressed to itself, and a host means a node that is not a router. +type ICMPFilter struct { + sysICMPFilter +} + +// Accept accepts incoming ICMP packets including the type field value +// typ. +func (f *ICMPFilter) Accept(typ ICMPType) { + f.accept(typ) +} + +// Block blocks incoming ICMP packets including the type field value +// typ. +func (f *ICMPFilter) Block(typ ICMPType) { + f.block(typ) +} + +// SetAll sets the filter action to the filter. +func (f *ICMPFilter) SetAll(block bool) { + f.setAll(block) +} + +// WillBlock reports whether the ICMP type will be blocked. +func (f *ICMPFilter) WillBlock(typ ICMPType) bool { + return f.willBlock(typ) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_linux.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_linux.go new file mode 100644 index 00000000..c9122533 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_linux.go @@ -0,0 +1,25 @@ +// 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. + +package ipv4 + +func (f *sysICMPFilter) accept(typ ICMPType) { + f.Data &^= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPFilter) block(typ ICMPType) { + f.Data |= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPFilter) setAll(block bool) { + if block { + f.Data = 1<<32 - 1 + } else { + f.Data = 0 + } +} + +func (f *sysICMPFilter) willBlock(typ ICMPType) bool { + return f.Data&(1<<(uint32(typ)&31)) != 0 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_stub.go new file mode 100644 index 00000000..9ee9b6a3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_stub.go @@ -0,0 +1,25 @@ +// 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. + +// +build !linux + +package ipv4 + +const sysSizeofICMPFilter = 0x0 + +type sysICMPFilter struct { +} + +func (f *sysICMPFilter) accept(typ ICMPType) { +} + +func (f *sysICMPFilter) block(typ ICMPType) { +} + +func (f *sysICMPFilter) setAll(block bool) { +} + +func (f *sysICMPFilter) willBlock(typ ICMPType) bool { + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_test.go new file mode 100644 index 00000000..3324b54d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/icmp_test.go @@ -0,0 +1,95 @@ +// 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. + +package ipv4_test + +import ( + "net" + "reflect" + "runtime" + "testing" + + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" +) + +var icmpStringTests = []struct { + in ipv4.ICMPType + out string +}{ + {ipv4.ICMPTypeDestinationUnreachable, "destination unreachable"}, + + {256, ""}, +} + +func TestICMPString(t *testing.T) { + for _, tt := range icmpStringTests { + s := tt.in.String() + if s != tt.out { + t.Errorf("got %s; want %s", s, tt.out) + } + } +} + +func TestICMPFilter(t *testing.T) { + switch runtime.GOOS { + case "linux": + default: + t.Skipf("not supported on %s", runtime.GOOS) + } + + var f ipv4.ICMPFilter + for _, toggle := range []bool{false, true} { + f.SetAll(toggle) + for _, typ := range []ipv4.ICMPType{ + ipv4.ICMPTypeDestinationUnreachable, + ipv4.ICMPTypeEchoReply, + ipv4.ICMPTypeTimeExceeded, + ipv4.ICMPTypeParameterProblem, + } { + f.Accept(typ) + if f.WillBlock(typ) { + t.Errorf("ipv4.ICMPFilter.Set(%v, false) failed", typ) + } + f.Block(typ) + if !f.WillBlock(typ) { + t.Errorf("ipv4.ICMPFilter.Set(%v, true) failed", typ) + } + } + } +} + +func TestSetICMPFilter(t *testing.T) { + switch runtime.GOOS { + case "linux": + default: + t.Skipf("not supported on %s", runtime.GOOS) + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + c, err := net.ListenPacket("ip4:icmp", "127.0.0.1") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + p := ipv4.NewPacketConn(c) + + var f ipv4.ICMPFilter + f.SetAll(true) + f.Accept(ipv4.ICMPTypeEcho) + f.Accept(ipv4.ICMPTypeEchoReply) + if err := p.SetICMPFilter(&f); err != nil { + t.Fatal(err) + } + kf, err := p.ICMPFilter() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(kf, &f) { + t.Fatalf("got %#v; want %#v", kf, f) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/mocktransponder_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/mocktransponder_test.go new file mode 100644 index 00000000..e55aaee9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/mocktransponder_test.go @@ -0,0 +1,21 @@ +// 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 ipv4_test + +import ( + "net" + "testing" +) + +func acceptor(t *testing.T, ln net.Listener, done chan<- bool) { + defer func() { done <- true }() + + c, err := ln.Accept() + if err != nil { + t.Error(err) + return + } + c.Close() +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicast_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicast_test.go new file mode 100644 index 00000000..d2bcf853 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicast_test.go @@ -0,0 +1,330 @@ +// 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 ipv4_test + +import ( + "bytes" + "net" + "os" + "runtime" + "testing" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" +) + +var packetConnReadWriteMulticastUDPTests = []struct { + addr string + grp, src *net.UDPAddr +}{ + {"224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727 + + {"232.0.1.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 +} + +func TestPacketConnReadWriteMulticastUDP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + for _, tt := range packetConnReadWriteMulticastUDPTests { + c, err := net.ListenPacket("udp4", tt.addr) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + grp := *tt.grp + grp.Port = c.LocalAddr().(*net.UDPAddr).Port + p := ipv4.NewPacketConn(c) + defer p.Close() + if tt.src == nil { + if err := p.JoinGroup(ifi, &grp); err != nil { + t.Fatal(err) + } + defer p.LeaveGroup(ifi, &grp) + } else { + if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil { + switch runtime.GOOS { + case "freebsd", "linux": + default: // platforms that don't support IGMPv2/3 fail here + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src) + } + if err := p.SetMulticastInterface(ifi); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastInterface(); err != nil { + t.Fatal(err) + } + if err := p.SetMulticastLoopback(true); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastLoopback(); err != nil { + t.Fatal(err) + } + cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface + wb := []byte("HELLO-R-U-THERE") + + for i, toggle := range []bool{true, false, true} { + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { + t.Fatal(err) + } + p.SetMulticastTTL(i + 1) + if n, err := p.WriteTo(wb, nil, &grp); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatalf("got %v; want %v", n, len(wb)) + } + rb := make([]byte, 128) + if n, _, _, err := p.ReadFrom(rb); err != nil { + t.Fatal(err) + } else if !bytes.Equal(rb[:n], wb) { + t.Fatalf("got %v; want %v", rb[:n], wb) + } + } + } +} + +var packetConnReadWriteMulticastICMPTests = []struct { + grp, src *net.IPAddr +}{ + {&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727 + + {&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 +} + +func TestPacketConnReadWriteMulticastICMP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + for _, tt := range packetConnReadWriteMulticastICMPTests { + c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + p := ipv4.NewPacketConn(c) + defer p.Close() + if tt.src == nil { + if err := p.JoinGroup(ifi, tt.grp); err != nil { + t.Fatal(err) + } + defer p.LeaveGroup(ifi, tt.grp) + } else { + if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil { + switch runtime.GOOS { + case "freebsd", "linux": + default: // platforms that don't support IGMPv2/3 fail here + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src) + } + if err := p.SetMulticastInterface(ifi); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastInterface(); err != nil { + t.Fatal(err) + } + if err := p.SetMulticastLoopback(true); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastLoopback(); err != nil { + t.Fatal(err) + } + cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface + + for i, toggle := range []bool{true, false, true} { + wb, err := (&icmp.Message{ + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: i + 1, + Data: []byte("HELLO-R-U-THERE"), + }, + }).Marshal(nil) + if err != nil { + t.Fatal(err) + } + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { + t.Fatal(err) + } + p.SetMulticastTTL(i + 1) + if n, err := p.WriteTo(wb, nil, tt.grp); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatalf("got %v; want %v", n, len(wb)) + } + rb := make([]byte, 128) + if n, _, _, err := p.ReadFrom(rb); err != nil { + t.Fatal(err) + } else { + m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n]) + if err != nil { + t.Fatal(err) + } + switch { + case m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1 + case m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0 + default: + t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) + } + } + } + } +} + +var rawConnReadWriteMulticastICMPTests = []struct { + grp, src *net.IPAddr +}{ + {&net.IPAddr{IP: net.IPv4(224, 0, 0, 254)}, nil}, // see RFC 4727 + + {&net.IPAddr{IP: net.IPv4(232, 0, 1, 254)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 +} + +func TestRawConnReadWriteMulticastICMP(t *testing.T) { + if testing.Short() { + t.Skip("to avoid external network") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + for _, tt := range rawConnReadWriteMulticastICMPTests { + c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + r, err := ipv4.NewRawConn(c) + if err != nil { + t.Fatal(err) + } + defer r.Close() + if tt.src == nil { + if err := r.JoinGroup(ifi, tt.grp); err != nil { + t.Fatal(err) + } + defer r.LeaveGroup(ifi, tt.grp) + } else { + if err := r.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil { + switch runtime.GOOS { + case "freebsd", "linux": + default: // platforms that don't support IGMPv2/3 fail here + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + defer r.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src) + } + if err := r.SetMulticastInterface(ifi); err != nil { + t.Fatal(err) + } + if _, err := r.MulticastInterface(); err != nil { + t.Fatal(err) + } + if err := r.SetMulticastLoopback(true); err != nil { + t.Fatal(err) + } + if _, err := r.MulticastLoopback(); err != nil { + t.Fatal(err) + } + cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface + + for i, toggle := range []bool{true, false, true} { + wb, err := (&icmp.Message{ + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: i + 1, + Data: []byte("HELLO-R-U-THERE"), + }, + }).Marshal(nil) + if err != nil { + t.Fatal(err) + } + wh := &ipv4.Header{ + Version: ipv4.Version, + Len: ipv4.HeaderLen, + TOS: i + 1, + TotalLen: ipv4.HeaderLen + len(wb), + Protocol: 1, + Dst: tt.grp.IP, + } + if err := r.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + if err := r.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { + t.Fatal(err) + } + r.SetMulticastTTL(i + 1) + if err := r.WriteTo(wh, wb, nil); err != nil { + t.Fatal(err) + } + rb := make([]byte, ipv4.HeaderLen+128) + if rh, b, _, err := r.ReadFrom(rb); err != nil { + t.Fatal(err) + } else { + m, err := icmp.ParseMessage(iana.ProtocolICMP, b) + if err != nil { + t.Fatal(err) + } + switch { + case (rh.Dst.IsLoopback() || rh.Dst.IsLinkLocalUnicast() || rh.Dst.IsGlobalUnicast()) && m.Type == ipv4.ICMPTypeEchoReply && m.Code == 0: // net.inet.icmp.bmcastecho=1 + case rh.Dst.IsMulticast() && m.Type == ipv4.ICMPTypeEcho && m.Code == 0: // net.inet.icmp.bmcastecho=0 + default: + t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) + } + } + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicastlistener_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicastlistener_test.go new file mode 100644 index 00000000..e342bf1d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicastlistener_test.go @@ -0,0 +1,249 @@ +// 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 ipv4_test + +import ( + "net" + "runtime" + "testing" + + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" +) + +var udpMultipleGroupListenerTests = []net.Addr{ + &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, // see RFC 4727 + &net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)}, + &net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)}, +} + +func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if testing.Short() { + t.Skip("to avoid external network") + } + + for _, gaddr := range udpMultipleGroupListenerTests { + c, err := net.ListenPacket("udp4", "0.0.0.0:0") // wildcard address with no reusable port + if err != nil { + t.Fatal(err) + } + defer c.Close() + + p := ipv4.NewPacketConn(c) + var mift []*net.Interface + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok { + continue + } + if err := p.JoinGroup(&ifi, gaddr); err != nil { + t.Fatal(err) + } + mift = append(mift, &ift[i]) + } + for _, ifi := range mift { + if err := p.LeaveGroup(ifi, gaddr); err != nil { + t.Fatal(err) + } + } + } +} + +func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if testing.Short() { + t.Skip("to avoid external network") + } + + for _, gaddr := range udpMultipleGroupListenerTests { + c1, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port + if err != nil { + t.Fatal(err) + } + defer c1.Close() + + c2, err := net.ListenPacket("udp4", "224.0.0.0:1024") // wildcard address with reusable port + if err != nil { + t.Fatal(err) + } + defer c2.Close() + + var ps [2]*ipv4.PacketConn + ps[0] = ipv4.NewPacketConn(c1) + ps[1] = ipv4.NewPacketConn(c2) + var mift []*net.Interface + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok { + continue + } + for _, p := range ps { + if err := p.JoinGroup(&ifi, gaddr); err != nil { + t.Fatal(err) + } + } + mift = append(mift, &ift[i]) + } + for _, ifi := range mift { + for _, p := range ps { + if err := p.LeaveGroup(ifi, gaddr); err != nil { + t.Fatal(err) + } + } + } + } +} + +func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if testing.Short() { + t.Skip("to avoid external network") + } + + gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 + type ml struct { + c *ipv4.PacketConn + ifi *net.Interface + } + var mlt []*ml + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + ip, ok := nettest.IsMulticastCapable("ip4", &ifi) + if !ok { + continue + } + c, err := net.ListenPacket("udp4", ip.String()+":"+"1024") // unicast address with non-reusable port + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv4.NewPacketConn(c) + if err := p.JoinGroup(&ifi, &gaddr); err != nil { + t.Fatal(err) + } + mlt = append(mlt, &ml{p, &ift[i]}) + } + for _, m := range mlt { + if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { + t.Fatal(err) + } + } +} + +func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if testing.Short() { + t.Skip("to avoid external network") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address + if err != nil { + t.Fatal(err) + } + defer c.Close() + + r, err := ipv4.NewRawConn(c) + if err != nil { + t.Fatal(err) + } + gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 + var mift []*net.Interface + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + if _, ok := nettest.IsMulticastCapable("ip4", &ifi); !ok { + continue + } + if err := r.JoinGroup(&ifi, &gaddr); err != nil { + t.Fatal(err) + } + mift = append(mift, &ift[i]) + } + for _, ifi := range mift { + if err := r.LeaveGroup(ifi, &gaddr); err != nil { + t.Fatal(err) + } + } +} + +func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if testing.Short() { + t.Skip("to avoid external network") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727 + type ml struct { + c *ipv4.RawConn + ifi *net.Interface + } + var mlt []*ml + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + ip, ok := nettest.IsMulticastCapable("ip4", &ifi) + if !ok { + continue + } + c, err := net.ListenPacket("ip4:253", ip.String()) // unicast address + if err != nil { + t.Fatal(err) + } + defer c.Close() + r, err := ipv4.NewRawConn(c) + if err != nil { + t.Fatal(err) + } + if err := r.JoinGroup(&ifi, &gaddr); err != nil { + t.Fatal(err) + } + mlt = append(mlt, &ml{r, &ift[i]}) + } + for _, m := range mlt { + if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { + t.Fatal(err) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicastsockopt_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicastsockopt_test.go new file mode 100644 index 00000000..c76dbe4d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/multicastsockopt_test.go @@ -0,0 +1,195 @@ +// 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 ipv4_test + +import ( + "net" + "runtime" + "testing" + + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" +) + +var packetConnMulticastSocketOptionTests = []struct { + net, proto, addr string + grp, src net.Addr +}{ + {"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, nil}, // see RFC 4727 + {"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727 + + {"udp4", "", "232.0.0.0:0", &net.UDPAddr{IP: net.IPv4(232, 0, 1, 249)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 + {"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 +} + +func TestPacketConnMulticastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris": + t.Skipf("not supported on %s", runtime.GOOS) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + m, ok := nettest.SupportsRawIPSocket() + for _, tt := range packetConnMulticastSocketOptionTests { + if tt.net == "ip4" && !ok { + t.Log(m) + continue + } + c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv4.NewPacketConn(c) + defer p.Close() + + if tt.src == nil { + testMulticastSocketOptions(t, p, ifi, tt.grp) + } else { + testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src) + } + } +} + +var rawConnMulticastSocketOptionTests = []struct { + grp, src net.Addr +}{ + {&net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}, nil}, // see RFC 4727 + + {&net.IPAddr{IP: net.IPv4(232, 0, 1, 250)}, &net.IPAddr{IP: net.IPv4(127, 0, 0, 1)}}, // see RFC 5771 +} + +func TestRawConnMulticastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris": + t.Skipf("not supported on %s", runtime.GOOS) + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + for _, tt := range rawConnMulticastSocketOptionTests { + c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + r, err := ipv4.NewRawConn(c) + if err != nil { + t.Fatal(err) + } + defer r.Close() + + if tt.src == nil { + testMulticastSocketOptions(t, r, ifi, tt.grp) + } else { + testSourceSpecificMulticastSocketOptions(t, r, ifi, tt.grp, tt.src) + } + } +} + +type testIPv4MulticastConn interface { + MulticastTTL() (int, error) + SetMulticastTTL(ttl int) error + MulticastLoopback() (bool, error) + SetMulticastLoopback(bool) error + JoinGroup(*net.Interface, net.Addr) error + LeaveGroup(*net.Interface, net.Addr) error + JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error + LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error + ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error + IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error +} + +func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp net.Addr) { + const ttl = 255 + if err := c.SetMulticastTTL(ttl); err != nil { + t.Error(err) + return + } + if v, err := c.MulticastTTL(); err != nil { + t.Error(err) + return + } else if v != ttl { + t.Errorf("got %v; want %v", v, ttl) + return + } + + for _, toggle := range []bool{true, false} { + if err := c.SetMulticastLoopback(toggle); err != nil { + t.Error(err) + return + } + if v, err := c.MulticastLoopback(); err != nil { + t.Error(err) + return + } else if v != toggle { + t.Errorf("got %v; want %v", v, toggle) + return + } + } + + if err := c.JoinGroup(ifi, grp); err != nil { + t.Error(err) + return + } + if err := c.LeaveGroup(ifi, grp); err != nil { + t.Error(err) + return + } +} + +func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, grp, src net.Addr) { + // MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP + if err := c.JoinGroup(ifi, grp); err != nil { + t.Error(err) + return + } + if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil { + switch runtime.GOOS { + case "freebsd", "linux": + default: // platforms that don't support IGMPv2/3 fail here + t.Logf("not supported on %s", runtime.GOOS) + return + } + t.Error(err) + return + } + if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + if err := c.LeaveGroup(ifi, grp); err != nil { + t.Error(err) + return + } + + // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP + if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + + // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP + if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + if err := c.LeaveGroup(ifi, grp); err != nil { + t.Error(err) + return + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/packet.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/packet.go new file mode 100644 index 00000000..09864314 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/packet.go @@ -0,0 +1,97 @@ +// 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 ipv4 + +import ( + "net" + "syscall" +) + +// A packetHandler represents the IPv4 datagram handler. +type packetHandler struct { + c *net.IPConn + rawOpt +} + +func (c *packetHandler) ok() bool { return c != nil && c.c != nil } + +// ReadFrom reads an IPv4 datagram from the endpoint c, copying the +// datagram into b. It returns the received datagram as the IPv4 +// header h, the payload p and the control message cm. +func (c *packetHandler) ReadFrom(b []byte) (h *Header, p []byte, cm *ControlMessage, err error) { + if !c.ok() { + return nil, nil, nil, syscall.EINVAL + } + oob := newControlMessage(&c.rawOpt) + n, oobn, _, src, err := c.c.ReadMsgIP(b, oob) + if err != nil { + return nil, nil, nil, err + } + var hs []byte + if hs, p, err = slicePacket(b[:n]); err != nil { + return nil, nil, nil, err + } + if h, err = ParseHeader(hs); err != nil { + return nil, nil, nil, err + } + if cm, err = parseControlMessage(oob[:oobn]); err != nil { + return nil, nil, nil, err + } + if src != nil && cm != nil { + cm.Src = src.IP + } + return +} + +func slicePacket(b []byte) (h, p []byte, err error) { + if len(b) < HeaderLen { + return nil, nil, errHeaderTooShort + } + hdrlen := int(b[0]&0x0f) << 2 + return b[:hdrlen], b[hdrlen:], nil +} + +// WriteTo writes an IPv4 datagram through the endpoint c, copying the +// datagram from the IPv4 header h and the payload p. The control +// message cm allows the datagram path and the outgoing interface to be +// specified. Currently only Darwin and Linux support this. The cm +// may be nil if control of the outgoing datagram is not required. +// +// The IPv4 header h must contain appropriate fields that include: +// +// Version = ipv4.Version +// Len = +// TOS = +// TotalLen = +// ID = platform sets an appropriate value if ID is zero +// FragOff = +// TTL = +// Protocol = +// Checksum = platform sets an appropriate value if Checksum is zero +// Src = platform sets an appropriate value if Src is nil +// Dst = +// Options = optional +func (c *packetHandler) WriteTo(h *Header, p []byte, cm *ControlMessage) error { + if !c.ok() { + return syscall.EINVAL + } + oob := marshalControlMessage(cm) + wh, err := h.Marshal() + if err != nil { + return err + } + dst := &net.IPAddr{} + if cm != nil { + if ip := cm.Dst.To4(); ip != nil { + dst.IP = ip + } + } + if dst.IP == nil { + dst.IP = h.Dst + } + wh = append(wh, p...) + _, _, err = c.c.WriteMsgIP(wh, oob, dst) + return err +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload.go new file mode 100644 index 00000000..d7698cbd --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload.go @@ -0,0 +1,15 @@ +// 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 ipv4 + +import "net" + +// A payloadHandler represents the IPv4 datagram payload handler. +type payloadHandler struct { + net.PacketConn + rawOpt +} + +func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload_cmsg.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload_cmsg.go new file mode 100644 index 00000000..d358fc3a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload_cmsg.go @@ -0,0 +1,81 @@ +// 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,!windows + +package ipv4 + +import ( + "net" + "syscall" +) + +// ReadFrom reads a payload of the received IPv4 datagram, from the +// endpoint c, copying the payload into b. It returns the number of +// bytes copied into b, the control message cm and the source address +// src of the received datagram. +func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { + if !c.ok() { + return 0, nil, nil, syscall.EINVAL + } + oob := newControlMessage(&c.rawOpt) + var oobn int + switch c := c.PacketConn.(type) { + case *net.UDPConn: + if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil { + return 0, nil, nil, err + } + case *net.IPConn: + if sockOpts[ssoStripHeader].name > 0 { + if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil { + return 0, nil, nil, err + } + } else { + nb := make([]byte, maxHeaderLen+len(b)) + if n, oobn, _, src, err = c.ReadMsgIP(nb, oob); err != nil { + return 0, nil, nil, err + } + hdrlen := int(nb[0]&0x0f) << 2 + copy(b, nb[hdrlen:]) + n -= hdrlen + } + default: + return 0, nil, nil, errInvalidConnType + } + if cm, err = parseControlMessage(oob[:oobn]); err != nil { + return 0, nil, nil, err + } + if cm != nil { + cm.Src = netAddrToIP4(src) + } + return +} + +// WriteTo writes a payload of the IPv4 datagram, to the destination +// address dst through the endpoint c, copying the payload from b. It +// returns the number of bytes written. The control message cm allows +// the datagram path and the outgoing interface to be specified. +// Currently only Darwin and Linux support this. The cm may be nil if +// control of the outgoing datagram is not required. +func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { + if !c.ok() { + return 0, syscall.EINVAL + } + oob := marshalControlMessage(cm) + if dst == nil { + return 0, errMissingAddress + } + switch c := c.PacketConn.(type) { + case *net.UDPConn: + n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr)) + case *net.IPConn: + n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr)) + default: + return 0, errInvalidConnType + } + if err != nil { + return 0, err + } + return +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload_nocmsg.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload_nocmsg.go new file mode 100644 index 00000000..d128c9c2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/payload_nocmsg.go @@ -0,0 +1,42 @@ +// 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 windows + +package ipv4 + +import ( + "net" + "syscall" +) + +// ReadFrom reads a payload of the received IPv4 datagram, from the +// endpoint c, copying the payload into b. It returns the number of +// bytes copied into b, the control message cm and the source address +// src of the received datagram. +func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { + if !c.ok() { + return 0, nil, nil, syscall.EINVAL + } + if n, src, err = c.PacketConn.ReadFrom(b); err != nil { + return 0, nil, nil, err + } + return +} + +// WriteTo writes a payload of the IPv4 datagram, to the destination +// address dst through the endpoint c, copying the payload from b. It +// returns the number of bytes written. The control message cm allows +// the datagram path and the outgoing interface to be specified. +// Currently only Darwin and Linux support this. The cm may be nil if +// control of the outgoing datagram is not required. +func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { + if !c.ok() { + return 0, syscall.EINVAL + } + if dst == nil { + return 0, errMissingAddress + } + return c.PacketConn.WriteTo(b, dst) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/readwrite_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/readwrite_test.go new file mode 100644 index 00000000..247d06c1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/readwrite_test.go @@ -0,0 +1,174 @@ +// 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 ipv4_test + +import ( + "bytes" + "net" + "runtime" + "strings" + "sync" + "testing" + + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" +) + +func benchmarkUDPListener() (net.PacketConn, net.Addr, error) { + c, err := net.ListenPacket("udp4", "127.0.0.1:0") + if err != nil { + return nil, nil, err + } + dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) + if err != nil { + c.Close() + return nil, nil, err + } + return c, dst, nil +} + +func BenchmarkReadWriteNetUDP(b *testing.B) { + c, dst, err := benchmarkUDPListener() + if err != nil { + b.Fatal(err) + } + defer c.Close() + + wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128) + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchmarkReadWriteNetUDP(b, c, wb, rb, dst) + } +} + +func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) { + if _, err := c.WriteTo(wb, dst); err != nil { + b.Fatal(err) + } + if _, _, err := c.ReadFrom(rb); err != nil { + b.Fatal(err) + } +} + +func BenchmarkReadWriteIPv4UDP(b *testing.B) { + c, dst, err := benchmarkUDPListener() + if err != nil { + b.Fatal(err) + } + defer c.Close() + + p := ipv4.NewPacketConn(c) + defer p.Close() + cf := ipv4.FlagTTL | ipv4.FlagInterface + if err := p.SetControlMessage(cf, true); err != nil { + b.Fatal(err) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + + wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128) + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchmarkReadWriteIPv4UDP(b, p, wb, rb, dst, ifi) + } +} + +func benchmarkReadWriteIPv4UDP(b *testing.B, p *ipv4.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) { + cm := ipv4.ControlMessage{TTL: 1} + if ifi != nil { + cm.IfIndex = ifi.Index + } + if n, err := p.WriteTo(wb, &cm, dst); err != nil { + b.Fatal(err) + } else if n != len(wb) { + b.Fatalf("got %v; want %v", n, len(wb)) + } + if _, _, _, err := p.ReadFrom(rb); err != nil { + b.Fatal(err) + } +} + +func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + + c, err := net.ListenPacket("udp4", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv4.NewPacketConn(c) + defer p.Close() + + dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) + if err != nil { + t.Fatal(err) + } + + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface + wb := []byte("HELLO-R-U-THERE") + + if err := p.SetControlMessage(cf, true); err != nil { // probe before test + if nettest.ProtocolNotSupported(err) { + t.Skipf("not supported on %s", runtime.GOOS) + } + t.Fatal(err) + } + + var wg sync.WaitGroup + reader := func() { + defer wg.Done() + rb := make([]byte, 128) + if n, cm, _, err := p.ReadFrom(rb); err != nil { + t.Error(err) + return + } else if !bytes.Equal(rb[:n], wb) { + t.Errorf("got %v; want %v", rb[:n], wb) + return + } else { + s := cm.String() + if strings.Contains(s, ",") { + t.Errorf("should be space-separated values: %s", s) + } + } + } + writer := func(toggle bool) { + defer wg.Done() + cm := ipv4.ControlMessage{ + Src: net.IPv4(127, 0, 0, 1), + } + if ifi != nil { + cm.IfIndex = ifi.Index + } + if err := p.SetControlMessage(cf, toggle); err != nil { + t.Error(err) + return + } + if n, err := p.WriteTo(wb, &cm, dst); err != nil { + t.Error(err) + return + } else if n != len(wb) { + t.Errorf("short write: %v", n) + return + } + } + + const N = 10 + wg.Add(N) + for i := 0; i < N; i++ { + go reader() + } + wg.Add(2 * N) + for i := 0; i < 2*N; i++ { + go writer(i%2 != 0) + } + wg.Add(N) + for i := 0; i < N; i++ { + go reader() + } + wg.Wait() +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt.go new file mode 100644 index 00000000..ace37d30 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt.go @@ -0,0 +1,46 @@ +// 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. + +package ipv4 + +// Sticky socket options +const ( + ssoTOS = iota // header field for unicast packet + ssoTTL // header field for unicast packet + ssoMulticastTTL // header field for multicast packet + ssoMulticastInterface // outbound interface for multicast packet + ssoMulticastLoopback // loopback for multicast packet + ssoReceiveTTL // header field on received packet + ssoReceiveDst // header field on received packet + ssoReceiveInterface // inbound interface on received packet + ssoPacketInfo // incbound or outbound packet path + ssoHeaderPrepend // ipv4 header prepend + ssoStripHeader // strip ipv4 header + ssoICMPFilter // icmp filter + ssoJoinGroup // any-source multicast + ssoLeaveGroup // any-source multicast + ssoJoinSourceGroup // source-specific multicast + ssoLeaveSourceGroup // source-specific multicast + ssoBlockSourceGroup // any-source or source-specific multicast + ssoUnblockSourceGroup // any-source or source-specific multicast + ssoMax +) + +// Sticky socket option value types +const ( + ssoTypeByte = iota + 1 + ssoTypeInt + ssoTypeInterface + ssoTypeICMPFilter + ssoTypeIPMreq + ssoTypeIPMreqn + ssoTypeGroupReq + ssoTypeGroupSourceReq +) + +// A sockOpt represents a binding for sticky socket option. +type sockOpt struct { + name int // option name, must be equal or greater than 1 + typ int // option value type, must be equal or greater than 1 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq.go new file mode 100644 index 00000000..4a6aa78e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq.go @@ -0,0 +1,83 @@ +// 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 darwin dragonfly freebsd netbsd openbsd windows + +package ipv4 + +import "net" + +func setIPMreqInterface(mreq *sysIPMreq, ifi *net.Interface) error { + if ifi == nil { + return nil + } + ifat, err := ifi.Addrs() + if err != nil { + return err + } + for _, ifa := range ifat { + switch ifa := ifa.(type) { + case *net.IPAddr: + if ip := ifa.IP.To4(); ip != nil { + copy(mreq.Interface[:], ip) + return nil + } + case *net.IPNet: + if ip := ifa.IP.To4(); ip != nil { + copy(mreq.Interface[:], ip) + return nil + } + } + } + return errNoSuchInterface +} + +func netIP4ToInterface(ip net.IP) (*net.Interface, error) { + ift, err := net.Interfaces() + if err != nil { + return nil, err + } + for _, ifi := range ift { + ifat, err := ifi.Addrs() + if err != nil { + return nil, err + } + for _, ifa := range ifat { + switch ifa := ifa.(type) { + case *net.IPAddr: + if ip.Equal(ifa.IP) { + return &ifi, nil + } + case *net.IPNet: + if ip.Equal(ifa.IP) { + return &ifi, nil + } + } + } + } + return nil, errNoSuchInterface +} + +func netInterfaceToIP4(ifi *net.Interface) (net.IP, error) { + if ifi == nil { + return net.IPv4zero.To4(), nil + } + ifat, err := ifi.Addrs() + if err != nil { + return nil, err + } + for _, ifa := range ifat { + switch ifa := ifa.(type) { + case *net.IPAddr: + if ip := ifa.IP.To4(); ip != nil { + return ip, nil + } + case *net.IPNet: + if ip := ifa.IP.To4(); ip != nil { + return ip, nil + } + } + } + return nil, errNoSuchInterface +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_stub.go new file mode 100644 index 00000000..45551528 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_stub.go @@ -0,0 +1,21 @@ +// 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 !darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!windows + +package ipv4 + +import "net" + +func setsockoptIPMreq(fd, name int, ifi *net.Interface, grp net.IP) error { + return errOpNoSupport +} + +func getsockoptInterface(fd, name int) (*net.Interface, error) { + return nil, errOpNoSupport +} + +func setsockoptInterface(fd, name int, ifi *net.Interface) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_unix.go new file mode 100644 index 00000000..fefa901e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_unix.go @@ -0,0 +1,46 @@ +// 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 darwin dragonfly freebsd netbsd openbsd + +package ipv4 + +import ( + "net" + "os" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func setsockoptIPMreq(fd, name int, ifi *net.Interface, grp net.IP) error { + mreq := sysIPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}} + if err := setIPMreqInterface(&mreq, ifi); err != nil { + return err + } + return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreq), sysSizeofIPMreq)) +} + +func getsockoptInterface(fd, name int) (*net.Interface, error) { + var b [4]byte + l := sysSockoptLen(4) + if err := getsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3])) + if err != nil { + return nil, err + } + return ifi, nil +} + +func setsockoptInterface(fd, name int, ifi *net.Interface) error { + ip, err := netInterfaceToIP4(ifi) + if err != nil { + return err + } + var b [4]byte + copy(b[:], ip) + return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&b[0]), sysSockoptLen(4))) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_windows.go new file mode 100644 index 00000000..431930df --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreq_windows.go @@ -0,0 +1,45 @@ +// 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 ipv4 + +import ( + "net" + "os" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func setsockoptIPMreq(fd syscall.Handle, name int, ifi *net.Interface, grp net.IP) error { + mreq := sysIPMreq{Multiaddr: [4]byte{grp[0], grp[1], grp[2], grp[3]}} + if err := setIPMreqInterface(&mreq, ifi); err != nil { + return err + } + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&mreq)), int32(sysSizeofIPMreq))) +} + +func getsockoptInterface(fd syscall.Handle, name int) (*net.Interface, error) { + var b [4]byte + l := int32(4) + if err := syscall.Getsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + ifi, err := netIP4ToInterface(net.IPv4(b[0], b[1], b[2], b[3])) + if err != nil { + return nil, err + } + return ifi, nil +} + +func setsockoptInterface(fd syscall.Handle, name int, ifi *net.Interface) error { + ip, err := netInterfaceToIP4(ifi) + if err != nil { + return err + } + var b [4]byte + copy(b[:], ip) + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(name), (*byte)(unsafe.Pointer(&b[0])), 4)) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go new file mode 100644 index 00000000..332f403e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreqn_stub.go @@ -0,0 +1,17 @@ +// 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. + +// +build !darwin,!freebsd,!linux,!windows + +package ipv4 + +import "net" + +func getsockoptIPMreqn(fd, name int) (*net.Interface, error) { + return nil, errOpNoSupport +} + +func setsockoptIPMreqn(fd, name int, ifi *net.Interface, grp net.IP) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go new file mode 100644 index 00000000..92c8e34c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_asmreqn_unix.go @@ -0,0 +1,42 @@ +// 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. + +// +build darwin freebsd linux + +package ipv4 + +import ( + "net" + "os" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func getsockoptIPMreqn(fd, name int) (*net.Interface, error) { + var mreqn sysIPMreqn + l := sysSockoptLen(sysSizeofIPMreqn) + if err := getsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + if mreqn.Ifindex == 0 { + return nil, nil + } + ifi, err := net.InterfaceByIndex(int(mreqn.Ifindex)) + if err != nil { + return nil, err + } + return ifi, nil +} + +func setsockoptIPMreqn(fd, name int, ifi *net.Interface, grp net.IP) error { + var mreqn sysIPMreqn + if ifi != nil { + mreqn.Ifindex = int32(ifi.Index) + } + if grp != nil { + mreqn.Multiaddr = [4]byte{grp[0], grp[1], grp[2], grp[3]} + } + return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), sysSizeofIPMreqn)) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go new file mode 100644 index 00000000..85465244 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_ssmreq_stub.go @@ -0,0 +1,17 @@ +// 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. + +// +build !darwin,!freebsd,!linux + +package ipv4 + +import "net" + +func setsockoptGroupReq(fd, name int, ifi *net.Interface, grp net.IP) error { + return errOpNoSupport +} + +func setsockoptGroupSourceReq(fd, name int, ifi *net.Interface, grp, src net.IP) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go new file mode 100644 index 00000000..6f647bc5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_ssmreq_unix.go @@ -0,0 +1,61 @@ +// 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. + +// +build darwin freebsd linux + +package ipv4 + +import ( + "net" + "os" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +var freebsd32o64 bool + +func setsockoptGroupReq(fd, name int, ifi *net.Interface, grp net.IP) error { + var gr sysGroupReq + if ifi != nil { + gr.Interface = uint32(ifi.Index) + } + gr.setGroup(grp) + var p unsafe.Pointer + var l sysSockoptLen + if freebsd32o64 { + var d [sysSizeofGroupReq + 4]byte + s := (*[sysSizeofGroupReq]byte)(unsafe.Pointer(&gr)) + copy(d[:4], s[:4]) + copy(d[8:], s[4:]) + p = unsafe.Pointer(&d[0]) + l = sysSizeofGroupReq + 4 + } else { + p = unsafe.Pointer(&gr) + l = sysSizeofGroupReq + } + return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, p, l)) +} + +func setsockoptGroupSourceReq(fd, name int, ifi *net.Interface, grp, src net.IP) error { + var gsr sysGroupSourceReq + if ifi != nil { + gsr.Interface = uint32(ifi.Index) + } + gsr.setSourceGroup(grp, src) + var p unsafe.Pointer + var l sysSockoptLen + if freebsd32o64 { + var d [sysSizeofGroupSourceReq + 4]byte + s := (*[sysSizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr)) + copy(d[:4], s[:4]) + copy(d[8:], s[4:]) + p = unsafe.Pointer(&d[0]) + l = sysSizeofGroupSourceReq + 4 + } else { + p = unsafe.Pointer(&gsr) + l = sysSizeofGroupSourceReq + } + return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, name, p, l)) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_stub.go new file mode 100644 index 00000000..9d19f5df --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_stub.go @@ -0,0 +1,11 @@ +// 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 nacl plan9 solaris + +package ipv4 + +func setInt(fd int, opt *sockOpt, v int) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_unix.go new file mode 100644 index 00000000..50cdbd81 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_unix.go @@ -0,0 +1,122 @@ +// 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 darwin dragonfly freebsd linux netbsd openbsd + +package ipv4 + +import ( + "net" + "os" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func getInt(fd int, opt *sockOpt) (int, error) { + if opt.name < 1 || (opt.typ != ssoTypeByte && opt.typ != ssoTypeInt) { + return 0, errOpNoSupport + } + var i int32 + var b byte + p := unsafe.Pointer(&i) + l := sysSockoptLen(4) + if opt.typ == ssoTypeByte { + p = unsafe.Pointer(&b) + l = sysSockoptLen(1) + } + if err := getsockopt(fd, iana.ProtocolIP, opt.name, p, &l); err != nil { + return 0, os.NewSyscallError("getsockopt", err) + } + if opt.typ == ssoTypeByte { + return int(b), nil + } + return int(i), nil +} + +func setInt(fd int, opt *sockOpt, v int) error { + if opt.name < 1 || (opt.typ != ssoTypeByte && opt.typ != ssoTypeInt) { + return errOpNoSupport + } + i := int32(v) + var b byte + p := unsafe.Pointer(&i) + l := sysSockoptLen(4) + if opt.typ == ssoTypeByte { + b = byte(v) + p = unsafe.Pointer(&b) + l = sysSockoptLen(1) + } + return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolIP, opt.name, p, l)) +} + +func getInterface(fd int, opt *sockOpt) (*net.Interface, error) { + if opt.name < 1 { + return nil, errOpNoSupport + } + switch opt.typ { + case ssoTypeInterface: + return getsockoptInterface(fd, opt.name) + case ssoTypeIPMreqn: + return getsockoptIPMreqn(fd, opt.name) + default: + return nil, errOpNoSupport + } +} + +func setInterface(fd int, opt *sockOpt, ifi *net.Interface) error { + if opt.name < 1 { + return errOpNoSupport + } + switch opt.typ { + case ssoTypeInterface: + return setsockoptInterface(fd, opt.name, ifi) + case ssoTypeIPMreqn: + return setsockoptIPMreqn(fd, opt.name, ifi, nil) + default: + return errOpNoSupport + } +} + +func getICMPFilter(fd int, opt *sockOpt) (*ICMPFilter, error) { + if opt.name < 1 || opt.typ != ssoTypeICMPFilter { + return nil, errOpNoSupport + } + var f ICMPFilter + l := sysSockoptLen(sysSizeofICMPFilter) + if err := getsockopt(fd, iana.ProtocolReserved, opt.name, unsafe.Pointer(&f.sysICMPFilter), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + return &f, nil +} + +func setICMPFilter(fd int, opt *sockOpt, f *ICMPFilter) error { + if opt.name < 1 || opt.typ != ssoTypeICMPFilter { + return errOpNoSupport + } + return os.NewSyscallError("setsockopt", setsockopt(fd, iana.ProtocolReserved, opt.name, unsafe.Pointer(&f.sysICMPFilter), sysSizeofICMPFilter)) +} + +func setGroup(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + if opt.name < 1 { + return errOpNoSupport + } + switch opt.typ { + case ssoTypeIPMreq: + return setsockoptIPMreq(fd, opt.name, ifi, grp) + case ssoTypeIPMreqn: + return setsockoptIPMreqn(fd, opt.name, ifi, grp) + case ssoTypeGroupReq: + return setsockoptGroupReq(fd, opt.name, ifi, grp) + default: + return errOpNoSupport + } +} + +func setSourceGroup(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error { + if opt.name < 1 || opt.typ != ssoTypeGroupSourceReq { + return errOpNoSupport + } + return setsockoptGroupSourceReq(fd, opt.name, ifi, grp, src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_windows.go new file mode 100644 index 00000000..c4c2441e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sockopt_windows.go @@ -0,0 +1,68 @@ +// 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 ipv4 + +import ( + "net" + "os" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func getInt(fd syscall.Handle, opt *sockOpt) (int, error) { + if opt.name < 1 || opt.typ != ssoTypeInt { + return 0, errOpNoSupport + } + var i int32 + l := int32(4) + if err := syscall.Getsockopt(fd, iana.ProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil { + return 0, os.NewSyscallError("getsockopt", err) + } + return int(i), nil +} + +func setInt(fd syscall.Handle, opt *sockOpt, v int) error { + if opt.name < 1 || opt.typ != ssoTypeInt { + return errOpNoSupport + } + i := int32(v) + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, iana.ProtocolIP, int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4)) +} + +func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return nil, errOpNoSupport + } + return getsockoptInterface(fd, opt.name) +} + +func setInterface(fd syscall.Handle, opt *sockOpt, ifi *net.Interface) error { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return errOpNoSupport + } + return setsockoptInterface(fd, opt.name, ifi) +} + +func getICMPFilter(fd syscall.Handle, opt *sockOpt) (*ICMPFilter, error) { + return nil, errOpNoSupport +} + +func setICMPFilter(fd syscall.Handle, opt *sockOpt, f *ICMPFilter) error { + return errOpNoSupport +} + +func setGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + if opt.name < 1 || opt.typ != ssoTypeIPMreq { + return errOpNoSupport + } + return setsockoptIPMreq(fd, opt.name, ifi, grp) +} + +func setSourceGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error { + // TODO(mikio): implement this + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_bsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_bsd.go new file mode 100644 index 00000000..a669a440 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_bsd.go @@ -0,0 +1,36 @@ +// 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. + +// +build dragonfly netbsd + +package ipv4 + +import ( + "net" + "syscall" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, + ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, + ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTOS: {sysIP_TOS, ssoTypeInt}, + ssoTTL: {sysIP_TTL, ssoTypeInt}, + ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte}, + ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt}, + ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt}, + ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt}, + ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt}, + ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq}, + ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq}, + } +) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_darwin.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_darwin.go new file mode 100644 index 00000000..3f347348 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_darwin.go @@ -0,0 +1,98 @@ +// 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. + +package ipv4 + +import ( + "net" + "syscall" + "unsafe" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, + ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, + ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTOS: {sysIP_TOS, ssoTypeInt}, + ssoTTL: {sysIP_TTL, ssoTypeInt}, + ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte}, + ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt}, + ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt}, + ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt}, + ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt}, + ssoStripHeader: {sysIP_STRIPHDR, ssoTypeInt}, + ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq}, + ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq}, + } +) + +func init() { + // Seems like kern.osreldate is veiled on latest OS X. We use + // kern.osrelease instead. + osver, err := syscall.Sysctl("kern.osrelease") + if err != nil { + return + } + var i int + for i = range osver { + if osver[i] == '.' { + break + } + } + // The IP_PKTINFO and protocol-independent multicast API were + // introduced in OS X 10.7 (Darwin 11.0.0). But it looks like + // those features require OS X 10.8 (Darwin 12.0.0) and above. + // See http://support.apple.com/kb/HT1633. + if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '2' { + ctlOpts[ctlPacketInfo].name = sysIP_PKTINFO + ctlOpts[ctlPacketInfo].length = sysSizeofInetPktinfo + ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo + ctlOpts[ctlPacketInfo].parse = parsePacketInfo + sockOpts[ssoPacketInfo].name = sysIP_RECVPKTINFO + sockOpts[ssoPacketInfo].typ = ssoTypeInt + sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn + sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP + sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq + sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP + sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq + sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP + sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq + sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP + sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq + sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE + sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq + sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE + sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq + } +} + +func (pi *sysInetPktinfo) setIfindex(i int) { + pi.Ifindex = uint32(i) +} + +func (gr *sysGroupReq) setGroup(grp net.IP) { + sa := (*sysSockaddrInet)(unsafe.Pointer(&gr.Pad_cgo_0[0])) + sa.Len = sysSizeofSockaddrInet + sa.Family = syscall.AF_INET + copy(sa.Addr[:], grp) +} + +func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) { + sa := (*sysSockaddrInet)(unsafe.Pointer(&gsr.Pad_cgo_0[0])) + sa.Len = sysSizeofSockaddrInet + sa.Family = syscall.AF_INET + copy(sa.Addr[:], grp) + sa = (*sysSockaddrInet)(unsafe.Pointer(&gsr.Pad_cgo_1[0])) + sa.Len = sysSizeofSockaddrInet + sa.Family = syscall.AF_INET + copy(sa.Addr[:], src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_freebsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_freebsd.go new file mode 100644 index 00000000..09ef4910 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_freebsd.go @@ -0,0 +1,75 @@ +// 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. + +package ipv4 + +import ( + "net" + "runtime" + "strings" + "syscall" + "unsafe" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, + ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, + ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTOS: {sysIP_TOS, ssoTypeInt}, + ssoTTL: {sysIP_TTL, ssoTypeInt}, + ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte}, + ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt}, + ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt}, + ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt}, + ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt}, + ssoJoinGroup: {sysMCAST_JOIN_GROUP, ssoTypeGroupReq}, + ssoLeaveGroup: {sysMCAST_LEAVE_GROUP, ssoTypeGroupReq}, + ssoJoinSourceGroup: {sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoLeaveSourceGroup: {sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoBlockSourceGroup: {sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq}, + ssoUnblockSourceGroup: {sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq}, + } +) + +func init() { + freebsdVersion, _ = syscall.SysctlUint32("kern.osreldate") + if freebsdVersion >= 1000000 { + sockOpts[ssoMulticastInterface].typ = ssoTypeIPMreqn + } + if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" { + archs, _ := syscall.Sysctl("kern.supported_archs") + for _, s := range strings.Fields(archs) { + if s == "amd64" { + freebsd32o64 = true + break + } + } + } +} + +func (gr *sysGroupReq) setGroup(grp net.IP) { + sa := (*sysSockaddrInet)(unsafe.Pointer(&gr.Group)) + sa.Len = sysSizeofSockaddrInet + sa.Family = syscall.AF_INET + copy(sa.Addr[:], grp) +} + +func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) { + sa := (*sysSockaddrInet)(unsafe.Pointer(&gsr.Group)) + sa.Len = sysSizeofSockaddrInet + sa.Family = syscall.AF_INET + copy(sa.Addr[:], grp) + sa = (*sysSockaddrInet)(unsafe.Pointer(&gsr.Source)) + sa.Len = sysSizeofSockaddrInet + sa.Family = syscall.AF_INET + copy(sa.Addr[:], src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_linux.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_linux.go new file mode 100644 index 00000000..b1f38789 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_linux.go @@ -0,0 +1,57 @@ +// 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. + +package ipv4 + +import ( + "net" + "syscall" + "unsafe" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTTL: {sysIP_TTL, 1, marshalTTL, parseTTL}, + ctlPacketInfo: {sysIP_PKTINFO, sysSizeofInetPktinfo, marshalPacketInfo, parsePacketInfo}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTOS: {sysIP_TOS, ssoTypeInt}, + ssoTTL: {sysIP_TTL, ssoTypeInt}, + ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeInt}, + ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeIPMreqn}, + ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt}, + ssoPacketInfo: {sysIP_PKTINFO, ssoTypeInt}, + ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt}, + ssoICMPFilter: {sysICMP_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {sysMCAST_JOIN_GROUP, ssoTypeGroupReq}, + ssoLeaveGroup: {sysMCAST_LEAVE_GROUP, ssoTypeGroupReq}, + ssoJoinSourceGroup: {sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoLeaveSourceGroup: {sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoBlockSourceGroup: {sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq}, + ssoUnblockSourceGroup: {sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq}, + } +) + +func (pi *sysInetPktinfo) setIfindex(i int) { + pi.Ifindex = int32(i) +} + +func (gr *sysGroupReq) setGroup(grp net.IP) { + sa := (*sysSockaddrInet)(unsafe.Pointer(&gr.Group)) + sa.Family = syscall.AF_INET + copy(sa.Addr[:], grp) +} + +func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) { + sa := (*sysSockaddrInet)(unsafe.Pointer(&gsr.Group)) + sa.Family = syscall.AF_INET + copy(sa.Addr[:], grp) + sa = (*sysSockaddrInet)(unsafe.Pointer(&gsr.Source)) + sa.Family = syscall.AF_INET + copy(sa.Addr[:], src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_openbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_openbsd.go new file mode 100644 index 00000000..550f2081 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_openbsd.go @@ -0,0 +1,34 @@ +// 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. + +package ipv4 + +import ( + "net" + "syscall" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTTL: {sysIP_RECVTTL, 1, marshalTTL, parseTTL}, + ctlDst: {sysIP_RECVDSTADDR, net.IPv4len, marshalDst, parseDst}, + ctlInterface: {sysIP_RECVIF, syscall.SizeofSockaddrDatalink, marshalInterface, parseInterface}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTOS: {sysIP_TOS, ssoTypeInt}, + ssoTTL: {sysIP_TTL, ssoTypeInt}, + ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeByte}, + ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeByte}, + ssoReceiveTTL: {sysIP_RECVTTL, ssoTypeInt}, + ssoReceiveDst: {sysIP_RECVDSTADDR, ssoTypeInt}, + ssoReceiveInterface: {sysIP_RECVIF, ssoTypeInt}, + ssoHeaderPrepend: {sysIP_HDRINCL, ssoTypeInt}, + ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq}, + ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq}, + } +) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_stub.go new file mode 100644 index 00000000..efbcc479 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_stub.go @@ -0,0 +1,15 @@ +// 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. + +// +build nacl plan9 solaris + +package ipv4 + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{} + + sockOpts = [ssoMax]sockOpt{} +) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_windows.go new file mode 100644 index 00000000..466489fe --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/sys_windows.go @@ -0,0 +1,61 @@ +// 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. + +package ipv4 + +const ( + // See ws2tcpip.h. + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + sysIP_DONTFRAGMENT = 0xe + sysIP_ADD_SOURCE_MEMBERSHIP = 0xf + sysIP_DROP_SOURCE_MEMBERSHIP = 0x10 + sysIP_PKTINFO = 0x13 + + sysSizeofInetPktinfo = 0x8 + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqSource = 0xc +) + +type sysInetPktinfo struct { + Addr [4]byte + Ifindex int32 +} + +type sysIPMreq struct { + Multiaddr [4]byte + Interface [4]byte +} + +type sysIPMreqSource struct { + Multiaddr [4]byte + Sourceaddr [4]byte + Interface [4]byte +} + +// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms738586(v=vs.85).aspx +var ( + ctlOpts = [ctlMax]ctlOpt{} + + sockOpts = [ssoMax]sockOpt{ + ssoTOS: {sysIP_TOS, ssoTypeInt}, + ssoTTL: {sysIP_TTL, ssoTypeInt}, + ssoMulticastTTL: {sysIP_MULTICAST_TTL, ssoTypeInt}, + ssoMulticastInterface: {sysIP_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastLoopback: {sysIP_MULTICAST_LOOP, ssoTypeInt}, + ssoJoinGroup: {sysIP_ADD_MEMBERSHIP, ssoTypeIPMreq}, + ssoLeaveGroup: {sysIP_DROP_MEMBERSHIP, ssoTypeIPMreq}, + } +) + +func (pi *sysInetPktinfo) setIfindex(i int) { + pi.Ifindex = int32(i) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/syscall_linux_386.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/syscall_linux_386.go new file mode 100644 index 00000000..ab4ad045 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/syscall_linux_386.go @@ -0,0 +1,31 @@ +// 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. + +package ipv4 + +import ( + "syscall" + "unsafe" +) + +const ( + sysGETSOCKOPT = 0xf + sysSETSOCKOPT = 0xe +) + +func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) + +func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error { + if _, errno := socketcall(sysGETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 { + return error(errno) + } + return nil +} + +func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error { + if _, errno := socketcall(sysSETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 { + return error(errno) + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/syscall_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/syscall_unix.go new file mode 100644 index 00000000..5fe8e83b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/syscall_unix.go @@ -0,0 +1,26 @@ +// 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. + +// +build darwin dragonfly freebsd linux,!386 netbsd openbsd + +package ipv4 + +import ( + "syscall" + "unsafe" +) + +func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error { + if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 { + return error(errno) + } + return nil +} + +func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error { + if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 { + return error(errno) + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/thunk_linux_386.s b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/thunk_linux_386.s new file mode 100644 index 00000000..daa78bc0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/thunk_linux_386.s @@ -0,0 +1,8 @@ +// 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. + +// +build go1.2 + +TEXT ·socketcall(SB),4,$0-36 + JMP syscall·socketcall(SB) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/unicast_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/unicast_test.go new file mode 100644 index 00000000..9c632cd8 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/unicast_test.go @@ -0,0 +1,246 @@ +// 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 ipv4_test + +import ( + "bytes" + "net" + "os" + "runtime" + "testing" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" +) + +func TestPacketConnReadWriteUnicastUDP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + c, err := net.ListenPacket("udp4", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + dst, err := net.ResolveUDPAddr("udp4", c.LocalAddr().String()) + if err != nil { + t.Fatal(err) + } + p := ipv4.NewPacketConn(c) + defer p.Close() + cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface + wb := []byte("HELLO-R-U-THERE") + + for i, toggle := range []bool{true, false, true} { + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + p.SetTTL(i + 1) + if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, err := p.WriteTo(wb, nil, dst); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatalf("got %v; want %v", n, len(wb)) + } + rb := make([]byte, 128) + if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, _, _, err := p.ReadFrom(rb); err != nil { + t.Fatal(err) + } else if !bytes.Equal(rb[:n], wb) { + t.Fatalf("got %v; want %v", rb[:n], wb) + } + } +} + +func TestPacketConnReadWriteUnicastICMP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + dst, err := net.ResolveIPAddr("ip4", "127.0.0.1") + if err != nil { + t.Fatal(err) + } + p := ipv4.NewPacketConn(c) + defer p.Close() + cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface + + for i, toggle := range []bool{true, false, true} { + wb, err := (&icmp.Message{ + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: i + 1, + Data: []byte("HELLO-R-U-THERE"), + }, + }).Marshal(nil) + if err != nil { + t.Fatal(err) + } + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + p.SetTTL(i + 1) + if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, err := p.WriteTo(wb, nil, dst); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatalf("got %v; want %v", n, len(wb)) + } + rb := make([]byte, 128) + loop: + if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, _, _, err := p.ReadFrom(rb); err != nil { + switch runtime.GOOS { + case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } else { + m, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:n]) + if err != nil { + t.Fatal(err) + } + if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho { + // On Linux we must handle own sent packets. + goto loop + } + if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 { + t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) + } + } + } +} + +func TestRawConnReadWriteUnicastICMP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + dst, err := net.ResolveIPAddr("ip4", "127.0.0.1") + if err != nil { + t.Fatal(err) + } + r, err := ipv4.NewRawConn(c) + if err != nil { + t.Fatal(err) + } + defer r.Close() + cf := ipv4.FlagTTL | ipv4.FlagDst | ipv4.FlagInterface + + for i, toggle := range []bool{true, false, true} { + wb, err := (&icmp.Message{ + Type: ipv4.ICMPTypeEcho, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: i + 1, + Data: []byte("HELLO-R-U-THERE"), + }, + }).Marshal(nil) + if err != nil { + t.Fatal(err) + } + wh := &ipv4.Header{ + Version: ipv4.Version, + Len: ipv4.HeaderLen, + TOS: i + 1, + TotalLen: ipv4.HeaderLen + len(wb), + TTL: i + 1, + Protocol: 1, + Dst: dst.IP, + } + if err := r.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + if err := r.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if err := r.WriteTo(wh, wb, nil); err != nil { + t.Fatal(err) + } + rb := make([]byte, ipv4.HeaderLen+128) + loop: + if err := r.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if _, b, _, err := r.ReadFrom(rb); err != nil { + switch runtime.GOOS { + case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } else { + m, err := icmp.ParseMessage(iana.ProtocolICMP, b) + if err != nil { + t.Fatal(err) + } + if runtime.GOOS == "linux" && m.Type == ipv4.ICMPTypeEcho { + // On Linux we must handle own sent packets. + goto loop + } + if m.Type != ipv4.ICMPTypeEchoReply || m.Code != 0 { + t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv4.ICMPTypeEchoReply, 0) + } + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/unicastsockopt_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/unicastsockopt_test.go new file mode 100644 index 00000000..25606f21 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/unicastsockopt_test.go @@ -0,0 +1,139 @@ +// 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 ipv4_test + +import ( + "net" + "runtime" + "testing" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv4" +) + +func TestConnUnicastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris": + t.Skipf("not supported on %s", runtime.GOOS) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + ln, err := net.Listen("tcp4", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + + done := make(chan bool) + go acceptor(t, ln, done) + + c, err := net.Dial("tcp4", ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + testUnicastSocketOptions(t, ipv4.NewConn(c)) + + <-done +} + +var packetConnUnicastSocketOptionTests = []struct { + net, proto, addr string +}{ + {"udp4", "", "127.0.0.1:0"}, + {"ip4", ":icmp", "127.0.0.1"}, +} + +func TestPacketConnUnicastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris": + t.Skipf("not supported on %s", runtime.GOOS) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + m, ok := nettest.SupportsRawIPSocket() + for _, tt := range packetConnUnicastSocketOptionTests { + if tt.net == "ip4" && !ok { + t.Log(m) + continue + } + c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + testUnicastSocketOptions(t, ipv4.NewPacketConn(c)) + } +} + +func TestRawConnUnicastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris": + t.Skipf("not supported on %s", runtime.GOOS) + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + c, err := net.ListenPacket("ip4:icmp", "127.0.0.1") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + r, err := ipv4.NewRawConn(c) + if err != nil { + t.Fatal(err) + } + + testUnicastSocketOptions(t, r) +} + +type testIPv4UnicastConn interface { + TOS() (int, error) + SetTOS(int) error + TTL() (int, error) + SetTTL(int) error +} + +func testUnicastSocketOptions(t *testing.T, c testIPv4UnicastConn) { + tos := iana.DiffServCS0 | iana.NotECNTransport + switch runtime.GOOS { + case "windows": + // IP_TOS option is supported on Windows 8 and beyond. + t.Skipf("not supported on %s", runtime.GOOS) + } + + if err := c.SetTOS(tos); err != nil { + t.Fatal(err) + } + if v, err := c.TOS(); err != nil { + t.Fatal(err) + } else if v != tos { + t.Fatalf("got %v; want %v", v, tos) + } + const ttl = 255 + if err := c.SetTTL(ttl); err != nil { + t.Fatal(err) + } + if v, err := c.TTL(); err != nil { + t.Fatal(err) + } else if v != ttl { + t.Fatalf("got %v; want %v", v, ttl) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_darwin.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_darwin.go new file mode 100644 index 00000000..087c6390 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_darwin.go @@ -0,0 +1,99 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_darwin.go + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x14 + sysIP_STRIPHDR = 0x17 + sysIP_RECVTTL = 0x18 + sysIP_BOUND_IF = 0x19 + sysIP_PKTINFO = 0x1a + sysIP_RECVPKTINFO = 0x1a + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + sysIP_MULTICAST_VIF = 0xe + sysIP_MULTICAST_IFINDEX = 0x42 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x46 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x47 + sysIP_BLOCK_SOURCE = 0x48 + sysIP_UNBLOCK_SOURCE = 0x49 + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sysInetPktinfo struct { + Ifindex uint32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr [4]byte /* in_addr */ + Sourceaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [128]byte +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [128]byte + Pad_cgo_1 [128]byte +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_dragonfly.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_dragonfly.go new file mode 100644 index 00000000..f5c9ccec --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_dragonfly.go @@ -0,0 +1,33 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_dragonfly.go + +// +build dragonfly + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x14 + sysIP_RECVTTL = 0x41 + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_MULTICAST_VIF = 0xe + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + + sysSizeofIPMreq = 0x8 +) + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_386.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_386.go new file mode 100644 index 00000000..6fd67e1e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_386.go @@ -0,0 +1,93 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_freebsd.go + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_SENDSRCADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x14 + sysIP_ONESBCAST = 0x17 + sysIP_BINDANY = 0x18 + sysIP_RECVTTL = 0x41 + sysIP_MINTTL = 0x42 + sysIP_DONTFRAG = 0x43 + sysIP_RECVTOS = 0x44 + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + sysIP_MULTICAST_VIF = 0xe + sysIP_ADD_SOURCE_MEMBERSHIP = 0x46 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x47 + sysIP_BLOCK_SOURCE = 0x48 + sysIP_UNBLOCK_SOURCE = 0x49 + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr [4]byte /* in_addr */ + Sourceaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysGroupReq struct { + Interface uint32 + Group sysSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Group sysSockaddrStorage + Source sysSockaddrStorage +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_amd64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_amd64.go new file mode 100644 index 00000000..ebac6d79 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_amd64.go @@ -0,0 +1,95 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_freebsd.go + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_SENDSRCADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x14 + sysIP_ONESBCAST = 0x17 + sysIP_BINDANY = 0x18 + sysIP_RECVTTL = 0x41 + sysIP_MINTTL = 0x42 + sysIP_DONTFRAG = 0x43 + sysIP_RECVTOS = 0x44 + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + sysIP_MULTICAST_VIF = 0xe + sysIP_ADD_SOURCE_MEMBERSHIP = 0x46 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x47 + sysIP_BLOCK_SOURCE = 0x48 + sysIP_UNBLOCK_SOURCE = 0x49 + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr [4]byte /* in_addr */ + Sourceaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage + Source sysSockaddrStorage +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_arm.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_arm.go new file mode 100644 index 00000000..ebac6d79 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_freebsd_arm.go @@ -0,0 +1,95 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_freebsd.go + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_SENDSRCADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x14 + sysIP_ONESBCAST = 0x17 + sysIP_BINDANY = 0x18 + sysIP_RECVTTL = 0x41 + sysIP_MINTTL = 0x42 + sysIP_DONTFRAG = 0x43 + sysIP_RECVTOS = 0x44 + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + sysIP_MULTICAST_VIF = 0xe + sysIP_ADD_SOURCE_MEMBERSHIP = 0x46 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x47 + sysIP_BLOCK_SOURCE = 0x48 + sysIP_UNBLOCK_SOURCE = 0x49 + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet struct { + Len uint8 + Family uint8 + Port uint16 + Addr [4]byte /* in_addr */ + Zero [8]int8 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr [4]byte /* in_addr */ + Sourceaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage + Source sysSockaddrStorage +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_386.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_386.go new file mode 100644 index 00000000..fc7a9ebf --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_386.go @@ -0,0 +1,130 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_amd64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_amd64.go new file mode 100644 index 00000000..e324b81b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_amd64.go @@ -0,0 +1,132 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_arm.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_arm.go new file mode 100644 index 00000000..fc7a9ebf --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_arm.go @@ -0,0 +1,130 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_arm64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_arm64.go new file mode 100644 index 00000000..ce4194a6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_arm64.go @@ -0,0 +1,134 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,arm64 + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_mips64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_mips64.go new file mode 100644 index 00000000..94116bfa --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_mips64.go @@ -0,0 +1,134 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,mips64 + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_mips64le.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_mips64le.go new file mode 100644 index 00000000..698d7db3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_mips64le.go @@ -0,0 +1,134 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,mips64le + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_ppc64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_ppc64.go new file mode 100644 index 00000000..9fe5ee2b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_ppc64.go @@ -0,0 +1,134 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,ppc64 + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_ppc64le.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_ppc64le.go new file mode 100644 index 00000000..3891f54e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_linux_ppc64le.go @@ -0,0 +1,134 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,ppc64le + +package ipv4 + +const ( + sysIP_TOS = 0x1 + sysIP_TTL = 0x2 + sysIP_HDRINCL = 0x3 + sysIP_OPTIONS = 0x4 + sysIP_ROUTER_ALERT = 0x5 + sysIP_RECVOPTS = 0x6 + sysIP_RETOPTS = 0x7 + sysIP_PKTINFO = 0x8 + sysIP_PKTOPTIONS = 0x9 + sysIP_MTU_DISCOVER = 0xa + sysIP_RECVERR = 0xb + sysIP_RECVTTL = 0xc + sysIP_RECVTOS = 0xd + sysIP_MTU = 0xe + sysIP_FREEBIND = 0xf + sysIP_TRANSPARENT = 0x13 + sysIP_RECVRETOPTS = 0x7 + sysIP_ORIGDSTADDR = 0x14 + sysIP_RECVORIGDSTADDR = 0x14 + sysIP_MINTTL = 0x15 + sysIP_NODEFRAG = 0x16 + sysIP_UNICAST_IF = 0x32 + + sysIP_MULTICAST_IF = 0x20 + sysIP_MULTICAST_TTL = 0x21 + sysIP_MULTICAST_LOOP = 0x22 + sysIP_ADD_MEMBERSHIP = 0x23 + sysIP_DROP_MEMBERSHIP = 0x24 + sysIP_UNBLOCK_SOURCE = 0x25 + sysIP_BLOCK_SOURCE = 0x26 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x27 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x28 + sysIP_MSFILTER = 0x29 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIP_MULTICAST_ALL = 0x31 + + sysICMP_FILTER = 0x1 + + sysSO_EE_ORIGIN_NONE = 0x0 + sysSO_EE_ORIGIN_LOCAL = 0x1 + sysSO_EE_ORIGIN_ICMP = 0x2 + sysSO_EE_ORIGIN_ICMP6 = 0x3 + sysSO_EE_ORIGIN_TXSTATUS = 0x4 + sysSO_EE_ORIGIN_TIMESTAMPING = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet = 0x10 + sysSizeofInetPktinfo = 0xc + sysSizeofSockExtendedErr = 0x10 + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqn = 0xc + sysSizeofIPMreqSource = 0xc + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPFilter = 0x4 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet struct { + Family uint16 + Port uint16 + Addr [4]byte /* in_addr */ + X__pad [8]uint8 +} + +type sysInetPktinfo struct { + Ifindex int32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysSockExtendedErr struct { + Errno uint32 + Origin uint8 + Type uint8 + Code uint8 + Pad uint8 + Info uint32 + Data uint32 +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqn struct { + Multiaddr [4]byte /* in_addr */ + Address [4]byte /* in_addr */ + Ifindex int32 +} + +type sysIPMreqSource struct { + Multiaddr uint32 + Interface uint32 + Sourceaddr uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPFilter struct { + Data uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_netbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_netbsd.go new file mode 100644 index 00000000..8a440eb6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_netbsd.go @@ -0,0 +1,30 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_netbsd.go + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x14 + sysIP_RECVTTL = 0x17 + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + + sysSizeofIPMreq = 0x8 +) + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_openbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_openbsd.go new file mode 100644 index 00000000..fd522b57 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_openbsd.go @@ -0,0 +1,30 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_openbsd.go + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x1e + sysIP_RECVTTL = 0x1f + + sysIP_MULTICAST_IF = 0x9 + sysIP_MULTICAST_TTL = 0xa + sysIP_MULTICAST_LOOP = 0xb + sysIP_ADD_MEMBERSHIP = 0xc + sysIP_DROP_MEMBERSHIP = 0xd + + sysSizeofIPMreq = 0x8 +) + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_solaris.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_solaris.go new file mode 100644 index 00000000..d7c23349 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv4/zsys_solaris.go @@ -0,0 +1,60 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_solaris.go + +// +build solaris + +package ipv4 + +const ( + sysIP_OPTIONS = 0x1 + sysIP_HDRINCL = 0x2 + sysIP_TOS = 0x3 + sysIP_TTL = 0x4 + sysIP_RECVOPTS = 0x5 + sysIP_RECVRETOPTS = 0x6 + sysIP_RECVDSTADDR = 0x7 + sysIP_RETOPTS = 0x8 + sysIP_RECVIF = 0x9 + sysIP_RECVSLLA = 0xa + sysIP_RECVTTL = 0xb + sysIP_NEXTHOP = 0x19 + sysIP_PKTINFO = 0x1a + sysIP_RECVPKTINFO = 0x1a + sysIP_DONTFRAG = 0x1b + sysIP_BOUND_IF = 0x41 + sysIP_UNSPEC_SRC = 0x42 + sysIP_BROADCAST_TTL = 0x43 + sysIP_DHCPINIT_IF = 0x45 + + sysIP_MULTICAST_IF = 0x10 + sysIP_MULTICAST_TTL = 0x11 + sysIP_MULTICAST_LOOP = 0x12 + sysIP_ADD_MEMBERSHIP = 0x13 + sysIP_DROP_MEMBERSHIP = 0x14 + sysIP_BLOCK_SOURCE = 0x15 + sysIP_UNBLOCK_SOURCE = 0x16 + sysIP_ADD_SOURCE_MEMBERSHIP = 0x17 + sysIP_DROP_SOURCE_MEMBERSHIP = 0x18 + + sysSizeofInetPktinfo = 0xc + + sysSizeofIPMreq = 0x8 + sysSizeofIPMreqSource = 0xc +) + +type sysInetPktinfo struct { + Ifindex uint32 + Spec_dst [4]byte /* in_addr */ + Addr [4]byte /* in_addr */ +} + +type sysIPMreq struct { + Multiaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} + +type sysIPMreqSource struct { + Multiaddr [4]byte /* in_addr */ + Sourceaddr [4]byte /* in_addr */ + Interface [4]byte /* in_addr */ +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control.go new file mode 100644 index 00000000..b7362aae --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control.go @@ -0,0 +1,85 @@ +// 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 ipv6 + +import ( + "fmt" + "net" + "sync" +) + +// Note that RFC 3542 obsoletes RFC 2292 but OS X Snow Leopard and the +// former still support RFC 2292 only. Please be aware that almost +// all protocol implementations prohibit using a combination of RFC +// 2292 and RFC 3542 for some practical reasons. + +type rawOpt struct { + sync.RWMutex + cflags ControlFlags +} + +func (c *rawOpt) set(f ControlFlags) { c.cflags |= f } +func (c *rawOpt) clear(f ControlFlags) { c.cflags &^= f } +func (c *rawOpt) isset(f ControlFlags) bool { return c.cflags&f != 0 } + +// A ControlFlags represents per packet basis IP-level socket option +// control flags. +type ControlFlags uint + +const ( + FlagTrafficClass ControlFlags = 1 << iota // pass the traffic class on the received packet + FlagHopLimit // pass the hop limit on the received packet + FlagSrc // pass the source address on the received packet + FlagDst // pass the destination address on the received packet + FlagInterface // pass the interface index on the received packet + FlagPathMTU // pass the path MTU on the received packet path +) + +const flagPacketInfo = FlagDst | FlagInterface + +// A ControlMessage represents per packet basis IP-level socket +// options. +type ControlMessage struct { + // Receiving socket options: SetControlMessage allows to + // receive the options from the protocol stack using ReadFrom + // method of PacketConn. + // + // Specifying socket options: ControlMessage for WriteTo + // method of PacketConn allows to send the options to the + // protocol stack. + // + TrafficClass int // traffic class, must be 1 <= value <= 255 when specifying + HopLimit int // hop limit, must be 1 <= value <= 255 when specifying + Src net.IP // source address, specifying only + Dst net.IP // destination address, receiving only + IfIndex int // interface index, must be 1 <= value when specifying + NextHop net.IP // next hop address, specifying only + MTU int // path MTU, receiving only +} + +func (cm *ControlMessage) String() string { + if cm == nil { + return "" + } + return fmt.Sprintf("tclass=%#x hoplim=%d src=%v dst=%v ifindex=%d nexthop=%v mtu=%d", cm.TrafficClass, cm.HopLimit, cm.Src, cm.Dst, cm.IfIndex, cm.NextHop, cm.MTU) +} + +// Ancillary data socket options +const ( + ctlTrafficClass = iota // header field + ctlHopLimit // header field + ctlPacketInfo // inbound or outbound packet path + ctlNextHop // nexthop + ctlPathMTU // path mtu + ctlMax +) + +// A ctlOpt represents a binding for ancillary data socket option. +type ctlOpt struct { + name int // option name, must be equal or greater than 1 + length int // option length + marshal func([]byte, *ControlMessage) []byte + parse func(*ControlMessage, []byte) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_rfc2292_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_rfc2292_unix.go new file mode 100644 index 00000000..ce201ce3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_rfc2292_unix.go @@ -0,0 +1,56 @@ +// 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 ipv6 + +import ( + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func marshal2292HopLimit(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_2292HOPLIMIT + m.SetLen(syscall.CmsgLen(4)) + if cm != nil { + data := b[syscall.CmsgLen(0):] + // TODO(mikio): fix potential misaligned memory access + *(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit) + } + return b[syscall.CmsgSpace(4):] +} + +func marshal2292PacketInfo(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_2292PKTINFO + m.SetLen(syscall.CmsgLen(sysSizeofInet6Pktinfo)) + if cm != nil { + pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)])) + if ip := cm.Src.To16(); ip != nil && ip.To4() == nil { + copy(pi.Addr[:], ip) + } + if cm.IfIndex > 0 { + pi.setIfindex(cm.IfIndex) + } + } + return b[syscall.CmsgSpace(sysSizeofInet6Pktinfo):] +} + +func marshal2292NextHop(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_2292NEXTHOP + m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6)) + if cm != nil { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)])) + sa.setSockaddr(cm.NextHop, cm.IfIndex) + } + return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):] +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_rfc3542_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_rfc3542_unix.go new file mode 100644 index 00000000..e55c4aa9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_rfc3542_unix.go @@ -0,0 +1,103 @@ +// 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 dragonfly freebsd linux netbsd openbsd + +package ipv6 + +import ( + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +func marshalTrafficClass(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_TCLASS + m.SetLen(syscall.CmsgLen(4)) + if cm != nil { + data := b[syscall.CmsgLen(0):] + // TODO(mikio): fix potential misaligned memory access + *(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.TrafficClass) + } + return b[syscall.CmsgSpace(4):] +} + +func parseTrafficClass(cm *ControlMessage, b []byte) { + // TODO(mikio): fix potential misaligned memory access + cm.TrafficClass = int(*(*int32)(unsafe.Pointer(&b[:4][0]))) +} + +func marshalHopLimit(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_HOPLIMIT + m.SetLen(syscall.CmsgLen(4)) + if cm != nil { + data := b[syscall.CmsgLen(0):] + // TODO(mikio): fix potential misaligned memory access + *(*int32)(unsafe.Pointer(&data[:4][0])) = int32(cm.HopLimit) + } + return b[syscall.CmsgSpace(4):] +} + +func parseHopLimit(cm *ControlMessage, b []byte) { + // TODO(mikio): fix potential misaligned memory access + cm.HopLimit = int(*(*int32)(unsafe.Pointer(&b[:4][0]))) +} + +func marshalPacketInfo(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_PKTINFO + m.SetLen(syscall.CmsgLen(sysSizeofInet6Pktinfo)) + if cm != nil { + pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[syscall.CmsgLen(0)])) + if ip := cm.Src.To16(); ip != nil && ip.To4() == nil { + copy(pi.Addr[:], ip) + } + if cm.IfIndex > 0 { + pi.setIfindex(cm.IfIndex) + } + } + return b[syscall.CmsgSpace(sysSizeofInet6Pktinfo):] +} + +func parsePacketInfo(cm *ControlMessage, b []byte) { + pi := (*sysInet6Pktinfo)(unsafe.Pointer(&b[0])) + cm.Dst = pi.Addr[:] + cm.IfIndex = int(pi.Ifindex) +} + +func marshalNextHop(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_NEXTHOP + m.SetLen(syscall.CmsgLen(sysSizeofSockaddrInet6)) + if cm != nil { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&b[syscall.CmsgLen(0)])) + sa.setSockaddr(cm.NextHop, cm.IfIndex) + } + return b[syscall.CmsgSpace(sysSizeofSockaddrInet6):] +} + +func parseNextHop(cm *ControlMessage, b []byte) { +} + +func marshalPathMTU(b []byte, cm *ControlMessage) []byte { + m := (*syscall.Cmsghdr)(unsafe.Pointer(&b[0])) + m.Level = iana.ProtocolIPv6 + m.Type = sysIPV6_PATHMTU + m.SetLen(syscall.CmsgLen(sysSizeofIPv6Mtuinfo)) + return b[syscall.CmsgSpace(sysSizeofIPv6Mtuinfo):] +} + +func parsePathMTU(cm *ControlMessage, b []byte) { + mi := (*sysIPv6Mtuinfo)(unsafe.Pointer(&b[0])) + cm.Dst = mi.Addr.Addr[:] + cm.IfIndex = int(mi.Addr.Scope_id) + cm.MTU = int(mi.Mtu) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_stub.go new file mode 100644 index 00000000..2fecf7e5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_stub.go @@ -0,0 +1,23 @@ +// 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 nacl plan9 solaris + +package ipv6 + +func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error { + return errOpNoSupport +} + +func newControlMessage(opt *rawOpt) (oob []byte) { + return nil +} + +func parseControlMessage(b []byte) (*ControlMessage, error) { + return nil, errOpNoSupport +} + +func marshalControlMessage(cm *ControlMessage) (oob []byte) { + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_unix.go new file mode 100644 index 00000000..2af5beb4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_unix.go @@ -0,0 +1,166 @@ +// 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 dragonfly freebsd linux netbsd openbsd + +package ipv6 + +import ( + "os" + "syscall" + + "golang.org/x/net/internal/iana" +) + +func setControlMessage(fd int, opt *rawOpt, cf ControlFlags, on bool) error { + opt.Lock() + defer opt.Unlock() + if cf&FlagTrafficClass != 0 && sockOpts[ssoReceiveTrafficClass].name > 0 { + if err := setInt(fd, &sockOpts[ssoReceiveTrafficClass], boolint(on)); err != nil { + return err + } + if on { + opt.set(FlagTrafficClass) + } else { + opt.clear(FlagTrafficClass) + } + } + if cf&FlagHopLimit != 0 && sockOpts[ssoReceiveHopLimit].name > 0 { + if err := setInt(fd, &sockOpts[ssoReceiveHopLimit], boolint(on)); err != nil { + return err + } + if on { + opt.set(FlagHopLimit) + } else { + opt.clear(FlagHopLimit) + } + } + if cf&flagPacketInfo != 0 && sockOpts[ssoReceivePacketInfo].name > 0 { + if err := setInt(fd, &sockOpts[ssoReceivePacketInfo], boolint(on)); err != nil { + return err + } + if on { + opt.set(cf & flagPacketInfo) + } else { + opt.clear(cf & flagPacketInfo) + } + } + if cf&FlagPathMTU != 0 && sockOpts[ssoReceivePathMTU].name > 0 { + if err := setInt(fd, &sockOpts[ssoReceivePathMTU], boolint(on)); err != nil { + return err + } + if on { + opt.set(FlagPathMTU) + } else { + opt.clear(FlagPathMTU) + } + } + return nil +} + +func newControlMessage(opt *rawOpt) (oob []byte) { + opt.RLock() + var l int + if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 { + l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length) + } + if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 { + l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length) + } + if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 { + l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length) + } + if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 { + l += syscall.CmsgSpace(ctlOpts[ctlPathMTU].length) + } + if l > 0 { + oob = make([]byte, l) + b := oob + if opt.isset(FlagTrafficClass) && ctlOpts[ctlTrafficClass].name > 0 { + b = ctlOpts[ctlTrafficClass].marshal(b, nil) + } + if opt.isset(FlagHopLimit) && ctlOpts[ctlHopLimit].name > 0 { + b = ctlOpts[ctlHopLimit].marshal(b, nil) + } + if opt.isset(flagPacketInfo) && ctlOpts[ctlPacketInfo].name > 0 { + b = ctlOpts[ctlPacketInfo].marshal(b, nil) + } + if opt.isset(FlagPathMTU) && ctlOpts[ctlPathMTU].name > 0 { + b = ctlOpts[ctlPathMTU].marshal(b, nil) + } + } + opt.RUnlock() + return +} + +func parseControlMessage(b []byte) (*ControlMessage, error) { + if len(b) == 0 { + return nil, nil + } + cmsgs, err := syscall.ParseSocketControlMessage(b) + if err != nil { + return nil, os.NewSyscallError("parse socket control message", err) + } + cm := &ControlMessage{} + for _, m := range cmsgs { + if m.Header.Level != iana.ProtocolIPv6 { + continue + } + switch int(m.Header.Type) { + case ctlOpts[ctlTrafficClass].name: + ctlOpts[ctlTrafficClass].parse(cm, m.Data[:]) + case ctlOpts[ctlHopLimit].name: + ctlOpts[ctlHopLimit].parse(cm, m.Data[:]) + case ctlOpts[ctlPacketInfo].name: + ctlOpts[ctlPacketInfo].parse(cm, m.Data[:]) + case ctlOpts[ctlPathMTU].name: + ctlOpts[ctlPathMTU].parse(cm, m.Data[:]) + } + } + return cm, nil +} + +func marshalControlMessage(cm *ControlMessage) (oob []byte) { + if cm == nil { + return + } + var l int + tclass := false + if ctlOpts[ctlTrafficClass].name > 0 && cm.TrafficClass > 0 { + tclass = true + l += syscall.CmsgSpace(ctlOpts[ctlTrafficClass].length) + } + hoplimit := false + if ctlOpts[ctlHopLimit].name > 0 && cm.HopLimit > 0 { + hoplimit = true + l += syscall.CmsgSpace(ctlOpts[ctlHopLimit].length) + } + pktinfo := false + if ctlOpts[ctlPacketInfo].name > 0 && (cm.Src.To16() != nil && cm.Src.To4() == nil || cm.IfIndex > 0) { + pktinfo = true + l += syscall.CmsgSpace(ctlOpts[ctlPacketInfo].length) + } + nexthop := false + if ctlOpts[ctlNextHop].name > 0 && cm.NextHop.To16() != nil && cm.NextHop.To4() == nil { + nexthop = true + l += syscall.CmsgSpace(ctlOpts[ctlNextHop].length) + } + if l > 0 { + oob = make([]byte, l) + b := oob + if tclass { + b = ctlOpts[ctlTrafficClass].marshal(b, cm) + } + if hoplimit { + b = ctlOpts[ctlHopLimit].marshal(b, cm) + } + if pktinfo { + b = ctlOpts[ctlPacketInfo].marshal(b, cm) + } + if nexthop { + b = ctlOpts[ctlNextHop].marshal(b, cm) + } + } + return +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_windows.go new file mode 100644 index 00000000..72fdc1b0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/control_windows.go @@ -0,0 +1,27 @@ +// 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 ipv6 + +import "syscall" + +func setControlMessage(fd syscall.Handle, opt *rawOpt, cf ControlFlags, on bool) error { + // TODO(mikio): implement this + return syscall.EWINDOWS +} + +func newControlMessage(opt *rawOpt) (oob []byte) { + // TODO(mikio): implement this + return nil +} + +func parseControlMessage(b []byte) (*ControlMessage, error) { + // TODO(mikio): implement this + return nil, syscall.EWINDOWS +} + +func marshalControlMessage(cm *ControlMessage) (oob []byte) { + // TODO(mikio): implement this + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_darwin.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_darwin.go new file mode 100644 index 00000000..4c7f476a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_darwin.go @@ -0,0 +1,112 @@ +// 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. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#define __APPLE_USE_RFC_3542 +#include +#include +*/ +import "C" + +const ( + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP + sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP + + sysIPV6_PORTRANGE = C.IPV6_PORTRANGE + sysICMP6_FILTER = C.ICMP6_FILTER + sysIPV6_2292PKTINFO = C.IPV6_2292PKTINFO + sysIPV6_2292HOPLIMIT = C.IPV6_2292HOPLIMIT + sysIPV6_2292NEXTHOP = C.IPV6_2292NEXTHOP + sysIPV6_2292HOPOPTS = C.IPV6_2292HOPOPTS + sysIPV6_2292DSTOPTS = C.IPV6_2292DSTOPTS + sysIPV6_2292RTHDR = C.IPV6_2292RTHDR + + sysIPV6_2292PKTOPTIONS = C.IPV6_2292PKTOPTIONS + + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_V6ONLY = C.IPV6_V6ONLY + + sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY + + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + sysIPV6_TCLASS = C.IPV6_TCLASS + + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + + sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + + sysIPV6_PATHMTU = C.IPV6_PATHMTU + + sysIPV6_PKTINFO = C.IPV6_PKTINFO + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + sysIPV6_RTHDR = C.IPV6_RTHDR + + sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL + + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + + sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR + + sysIPV6_MSFILTER = C.IPV6_MSFILTER + sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP + sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP + sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP + sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP + sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE + sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE + + sysIPV6_BOUND_IF = C.IPV6_BOUND_IF + + sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT + sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH + sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW + + sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage + sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + + sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + sysSizeofGroupReq = C.sizeof_struct_group_req + sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req + + sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sysSockaddrStorage C.struct_sockaddr_storage + +type sysSockaddrInet6 C.struct_sockaddr_in6 + +type sysInet6Pktinfo C.struct_in6_pktinfo + +type sysIPv6Mtuinfo C.struct_ip6_mtuinfo + +type sysIPv6Mreq C.struct_ipv6_mreq + +type sysICMPv6Filter C.struct_icmp6_filter + +type sysGroupReq C.struct_group_req + +type sysGroupSourceReq C.struct_group_source_req diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_dragonfly.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_dragonfly.go new file mode 100644 index 00000000..c72487ce --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_dragonfly.go @@ -0,0 +1,84 @@ +// 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. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#include +#include + +#include +#include +*/ +import "C" + +const ( + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP + sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP + sysIPV6_PORTRANGE = C.IPV6_PORTRANGE + sysICMP6_FILTER = C.ICMP6_FILTER + + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_V6ONLY = C.IPV6_V6ONLY + + sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY + + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + + sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + + sysIPV6_PATHMTU = C.IPV6_PATHMTU + + sysIPV6_PKTINFO = C.IPV6_PKTINFO + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + sysIPV6_RTHDR = C.IPV6_RTHDR + + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + + sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL + + sysIPV6_TCLASS = C.IPV6_TCLASS + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + + sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR + + sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT + sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH + sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW + + sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + + sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + + sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sysSockaddrInet6 C.struct_sockaddr_in6 + +type sysInet6Pktinfo C.struct_in6_pktinfo + +type sysIPv6Mtuinfo C.struct_ip6_mtuinfo + +type sysIPv6Mreq C.struct_ipv6_mreq + +type sysICMPv6Filter C.struct_icmp6_filter diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_freebsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_freebsd.go new file mode 100644 index 00000000..de199ec6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_freebsd.go @@ -0,0 +1,105 @@ +// 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. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#include +#include + +#include +#include +*/ +import "C" + +const ( + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP + sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP + sysIPV6_PORTRANGE = C.IPV6_PORTRANGE + sysICMP6_FILTER = C.ICMP6_FILTER + + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_V6ONLY = C.IPV6_V6ONLY + + sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY + + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + + sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + + sysIPV6_PATHMTU = C.IPV6_PATHMTU + + sysIPV6_PKTINFO = C.IPV6_PKTINFO + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + sysIPV6_RTHDR = C.IPV6_RTHDR + + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + + sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL + + sysIPV6_TCLASS = C.IPV6_TCLASS + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + + sysIPV6_PREFER_TEMPADDR = C.IPV6_PREFER_TEMPADDR + + sysIPV6_BINDANY = C.IPV6_BINDANY + + sysIPV6_MSFILTER = C.IPV6_MSFILTER + + sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP + sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP + sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP + sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP + sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE + sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE + + sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT + sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH + sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW + + sysSizeofSockaddrStorage = C.sizeof_struct_sockaddr_storage + sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + + sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + sysSizeofGroupReq = C.sizeof_struct_group_req + sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req + + sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sysSockaddrStorage C.struct_sockaddr_storage + +type sysSockaddrInet6 C.struct_sockaddr_in6 + +type sysInet6Pktinfo C.struct_in6_pktinfo + +type sysIPv6Mtuinfo C.struct_ip6_mtuinfo + +type sysIPv6Mreq C.struct_ipv6_mreq + +type sysGroupReq C.struct_group_req + +type sysGroupSourceReq C.struct_group_source_req + +type sysICMPv6Filter C.struct_icmp6_filter diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_linux.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_linux.go new file mode 100644 index 00000000..d83abce3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_linux.go @@ -0,0 +1,136 @@ +// 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. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#include +#include +#include +#include +*/ +import "C" + +const ( + sysIPV6_ADDRFORM = C.IPV6_ADDRFORM + sysIPV6_2292PKTINFO = C.IPV6_2292PKTINFO + sysIPV6_2292HOPOPTS = C.IPV6_2292HOPOPTS + sysIPV6_2292DSTOPTS = C.IPV6_2292DSTOPTS + sysIPV6_2292RTHDR = C.IPV6_2292RTHDR + sysIPV6_2292PKTOPTIONS = C.IPV6_2292PKTOPTIONS + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_2292HOPLIMIT = C.IPV6_2292HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_FLOWINFO = C.IPV6_FLOWINFO + + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_ADD_MEMBERSHIP = C.IPV6_ADD_MEMBERSHIP + sysIPV6_DROP_MEMBERSHIP = C.IPV6_DROP_MEMBERSHIP + sysMCAST_JOIN_GROUP = C.MCAST_JOIN_GROUP + sysMCAST_LEAVE_GROUP = C.MCAST_LEAVE_GROUP + sysMCAST_JOIN_SOURCE_GROUP = C.MCAST_JOIN_SOURCE_GROUP + sysMCAST_LEAVE_SOURCE_GROUP = C.MCAST_LEAVE_SOURCE_GROUP + sysMCAST_BLOCK_SOURCE = C.MCAST_BLOCK_SOURCE + sysMCAST_UNBLOCK_SOURCE = C.MCAST_UNBLOCK_SOURCE + sysMCAST_MSFILTER = C.MCAST_MSFILTER + sysIPV6_ROUTER_ALERT = C.IPV6_ROUTER_ALERT + sysIPV6_MTU_DISCOVER = C.IPV6_MTU_DISCOVER + sysIPV6_MTU = C.IPV6_MTU + sysIPV6_RECVERR = C.IPV6_RECVERR + sysIPV6_V6ONLY = C.IPV6_V6ONLY + sysIPV6_JOIN_ANYCAST = C.IPV6_JOIN_ANYCAST + sysIPV6_LEAVE_ANYCAST = C.IPV6_LEAVE_ANYCAST + + //sysIPV6_PMTUDISC_DONT = C.IPV6_PMTUDISC_DONT + //sysIPV6_PMTUDISC_WANT = C.IPV6_PMTUDISC_WANT + //sysIPV6_PMTUDISC_DO = C.IPV6_PMTUDISC_DO + //sysIPV6_PMTUDISC_PROBE = C.IPV6_PMTUDISC_PROBE + //sysIPV6_PMTUDISC_INTERFACE = C.IPV6_PMTUDISC_INTERFACE + //sysIPV6_PMTUDISC_OMIT = C.IPV6_PMTUDISC_OMIT + + sysIPV6_FLOWLABEL_MGR = C.IPV6_FLOWLABEL_MGR + sysIPV6_FLOWINFO_SEND = C.IPV6_FLOWINFO_SEND + + sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY + sysIPV6_XFRM_POLICY = C.IPV6_XFRM_POLICY + + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + sysIPV6_PKTINFO = C.IPV6_PKTINFO + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + sysIPV6_RTHDR = C.IPV6_RTHDR + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + sysIPV6_PATHMTU = C.IPV6_PATHMTU + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + sysIPV6_TCLASS = C.IPV6_TCLASS + + sysIPV6_ADDR_PREFERENCES = C.IPV6_ADDR_PREFERENCES + + sysIPV6_PREFER_SRC_TMP = C.IPV6_PREFER_SRC_TMP + sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = C.IPV6_PREFER_SRC_PUBTMP_DEFAULT + sysIPV6_PREFER_SRC_COA = C.IPV6_PREFER_SRC_COA + sysIPV6_PREFER_SRC_HOME = C.IPV6_PREFER_SRC_HOME + sysIPV6_PREFER_SRC_CGA = C.IPV6_PREFER_SRC_CGA + sysIPV6_PREFER_SRC_NONCGA = C.IPV6_PREFER_SRC_NONCGA + + sysIPV6_MINHOPCOUNT = C.IPV6_MINHOPCOUNT + + sysIPV6_ORIGDSTADDR = C.IPV6_ORIGDSTADDR + sysIPV6_RECVORIGDSTADDR = C.IPV6_RECVORIGDSTADDR + sysIPV6_TRANSPARENT = C.IPV6_TRANSPARENT + sysIPV6_UNICAST_IF = C.IPV6_UNICAST_IF + + sysICMPV6_FILTER = C.ICMPV6_FILTER + + sysICMPV6_FILTER_BLOCK = C.ICMPV6_FILTER_BLOCK + sysICMPV6_FILTER_PASS = C.ICMPV6_FILTER_PASS + sysICMPV6_FILTER_BLOCKOTHERS = C.ICMPV6_FILTER_BLOCKOTHERS + sysICMPV6_FILTER_PASSONLY = C.ICMPV6_FILTER_PASSONLY + + sysSizeofKernelSockaddrStorage = C.sizeof_struct___kernel_sockaddr_storage + sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + sysSizeofIPv6FlowlabelReq = C.sizeof_struct_in6_flowlabel_req + + sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + sysSizeofGroupReq = C.sizeof_struct_group_req + sysSizeofGroupSourceReq = C.sizeof_struct_group_source_req + + sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sysKernelSockaddrStorage C.struct___kernel_sockaddr_storage + +type sysSockaddrInet6 C.struct_sockaddr_in6 + +type sysInet6Pktinfo C.struct_in6_pktinfo + +type sysIPv6Mtuinfo C.struct_ip6_mtuinfo + +type sysIPv6FlowlabelReq C.struct_in6_flowlabel_req + +type sysIPv6Mreq C.struct_ipv6_mreq + +type sysGroupReq C.struct_group_req + +type sysGroupSourceReq C.struct_group_source_req + +type sysICMPv6Filter C.struct_icmp6_filter diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_netbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_netbsd.go new file mode 100644 index 00000000..7bd09e8e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_netbsd.go @@ -0,0 +1,80 @@ +// 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. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#include +#include + +#include +#include +*/ +import "C" + +const ( + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP + sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP + sysIPV6_PORTRANGE = C.IPV6_PORTRANGE + sysICMP6_FILTER = C.ICMP6_FILTER + + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_V6ONLY = C.IPV6_V6ONLY + + sysIPV6_IPSEC_POLICY = C.IPV6_IPSEC_POLICY + + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + + sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + sysIPV6_PATHMTU = C.IPV6_PATHMTU + + sysIPV6_PKTINFO = C.IPV6_PKTINFO + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + sysIPV6_RTHDR = C.IPV6_RTHDR + + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + + sysIPV6_TCLASS = C.IPV6_TCLASS + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + + sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT + sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH + sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW + + sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + + sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + + sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sysSockaddrInet6 C.struct_sockaddr_in6 + +type sysInet6Pktinfo C.struct_in6_pktinfo + +type sysIPv6Mtuinfo C.struct_ip6_mtuinfo + +type sysIPv6Mreq C.struct_ipv6_mreq + +type sysICMPv6Filter C.struct_icmp6_filter diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_openbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_openbsd.go new file mode 100644 index 00000000..6796d9b2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_openbsd.go @@ -0,0 +1,89 @@ +// 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. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#include +#include + +#include +#include +*/ +import "C" + +const ( + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP + sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP + sysIPV6_PORTRANGE = C.IPV6_PORTRANGE + sysICMP6_FILTER = C.ICMP6_FILTER + + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_V6ONLY = C.IPV6_V6ONLY + + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + + sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + + sysIPV6_PATHMTU = C.IPV6_PATHMTU + + sysIPV6_PKTINFO = C.IPV6_PKTINFO + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + sysIPV6_RTHDR = C.IPV6_RTHDR + + sysIPV6_AUTH_LEVEL = C.IPV6_AUTH_LEVEL + sysIPV6_ESP_TRANS_LEVEL = C.IPV6_ESP_TRANS_LEVEL + sysIPV6_ESP_NETWORK_LEVEL = C.IPV6_ESP_NETWORK_LEVEL + sysIPSEC6_OUTSA = C.IPSEC6_OUTSA + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + + sysIPV6_AUTOFLOWLABEL = C.IPV6_AUTOFLOWLABEL + sysIPV6_IPCOMP_LEVEL = C.IPV6_IPCOMP_LEVEL + + sysIPV6_TCLASS = C.IPV6_TCLASS + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + sysIPV6_PIPEX = C.IPV6_PIPEX + + sysIPV6_RTABLE = C.IPV6_RTABLE + + sysIPV6_PORTRANGE_DEFAULT = C.IPV6_PORTRANGE_DEFAULT + sysIPV6_PORTRANGE_HIGH = C.IPV6_PORTRANGE_HIGH + sysIPV6_PORTRANGE_LOW = C.IPV6_PORTRANGE_LOW + + sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + + sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + + sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sysSockaddrInet6 C.struct_sockaddr_in6 + +type sysInet6Pktinfo C.struct_in6_pktinfo + +type sysIPv6Mtuinfo C.struct_ip6_mtuinfo + +type sysIPv6Mreq C.struct_ipv6_mreq + +type sysICMPv6Filter C.struct_icmp6_filter diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_solaris.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_solaris.go new file mode 100644 index 00000000..972b1712 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/defs_solaris.go @@ -0,0 +1,96 @@ +// 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. + +// +build ignore + +// +godefs map struct_in6_addr [16]byte /* in6_addr */ + +package ipv6 + +/* +#include +#include +*/ +import "C" + +const ( + sysIPV6_UNICAST_HOPS = C.IPV6_UNICAST_HOPS + sysIPV6_MULTICAST_IF = C.IPV6_MULTICAST_IF + sysIPV6_MULTICAST_HOPS = C.IPV6_MULTICAST_HOPS + sysIPV6_MULTICAST_LOOP = C.IPV6_MULTICAST_LOOP + sysIPV6_JOIN_GROUP = C.IPV6_JOIN_GROUP + sysIPV6_LEAVE_GROUP = C.IPV6_LEAVE_GROUP + + sysIPV6_PKTINFO = C.IPV6_PKTINFO + + sysIPV6_HOPLIMIT = C.IPV6_HOPLIMIT + sysIPV6_NEXTHOP = C.IPV6_NEXTHOP + sysIPV6_HOPOPTS = C.IPV6_HOPOPTS + sysIPV6_DSTOPTS = C.IPV6_DSTOPTS + + sysIPV6_RTHDR = C.IPV6_RTHDR + sysIPV6_RTHDRDSTOPTS = C.IPV6_RTHDRDSTOPTS + + sysIPV6_RECVPKTINFO = C.IPV6_RECVPKTINFO + sysIPV6_RECVHOPLIMIT = C.IPV6_RECVHOPLIMIT + sysIPV6_RECVHOPOPTS = C.IPV6_RECVHOPOPTS + + sysIPV6_RECVRTHDR = C.IPV6_RECVRTHDR + + sysIPV6_RECVRTHDRDSTOPTS = C.IPV6_RECVRTHDRDSTOPTS + + sysIPV6_CHECKSUM = C.IPV6_CHECKSUM + sysIPV6_RECVTCLASS = C.IPV6_RECVTCLASS + sysIPV6_USE_MIN_MTU = C.IPV6_USE_MIN_MTU + sysIPV6_DONTFRAG = C.IPV6_DONTFRAG + sysIPV6_SEC_OPT = C.IPV6_SEC_OPT + sysIPV6_SRC_PREFERENCES = C.IPV6_SRC_PREFERENCES + sysIPV6_RECVPATHMTU = C.IPV6_RECVPATHMTU + sysIPV6_PATHMTU = C.IPV6_PATHMTU + sysIPV6_TCLASS = C.IPV6_TCLASS + sysIPV6_V6ONLY = C.IPV6_V6ONLY + + sysIPV6_RECVDSTOPTS = C.IPV6_RECVDSTOPTS + + sysIPV6_PREFER_SRC_HOME = C.IPV6_PREFER_SRC_HOME + sysIPV6_PREFER_SRC_COA = C.IPV6_PREFER_SRC_COA + sysIPV6_PREFER_SRC_PUBLIC = C.IPV6_PREFER_SRC_PUBLIC + sysIPV6_PREFER_SRC_TMP = C.IPV6_PREFER_SRC_TMP + sysIPV6_PREFER_SRC_NONCGA = C.IPV6_PREFER_SRC_NONCGA + sysIPV6_PREFER_SRC_CGA = C.IPV6_PREFER_SRC_CGA + + sysIPV6_PREFER_SRC_MIPMASK = C.IPV6_PREFER_SRC_MIPMASK + sysIPV6_PREFER_SRC_MIPDEFAULT = C.IPV6_PREFER_SRC_MIPDEFAULT + sysIPV6_PREFER_SRC_TMPMASK = C.IPV6_PREFER_SRC_TMPMASK + sysIPV6_PREFER_SRC_TMPDEFAULT = C.IPV6_PREFER_SRC_TMPDEFAULT + sysIPV6_PREFER_SRC_CGAMASK = C.IPV6_PREFER_SRC_CGAMASK + sysIPV6_PREFER_SRC_CGADEFAULT = C.IPV6_PREFER_SRC_CGADEFAULT + + sysIPV6_PREFER_SRC_MASK = C.IPV6_PREFER_SRC_MASK + + sysIPV6_PREFER_SRC_DEFAULT = C.IPV6_PREFER_SRC_DEFAULT + + sysIPV6_BOUND_IF = C.IPV6_BOUND_IF + sysIPV6_UNSPEC_SRC = C.IPV6_UNSPEC_SRC + + sysICMP6_FILTER = C.ICMP6_FILTER + + sysSizeofSockaddrInet6 = C.sizeof_struct_sockaddr_in6 + sysSizeofInet6Pktinfo = C.sizeof_struct_in6_pktinfo + sysSizeofIPv6Mtuinfo = C.sizeof_struct_ip6_mtuinfo + + sysSizeofIPv6Mreq = C.sizeof_struct_ipv6_mreq + + sysSizeofICMPv6Filter = C.sizeof_struct_icmp6_filter +) + +type sysSockaddrInet6 C.struct_sockaddr_in6 + +type sysInet6Pktinfo C.struct_in6_pktinfo + +type sysIPv6Mtuinfo C.struct_ip6_mtuinfo + +type sysIPv6Mreq C.struct_ipv6_mreq + +type sysICMPv6Filter C.struct_icmp6_filter diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/dgramopt_posix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/dgramopt_posix.go new file mode 100644 index 00000000..93ff2f1a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/dgramopt_posix.go @@ -0,0 +1,288 @@ +// 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 dragonfly freebsd linux netbsd openbsd windows + +package ipv6 + +import ( + "net" + "syscall" +) + +// MulticastHopLimit returns the hop limit field value for outgoing +// multicast packets. +func (c *dgramOpt) MulticastHopLimit() (int, error) { + if !c.ok() { + return 0, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return 0, err + } + return getInt(fd, &sockOpts[ssoMulticastHopLimit]) +} + +// SetMulticastHopLimit sets the hop limit field value for future +// outgoing multicast packets. +func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoMulticastHopLimit], hoplim) +} + +// MulticastInterface returns the default interface for multicast +// packet transmissions. +func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { + if !c.ok() { + return nil, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return nil, err + } + return getInterface(fd, &sockOpts[ssoMulticastInterface]) +} + +// SetMulticastInterface sets the default interface for future +// multicast packet transmissions. +func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInterface(fd, &sockOpts[ssoMulticastInterface], ifi) +} + +// MulticastLoopback reports whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) MulticastLoopback() (bool, error) { + if !c.ok() { + return false, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return false, err + } + on, err := getInt(fd, &sockOpts[ssoMulticastLoopback]) + if err != nil { + return false, err + } + return on == 1, nil +} + +// SetMulticastLoopback sets whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) SetMulticastLoopback(on bool) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoMulticastLoopback], boolint(on)) +} + +// JoinGroup joins the group address group on the interface ifi. +// By default all sources that can cast data to group are accepted. +// It's possible to mute and unmute data transmission from a specific +// source by using ExcludeSourceSpecificGroup and +// IncludeSourceSpecificGroup. +// JoinGroup uses the system assigned multicast interface when ifi is +// nil, although this is not recommended because the assignment +// depends on platforms and sometimes it might require routing +// configuration. +func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP16(group) + if grp == nil { + return errMissingAddress + } + return setGroup(fd, &sockOpts[ssoJoinGroup], ifi, grp) +} + +// LeaveGroup leaves the group address group on the interface ifi +// regardless of whether the group is any-source group or +// source-specific group. +func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP16(group) + if grp == nil { + return errMissingAddress + } + return setGroup(fd, &sockOpts[ssoLeaveGroup], ifi, grp) +} + +// JoinSourceSpecificGroup joins the source-specific group comprising +// group and source on the interface ifi. +// JoinSourceSpecificGroup uses the system assigned multicast +// interface when ifi is nil, although this is not recommended because +// the assignment depends on platforms and sometimes it might require +// routing configuration. +func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP16(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP16(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoJoinSourceGroup], ifi, grp, src) +} + +// LeaveSourceSpecificGroup leaves the source-specific group on the +// interface ifi. +func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP16(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP16(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoLeaveSourceGroup], ifi, grp, src) +} + +// ExcludeSourceSpecificGroup excludes the source-specific group from +// the already joined any-source groups by JoinGroup on the interface +// ifi. +func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP16(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP16(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoBlockSourceGroup], ifi, grp, src) +} + +// IncludeSourceSpecificGroup includes the excluded source-specific +// group by ExcludeSourceSpecificGroup again on the interface ifi. +func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + grp := netAddrToIP16(group) + if grp == nil { + return errMissingAddress + } + src := netAddrToIP16(source) + if src == nil { + return errMissingAddress + } + return setSourceGroup(fd, &sockOpts[ssoUnblockSourceGroup], ifi, grp, src) +} + +// Checksum reports whether the kernel will compute, store or verify a +// checksum for both incoming and outgoing packets. If on is true, it +// returns an offset in bytes into the data of where the checksum +// field is located. +func (c *dgramOpt) Checksum() (on bool, offset int, err error) { + if !c.ok() { + return false, 0, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return false, 0, err + } + offset, err = getInt(fd, &sockOpts[ssoChecksum]) + if err != nil { + return false, 0, err + } + if offset < 0 { + return false, 0, nil + } + return true, offset, nil +} + +// SetChecksum enables the kernel checksum processing. If on is ture, +// the offset should be an offset in bytes into the data of where the +// checksum field is located. +func (c *dgramOpt) SetChecksum(on bool, offset int) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + if !on { + offset = -1 + } + return setInt(fd, &sockOpts[ssoChecksum], offset) +} + +// ICMPFilter returns an ICMP filter. +func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { + if !c.ok() { + return nil, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return nil, err + } + return getICMPFilter(fd, &sockOpts[ssoICMPFilter]) +} + +// SetICMPFilter deploys the ICMP filter. +func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setICMPFilter(fd, &sockOpts[ssoICMPFilter], f) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/dgramopt_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/dgramopt_stub.go new file mode 100644 index 00000000..fb067fb2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/dgramopt_stub.go @@ -0,0 +1,119 @@ +// 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 nacl plan9 solaris + +package ipv6 + +import "net" + +// MulticastHopLimit returns the hop limit field value for outgoing +// multicast packets. +func (c *dgramOpt) MulticastHopLimit() (int, error) { + return 0, errOpNoSupport +} + +// SetMulticastHopLimit sets the hop limit field value for future +// outgoing multicast packets. +func (c *dgramOpt) SetMulticastHopLimit(hoplim int) error { + return errOpNoSupport +} + +// MulticastInterface returns the default interface for multicast +// packet transmissions. +func (c *dgramOpt) MulticastInterface() (*net.Interface, error) { + return nil, errOpNoSupport +} + +// SetMulticastInterface sets the default interface for future +// multicast packet transmissions. +func (c *dgramOpt) SetMulticastInterface(ifi *net.Interface) error { + return errOpNoSupport +} + +// MulticastLoopback reports whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) MulticastLoopback() (bool, error) { + return false, errOpNoSupport +} + +// SetMulticastLoopback sets whether transmitted multicast packets +// should be copied and send back to the originator. +func (c *dgramOpt) SetMulticastLoopback(on bool) error { + return errOpNoSupport +} + +// JoinGroup joins the group address group on the interface ifi. +// By default all sources that can cast data to group are accepted. +// It's possible to mute and unmute data transmission from a specific +// source by using ExcludeSourceSpecificGroup and +// IncludeSourceSpecificGroup. +// JoinGroup uses the system assigned multicast interface when ifi is +// nil, although this is not recommended because the assignment +// depends on platforms and sometimes it might require routing +// configuration. +func (c *dgramOpt) JoinGroup(ifi *net.Interface, group net.Addr) error { + return errOpNoSupport +} + +// LeaveGroup leaves the group address group on the interface ifi +// regardless of whether the group is any-source group or +// source-specific group. +func (c *dgramOpt) LeaveGroup(ifi *net.Interface, group net.Addr) error { + return errOpNoSupport +} + +// JoinSourceSpecificGroup joins the source-specific group comprising +// group and source on the interface ifi. +// JoinSourceSpecificGroup uses the system assigned multicast +// interface when ifi is nil, although this is not recommended because +// the assignment depends on platforms and sometimes it might require +// routing configuration. +func (c *dgramOpt) JoinSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// LeaveSourceSpecificGroup leaves the source-specific group on the +// interface ifi. +func (c *dgramOpt) LeaveSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// ExcludeSourceSpecificGroup excludes the source-specific group from +// the already joined any-source groups by JoinGroup on the interface +// ifi. +func (c *dgramOpt) ExcludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// IncludeSourceSpecificGroup includes the excluded source-specific +// group by ExcludeSourceSpecificGroup again on the interface ifi. +func (c *dgramOpt) IncludeSourceSpecificGroup(ifi *net.Interface, group, source net.Addr) error { + return errOpNoSupport +} + +// Checksum reports whether the kernel will compute, store or verify a +// checksum for both incoming and outgoing packets. If on is true, it +// returns an offset in bytes into the data of where the checksum +// field is located. +func (c *dgramOpt) Checksum() (on bool, offset int, err error) { + return false, 0, errOpNoSupport +} + +// SetChecksum enables the kernel checksum processing. If on is ture, +// the offset should be an offset in bytes into the data of where the +// checksum field is located. +func (c *dgramOpt) SetChecksum(on bool, offset int) error { + return errOpNoSupport +} + +// ICMPFilter returns an ICMP filter. +func (c *dgramOpt) ICMPFilter() (*ICMPFilter, error) { + return nil, errOpNoSupport +} + +// SetICMPFilter deploys the ICMP filter. +func (c *dgramOpt) SetICMPFilter(f *ICMPFilter) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/doc.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/doc.go new file mode 100644 index 00000000..dd13aa21 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/doc.go @@ -0,0 +1,240 @@ +// 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 ipv6 implements IP-level socket options for the Internet +// Protocol version 6. +// +// The package provides IP-level socket options that allow +// manipulation of IPv6 facilities. +// +// The IPv6 protocol is defined in RFC 2460. +// Basic and advanced socket interface extensions are defined in RFC +// 3493 and RFC 3542. +// Socket interface extensions for multicast source filters are +// defined in RFC 3678. +// MLDv1 and MLDv2 are defined in RFC 2710 and RFC 3810. +// Source-specific multicast is defined in RFC 4607. +// +// +// Unicasting +// +// The options for unicasting are available for net.TCPConn, +// net.UDPConn and net.IPConn which are created as network connections +// that use the IPv6 transport. When a single TCP connection carrying +// a data flow of multiple packets needs to indicate the flow is +// important, ipv6.Conn is used to set the traffic class field on the +// IPv6 header for each packet. +// +// ln, err := net.Listen("tcp6", "[::]:1024") +// if err != nil { +// // error handling +// } +// defer ln.Close() +// for { +// c, err := ln.Accept() +// if err != nil { +// // error handling +// } +// go func(c net.Conn) { +// defer c.Close() +// +// The outgoing packets will be labeled DiffServ assured forwarding +// class 1 low drop precedence, known as AF11 packets. +// +// if err := ipv6.NewConn(c).SetTrafficClass(0x28); err != nil { +// // error handling +// } +// if _, err := c.Write(data); err != nil { +// // error handling +// } +// }(c) +// } +// +// +// Multicasting +// +// The options for multicasting are available for net.UDPConn and +// net.IPconn which are created as network connections that use the +// IPv6 transport. A few network facilities must be prepared before +// you begin multicasting, at a minimum joining network interfaces and +// multicast groups. +// +// en0, err := net.InterfaceByName("en0") +// if err != nil { +// // error handling +// } +// en1, err := net.InterfaceByIndex(911) +// if err != nil { +// // error handling +// } +// group := net.ParseIP("ff02::114") +// +// First, an application listens to an appropriate address with an +// appropriate service port. +// +// c, err := net.ListenPacket("udp6", "[::]:1024") +// if err != nil { +// // error handling +// } +// defer c.Close() +// +// Second, the application joins multicast groups, starts listening to +// the groups on the specified network interfaces. Note that the +// service port for transport layer protocol does not matter with this +// operation as joining groups affects only network and link layer +// protocols, such as IPv6 and Ethernet. +// +// p := ipv6.NewPacketConn(c) +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: group}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en1, &net.UDPAddr{IP: group}); err != nil { +// // error handling +// } +// +// The application might set per packet control message transmissions +// between the protocol stack within the kernel. When the application +// needs a destination address on an incoming packet, +// SetControlMessage of ipv6.PacketConn is used to enable control +// message transmissons. +// +// if err := p.SetControlMessage(ipv6.FlagDst, true); err != nil { +// // error handling +// } +// +// The application could identify whether the received packets are +// of interest by using the control message that contains the +// destination address of the received packet. +// +// b := make([]byte, 1500) +// for { +// n, rcm, src, err := p.ReadFrom(b) +// if err != nil { +// // error handling +// } +// if rcm.Dst.IsMulticast() { +// if rcm.Dst.Equal(group) { +// // joined group, do something +// } else { +// // unknown group, discard +// continue +// } +// } +// +// The application can also send both unicast and multicast packets. +// +// p.SetTrafficClass(0x0) +// p.SetHopLimit(16) +// if _, err := p.WriteTo(data[:n], nil, src); err != nil { +// // error handling +// } +// dst := &net.UDPAddr{IP: group, Port: 1024} +// wcm := ipv6.ControlMessage{TrafficClass: 0xe0, HopLimit: 1} +// for _, ifi := range []*net.Interface{en0, en1} { +// wcm.IfIndex = ifi.Index +// if _, err := p.WriteTo(data[:n], &wcm, dst); err != nil { +// // error handling +// } +// } +// } +// +// +// More multicasting +// +// An application that uses PacketConn may join multiple multicast +// groups. For example, a UDP listener with port 1024 might join two +// different groups across over two different network interfaces by +// using: +// +// c, err := net.ListenPacket("udp6", "[::]:1024") +// if err != nil { +// // error handling +// } +// defer c.Close() +// p := ipv6.NewPacketConn(c) +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en1, &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}); err != nil { +// // error handling +// } +// +// It is possible for multiple UDP listeners that listen on the same +// UDP port to join the same multicast group. The net package will +// provide a socket that listens to a wildcard address with reusable +// UDP port when an appropriate multicast address prefix is passed to +// the net.ListenPacket or net.ListenUDP. +// +// c1, err := net.ListenPacket("udp6", "[ff02::]:1024") +// if err != nil { +// // error handling +// } +// defer c1.Close() +// c2, err := net.ListenPacket("udp6", "[ff02::]:1024") +// if err != nil { +// // error handling +// } +// defer c2.Close() +// p1 := ipv6.NewPacketConn(c1) +// if err := p1.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil { +// // error handling +// } +// p2 := ipv6.NewPacketConn(c2) +// if err := p2.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil { +// // error handling +// } +// +// Also it is possible for the application to leave or rejoin a +// multicast group on the network interface. +// +// if err := p.LeaveGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff02::114")}); err != nil { +// // error handling +// } +// if err := p.JoinGroup(en0, &net.UDPAddr{IP: net.ParseIP("ff01::114")}); err != nil { +// // error handling +// } +// +// +// Source-specific multicasting +// +// An application that uses PacketConn on MLDv2 supported platform is +// able to join source-specific multicast groups. +// The application may use JoinSourceSpecificGroup and +// LeaveSourceSpecificGroup for the operation known as "include" mode, +// +// ssmgroup := net.UDPAddr{IP: net.ParseIP("ff32::8000:9")} +// ssmsource := net.UDPAddr{IP: net.ParseIP("fe80::cafe")} +// if err := p.JoinSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { +// // error handling +// } +// if err := p.LeaveSourceSpecificGroup(en0, &ssmgroup, &ssmsource); err != nil { +// // error handling +// } +// +// or JoinGroup, ExcludeSourceSpecificGroup, +// IncludeSourceSpecificGroup and LeaveGroup for the operation known +// as "exclude" mode. +// +// exclsource := net.UDPAddr{IP: net.ParseIP("fe80::dead")} +// if err := p.JoinGroup(en0, &ssmgroup); err != nil { +// // error handling +// } +// if err := p.ExcludeSourceSpecificGroup(en0, &ssmgroup, &exclsource); err != nil { +// // error handling +// } +// if err := p.LeaveGroup(en0, &ssmgroup); err != nil { +// // error handling +// } +// +// Note that it depends on each platform implementation what happens +// when an application which runs on MLDv2 unsupported platform uses +// JoinSourceSpecificGroup and LeaveSourceSpecificGroup. +// In general the platform tries to fall back to conversations using +// MLDv1 and starts to listen to multicast traffic. +// In the fallback case, ExcludeSourceSpecificGroup and +// IncludeSourceSpecificGroup may return an error. +package ipv6 // import "golang.org/x/net/ipv6" diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/endpoint.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/endpoint.go new file mode 100644 index 00000000..966eaa89 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/endpoint.go @@ -0,0 +1,123 @@ +// 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 ipv6 + +import ( + "net" + "syscall" + "time" +) + +// A Conn represents a network endpoint that uses IPv6 transport. +// It allows to set basic IP-level socket options such as traffic +// class and hop limit. +type Conn struct { + genericOpt +} + +type genericOpt struct { + net.Conn +} + +func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil } + +// PathMTU returns a path MTU value for the destination associated +// with the endpoint. +func (c *Conn) PathMTU() (int, error) { + if !c.genericOpt.ok() { + return 0, syscall.EINVAL + } + fd, err := c.genericOpt.sysfd() + if err != nil { + return 0, err + } + _, mtu, err := getMTUInfo(fd, &sockOpts[ssoPathMTU]) + if err != nil { + return 0, err + } + return mtu, nil +} + +// NewConn returns a new Conn. +func NewConn(c net.Conn) *Conn { + return &Conn{ + genericOpt: genericOpt{Conn: c}, + } +} + +// A PacketConn represents a packet network endpoint that uses IPv6 +// transport. It is used to control several IP-level socket options +// including IPv6 header manipulation. It also provides datagram +// based network I/O methods specific to the IPv6 and higher layer +// protocols such as OSPF, GRE, and UDP. +type PacketConn struct { + genericOpt + dgramOpt + payloadHandler +} + +type dgramOpt struct { + net.PacketConn +} + +func (c *dgramOpt) ok() bool { return c != nil && c.PacketConn != nil } + +// SetControlMessage allows to receive the per packet basis IP-level +// socket options. +func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + fd, err := c.payloadHandler.sysfd() + if err != nil { + return err + } + return setControlMessage(fd, &c.payloadHandler.rawOpt, cf, on) +} + +// SetDeadline sets the read and write deadlines associated with the +// endpoint. +func (c *PacketConn) SetDeadline(t time.Time) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.SetDeadline(t) +} + +// SetReadDeadline sets the read deadline associated with the +// endpoint. +func (c *PacketConn) SetReadDeadline(t time.Time) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.SetReadDeadline(t) +} + +// SetWriteDeadline sets the write deadline associated with the +// endpoint. +func (c *PacketConn) SetWriteDeadline(t time.Time) error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.SetWriteDeadline(t) +} + +// Close closes the endpoint. +func (c *PacketConn) Close() error { + if !c.payloadHandler.ok() { + return syscall.EINVAL + } + return c.payloadHandler.Close() +} + +// NewPacketConn returns a new PacketConn using c as its underlying +// transport. +func NewPacketConn(c net.PacketConn) *PacketConn { + return &PacketConn{ + genericOpt: genericOpt{Conn: c.(net.Conn)}, + dgramOpt: dgramOpt{PacketConn: c}, + payloadHandler: payloadHandler{PacketConn: c}, + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/example_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/example_test.go new file mode 100644 index 00000000..e761aa2a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/example_test.go @@ -0,0 +1,216 @@ +// 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. + +package ipv6_test + +import ( + "fmt" + "log" + "net" + "os" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/ipv6" +) + +func ExampleConn_markingTCP() { + ln, err := net.Listen("tcp", "[::]:1024") + if err != nil { + log.Fatal(err) + } + defer ln.Close() + + for { + c, err := ln.Accept() + if err != nil { + log.Fatal(err) + } + go func(c net.Conn) { + defer c.Close() + if c.RemoteAddr().(*net.TCPAddr).IP.To16() != nil && c.RemoteAddr().(*net.TCPAddr).IP.To4() == nil { + p := ipv6.NewConn(c) + if err := p.SetTrafficClass(0x28); err != nil { // DSCP AF11 + log.Fatal(err) + } + if err := p.SetHopLimit(128); err != nil { + log.Fatal(err) + } + } + if _, err := c.Write([]byte("HELLO-R-U-THERE-ACK")); err != nil { + log.Fatal(err) + } + }(c) + } +} + +func ExamplePacketConn_servingOneShotMulticastDNS() { + c, err := net.ListenPacket("udp6", "[::]:5353") // mDNS over UDP + if err != nil { + log.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + + en0, err := net.InterfaceByName("en0") + if err != nil { + log.Fatal(err) + } + mDNSLinkLocal := net.UDPAddr{IP: net.ParseIP("ff02::fb")} + if err := p.JoinGroup(en0, &mDNSLinkLocal); err != nil { + log.Fatal(err) + } + defer p.LeaveGroup(en0, &mDNSLinkLocal) + if err := p.SetControlMessage(ipv6.FlagDst|ipv6.FlagInterface, true); err != nil { + log.Fatal(err) + } + + var wcm ipv6.ControlMessage + b := make([]byte, 1500) + for { + _, rcm, peer, err := p.ReadFrom(b) + if err != nil { + log.Fatal(err) + } + if !rcm.Dst.IsMulticast() || !rcm.Dst.Equal(mDNSLinkLocal.IP) { + continue + } + wcm.IfIndex = rcm.IfIndex + answers := []byte("FAKE-MDNS-ANSWERS") // fake mDNS answers, you need to implement this + if _, err := p.WriteTo(answers, &wcm, peer); err != nil { + log.Fatal(err) + } + } +} + +func ExamplePacketConn_tracingIPPacketRoute() { + // Tracing an IP packet route to www.google.com. + + const host = "www.google.com" + ips, err := net.LookupIP(host) + if err != nil { + log.Fatal(err) + } + var dst net.IPAddr + for _, ip := range ips { + if ip.To16() != nil && ip.To4() == nil { + dst.IP = ip + fmt.Printf("using %v for tracing an IP packet route to %s\n", dst.IP, host) + break + } + } + if dst.IP == nil { + log.Fatal("no AAAA record found") + } + + c, err := net.ListenPacket("ip6:58", "::") // ICMP for IPv6 + if err != nil { + log.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + + if err := p.SetControlMessage(ipv6.FlagHopLimit|ipv6.FlagSrc|ipv6.FlagDst|ipv6.FlagInterface, true); err != nil { + log.Fatal(err) + } + wm := icmp.Message{ + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, + Data: []byte("HELLO-R-U-THERE"), + }, + } + var f ipv6.ICMPFilter + f.SetAll(true) + f.Accept(ipv6.ICMPTypeTimeExceeded) + f.Accept(ipv6.ICMPTypeEchoReply) + if err := p.SetICMPFilter(&f); err != nil { + log.Fatal(err) + } + + var wcm ipv6.ControlMessage + rb := make([]byte, 1500) + for i := 1; i <= 64; i++ { // up to 64 hops + wm.Body.(*icmp.Echo).Seq = i + wb, err := wm.Marshal(nil) + if err != nil { + log.Fatal(err) + } + + // In the real world usually there are several + // multiple traffic-engineered paths for each hop. + // You may need to probe a few times to each hop. + begin := time.Now() + wcm.HopLimit = i + if _, err := p.WriteTo(wb, &wcm, &dst); err != nil { + log.Fatal(err) + } + if err := p.SetReadDeadline(time.Now().Add(3 * time.Second)); err != nil { + log.Fatal(err) + } + n, rcm, peer, err := p.ReadFrom(rb) + if err != nil { + if err, ok := err.(net.Error); ok && err.Timeout() { + fmt.Printf("%v\t*\n", i) + continue + } + log.Fatal(err) + } + rm, err := icmp.ParseMessage(58, rb[:n]) + if err != nil { + log.Fatal(err) + } + rtt := time.Since(begin) + + // In the real world you need to determine whether the + // received message is yours using ControlMessage.Src, + // ControlMesage.Dst, icmp.Echo.ID and icmp.Echo.Seq. + switch rm.Type { + case ipv6.ICMPTypeTimeExceeded: + names, _ := net.LookupAddr(peer.String()) + fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm) + case ipv6.ICMPTypeEchoReply: + names, _ := net.LookupAddr(peer.String()) + fmt.Printf("%d\t%v %+v %v\n\t%+v\n", i, peer, names, rtt, rcm) + return + } + } +} + +func ExamplePacketConn_advertisingOSPFHello() { + c, err := net.ListenPacket("ip6:89", "::") // OSPF for IPv6 + if err != nil { + log.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + + en0, err := net.InterfaceByName("en0") + if err != nil { + log.Fatal(err) + } + allSPFRouters := net.IPAddr{IP: net.ParseIP("ff02::5")} + if err := p.JoinGroup(en0, &allSPFRouters); err != nil { + log.Fatal(err) + } + defer p.LeaveGroup(en0, &allSPFRouters) + + hello := make([]byte, 24) // fake hello data, you need to implement this + ospf := make([]byte, 16) // fake ospf header, you need to implement this + ospf[0] = 3 // version 3 + ospf[1] = 1 // hello packet + ospf = append(ospf, hello...) + if err := p.SetChecksum(true, 12); err != nil { + log.Fatal(err) + } + + cm := ipv6.ControlMessage{ + TrafficClass: 0xc0, // DSCP CS6 + HopLimit: 1, + IfIndex: en0.Index, + } + if _, err := p.WriteTo(ospf, &cm, &allSPFRouters); err != nil { + log.Fatal(err) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/gen.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/gen.go new file mode 100644 index 00000000..b1e0ea37 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/gen.go @@ -0,0 +1,208 @@ +// 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 ignore + +//go:generate go run gen.go + +// This program generates system adaptation constants and types, +// internet protocol constants and tables by reading template files +// and IANA protocol registries. +package main + +import ( + "bytes" + "encoding/xml" + "fmt" + "go/format" + "io" + "io/ioutil" + "net/http" + "os" + "os/exec" + "runtime" + "strconv" + "strings" +) + +func main() { + if err := genzsys(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + if err := geniana(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func genzsys() error { + defs := "defs_" + runtime.GOOS + ".go" + f, err := os.Open(defs) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + f.Close() + cmd := exec.Command("go", "tool", "cgo", "-godefs", defs) + b, err := cmd.Output() + if err != nil { + return err + } + // The ipv6 pacakge still supports go1.2, and so we need to + // take care of additional platforms in go1.3 and above for + // working with go1.2. + switch { + case runtime.GOOS == "dragonfly" || runtime.GOOS == "solaris": + b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+"\n\npackage ipv6\n"), 1) + case runtime.GOOS == "linux" && (runtime.GOARCH == "arm64" || runtime.GOARCH == "mips64" || runtime.GOARCH == "mips64le" || runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le"): + b = bytes.Replace(b, []byte("package ipv6\n"), []byte("// +build "+runtime.GOOS+","+runtime.GOARCH+"\n\npackage ipv6\n"), 1) + } + b, err = format.Source(b) + if err != nil { + return err + } + zsys := "zsys_" + runtime.GOOS + ".go" + switch runtime.GOOS { + case "freebsd", "linux": + zsys = "zsys_" + runtime.GOOS + "_" + runtime.GOARCH + ".go" + } + if err := ioutil.WriteFile(zsys, b, 0644); err != nil { + return err + } + return nil +} + +var registries = []struct { + url string + parse func(io.Writer, io.Reader) error +}{ + { + "http://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xml", + parseICMPv6Parameters, + }, +} + +func geniana() error { + var bb bytes.Buffer + fmt.Fprintf(&bb, "// go generate gen.go\n") + fmt.Fprintf(&bb, "// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT\n\n") + fmt.Fprintf(&bb, "package ipv6\n\n") + for _, r := range registries { + resp, err := http.Get(r.url) + if err != nil { + return err + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("got HTTP status code %v for %v\n", resp.StatusCode, r.url) + } + if err := r.parse(&bb, resp.Body); err != nil { + return err + } + fmt.Fprintf(&bb, "\n") + } + b, err := format.Source(bb.Bytes()) + if err != nil { + return err + } + if err := ioutil.WriteFile("iana.go", b, 0644); err != nil { + return err + } + return nil +} + +func parseICMPv6Parameters(w io.Writer, r io.Reader) error { + dec := xml.NewDecoder(r) + var icp icmpv6Parameters + if err := dec.Decode(&icp); err != nil { + return err + } + prs := icp.escape() + fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) + fmt.Fprintf(w, "const (\n") + for _, pr := range prs { + if pr.Name == "" { + continue + } + fmt.Fprintf(w, "ICMPType%s ICMPType = %d", pr.Name, pr.Value) + fmt.Fprintf(w, "// %s\n", pr.OrigName) + } + fmt.Fprintf(w, ")\n\n") + fmt.Fprintf(w, "// %s, Updated: %s\n", icp.Title, icp.Updated) + fmt.Fprintf(w, "var icmpTypes = map[ICMPType]string{\n") + for _, pr := range prs { + if pr.Name == "" { + continue + } + fmt.Fprintf(w, "%d: %q,\n", pr.Value, strings.ToLower(pr.OrigName)) + } + fmt.Fprintf(w, "}\n") + return nil +} + +type icmpv6Parameters struct { + XMLName xml.Name `xml:"registry"` + Title string `xml:"title"` + Updated string `xml:"updated"` + Registries []struct { + Title string `xml:"title"` + Records []struct { + Value string `xml:"value"` + Name string `xml:"name"` + } `xml:"record"` + } `xml:"registry"` +} + +type canonICMPv6ParamRecord struct { + OrigName string + Name string + Value int +} + +func (icp *icmpv6Parameters) escape() []canonICMPv6ParamRecord { + id := -1 + for i, r := range icp.Registries { + if strings.Contains(r.Title, "Type") || strings.Contains(r.Title, "type") { + id = i + break + } + } + if id < 0 { + return nil + } + prs := make([]canonICMPv6ParamRecord, len(icp.Registries[id].Records)) + sr := strings.NewReplacer( + "Messages", "", + "Message", "", + "ICMP", "", + "+", "P", + "-", "", + "/", "", + ".", "", + " ", "", + ) + for i, pr := range icp.Registries[id].Records { + if strings.Contains(pr.Name, "Reserved") || + strings.Contains(pr.Name, "Unassigned") || + strings.Contains(pr.Name, "Deprecated") || + strings.Contains(pr.Name, "Experiment") || + strings.Contains(pr.Name, "experiment") { + continue + } + ss := strings.Split(pr.Name, "\n") + if len(ss) > 1 { + prs[i].Name = strings.Join(ss, " ") + } else { + prs[i].Name = ss[0] + } + s := strings.TrimSpace(prs[i].Name) + prs[i].OrigName = s + prs[i].Name = sr.Replace(s) + prs[i].Value, _ = strconv.Atoi(pr.Value) + } + return prs +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/genericopt_posix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/genericopt_posix.go new file mode 100644 index 00000000..dd77a016 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/genericopt_posix.go @@ -0,0 +1,60 @@ +// 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 dragonfly freebsd linux netbsd openbsd windows + +package ipv6 + +import "syscall" + +// TrafficClass returns the traffic class field value for outgoing +// packets. +func (c *genericOpt) TrafficClass() (int, error) { + if !c.ok() { + return 0, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return 0, err + } + return getInt(fd, &sockOpts[ssoTrafficClass]) +} + +// SetTrafficClass sets the traffic class field value for future +// outgoing packets. +func (c *genericOpt) SetTrafficClass(tclass int) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoTrafficClass], tclass) +} + +// HopLimit returns the hop limit field value for outgoing packets. +func (c *genericOpt) HopLimit() (int, error) { + if !c.ok() { + return 0, syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return 0, err + } + return getInt(fd, &sockOpts[ssoHopLimit]) +} + +// SetHopLimit sets the hop limit field value for future outgoing +// packets. +func (c *genericOpt) SetHopLimit(hoplim int) error { + if !c.ok() { + return syscall.EINVAL + } + fd, err := c.sysfd() + if err != nil { + return err + } + return setInt(fd, &sockOpts[ssoHopLimit], hoplim) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/genericopt_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/genericopt_stub.go new file mode 100644 index 00000000..f5c37224 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/genericopt_stub.go @@ -0,0 +1,30 @@ +// 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 nacl plan9 solaris + +package ipv6 + +// TrafficClass returns the traffic class field value for outgoing +// packets. +func (c *genericOpt) TrafficClass() (int, error) { + return 0, errOpNoSupport +} + +// SetTrafficClass sets the traffic class field value for future +// outgoing packets. +func (c *genericOpt) SetTrafficClass(tclass int) error { + return errOpNoSupport +} + +// HopLimit returns the hop limit field value for outgoing packets. +func (c *genericOpt) HopLimit() (int, error) { + return 0, errOpNoSupport +} + +// SetHopLimit sets the hop limit field value for future outgoing +// packets. +func (c *genericOpt) SetHopLimit(hoplim int) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/header.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/header.go new file mode 100644 index 00000000..ad73776b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/header.go @@ -0,0 +1,54 @@ +// 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. + +package ipv6 + +import ( + "fmt" + "net" +) + +const ( + Version = 6 // protocol version + HeaderLen = 40 // header length +) + +// A Header represents an IPv6 base header. +type Header struct { + Version int // protocol version + TrafficClass int // traffic class + FlowLabel int // flow label + PayloadLen int // payload length + NextHeader int // next header + HopLimit int // hop limit + Src net.IP // source address + Dst net.IP // destination address +} + +func (h *Header) String() string { + if h == nil { + return "" + } + return fmt.Sprintf("ver=%d tclass=%#x flowlbl=%#x payloadlen=%d nxthdr=%d hoplim=%d src=%v dst=%v", h.Version, h.TrafficClass, h.FlowLabel, h.PayloadLen, h.NextHeader, h.HopLimit, h.Src, h.Dst) +} + +// ParseHeader parses b as an IPv6 base header. +func ParseHeader(b []byte) (*Header, error) { + if len(b) < HeaderLen { + return nil, errHeaderTooShort + } + h := &Header{ + Version: int(b[0]) >> 4, + TrafficClass: int(b[0]&0x0f)<<4 | int(b[1])>>4, + FlowLabel: int(b[1]&0x0f)<<16 | int(b[2])<<8 | int(b[3]), + PayloadLen: int(b[4])<<8 | int(b[5]), + NextHeader: int(b[6]), + HopLimit: int(b[7]), + } + h.Src = make(net.IP, net.IPv6len) + copy(h.Src, b[8:24]) + h.Dst = make(net.IP, net.IPv6len) + copy(h.Dst, b[24:40]) + return h, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/header_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/header_test.go new file mode 100644 index 00000000..ca11dc23 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/header_test.go @@ -0,0 +1,55 @@ +// 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. + +package ipv6_test + +import ( + "net" + "reflect" + "strings" + "testing" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/ipv6" +) + +var ( + wireHeaderFromKernel = [ipv6.HeaderLen]byte{ + 0x69, 0x8b, 0xee, 0xf1, + 0xca, 0xfe, 0x2c, 0x01, + 0x20, 0x01, 0x0d, 0xb8, + 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + 0x20, 0x01, 0x0d, 0xb8, + 0x00, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + } + + testHeader = &ipv6.Header{ + Version: ipv6.Version, + TrafficClass: iana.DiffServAF43, + FlowLabel: 0xbeef1, + PayloadLen: 0xcafe, + NextHeader: iana.ProtocolIPv6Frag, + HopLimit: 1, + Src: net.ParseIP("2001:db8:1::1"), + Dst: net.ParseIP("2001:db8:2::1"), + } +) + +func TestParseHeader(t *testing.T) { + h, err := ipv6.ParseHeader(wireHeaderFromKernel[:]) + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(h, testHeader) { + t.Fatalf("got %#v; want %#v", h, testHeader) + } + s := h.String() + if strings.Contains(s, ",") { + t.Fatalf("should be space-separated values: %s", s) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper.go new file mode 100644 index 00000000..4a6f1069 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper.go @@ -0,0 +1,39 @@ +// 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 ipv6 + +import ( + "errors" + "net" +) + +var ( + errMissingAddress = errors.New("missing address") + errHeaderTooShort = errors.New("header too short") + errInvalidConnType = errors.New("invalid conn type") + errOpNoSupport = errors.New("operation not supported") + errNoSuchInterface = errors.New("no such interface") +) + +func boolint(b bool) int { + if b { + return 1 + } + return 0 +} + +func netAddrToIP16(a net.Addr) net.IP { + switch v := a.(type) { + case *net.UDPAddr: + if ip := v.IP.To16(); ip != nil && ip.To4() == nil { + return ip + } + case *net.IPAddr: + if ip := v.IP.To16(); ip != nil && ip.To4() == nil { + return ip + } + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_stub.go new file mode 100644 index 00000000..20354ab2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_stub.go @@ -0,0 +1,19 @@ +// 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 nacl plan9 solaris + +package ipv6 + +func (c *genericOpt) sysfd() (int, error) { + return 0, errOpNoSupport +} + +func (c *dgramOpt) sysfd() (int, error) { + return 0, errOpNoSupport +} + +func (c *payloadHandler) sysfd() (int, error) { + return 0, errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_unix.go new file mode 100644 index 00000000..92868ed2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_unix.go @@ -0,0 +1,46 @@ +// 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 dragonfly freebsd linux netbsd openbsd + +package ipv6 + +import ( + "net" + "reflect" +) + +func (c *genericOpt) sysfd() (int, error) { + switch p := c.Conn.(type) { + case *net.TCPConn, *net.UDPConn, *net.IPConn: + return sysfd(p) + } + return 0, errInvalidConnType +} + +func (c *dgramOpt) sysfd() (int, error) { + switch p := c.PacketConn.(type) { + case *net.UDPConn, *net.IPConn: + return sysfd(p.(net.Conn)) + } + return 0, errInvalidConnType +} + +func (c *payloadHandler) sysfd() (int, error) { + return sysfd(c.PacketConn.(net.Conn)) +} + +func sysfd(c net.Conn) (int, error) { + cv := reflect.ValueOf(c) + switch ce := cv.Elem(); ce.Kind() { + case reflect.Struct: + nfd := ce.FieldByName("conn").FieldByName("fd") + switch fe := nfd.Elem(); fe.Kind() { + case reflect.Struct: + fd := fe.FieldByName("sysfd") + return int(fd.Int()), nil + } + } + return 0, errInvalidConnType +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_windows.go new file mode 100644 index 00000000..28c401b5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/helper_windows.go @@ -0,0 +1,45 @@ +// 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 ipv6 + +import ( + "net" + "reflect" + "syscall" +) + +func (c *genericOpt) sysfd() (syscall.Handle, error) { + switch p := c.Conn.(type) { + case *net.TCPConn, *net.UDPConn, *net.IPConn: + return sysfd(p) + } + return syscall.InvalidHandle, errInvalidConnType +} + +func (c *dgramOpt) sysfd() (syscall.Handle, error) { + switch p := c.PacketConn.(type) { + case *net.UDPConn, *net.IPConn: + return sysfd(p.(net.Conn)) + } + return syscall.InvalidHandle, errInvalidConnType +} + +func (c *payloadHandler) sysfd() (syscall.Handle, error) { + return sysfd(c.PacketConn.(net.Conn)) +} + +func sysfd(c net.Conn) (syscall.Handle, error) { + cv := reflect.ValueOf(c) + switch ce := cv.Elem(); ce.Kind() { + case reflect.Struct: + netfd := ce.FieldByName("conn").FieldByName("fd") + switch fe := netfd.Elem(); fe.Kind() { + case reflect.Struct: + fd := fe.FieldByName("sysfd") + return syscall.Handle(fd.Uint()), nil + } + } + return syscall.InvalidHandle, errInvalidConnType +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/iana.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/iana.go new file mode 100644 index 00000000..3c6214fb --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/iana.go @@ -0,0 +1,82 @@ +// go generate gen.go +// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +package ipv6 + +// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2015-07-07 +const ( + ICMPTypeDestinationUnreachable ICMPType = 1 // Destination Unreachable + ICMPTypePacketTooBig ICMPType = 2 // Packet Too Big + ICMPTypeTimeExceeded ICMPType = 3 // Time Exceeded + ICMPTypeParameterProblem ICMPType = 4 // Parameter Problem + ICMPTypeEchoRequest ICMPType = 128 // Echo Request + ICMPTypeEchoReply ICMPType = 129 // Echo Reply + ICMPTypeMulticastListenerQuery ICMPType = 130 // Multicast Listener Query + ICMPTypeMulticastListenerReport ICMPType = 131 // Multicast Listener Report + ICMPTypeMulticastListenerDone ICMPType = 132 // Multicast Listener Done + ICMPTypeRouterSolicitation ICMPType = 133 // Router Solicitation + ICMPTypeRouterAdvertisement ICMPType = 134 // Router Advertisement + ICMPTypeNeighborSolicitation ICMPType = 135 // Neighbor Solicitation + ICMPTypeNeighborAdvertisement ICMPType = 136 // Neighbor Advertisement + ICMPTypeRedirect ICMPType = 137 // Redirect Message + ICMPTypeRouterRenumbering ICMPType = 138 // Router Renumbering + ICMPTypeNodeInformationQuery ICMPType = 139 // ICMP Node Information Query + ICMPTypeNodeInformationResponse ICMPType = 140 // ICMP Node Information Response + ICMPTypeInverseNeighborDiscoverySolicitation ICMPType = 141 // Inverse Neighbor Discovery Solicitation Message + ICMPTypeInverseNeighborDiscoveryAdvertisement ICMPType = 142 // Inverse Neighbor Discovery Advertisement Message + ICMPTypeVersion2MulticastListenerReport ICMPType = 143 // Version 2 Multicast Listener Report + ICMPTypeHomeAgentAddressDiscoveryRequest ICMPType = 144 // Home Agent Address Discovery Request Message + ICMPTypeHomeAgentAddressDiscoveryReply ICMPType = 145 // Home Agent Address Discovery Reply Message + ICMPTypeMobilePrefixSolicitation ICMPType = 146 // Mobile Prefix Solicitation + ICMPTypeMobilePrefixAdvertisement ICMPType = 147 // Mobile Prefix Advertisement + ICMPTypeCertificationPathSolicitation ICMPType = 148 // Certification Path Solicitation Message + ICMPTypeCertificationPathAdvertisement ICMPType = 149 // Certification Path Advertisement Message + ICMPTypeMulticastRouterAdvertisement ICMPType = 151 // Multicast Router Advertisement + ICMPTypeMulticastRouterSolicitation ICMPType = 152 // Multicast Router Solicitation + ICMPTypeMulticastRouterTermination ICMPType = 153 // Multicast Router Termination + ICMPTypeFMIPv6 ICMPType = 154 // FMIPv6 Messages + ICMPTypeRPLControl ICMPType = 155 // RPL Control Message + ICMPTypeILNPv6LocatorUpdate ICMPType = 156 // ILNPv6 Locator Update Message + ICMPTypeDuplicateAddressRequest ICMPType = 157 // Duplicate Address Request + ICMPTypeDuplicateAddressConfirmation ICMPType = 158 // Duplicate Address Confirmation + ICMPTypeMPLControl ICMPType = 159 // MPL Control Message +) + +// Internet Control Message Protocol version 6 (ICMPv6) Parameters, Updated: 2015-07-07 +var icmpTypes = map[ICMPType]string{ + 1: "destination unreachable", + 2: "packet too big", + 3: "time exceeded", + 4: "parameter problem", + 128: "echo request", + 129: "echo reply", + 130: "multicast listener query", + 131: "multicast listener report", + 132: "multicast listener done", + 133: "router solicitation", + 134: "router advertisement", + 135: "neighbor solicitation", + 136: "neighbor advertisement", + 137: "redirect message", + 138: "router renumbering", + 139: "icmp node information query", + 140: "icmp node information response", + 141: "inverse neighbor discovery solicitation message", + 142: "inverse neighbor discovery advertisement message", + 143: "version 2 multicast listener report", + 144: "home agent address discovery request message", + 145: "home agent address discovery reply message", + 146: "mobile prefix solicitation", + 147: "mobile prefix advertisement", + 148: "certification path solicitation message", + 149: "certification path advertisement message", + 151: "multicast router advertisement", + 152: "multicast router solicitation", + 153: "multicast router termination", + 154: "fmipv6 messages", + 155: "rpl control message", + 156: "ilnpv6 locator update message", + 157: "duplicate address request", + 158: "duplicate address confirmation", + 159: "mpl control message", +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp.go new file mode 100644 index 00000000..a2de65a0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp.go @@ -0,0 +1,57 @@ +// 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 ipv6 + +import "golang.org/x/net/internal/iana" + +// An ICMPType represents a type of ICMP message. +type ICMPType int + +func (typ ICMPType) String() string { + s, ok := icmpTypes[typ] + if !ok { + return "" + } + return s +} + +// Protocol returns the ICMPv6 protocol number. +func (typ ICMPType) Protocol() int { + return iana.ProtocolIPv6ICMP +} + +// An ICMPFilter represents an ICMP message filter for incoming +// packets. The filter belongs to a packet delivery path on a host and +// it cannot interact with forwarding packets or tunnel-outer packets. +// +// Note: RFC 2460 defines a reasonable role model. A node means a +// device that implements IP. A router means a node that forwards IP +// packets not explicitly addressed to itself, and a host means a node +// that is not a router. +type ICMPFilter struct { + sysICMPv6Filter +} + +// Accept accepts incoming ICMP packets including the type field value +// typ. +func (f *ICMPFilter) Accept(typ ICMPType) { + f.accept(typ) +} + +// Block blocks incoming ICMP packets including the type field value +// typ. +func (f *ICMPFilter) Block(typ ICMPType) { + f.block(typ) +} + +// SetAll sets the filter action to the filter. +func (f *ICMPFilter) SetAll(block bool) { + f.setAll(block) +} + +// WillBlock reports whether the ICMP type will be blocked. +func (f *ICMPFilter) WillBlock(typ ICMPType) bool { + return f.willBlock(typ) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_bsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_bsd.go new file mode 100644 index 00000000..30e3ce42 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_bsd.go @@ -0,0 +1,29 @@ +// 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 dragonfly freebsd netbsd openbsd + +package ipv6 + +func (f *sysICMPv6Filter) accept(typ ICMPType) { + f.Filt[typ>>5] |= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { + f.Filt[typ>>5] &^= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPv6Filter) setAll(block bool) { + for i := range f.Filt { + if block { + f.Filt[i] = 0 + } else { + f.Filt[i] = 1<<32 - 1 + } + } +} + +func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool { + return f.Filt[typ>>5]&(1<<(uint32(typ)&31)) == 0 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_linux.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_linux.go new file mode 100644 index 00000000..a67ecf69 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_linux.go @@ -0,0 +1,27 @@ +// 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 ipv6 + +func (f *sysICMPv6Filter) accept(typ ICMPType) { + f.Data[typ>>5] &^= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { + f.Data[typ>>5] |= 1 << (uint32(typ) & 31) +} + +func (f *sysICMPv6Filter) setAll(block bool) { + for i := range f.Data { + if block { + f.Data[i] = 1<<32 - 1 + } else { + f.Data[i] = 0 + } + } +} + +func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool { + return f.Data[typ>>5]&(1<<(uint32(typ)&31)) != 0 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_solaris.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_solaris.go new file mode 100644 index 00000000..a942f354 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_solaris.go @@ -0,0 +1,24 @@ +// 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 solaris + +package ipv6 + +func (f *sysICMPv6Filter) accept(typ ICMPType) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) setAll(block bool) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool { + // TODO(mikio): implement this + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_stub.go new file mode 100644 index 00000000..c1263eca --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_stub.go @@ -0,0 +1,23 @@ +// 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 nacl plan9 + +package ipv6 + +type sysICMPv6Filter struct { +} + +func (f *sysICMPv6Filter) accept(typ ICMPType) { +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { +} + +func (f *sysICMPv6Filter) setAll(block bool) { +} + +func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool { + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_test.go new file mode 100644 index 00000000..e192d6d8 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_test.go @@ -0,0 +1,96 @@ +// 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 ipv6_test + +import ( + "net" + "reflect" + "runtime" + "testing" + + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +var icmpStringTests = []struct { + in ipv6.ICMPType + out string +}{ + {ipv6.ICMPTypeDestinationUnreachable, "destination unreachable"}, + + {256, ""}, +} + +func TestICMPString(t *testing.T) { + for _, tt := range icmpStringTests { + s := tt.in.String() + if s != tt.out { + t.Errorf("got %s; want %s", s, tt.out) + } + } +} + +func TestICMPFilter(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + + var f ipv6.ICMPFilter + for _, toggle := range []bool{false, true} { + f.SetAll(toggle) + for _, typ := range []ipv6.ICMPType{ + ipv6.ICMPTypeDestinationUnreachable, + ipv6.ICMPTypeEchoReply, + ipv6.ICMPTypeNeighborSolicitation, + ipv6.ICMPTypeDuplicateAddressConfirmation, + } { + f.Accept(typ) + if f.WillBlock(typ) { + t.Errorf("ipv6.ICMPFilter.Set(%v, false) failed", typ) + } + f.Block(typ) + if !f.WillBlock(typ) { + t.Errorf("ipv6.ICMPFilter.Set(%v, true) failed", typ) + } + } + } +} + +func TestSetICMPFilter(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + c, err := net.ListenPacket("ip6:ipv6-icmp", "::1") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + p := ipv6.NewPacketConn(c) + + var f ipv6.ICMPFilter + f.SetAll(true) + f.Accept(ipv6.ICMPTypeEchoRequest) + f.Accept(ipv6.ICMPTypeEchoReply) + if err := p.SetICMPFilter(&f); err != nil { + t.Fatal(err) + } + kf, err := p.ICMPFilter() + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(kf, &f) { + t.Fatalf("got %#v; want %#v", kf, f) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_windows.go new file mode 100644 index 00000000..9dcfb810 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/icmp_windows.go @@ -0,0 +1,26 @@ +// 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 ipv6 + +type sysICMPv6Filter struct { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) accept(typ ICMPType) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) block(typ ICMPType) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) setAll(block bool) { + // TODO(mikio): implement this +} + +func (f *sysICMPv6Filter) willBlock(typ ICMPType) bool { + // TODO(mikio): implement this + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/mocktransponder_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/mocktransponder_test.go new file mode 100644 index 00000000..d587922a --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/mocktransponder_test.go @@ -0,0 +1,32 @@ +// 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 ipv6_test + +import ( + "net" + "testing" +) + +func connector(t *testing.T, network, addr string, done chan<- bool) { + defer func() { done <- true }() + + c, err := net.Dial(network, addr) + if err != nil { + t.Error(err) + return + } + c.Close() +} + +func acceptor(t *testing.T, ln net.Listener, done chan<- bool) { + defer func() { done <- true }() + + c, err := ln.Accept() + if err != nil { + t.Error(err) + return + } + c.Close() +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicast_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicast_test.go new file mode 100644 index 00000000..a3a8979d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicast_test.go @@ -0,0 +1,260 @@ +// 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 ipv6_test + +import ( + "bytes" + "net" + "os" + "runtime" + "testing" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +var packetConnReadWriteMulticastUDPTests = []struct { + addr string + grp, src *net.UDPAddr +}{ + {"[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727 + + {"[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771 +} + +func TestPacketConnReadWriteMulticastUDP(t *testing.T) { + switch runtime.GOOS { + case "freebsd": // due to a bug on loopback marking + // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065. + t.Skipf("not supported on %s", runtime.GOOS) + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + for _, tt := range packetConnReadWriteMulticastUDPTests { + c, err := net.ListenPacket("udp6", tt.addr) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + grp := *tt.grp + grp.Port = c.LocalAddr().(*net.UDPAddr).Port + p := ipv6.NewPacketConn(c) + defer p.Close() + if tt.src == nil { + if err := p.JoinGroup(ifi, &grp); err != nil { + t.Fatal(err) + } + defer p.LeaveGroup(ifi, &grp) + } else { + if err := p.JoinSourceSpecificGroup(ifi, &grp, tt.src); err != nil { + switch runtime.GOOS { + case "freebsd", "linux": + default: // platforms that don't support MLDv2 fail here + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + defer p.LeaveSourceSpecificGroup(ifi, &grp, tt.src) + } + if err := p.SetMulticastInterface(ifi); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastInterface(); err != nil { + t.Fatal(err) + } + if err := p.SetMulticastLoopback(true); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastLoopback(); err != nil { + t.Fatal(err) + } + + cm := ipv6.ControlMessage{ + TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, + Src: net.IPv6loopback, + IfIndex: ifi.Index, + } + cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU + wb := []byte("HELLO-R-U-THERE") + + for i, toggle := range []bool{true, false, true} { + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { + t.Fatal(err) + } + cm.HopLimit = i + 1 + if n, err := p.WriteTo(wb, &cm, &grp); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatal(err) + } + rb := make([]byte, 128) + if n, _, _, err := p.ReadFrom(rb); err != nil { + t.Fatal(err) + } else if !bytes.Equal(rb[:n], wb) { + t.Fatalf("got %v; want %v", rb[:n], wb) + } + } + } +} + +var packetConnReadWriteMulticastICMPTests = []struct { + grp, src *net.IPAddr +}{ + {&net.IPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727 + + {&net.IPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771 +} + +func TestPacketConnReadWriteMulticastICMP(t *testing.T) { + switch runtime.GOOS { + case "freebsd": // due to a bug on loopback marking + // See http://www.freebsd.org/cgi/query-pr.cgi?pr=180065. + t.Skipf("not supported on %s", runtime.GOOS) + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + for _, tt := range packetConnReadWriteMulticastICMPTests { + c, err := net.ListenPacket("ip6:ipv6-icmp", "::") + if err != nil { + t.Fatal(err) + } + defer c.Close() + + pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, tt.grp.IP) + p := ipv6.NewPacketConn(c) + defer p.Close() + if tt.src == nil { + if err := p.JoinGroup(ifi, tt.grp); err != nil { + t.Fatal(err) + } + defer p.LeaveGroup(ifi, tt.grp) + } else { + if err := p.JoinSourceSpecificGroup(ifi, tt.grp, tt.src); err != nil { + switch runtime.GOOS { + case "freebsd", "linux": + default: // platforms that don't support MLDv2 fail here + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + defer p.LeaveSourceSpecificGroup(ifi, tt.grp, tt.src) + } + if err := p.SetMulticastInterface(ifi); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastInterface(); err != nil { + t.Fatal(err) + } + if err := p.SetMulticastLoopback(true); err != nil { + t.Fatal(err) + } + if _, err := p.MulticastLoopback(); err != nil { + t.Fatal(err) + } + + cm := ipv6.ControlMessage{ + TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, + Src: net.IPv6loopback, + IfIndex: ifi.Index, + } + cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU + + var f ipv6.ICMPFilter + f.SetAll(true) + f.Accept(ipv6.ICMPTypeEchoReply) + if err := p.SetICMPFilter(&f); err != nil { + t.Fatal(err) + } + + var psh []byte + for i, toggle := range []bool{true, false, true} { + if toggle { + psh = nil + if err := p.SetChecksum(true, 2); err != nil { + t.Fatal(err) + } + } else { + psh = pshicmp + // Some platforms never allow to + // disable the kernel checksum + // processing. + p.SetChecksum(false, -1) + } + wb, err := (&icmp.Message{ + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: i + 1, + Data: []byte("HELLO-R-U-THERE"), + }, + }).Marshal(psh) + if err != nil { + t.Fatal(err) + } + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } + if err := p.SetDeadline(time.Now().Add(200 * time.Millisecond)); err != nil { + t.Fatal(err) + } + cm.HopLimit = i + 1 + if n, err := p.WriteTo(wb, &cm, tt.grp); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatalf("got %v; want %v", n, len(wb)) + } + rb := make([]byte, 128) + if n, _, _, err := p.ReadFrom(rb); err != nil { + switch runtime.GOOS { + case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } else { + if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil { + t.Fatal(err) + } else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 { + t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0) + } + } + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicastlistener_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicastlistener_test.go new file mode 100644 index 00000000..9711f751 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicastlistener_test.go @@ -0,0 +1,246 @@ +// 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 ipv6_test + +import ( + "fmt" + "net" + "runtime" + "testing" + + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +var udpMultipleGroupListenerTests = []net.Addr{ + &net.UDPAddr{IP: net.ParseIP("ff02::114")}, // see RFC 4727 + &net.UDPAddr{IP: net.ParseIP("ff02::1:114")}, + &net.UDPAddr{IP: net.ParseIP("ff02::2:114")}, +} + +func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + for _, gaddr := range udpMultipleGroupListenerTests { + c, err := net.ListenPacket("udp6", "[::]:0") // wildcard address with non-reusable port + if err != nil { + t.Fatal(err) + } + defer c.Close() + + p := ipv6.NewPacketConn(c) + var mift []*net.Interface + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + if _, ok := nettest.IsMulticastCapable("ip6", &ifi); !ok { + continue + } + if err := p.JoinGroup(&ifi, gaddr); err != nil { + t.Fatal(err) + } + mift = append(mift, &ift[i]) + } + for _, ifi := range mift { + if err := p.LeaveGroup(ifi, gaddr); err != nil { + t.Fatal(err) + } + } + } +} + +func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + for _, gaddr := range udpMultipleGroupListenerTests { + c1, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port + if err != nil { + t.Fatal(err) + } + defer c1.Close() + + c2, err := net.ListenPacket("udp6", "[ff02::]:1024") // wildcard address with reusable port + if err != nil { + t.Fatal(err) + } + defer c2.Close() + + var ps [2]*ipv6.PacketConn + ps[0] = ipv6.NewPacketConn(c1) + ps[1] = ipv6.NewPacketConn(c2) + var mift []*net.Interface + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + if _, ok := nettest.IsMulticastCapable("ip6", &ifi); !ok { + continue + } + for _, p := range ps { + if err := p.JoinGroup(&ifi, gaddr); err != nil { + t.Fatal(err) + } + } + mift = append(mift, &ift[i]) + } + for _, ifi := range mift { + for _, p := range ps { + if err := p.LeaveGroup(ifi, gaddr); err != nil { + t.Fatal(err) + } + } + } + } +} + +func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727 + type ml struct { + c *ipv6.PacketConn + ifi *net.Interface + } + var mlt []*ml + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + ip, ok := nettest.IsMulticastCapable("ip6", &ifi) + if !ok { + continue + } + c, err := net.ListenPacket("udp6", fmt.Sprintf("[%s%%%s]:1024", ip.String(), ifi.Name)) // unicast address with non-reusable port + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + if err := p.JoinGroup(&ifi, &gaddr); err != nil { + t.Fatal(err) + } + mlt = append(mlt, &ml{p, &ift[i]}) + } + for _, m := range mlt { + if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { + t.Fatal(err) + } + } +} + +func TestIPSinglePacketConnWithSingleGroupListener(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + c, err := net.ListenPacket("ip6:ipv6-icmp", "::") // wildcard address + if err != nil { + t.Fatal(err) + } + defer c.Close() + + p := ipv6.NewPacketConn(c) + gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727 + var mift []*net.Interface + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + if _, ok := nettest.IsMulticastCapable("ip6", &ifi); !ok { + continue + } + if err := p.JoinGroup(&ifi, &gaddr); err != nil { + t.Fatal(err) + } + mift = append(mift, &ift[i]) + } + for _, ifi := range mift { + if err := p.LeaveGroup(ifi, &gaddr); err != nil { + t.Fatal(err) + } + } +} + +func TestIPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) { + switch runtime.GOOS { + case "darwin", "dragonfly", "openbsd": // platforms that return fe80::1%lo0: bind: can't assign requested address + t.Skipf("not supported on %s", runtime.GOOS) + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + gaddr := net.IPAddr{IP: net.ParseIP("ff02::114")} // see RFC 4727 + type ml struct { + c *ipv6.PacketConn + ifi *net.Interface + } + var mlt []*ml + + ift, err := net.Interfaces() + if err != nil { + t.Fatal(err) + } + for i, ifi := range ift { + ip, ok := nettest.IsMulticastCapable("ip6", &ifi) + if !ok { + continue + } + c, err := net.ListenPacket("ip6:ipv6-icmp", fmt.Sprintf("%s%%%s", ip.String(), ifi.Name)) // unicast address + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + if err := p.JoinGroup(&ifi, &gaddr); err != nil { + t.Fatal(err) + } + mlt = append(mlt, &ml{p, &ift[i]}) + } + for _, m := range mlt { + if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil { + t.Fatal(err) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicastsockopt_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicastsockopt_test.go new file mode 100644 index 00000000..fe0e6e1b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/multicastsockopt_test.go @@ -0,0 +1,157 @@ +// 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 ipv6_test + +import ( + "net" + "runtime" + "testing" + + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +var packetConnMulticastSocketOptionTests = []struct { + net, proto, addr string + grp, src net.Addr +}{ + {"udp6", "", "[ff02::]:0", &net.UDPAddr{IP: net.ParseIP("ff02::114")}, nil}, // see RFC 4727 + {"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff02::115")}, nil}, // see RFC 4727 + + {"udp6", "", "[ff30::8000:0]:0", &net.UDPAddr{IP: net.ParseIP("ff30::8000:1")}, &net.UDPAddr{IP: net.IPv6loopback}}, // see RFC 5771 + {"ip6", ":ipv6-icmp", "::", &net.IPAddr{IP: net.ParseIP("ff30::8000:2")}, &net.IPAddr{IP: net.IPv6loopback}}, // see RFC 5771 +} + +func TestPacketConnMulticastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagMulticast|net.FlagLoopback) + if ifi == nil { + t.Skipf("not available on %s", runtime.GOOS) + } + + m, ok := nettest.SupportsRawIPSocket() + for _, tt := range packetConnMulticastSocketOptionTests { + if tt.net == "ip6" && !ok { + t.Log(m) + continue + } + c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + defer p.Close() + + if tt.src == nil { + testMulticastSocketOptions(t, p, ifi, tt.grp) + } else { + testSourceSpecificMulticastSocketOptions(t, p, ifi, tt.grp, tt.src) + } + } +} + +type testIPv6MulticastConn interface { + MulticastHopLimit() (int, error) + SetMulticastHopLimit(ttl int) error + MulticastLoopback() (bool, error) + SetMulticastLoopback(bool) error + JoinGroup(*net.Interface, net.Addr) error + LeaveGroup(*net.Interface, net.Addr) error + JoinSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error + LeaveSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error + ExcludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error + IncludeSourceSpecificGroup(*net.Interface, net.Addr, net.Addr) error +} + +func testMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp net.Addr) { + const hoplim = 255 + if err := c.SetMulticastHopLimit(hoplim); err != nil { + t.Error(err) + return + } + if v, err := c.MulticastHopLimit(); err != nil { + t.Error(err) + return + } else if v != hoplim { + t.Errorf("got %v; want %v", v, hoplim) + return + } + + for _, toggle := range []bool{true, false} { + if err := c.SetMulticastLoopback(toggle); err != nil { + t.Error(err) + return + } + if v, err := c.MulticastLoopback(); err != nil { + t.Error(err) + return + } else if v != toggle { + t.Errorf("got %v; want %v", v, toggle) + return + } + } + + if err := c.JoinGroup(ifi, grp); err != nil { + t.Error(err) + return + } + if err := c.LeaveGroup(ifi, grp); err != nil { + t.Error(err) + return + } +} + +func testSourceSpecificMulticastSocketOptions(t *testing.T, c testIPv6MulticastConn, ifi *net.Interface, grp, src net.Addr) { + // MCAST_JOIN_GROUP -> MCAST_BLOCK_SOURCE -> MCAST_UNBLOCK_SOURCE -> MCAST_LEAVE_GROUP + if err := c.JoinGroup(ifi, grp); err != nil { + t.Error(err) + return + } + if err := c.ExcludeSourceSpecificGroup(ifi, grp, src); err != nil { + switch runtime.GOOS { + case "freebsd", "linux": + default: // platforms that don't support MLDv2 fail here + t.Logf("not supported on %s", runtime.GOOS) + return + } + t.Error(err) + return + } + if err := c.IncludeSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + if err := c.LeaveGroup(ifi, grp); err != nil { + t.Error(err) + return + } + + // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_SOURCE_GROUP + if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + if err := c.LeaveSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + + // MCAST_JOIN_SOURCE_GROUP -> MCAST_LEAVE_GROUP + if err := c.JoinSourceSpecificGroup(ifi, grp, src); err != nil { + t.Error(err) + return + } + if err := c.LeaveGroup(ifi, grp); err != nil { + t.Error(err) + return + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload.go new file mode 100644 index 00000000..529b20bc --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload.go @@ -0,0 +1,15 @@ +// 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 ipv6 + +import "net" + +// A payloadHandler represents the IPv6 datagram payload handler. +type payloadHandler struct { + net.PacketConn + rawOpt +} + +func (c *payloadHandler) ok() bool { return c != nil && c.PacketConn != nil } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload_cmsg.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload_cmsg.go new file mode 100644 index 00000000..8e90d324 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload_cmsg.go @@ -0,0 +1,70 @@ +// 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 !nacl,!plan9,!windows + +package ipv6 + +import ( + "net" + "syscall" +) + +// ReadFrom reads a payload of the received IPv6 datagram, from the +// endpoint c, copying the payload into b. It returns the number of +// bytes copied into b, the control message cm and the source address +// src of the received datagram. +func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { + if !c.ok() { + return 0, nil, nil, syscall.EINVAL + } + oob := newControlMessage(&c.rawOpt) + var oobn int + switch c := c.PacketConn.(type) { + case *net.UDPConn: + if n, oobn, _, src, err = c.ReadMsgUDP(b, oob); err != nil { + return 0, nil, nil, err + } + case *net.IPConn: + if n, oobn, _, src, err = c.ReadMsgIP(b, oob); err != nil { + return 0, nil, nil, err + } + default: + return 0, nil, nil, errInvalidConnType + } + if cm, err = parseControlMessage(oob[:oobn]); err != nil { + return 0, nil, nil, err + } + if cm != nil { + cm.Src = netAddrToIP16(src) + } + return +} + +// WriteTo writes a payload of the IPv6 datagram, to the destination +// address dst through the endpoint c, copying the payload from b. It +// returns the number of bytes written. The control message cm allows +// the IPv6 header fields and the datagram path to be specified. The +// cm may be nil if control of the outgoing datagram is not required. +func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { + if !c.ok() { + return 0, syscall.EINVAL + } + oob := marshalControlMessage(cm) + if dst == nil { + return 0, errMissingAddress + } + switch c := c.PacketConn.(type) { + case *net.UDPConn: + n, _, err = c.WriteMsgUDP(b, oob, dst.(*net.UDPAddr)) + case *net.IPConn: + n, _, err = c.WriteMsgIP(b, oob, dst.(*net.IPAddr)) + default: + return 0, errInvalidConnType + } + if err != nil { + return 0, err + } + return +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload_nocmsg.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload_nocmsg.go new file mode 100644 index 00000000..499204d0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/payload_nocmsg.go @@ -0,0 +1,41 @@ +// 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 nacl plan9 windows + +package ipv6 + +import ( + "net" + "syscall" +) + +// ReadFrom reads a payload of the received IPv6 datagram, from the +// endpoint c, copying the payload into b. It returns the number of +// bytes copied into b, the control message cm and the source address +// src of the received datagram. +func (c *payloadHandler) ReadFrom(b []byte) (n int, cm *ControlMessage, src net.Addr, err error) { + if !c.ok() { + return 0, nil, nil, syscall.EINVAL + } + if n, src, err = c.PacketConn.ReadFrom(b); err != nil { + return 0, nil, nil, err + } + return +} + +// WriteTo writes a payload of the IPv6 datagram, to the destination +// address dst through the endpoint c, copying the payload from b. It +// returns the number of bytes written. The control message cm allows +// the IPv6 header fields and the datagram path to be specified. The +// cm may be nil if control of the outgoing datagram is not required. +func (c *payloadHandler) WriteTo(b []byte, cm *ControlMessage, dst net.Addr) (n int, err error) { + if !c.ok() { + return 0, syscall.EINVAL + } + if dst == nil { + return 0, errMissingAddress + } + return c.PacketConn.WriteTo(b, dst) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/readwrite_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/readwrite_test.go new file mode 100644 index 00000000..8c8c6fde --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/readwrite_test.go @@ -0,0 +1,189 @@ +// 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 ipv6_test + +import ( + "bytes" + "net" + "runtime" + "strings" + "sync" + "testing" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +func benchmarkUDPListener() (net.PacketConn, net.Addr, error) { + c, err := net.ListenPacket("udp6", "[::1]:0") + if err != nil { + return nil, nil, err + } + dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String()) + if err != nil { + c.Close() + return nil, nil, err + } + return c, dst, nil +} + +func BenchmarkReadWriteNetUDP(b *testing.B) { + if !supportsIPv6 { + b.Skip("ipv6 is not supported") + } + + c, dst, err := benchmarkUDPListener() + if err != nil { + b.Fatal(err) + } + defer c.Close() + + wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128) + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchmarkReadWriteNetUDP(b, c, wb, rb, dst) + } +} + +func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) { + if _, err := c.WriteTo(wb, dst); err != nil { + b.Fatal(err) + } + if _, _, err := c.ReadFrom(rb); err != nil { + b.Fatal(err) + } +} + +func BenchmarkReadWriteIPv6UDP(b *testing.B) { + if !supportsIPv6 { + b.Skip("ipv6 is not supported") + } + + c, dst, err := benchmarkUDPListener() + if err != nil { + b.Fatal(err) + } + defer c.Close() + + p := ipv6.NewPacketConn(c) + cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU + if err := p.SetControlMessage(cf, true); err != nil { + b.Fatal(err) + } + ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback) + + wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128) + b.ResetTimer() + for i := 0; i < b.N; i++ { + benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi) + } +} + +func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) { + cm := ipv6.ControlMessage{ + TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, + HopLimit: 1, + } + if ifi != nil { + cm.IfIndex = ifi.Index + } + if n, err := p.WriteTo(wb, &cm, dst); err != nil { + b.Fatal(err) + } else if n != len(wb) { + b.Fatalf("got %v; want %v", n, len(wb)) + } + if _, _, _, err := p.ReadFrom(rb); err != nil { + b.Fatal(err) + } +} + +func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + c, err := net.ListenPacket("udp6", "[::1]:0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + defer p.Close() + + dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String()) + if err != nil { + t.Fatal(err) + } + + ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback) + cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU + wb := []byte("HELLO-R-U-THERE") + + if err := p.SetControlMessage(cf, true); err != nil { // probe before test + if nettest.ProtocolNotSupported(err) { + t.Skipf("not supported on %s", runtime.GOOS) + } + t.Fatal(err) + } + + var wg sync.WaitGroup + reader := func() { + defer wg.Done() + rb := make([]byte, 128) + if n, cm, _, err := p.ReadFrom(rb); err != nil { + t.Error(err) + return + } else if !bytes.Equal(rb[:n], wb) { + t.Errorf("got %v; want %v", rb[:n], wb) + return + } else { + s := cm.String() + if strings.Contains(s, ",") { + t.Errorf("should be space-separated values: %s", s) + } + } + } + writer := func(toggle bool) { + defer wg.Done() + cm := ipv6.ControlMessage{ + TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, + Src: net.IPv6loopback, + } + if ifi != nil { + cm.IfIndex = ifi.Index + } + if err := p.SetControlMessage(cf, toggle); err != nil { + t.Error(err) + return + } + if n, err := p.WriteTo(wb, &cm, dst); err != nil { + t.Error(err) + return + } else if n != len(wb) { + t.Errorf("got %v; want %v", n, len(wb)) + return + } + } + + const N = 10 + wg.Add(N) + for i := 0; i < N; i++ { + go reader() + } + wg.Add(2 * N) + for i := 0; i < 2*N; i++ { + go writer(i%2 != 0) + } + wg.Add(N) + for i := 0; i < N; i++ { + go reader() + } + wg.Wait() +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt.go new file mode 100644 index 00000000..f0cfc2f9 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt.go @@ -0,0 +1,46 @@ +// 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. + +package ipv6 + +// Sticky socket options +const ( + ssoTrafficClass = iota // header field for unicast packet, RFC 3542 + ssoHopLimit // header field for unicast packet, RFC 3493 + ssoMulticastInterface // outbound interface for multicast packet, RFC 3493 + ssoMulticastHopLimit // header field for multicast packet, RFC 3493 + ssoMulticastLoopback // loopback for multicast packet, RFC 3493 + ssoReceiveTrafficClass // header field on received packet, RFC 3542 + ssoReceiveHopLimit // header field on received packet, RFC 2292 or 3542 + ssoReceivePacketInfo // incbound or outbound packet path, RFC 2292 or 3542 + ssoReceivePathMTU // path mtu, RFC 3542 + ssoPathMTU // path mtu, RFC 3542 + ssoChecksum // packet checksum, RFC 2292 or 3542 + ssoICMPFilter // icmp filter, RFC 2292 or 3542 + ssoJoinGroup // any-source multicast, RFC 3493 + ssoLeaveGroup // any-source multicast, RFC 3493 + ssoJoinSourceGroup // source-specific multicast + ssoLeaveSourceGroup // source-specific multicast + ssoBlockSourceGroup // any-source or source-specific multicast + ssoUnblockSourceGroup // any-source or source-specific multicast + ssoMax +) + +// Sticky socket option value types +const ( + ssoTypeInt = iota + 1 + ssoTypeInterface + ssoTypeICMPFilter + ssoTypeMTUInfo + ssoTypeIPMreq + ssoTypeGroupReq + ssoTypeGroupSourceReq +) + +// A sockOpt represents a binding for sticky socket option. +type sockOpt struct { + level int // option level + name int // option name, must be equal or greater than 1 + typ int // option value type, must be equal or greater than 1 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_asmreq_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_asmreq_unix.go new file mode 100644 index 00000000..b7fd4fe6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_asmreq_unix.go @@ -0,0 +1,22 @@ +// 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 dragonfly freebsd linux netbsd openbsd + +package ipv6 + +import ( + "net" + "os" + "unsafe" +) + +func setsockoptIPMreq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + var mreq sysIPv6Mreq + copy(mreq.Multiaddr[:], grp) + if ifi != nil { + mreq.setIfindex(ifi.Index) + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mreq), sysSizeofIPv6Mreq)) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_asmreq_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_asmreq_windows.go new file mode 100644 index 00000000..c03c7313 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_asmreq_windows.go @@ -0,0 +1,21 @@ +// 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 ipv6 + +import ( + "net" + "os" + "syscall" + "unsafe" +) + +func setsockoptIPMreq(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + var mreq sysIPv6Mreq + copy(mreq.Multiaddr[:], grp) + if ifi != nil { + mreq.setIfindex(ifi.Index) + } + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&mreq)), sysSizeofIPv6Mreq)) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_ssmreq_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_ssmreq_stub.go new file mode 100644 index 00000000..7732e49f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_ssmreq_stub.go @@ -0,0 +1,17 @@ +// 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. + +// +build !darwin,!freebsd,!linux + +package ipv6 + +import "net" + +func setsockoptGroupReq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + return errOpNoSupport +} + +func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error { + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_ssmreq_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_ssmreq_unix.go new file mode 100644 index 00000000..c64d6d58 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_ssmreq_unix.go @@ -0,0 +1,59 @@ +// 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. + +// +build darwin freebsd linux + +package ipv6 + +import ( + "net" + "os" + "unsafe" +) + +var freebsd32o64 bool + +func setsockoptGroupReq(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + var gr sysGroupReq + if ifi != nil { + gr.Interface = uint32(ifi.Index) + } + gr.setGroup(grp) + var p unsafe.Pointer + var l sysSockoptLen + if freebsd32o64 { + var d [sysSizeofGroupReq + 4]byte + s := (*[sysSizeofGroupReq]byte)(unsafe.Pointer(&gr)) + copy(d[:4], s[:4]) + copy(d[8:], s[4:]) + p = unsafe.Pointer(&d[0]) + l = sysSizeofGroupReq + 4 + } else { + p = unsafe.Pointer(&gr) + l = sysSizeofGroupReq + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l)) +} + +func setsockoptGroupSourceReq(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error { + var gsr sysGroupSourceReq + if ifi != nil { + gsr.Interface = uint32(ifi.Index) + } + gsr.setSourceGroup(grp, src) + var p unsafe.Pointer + var l sysSockoptLen + if freebsd32o64 { + var d [sysSizeofGroupSourceReq + 4]byte + s := (*[sysSizeofGroupSourceReq]byte)(unsafe.Pointer(&gsr)) + copy(d[:4], s[:4]) + copy(d[8:], s[4:]) + p = unsafe.Pointer(&d[0]) + l = sysSizeofGroupSourceReq + 4 + } else { + p = unsafe.Pointer(&gsr) + l = sysSizeofGroupSourceReq + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, p, l)) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_stub.go new file mode 100644 index 00000000..b8dacfde --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_stub.go @@ -0,0 +1,13 @@ +// 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 nacl plan9 solaris + +package ipv6 + +import "net" + +func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) { + return nil, 0, errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_test.go new file mode 100644 index 00000000..9c219031 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_test.go @@ -0,0 +1,133 @@ +// 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 ipv6_test + +import ( + "fmt" + "net" + "runtime" + "testing" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +var supportsIPv6 bool = nettest.SupportsIPv6() + +func TestConnInitiatorPathMTU(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + ln, err := net.Listen("tcp6", "[::1]:0") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + + done := make(chan bool) + go acceptor(t, ln, done) + + c, err := net.Dial("tcp6", ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil { + switch runtime.GOOS { + case "darwin": // older darwin kernels don't support IPV6_PATHMTU option + t.Logf("not supported on %s", runtime.GOOS) + default: + t.Fatal(err) + } + } else { + t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu) + } + + <-done +} + +func TestConnResponderPathMTU(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + ln, err := net.Listen("tcp6", "[::1]:0") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + + done := make(chan bool) + go connector(t, "tcp6", ln.Addr().String(), done) + + c, err := ln.Accept() + if err != nil { + t.Fatal(err) + } + defer c.Close() + + if pmtu, err := ipv6.NewConn(c).PathMTU(); err != nil { + switch runtime.GOOS { + case "darwin": // older darwin kernels don't support IPV6_PATHMTU option + t.Logf("not supported on %s", runtime.GOOS) + default: + t.Fatal(err) + } + } else { + t.Logf("path mtu for %v: %v", c.RemoteAddr(), pmtu) + } + + <-done +} + +func TestPacketConnChecksum(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + c, err := net.ListenPacket(fmt.Sprintf("ip6:%d", iana.ProtocolOSPFIGP), "::") // OSPF for IPv6 + if err != nil { + t.Fatal(err) + } + defer c.Close() + + p := ipv6.NewPacketConn(c) + offset := 12 // see RFC 5340 + + for _, toggle := range []bool{false, true} { + if err := p.SetChecksum(toggle, offset); err != nil { + if toggle { + t.Fatalf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err) + } else { + // Some platforms never allow to disable the kernel + // checksum processing. + t.Logf("ipv6.PacketConn.SetChecksum(%v, %v) failed: %v", toggle, offset, err) + } + } + if on, offset, err := p.Checksum(); err != nil { + t.Fatal(err) + } else { + t.Logf("kernel checksum processing enabled=%v, offset=%v", on, offset) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_unix.go new file mode 100644 index 00000000..25ea545f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_unix.go @@ -0,0 +1,122 @@ +// 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 dragonfly freebsd linux netbsd openbsd + +package ipv6 + +import ( + "net" + "os" + "unsafe" +) + +func getInt(fd int, opt *sockOpt) (int, error) { + if opt.name < 1 || opt.typ != ssoTypeInt { + return 0, errOpNoSupport + } + var i int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil { + return 0, os.NewSyscallError("getsockopt", err) + } + return int(i), nil +} + +func setInt(fd int, opt *sockOpt, v int) error { + if opt.name < 1 || opt.typ != ssoTypeInt { + return errOpNoSupport + } + i := int32(v) + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4))) +} + +func getInterface(fd int, opt *sockOpt) (*net.Interface, error) { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return nil, errOpNoSupport + } + var i int32 + l := sysSockoptLen(4) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + if i == 0 { + return nil, nil + } + ifi, err := net.InterfaceByIndex(int(i)) + if err != nil { + return nil, err + } + return ifi, nil +} + +func setInterface(fd int, opt *sockOpt, ifi *net.Interface) error { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return errOpNoSupport + } + var i int32 + if ifi != nil { + i = int32(ifi.Index) + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&i), sysSockoptLen(4))) +} + +func getICMPFilter(fd int, opt *sockOpt) (*ICMPFilter, error) { + if opt.name < 1 || opt.typ != ssoTypeICMPFilter { + return nil, errOpNoSupport + } + var f ICMPFilter + l := sysSockoptLen(sysSizeofICMPv6Filter) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + return &f, nil +} + +func setICMPFilter(fd int, opt *sockOpt, f *ICMPFilter) error { + if opt.name < 1 || opt.typ != ssoTypeICMPFilter { + return errOpNoSupport + } + return os.NewSyscallError("setsockopt", setsockopt(fd, opt.level, opt.name, unsafe.Pointer(&f.sysICMPv6Filter), sysSizeofICMPv6Filter)) +} + +func getMTUInfo(fd int, opt *sockOpt) (*net.Interface, int, error) { + if opt.name < 1 || opt.typ != ssoTypeMTUInfo { + return nil, 0, errOpNoSupport + } + var mi sysIPv6Mtuinfo + l := sysSockoptLen(sysSizeofIPv6Mtuinfo) + if err := getsockopt(fd, opt.level, opt.name, unsafe.Pointer(&mi), &l); err != nil { + return nil, 0, os.NewSyscallError("getsockopt", err) + } + if mi.Addr.Scope_id == 0 { + return nil, int(mi.Mtu), nil + } + ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id)) + if err != nil { + return nil, 0, err + } + return ifi, int(mi.Mtu), nil +} + +func setGroup(fd int, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + if opt.name < 1 { + return errOpNoSupport + } + switch opt.typ { + case ssoTypeIPMreq: + return setsockoptIPMreq(fd, opt, ifi, grp) + case ssoTypeGroupReq: + return setsockoptGroupReq(fd, opt, ifi, grp) + default: + return errOpNoSupport + } +} + +func setSourceGroup(fd int, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error { + if opt.name < 1 || opt.typ != ssoTypeGroupSourceReq { + return errOpNoSupport + } + return setsockoptGroupSourceReq(fd, opt, ifi, grp, src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_windows.go new file mode 100644 index 00000000..32c73b72 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sockopt_windows.go @@ -0,0 +1,86 @@ +// 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 ipv6 + +import ( + "net" + "os" + "syscall" + "unsafe" +) + +func getInt(fd syscall.Handle, opt *sockOpt) (int, error) { + if opt.name < 1 || opt.typ != ssoTypeInt { + return 0, errOpNoSupport + } + var i int32 + l := int32(4) + if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil { + return 0, os.NewSyscallError("getsockopt", err) + } + return int(i), nil +} + +func setInt(fd syscall.Handle, opt *sockOpt, v int) error { + if opt.name < 1 || opt.typ != ssoTypeInt { + return errOpNoSupport + } + i := int32(v) + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4)) +} + +func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return nil, errOpNoSupport + } + var i int32 + l := int32(4) + if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil { + return nil, os.NewSyscallError("getsockopt", err) + } + if i == 0 { + return nil, nil + } + ifi, err := net.InterfaceByIndex(int(i)) + if err != nil { + return nil, err + } + return ifi, nil +} + +func setInterface(fd syscall.Handle, opt *sockOpt, ifi *net.Interface) error { + if opt.name < 1 || opt.typ != ssoTypeInterface { + return errOpNoSupport + } + var i int32 + if ifi != nil { + i = int32(ifi.Index) + } + return os.NewSyscallError("setsockopt", syscall.Setsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), 4)) +} + +func getICMPFilter(fd syscall.Handle, opt *sockOpt) (*ICMPFilter, error) { + return nil, errOpNoSupport +} + +func setICMPFilter(fd syscall.Handle, opt *sockOpt, f *ICMPFilter) error { + return errOpNoSupport +} + +func getMTUInfo(fd syscall.Handle, opt *sockOpt) (*net.Interface, int, error) { + return nil, 0, errOpNoSupport +} + +func setGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp net.IP) error { + if opt.name < 1 || opt.typ != ssoTypeIPMreq { + return errOpNoSupport + } + return setsockoptIPMreq(fd, opt, ifi, grp) +} + +func setSourceGroup(fd syscall.Handle, opt *sockOpt, ifi *net.Interface, grp, src net.IP) error { + // TODO(mikio): implement this + return errOpNoSupport +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_bsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_bsd.go new file mode 100644 index 00000000..75a8863b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_bsd.go @@ -0,0 +1,58 @@ +// 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 dragonfly netbsd openbsd + +package ipv6 + +import ( + "net" + "syscall" + + "golang.org/x/net/internal/iana" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}, + ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}, + ctlPacketInfo: {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}, + ctlNextHop: {sysIPV6_NEXTHOP, sysSizeofSockaddrInet6, marshalNextHop, parseNextHop}, + ctlPathMTU: {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTrafficClass: {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt}, + ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt}, + ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt}, + ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt}, + ssoReceivePathMTU: {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt}, + ssoPathMTU: {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo}, + ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt}, + ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq}, + ssoLeaveGroup: {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq}, + } +) + +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], ip) + sa.Scope_id = uint32(i) +} + +func (pi *sysInet6Pktinfo) setIfindex(i int) { + pi.Ifindex = uint32(i) +} + +func (mreq *sysIPv6Mreq) setIfindex(i int) { + mreq.Interface = uint32(i) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_darwin.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_darwin.go new file mode 100644 index 00000000..411fb498 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_darwin.go @@ -0,0 +1,135 @@ +// 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 ipv6 + +import ( + "net" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlHopLimit: {sysIPV6_2292HOPLIMIT, 4, marshal2292HopLimit, parseHopLimit}, + ctlPacketInfo: {sysIPV6_2292PKTINFO, sysSizeofInet6Pktinfo, marshal2292PacketInfo, parsePacketInfo}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_2292HOPLIMIT, ssoTypeInt}, + ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_2292PKTINFO, ssoTypeInt}, + ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt}, + ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq}, + ssoLeaveGroup: {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq}, + } +) + +func init() { + // Seems like kern.osreldate is veiled on latest OS X. We use + // kern.osrelease instead. + osver, err := syscall.Sysctl("kern.osrelease") + if err != nil { + return + } + var i int + for i = range osver { + if osver[i] == '.' { + break + } + } + // The IP_PKTINFO and protocol-independent multicast API were + // introduced in OS X 10.7 (Darwin 11.0.0). But it looks like + // those features require OS X 10.8 (Darwin 12.0.0) and above. + // See http://support.apple.com/kb/HT1633. + if i > 2 || i == 2 && osver[0] >= '1' && osver[1] >= '2' { + ctlOpts[ctlTrafficClass].name = sysIPV6_TCLASS + ctlOpts[ctlTrafficClass].length = 4 + ctlOpts[ctlTrafficClass].marshal = marshalTrafficClass + ctlOpts[ctlTrafficClass].parse = parseTrafficClass + ctlOpts[ctlHopLimit].name = sysIPV6_HOPLIMIT + ctlOpts[ctlHopLimit].marshal = marshalHopLimit + ctlOpts[ctlPacketInfo].name = sysIPV6_PKTINFO + ctlOpts[ctlPacketInfo].marshal = marshalPacketInfo + ctlOpts[ctlNextHop].name = sysIPV6_NEXTHOP + ctlOpts[ctlNextHop].length = sysSizeofSockaddrInet6 + ctlOpts[ctlNextHop].marshal = marshalNextHop + ctlOpts[ctlNextHop].parse = parseNextHop + ctlOpts[ctlPathMTU].name = sysIPV6_PATHMTU + ctlOpts[ctlPathMTU].length = sysSizeofIPv6Mtuinfo + ctlOpts[ctlPathMTU].marshal = marshalPathMTU + ctlOpts[ctlPathMTU].parse = parsePathMTU + sockOpts[ssoTrafficClass].level = iana.ProtocolIPv6 + sockOpts[ssoTrafficClass].name = sysIPV6_TCLASS + sockOpts[ssoTrafficClass].typ = ssoTypeInt + sockOpts[ssoReceiveTrafficClass].level = iana.ProtocolIPv6 + sockOpts[ssoReceiveTrafficClass].name = sysIPV6_RECVTCLASS + sockOpts[ssoReceiveTrafficClass].typ = ssoTypeInt + sockOpts[ssoReceiveHopLimit].name = sysIPV6_RECVHOPLIMIT + sockOpts[ssoReceivePacketInfo].name = sysIPV6_RECVPKTINFO + sockOpts[ssoReceivePathMTU].level = iana.ProtocolIPv6 + sockOpts[ssoReceivePathMTU].name = sysIPV6_RECVPATHMTU + sockOpts[ssoReceivePathMTU].typ = ssoTypeInt + sockOpts[ssoPathMTU].level = iana.ProtocolIPv6 + sockOpts[ssoPathMTU].name = sysIPV6_PATHMTU + sockOpts[ssoPathMTU].typ = ssoTypeMTUInfo + sockOpts[ssoJoinGroup].name = sysMCAST_JOIN_GROUP + sockOpts[ssoJoinGroup].typ = ssoTypeGroupReq + sockOpts[ssoLeaveGroup].name = sysMCAST_LEAVE_GROUP + sockOpts[ssoLeaveGroup].typ = ssoTypeGroupReq + sockOpts[ssoJoinSourceGroup].level = iana.ProtocolIPv6 + sockOpts[ssoJoinSourceGroup].name = sysMCAST_JOIN_SOURCE_GROUP + sockOpts[ssoJoinSourceGroup].typ = ssoTypeGroupSourceReq + sockOpts[ssoLeaveSourceGroup].level = iana.ProtocolIPv6 + sockOpts[ssoLeaveSourceGroup].name = sysMCAST_LEAVE_SOURCE_GROUP + sockOpts[ssoLeaveSourceGroup].typ = ssoTypeGroupSourceReq + sockOpts[ssoBlockSourceGroup].level = iana.ProtocolIPv6 + sockOpts[ssoBlockSourceGroup].name = sysMCAST_BLOCK_SOURCE + sockOpts[ssoBlockSourceGroup].typ = ssoTypeGroupSourceReq + sockOpts[ssoUnblockSourceGroup].level = iana.ProtocolIPv6 + sockOpts[ssoUnblockSourceGroup].name = sysMCAST_UNBLOCK_SOURCE + sockOpts[ssoUnblockSourceGroup].typ = ssoTypeGroupSourceReq + } +} + +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], ip) + sa.Scope_id = uint32(i) +} + +func (pi *sysInet6Pktinfo) setIfindex(i int) { + pi.Ifindex = uint32(i) +} + +func (mreq *sysIPv6Mreq) setIfindex(i int) { + mreq.Interface = uint32(i) +} + +func (gr *sysGroupReq) setGroup(grp net.IP) { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Pad_cgo_0[0])) + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) +} + +func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Pad_cgo_0[0])) + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) + sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Pad_cgo_1[0])) + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_freebsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_freebsd.go new file mode 100644 index 00000000..b68725cb --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_freebsd.go @@ -0,0 +1,93 @@ +// 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 ipv6 + +import ( + "net" + "runtime" + "strings" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}, + ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}, + ctlPacketInfo: {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}, + ctlNextHop: {sysIPV6_NEXTHOP, sysSizeofSockaddrInet6, marshalNextHop, parseNextHop}, + ctlPathMTU: {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTrafficClass: {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt}, + ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt}, + ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt}, + ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt}, + ssoReceivePathMTU: {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt}, + ssoPathMTU: {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo}, + ssoChecksum: {iana.ProtocolIPv6, sysIPV6_CHECKSUM, ssoTypeInt}, + ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMP6_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq}, + ssoLeaveGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq}, + ssoJoinSourceGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoLeaveSourceGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoBlockSourceGroup: {iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq}, + ssoUnblockSourceGroup: {iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq}, + } +) + +func init() { + if runtime.GOOS == "freebsd" && runtime.GOARCH == "386" { + archs, _ := syscall.Sysctl("kern.supported_archs") + for _, s := range strings.Fields(archs) { + if s == "amd64" { + freebsd32o64 = true + break + } + } + } +} + +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], ip) + sa.Scope_id = uint32(i) +} + +func (pi *sysInet6Pktinfo) setIfindex(i int) { + pi.Ifindex = uint32(i) +} + +func (mreq *sysIPv6Mreq) setIfindex(i int) { + mreq.Interface = uint32(i) +} + +func (gr *sysGroupReq) setGroup(grp net.IP) { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Group)) + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) +} + +func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Group)) + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) + sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Source)) + sa.Len = sysSizeofSockaddrInet6 + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_linux.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_linux.go new file mode 100644 index 00000000..2fa6088d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_linux.go @@ -0,0 +1,74 @@ +// 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 ipv6 + +import ( + "net" + "syscall" + "unsafe" + + "golang.org/x/net/internal/iana" +) + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{ + ctlTrafficClass: {sysIPV6_TCLASS, 4, marshalTrafficClass, parseTrafficClass}, + ctlHopLimit: {sysIPV6_HOPLIMIT, 4, marshalHopLimit, parseHopLimit}, + ctlPacketInfo: {sysIPV6_PKTINFO, sysSizeofInet6Pktinfo, marshalPacketInfo, parsePacketInfo}, + ctlPathMTU: {sysIPV6_PATHMTU, sysSizeofIPv6Mtuinfo, marshalPathMTU, parsePathMTU}, + } + + sockOpts = [ssoMax]sockOpt{ + ssoTrafficClass: {iana.ProtocolIPv6, sysIPV6_TCLASS, ssoTypeInt}, + ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoReceiveTrafficClass: {iana.ProtocolIPv6, sysIPV6_RECVTCLASS, ssoTypeInt}, + ssoReceiveHopLimit: {iana.ProtocolIPv6, sysIPV6_RECVHOPLIMIT, ssoTypeInt}, + ssoReceivePacketInfo: {iana.ProtocolIPv6, sysIPV6_RECVPKTINFO, ssoTypeInt}, + ssoReceivePathMTU: {iana.ProtocolIPv6, sysIPV6_RECVPATHMTU, ssoTypeInt}, + ssoPathMTU: {iana.ProtocolIPv6, sysIPV6_PATHMTU, ssoTypeMTUInfo}, + ssoChecksum: {iana.ProtocolReserved, sysIPV6_CHECKSUM, ssoTypeInt}, + ssoICMPFilter: {iana.ProtocolIPv6ICMP, sysICMPV6_FILTER, ssoTypeICMPFilter}, + ssoJoinGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_GROUP, ssoTypeGroupReq}, + ssoLeaveGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_GROUP, ssoTypeGroupReq}, + ssoJoinSourceGroup: {iana.ProtocolIPv6, sysMCAST_JOIN_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoLeaveSourceGroup: {iana.ProtocolIPv6, sysMCAST_LEAVE_SOURCE_GROUP, ssoTypeGroupSourceReq}, + ssoBlockSourceGroup: {iana.ProtocolIPv6, sysMCAST_BLOCK_SOURCE, ssoTypeGroupSourceReq}, + ssoUnblockSourceGroup: {iana.ProtocolIPv6, sysMCAST_UNBLOCK_SOURCE, ssoTypeGroupSourceReq}, + } +) + +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], ip) + sa.Scope_id = uint32(i) +} + +func (pi *sysInet6Pktinfo) setIfindex(i int) { + pi.Ifindex = int32(i) +} + +func (mreq *sysIPv6Mreq) setIfindex(i int) { + mreq.Ifindex = int32(i) +} + +func (gr *sysGroupReq) setGroup(grp net.IP) { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&gr.Group)) + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) +} + +func (gsr *sysGroupSourceReq) setSourceGroup(grp, src net.IP) { + sa := (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Group)) + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], grp) + sa = (*sysSockaddrInet6)(unsafe.Pointer(&gsr.Source)) + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], src) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_stub.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_stub.go new file mode 100644 index 00000000..6c9a1430 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_stub.go @@ -0,0 +1,15 @@ +// 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. + +// +build nacl plan9 solaris + +package ipv6 + +type sysSockoptLen int32 + +var ( + ctlOpts = [ctlMax]ctlOpt{} + + sockOpts = [ssoMax]sockOpt{} +) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_windows.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_windows.go new file mode 100644 index 00000000..fda87573 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/sys_windows.go @@ -0,0 +1,63 @@ +// 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 ipv6 + +import ( + "net" + "syscall" + + "golang.org/x/net/internal/iana" +) + +const ( + // See ws2tcpip.h. + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PKTINFO = 0x13 + + sysSizeofSockaddrInet6 = 0x1c + + sysSizeofIPv6Mreq = 0x14 +) + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +var ( + ctlOpts = [ctlMax]ctlOpt{} + + sockOpts = [ssoMax]sockOpt{ + ssoHopLimit: {iana.ProtocolIPv6, sysIPV6_UNICAST_HOPS, ssoTypeInt}, + ssoMulticastInterface: {iana.ProtocolIPv6, sysIPV6_MULTICAST_IF, ssoTypeInterface}, + ssoMulticastHopLimit: {iana.ProtocolIPv6, sysIPV6_MULTICAST_HOPS, ssoTypeInt}, + ssoMulticastLoopback: {iana.ProtocolIPv6, sysIPV6_MULTICAST_LOOP, ssoTypeInt}, + ssoJoinGroup: {iana.ProtocolIPv6, sysIPV6_JOIN_GROUP, ssoTypeIPMreq}, + ssoLeaveGroup: {iana.ProtocolIPv6, sysIPV6_LEAVE_GROUP, ssoTypeIPMreq}, + } +) + +func (sa *sysSockaddrInet6) setSockaddr(ip net.IP, i int) { + sa.Family = syscall.AF_INET6 + copy(sa.Addr[:], ip) + sa.Scope_id = uint32(i) +} + +func (mreq *sysIPv6Mreq) setIfindex(i int) { + mreq.Interface = uint32(i) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/syscall_linux_386.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/syscall_linux_386.go new file mode 100644 index 00000000..82633a56 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/syscall_linux_386.go @@ -0,0 +1,31 @@ +// Copyright 2009 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 ipv6 + +import ( + "syscall" + "unsafe" +) + +const ( + sysGETSOCKOPT = 0xf + sysSETSOCKOPT = 0xe +) + +func socketcall(call int, a0, a1, a2, a3, a4, a5 uintptr) (int, syscall.Errno) + +func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error { + if _, errno := socketcall(sysGETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 { + return error(errno) + } + return nil +} + +func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error { + if _, errno := socketcall(sysSETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 { + return error(errno) + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/syscall_unix.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/syscall_unix.go new file mode 100644 index 00000000..a2bd8363 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/syscall_unix.go @@ -0,0 +1,26 @@ +// 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 dragonfly freebsd linux,!386 netbsd openbsd + +package ipv6 + +import ( + "syscall" + "unsafe" +) + +func getsockopt(fd, level, name int, v unsafe.Pointer, l *sysSockoptLen) error { + if _, _, errno := syscall.Syscall6(syscall.SYS_GETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(unsafe.Pointer(l)), 0); errno != 0 { + return error(errno) + } + return nil +} + +func setsockopt(fd, level, name int, v unsafe.Pointer, l sysSockoptLen) error { + if _, _, errno := syscall.Syscall6(syscall.SYS_SETSOCKOPT, uintptr(fd), uintptr(level), uintptr(name), uintptr(v), uintptr(l), 0); errno != 0 { + return error(errno) + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/thunk_linux_386.s b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/thunk_linux_386.s new file mode 100644 index 00000000..daa78bc0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/thunk_linux_386.s @@ -0,0 +1,8 @@ +// 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. + +// +build go1.2 + +TEXT ·socketcall(SB),4,$0-36 + JMP syscall·socketcall(SB) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/unicast_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/unicast_test.go new file mode 100644 index 00000000..db5b08a2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/unicast_test.go @@ -0,0 +1,182 @@ +// 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 ipv6_test + +import ( + "bytes" + "net" + "os" + "runtime" + "testing" + "time" + + "golang.org/x/net/icmp" + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +func TestPacketConnReadWriteUnicastUDP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + c, err := net.ListenPacket("udp6", "[::1]:0") + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + defer p.Close() + + dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String()) + if err != nil { + t.Fatal(err) + } + + cm := ipv6.ControlMessage{ + TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, + Src: net.IPv6loopback, + } + cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU + ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback) + if ifi != nil { + cm.IfIndex = ifi.Index + } + wb := []byte("HELLO-R-U-THERE") + + for i, toggle := range []bool{true, false, true} { + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Skipf("not supported on %s", runtime.GOOS) + } + t.Fatal(err) + } + cm.HopLimit = i + 1 + if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, err := p.WriteTo(wb, &cm, dst); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatalf("got %v; want %v", n, len(wb)) + } + rb := make([]byte, 128) + if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, _, _, err := p.ReadFrom(rb); err != nil { + t.Fatal(err) + } else if !bytes.Equal(rb[:n], wb) { + t.Fatalf("got %v; want %v", rb[:n], wb) + } + } +} + +func TestPacketConnReadWriteUnicastICMP(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + if m, ok := nettest.SupportsRawIPSocket(); !ok { + t.Skip(m) + } + + c, err := net.ListenPacket("ip6:ipv6-icmp", "::1") + if err != nil { + t.Fatal(err) + } + defer c.Close() + p := ipv6.NewPacketConn(c) + defer p.Close() + + dst, err := net.ResolveIPAddr("ip6", "::1") + if err != nil { + t.Fatal(err) + } + + pshicmp := icmp.IPv6PseudoHeader(c.LocalAddr().(*net.IPAddr).IP, dst.IP) + cm := ipv6.ControlMessage{ + TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced, + Src: net.IPv6loopback, + } + cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU + ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback) + if ifi != nil { + cm.IfIndex = ifi.Index + } + + var f ipv6.ICMPFilter + f.SetAll(true) + f.Accept(ipv6.ICMPTypeEchoReply) + if err := p.SetICMPFilter(&f); err != nil { + t.Fatal(err) + } + + var psh []byte + for i, toggle := range []bool{true, false, true} { + if toggle { + psh = nil + if err := p.SetChecksum(true, 2); err != nil { + t.Fatal(err) + } + } else { + psh = pshicmp + // Some platforms never allow to disable the + // kernel checksum processing. + p.SetChecksum(false, -1) + } + wb, err := (&icmp.Message{ + Type: ipv6.ICMPTypeEchoRequest, Code: 0, + Body: &icmp.Echo{ + ID: os.Getpid() & 0xffff, Seq: i + 1, + Data: []byte("HELLO-R-U-THERE"), + }, + }).Marshal(psh) + if err != nil { + t.Fatal(err) + } + if err := p.SetControlMessage(cf, toggle); err != nil { + if nettest.ProtocolNotSupported(err) { + t.Skipf("not supported on %s", runtime.GOOS) + } + t.Fatal(err) + } + cm.HopLimit = i + 1 + if err := p.SetWriteDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, err := p.WriteTo(wb, &cm, dst); err != nil { + t.Fatal(err) + } else if n != len(wb) { + t.Fatalf("got %v; want %v", n, len(wb)) + } + rb := make([]byte, 128) + if err := p.SetReadDeadline(time.Now().Add(100 * time.Millisecond)); err != nil { + t.Fatal(err) + } + if n, _, _, err := p.ReadFrom(rb); err != nil { + switch runtime.GOOS { + case "darwin": // older darwin kernels have some limitation on receiving icmp packet through raw socket + t.Logf("not supported on %s", runtime.GOOS) + continue + } + t.Fatal(err) + } else { + if m, err := icmp.ParseMessage(iana.ProtocolIPv6ICMP, rb[:n]); err != nil { + t.Fatal(err) + } else if m.Type != ipv6.ICMPTypeEchoReply || m.Code != 0 { + t.Fatalf("got type=%v, code=%v; want type=%v, code=%v", m.Type, m.Code, ipv6.ICMPTypeEchoReply, 0) + } + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/unicastsockopt_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/unicastsockopt_test.go new file mode 100644 index 00000000..7bb2e440 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/unicastsockopt_test.go @@ -0,0 +1,111 @@ +// 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 ipv6_test + +import ( + "net" + "runtime" + "testing" + + "golang.org/x/net/internal/iana" + "golang.org/x/net/internal/nettest" + "golang.org/x/net/ipv6" +) + +func TestConnUnicastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + ln, err := net.Listen("tcp6", "[::1]:0") + if err != nil { + t.Fatal(err) + } + defer ln.Close() + + done := make(chan bool) + go acceptor(t, ln, done) + + c, err := net.Dial("tcp6", ln.Addr().String()) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + testUnicastSocketOptions(t, ipv6.NewConn(c)) + + <-done +} + +var packetConnUnicastSocketOptionTests = []struct { + net, proto, addr string +}{ + {"udp6", "", "[::1]:0"}, + {"ip6", ":ipv6-icmp", "::1"}, +} + +func TestPacketConnUnicastSocketOptions(t *testing.T) { + switch runtime.GOOS { + case "nacl", "plan9", "solaris", "windows": + t.Skipf("not supported on %s", runtime.GOOS) + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + + m, ok := nettest.SupportsRawIPSocket() + for _, tt := range packetConnUnicastSocketOptionTests { + if tt.net == "ip6" && !ok { + t.Log(m) + continue + } + c, err := net.ListenPacket(tt.net+tt.proto, tt.addr) + if err != nil { + t.Fatal(err) + } + defer c.Close() + + testUnicastSocketOptions(t, ipv6.NewPacketConn(c)) + } +} + +type testIPv6UnicastConn interface { + TrafficClass() (int, error) + SetTrafficClass(int) error + HopLimit() (int, error) + SetHopLimit(int) error +} + +func testUnicastSocketOptions(t *testing.T, c testIPv6UnicastConn) { + tclass := iana.DiffServCS0 | iana.NotECNTransport + if err := c.SetTrafficClass(tclass); err != nil { + switch runtime.GOOS { + case "darwin": // older darwin kernels don't support IPV6_TCLASS option + t.Logf("not supported on %s", runtime.GOOS) + goto next + } + t.Fatal(err) + } + if v, err := c.TrafficClass(); err != nil { + t.Fatal(err) + } else if v != tclass { + t.Fatalf("got %v; want %v", v, tclass) + } + +next: + hoplim := 255 + if err := c.SetHopLimit(hoplim); err != nil { + t.Fatal(err) + } + if v, err := c.HopLimit(); err != nil { + t.Fatal(err) + } else if v != hoplim { + t.Fatalf("got %v; want %v", v, hoplim) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_darwin.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_darwin.go new file mode 100644 index 00000000..cb044b03 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_darwin.go @@ -0,0 +1,131 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_darwin.go + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + + sysIPV6_PORTRANGE = 0xe + sysICMP6_FILTER = 0x12 + sysIPV6_2292PKTINFO = 0x13 + sysIPV6_2292HOPLIMIT = 0x14 + sysIPV6_2292NEXTHOP = 0x15 + sysIPV6_2292HOPOPTS = 0x16 + sysIPV6_2292DSTOPTS = 0x17 + sysIPV6_2292RTHDR = 0x18 + + sysIPV6_2292PKTOPTIONS = 0x19 + + sysIPV6_CHECKSUM = 0x1a + sysIPV6_V6ONLY = 0x1b + + sysIPV6_IPSEC_POLICY = 0x1c + + sysIPV6_RECVTCLASS = 0x23 + sysIPV6_TCLASS = 0x24 + + sysIPV6_RTHDRDSTOPTS = 0x39 + + sysIPV6_RECVPKTINFO = 0x3d + + sysIPV6_RECVHOPLIMIT = 0x25 + sysIPV6_RECVRTHDR = 0x26 + sysIPV6_RECVHOPOPTS = 0x27 + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_USE_MIN_MTU = 0x2a + sysIPV6_RECVPATHMTU = 0x2b + + sysIPV6_PATHMTU = 0x2c + + sysIPV6_PKTINFO = 0x2e + sysIPV6_HOPLIMIT = 0x2f + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x31 + sysIPV6_DSTOPTS = 0x32 + sysIPV6_RTHDR = 0x33 + + sysIPV6_AUTOFLOWLABEL = 0x3b + + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_PREFER_TEMPADDR = 0x3f + + sysIPV6_MSFILTER = 0x4a + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysIPV6_BOUND_IF = 0x7d + + sysIPV6_PORTRANGE_DEFAULT = 0x0 + sysIPV6_PORTRANGE_HIGH = 0x1 + sysIPV6_PORTRANGE_LOW = 0x2 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysICMPv6Filter struct { + Filt [8]uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [128]byte +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [128]byte + Pad_cgo_1 [128]byte +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_dragonfly.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_dragonfly.go new file mode 100644 index 00000000..5a03ab73 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_dragonfly.go @@ -0,0 +1,90 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_dragonfly.go + +// +build dragonfly + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PORTRANGE = 0xe + sysICMP6_FILTER = 0x12 + + sysIPV6_CHECKSUM = 0x1a + sysIPV6_V6ONLY = 0x1b + + sysIPV6_IPSEC_POLICY = 0x1c + + sysIPV6_RTHDRDSTOPTS = 0x23 + sysIPV6_RECVPKTINFO = 0x24 + sysIPV6_RECVHOPLIMIT = 0x25 + sysIPV6_RECVRTHDR = 0x26 + sysIPV6_RECVHOPOPTS = 0x27 + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_USE_MIN_MTU = 0x2a + sysIPV6_RECVPATHMTU = 0x2b + + sysIPV6_PATHMTU = 0x2c + + sysIPV6_PKTINFO = 0x2e + sysIPV6_HOPLIMIT = 0x2f + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x31 + sysIPV6_DSTOPTS = 0x32 + sysIPV6_RTHDR = 0x33 + + sysIPV6_RECVTCLASS = 0x39 + + sysIPV6_AUTOFLOWLABEL = 0x3b + + sysIPV6_TCLASS = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_PREFER_TEMPADDR = 0x3f + + sysIPV6_PORTRANGE_DEFAULT = 0x0 + sysIPV6_PORTRANGE_HIGH = 0x1 + sysIPV6_PORTRANGE_LOW = 0x2 + + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + + sysSizeofIPv6Mreq = 0x14 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysICMPv6Filter struct { + Filt [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_386.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_386.go new file mode 100644 index 00000000..4ace96f0 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_386.go @@ -0,0 +1,122 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_freebsd.go + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PORTRANGE = 0xe + sysICMP6_FILTER = 0x12 + + sysIPV6_CHECKSUM = 0x1a + sysIPV6_V6ONLY = 0x1b + + sysIPV6_IPSEC_POLICY = 0x1c + + sysIPV6_RTHDRDSTOPTS = 0x23 + + sysIPV6_RECVPKTINFO = 0x24 + sysIPV6_RECVHOPLIMIT = 0x25 + sysIPV6_RECVRTHDR = 0x26 + sysIPV6_RECVHOPOPTS = 0x27 + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_USE_MIN_MTU = 0x2a + sysIPV6_RECVPATHMTU = 0x2b + + sysIPV6_PATHMTU = 0x2c + + sysIPV6_PKTINFO = 0x2e + sysIPV6_HOPLIMIT = 0x2f + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x31 + sysIPV6_DSTOPTS = 0x32 + sysIPV6_RTHDR = 0x33 + + sysIPV6_RECVTCLASS = 0x39 + + sysIPV6_AUTOFLOWLABEL = 0x3b + + sysIPV6_TCLASS = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_PREFER_TEMPADDR = 0x3f + + sysIPV6_BINDANY = 0x40 + + sysIPV6_MSFILTER = 0x4a + + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysIPV6_PORTRANGE_DEFAULT = 0x0 + sysIPV6_PORTRANGE_HIGH = 0x1 + sysIPV6_PORTRANGE_LOW = 0x2 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysGroupReq struct { + Interface uint32 + Group sysSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Group sysSockaddrStorage + Source sysSockaddrStorage +} + +type sysICMPv6Filter struct { + Filt [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_amd64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_amd64.go new file mode 100644 index 00000000..4a62c2d5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_amd64.go @@ -0,0 +1,124 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_freebsd.go + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PORTRANGE = 0xe + sysICMP6_FILTER = 0x12 + + sysIPV6_CHECKSUM = 0x1a + sysIPV6_V6ONLY = 0x1b + + sysIPV6_IPSEC_POLICY = 0x1c + + sysIPV6_RTHDRDSTOPTS = 0x23 + + sysIPV6_RECVPKTINFO = 0x24 + sysIPV6_RECVHOPLIMIT = 0x25 + sysIPV6_RECVRTHDR = 0x26 + sysIPV6_RECVHOPOPTS = 0x27 + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_USE_MIN_MTU = 0x2a + sysIPV6_RECVPATHMTU = 0x2b + + sysIPV6_PATHMTU = 0x2c + + sysIPV6_PKTINFO = 0x2e + sysIPV6_HOPLIMIT = 0x2f + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x31 + sysIPV6_DSTOPTS = 0x32 + sysIPV6_RTHDR = 0x33 + + sysIPV6_RECVTCLASS = 0x39 + + sysIPV6_AUTOFLOWLABEL = 0x3b + + sysIPV6_TCLASS = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_PREFER_TEMPADDR = 0x3f + + sysIPV6_BINDANY = 0x40 + + sysIPV6_MSFILTER = 0x4a + + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysIPV6_PORTRANGE_DEFAULT = 0x0 + sysIPV6_PORTRANGE_HIGH = 0x1 + sysIPV6_PORTRANGE_LOW = 0x2 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage + Source sysSockaddrStorage +} + +type sysICMPv6Filter struct { + Filt [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_arm.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_arm.go new file mode 100644 index 00000000..4a62c2d5 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_freebsd_arm.go @@ -0,0 +1,124 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_freebsd.go + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PORTRANGE = 0xe + sysICMP6_FILTER = 0x12 + + sysIPV6_CHECKSUM = 0x1a + sysIPV6_V6ONLY = 0x1b + + sysIPV6_IPSEC_POLICY = 0x1c + + sysIPV6_RTHDRDSTOPTS = 0x23 + + sysIPV6_RECVPKTINFO = 0x24 + sysIPV6_RECVHOPLIMIT = 0x25 + sysIPV6_RECVRTHDR = 0x26 + sysIPV6_RECVHOPOPTS = 0x27 + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_USE_MIN_MTU = 0x2a + sysIPV6_RECVPATHMTU = 0x2b + + sysIPV6_PATHMTU = 0x2c + + sysIPV6_PKTINFO = 0x2e + sysIPV6_HOPLIMIT = 0x2f + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x31 + sysIPV6_DSTOPTS = 0x32 + sysIPV6_RTHDR = 0x33 + + sysIPV6_RECVTCLASS = 0x39 + + sysIPV6_AUTOFLOWLABEL = 0x3b + + sysIPV6_TCLASS = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_PREFER_TEMPADDR = 0x3f + + sysIPV6_BINDANY = 0x40 + + sysIPV6_MSFILTER = 0x4a + + sysMCAST_JOIN_GROUP = 0x50 + sysMCAST_LEAVE_GROUP = 0x51 + sysMCAST_JOIN_SOURCE_GROUP = 0x52 + sysMCAST_LEAVE_SOURCE_GROUP = 0x53 + sysMCAST_BLOCK_SOURCE = 0x54 + sysMCAST_UNBLOCK_SOURCE = 0x55 + + sysIPV6_PORTRANGE_DEFAULT = 0x0 + sysIPV6_PORTRANGE_HIGH = 0x1 + sysIPV6_PORTRANGE_LOW = 0x2 + + sysSizeofSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrStorage struct { + Len uint8 + Family uint8 + X__ss_pad1 [6]int8 + X__ss_align int64 + X__ss_pad2 [112]int8 +} + +type sysSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysSockaddrStorage + Source sysSockaddrStorage +} + +type sysICMPv6Filter struct { + Filt [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_386.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_386.go new file mode 100644 index 00000000..27279292 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_386.go @@ -0,0 +1,152 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_amd64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_amd64.go new file mode 100644 index 00000000..2f742e95 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_amd64.go @@ -0,0 +1,154 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_arm.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_arm.go new file mode 100644 index 00000000..27279292 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_arm.go @@ -0,0 +1,152 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x84 + sysSizeofGroupSourceReq = 0x104 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_arm64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_arm64.go new file mode 100644 index 00000000..ab104645 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_arm64.go @@ -0,0 +1,156 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,arm64 + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_mips64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_mips64.go new file mode 100644 index 00000000..ec8ce157 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_mips64.go @@ -0,0 +1,156 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,mips64 + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_mips64le.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_mips64le.go new file mode 100644 index 00000000..2341ae67 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_mips64le.go @@ -0,0 +1,156 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,mips64le + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_ppc64.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_ppc64.go new file mode 100644 index 00000000..b99b8a51 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_ppc64.go @@ -0,0 +1,156 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,ppc64 + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_ppc64le.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_ppc64le.go new file mode 100644 index 00000000..992b56e2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_linux_ppc64le.go @@ -0,0 +1,156 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,ppc64le + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_netbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_netbsd.go new file mode 100644 index 00000000..d6ec88e3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_netbsd.go @@ -0,0 +1,84 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_netbsd.go + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PORTRANGE = 0xe + sysICMP6_FILTER = 0x12 + + sysIPV6_CHECKSUM = 0x1a + sysIPV6_V6ONLY = 0x1b + + sysIPV6_IPSEC_POLICY = 0x1c + + sysIPV6_RTHDRDSTOPTS = 0x23 + + sysIPV6_RECVPKTINFO = 0x24 + sysIPV6_RECVHOPLIMIT = 0x25 + sysIPV6_RECVRTHDR = 0x26 + sysIPV6_RECVHOPOPTS = 0x27 + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_USE_MIN_MTU = 0x2a + sysIPV6_RECVPATHMTU = 0x2b + sysIPV6_PATHMTU = 0x2c + + sysIPV6_PKTINFO = 0x2e + sysIPV6_HOPLIMIT = 0x2f + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x31 + sysIPV6_DSTOPTS = 0x32 + sysIPV6_RTHDR = 0x33 + + sysIPV6_RECVTCLASS = 0x39 + + sysIPV6_TCLASS = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_PORTRANGE_DEFAULT = 0x0 + sysIPV6_PORTRANGE_HIGH = 0x1 + sysIPV6_PORTRANGE_LOW = 0x2 + + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + + sysSizeofIPv6Mreq = 0x14 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysICMPv6Filter struct { + Filt [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_openbsd.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_openbsd.go new file mode 100644 index 00000000..3e080b78 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_openbsd.go @@ -0,0 +1,93 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_openbsd.go + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x4 + sysIPV6_MULTICAST_IF = 0x9 + sysIPV6_MULTICAST_HOPS = 0xa + sysIPV6_MULTICAST_LOOP = 0xb + sysIPV6_JOIN_GROUP = 0xc + sysIPV6_LEAVE_GROUP = 0xd + sysIPV6_PORTRANGE = 0xe + sysICMP6_FILTER = 0x12 + + sysIPV6_CHECKSUM = 0x1a + sysIPV6_V6ONLY = 0x1b + + sysIPV6_RTHDRDSTOPTS = 0x23 + + sysIPV6_RECVPKTINFO = 0x24 + sysIPV6_RECVHOPLIMIT = 0x25 + sysIPV6_RECVRTHDR = 0x26 + sysIPV6_RECVHOPOPTS = 0x27 + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_USE_MIN_MTU = 0x2a + sysIPV6_RECVPATHMTU = 0x2b + + sysIPV6_PATHMTU = 0x2c + + sysIPV6_PKTINFO = 0x2e + sysIPV6_HOPLIMIT = 0x2f + sysIPV6_NEXTHOP = 0x30 + sysIPV6_HOPOPTS = 0x31 + sysIPV6_DSTOPTS = 0x32 + sysIPV6_RTHDR = 0x33 + + sysIPV6_AUTH_LEVEL = 0x35 + sysIPV6_ESP_TRANS_LEVEL = 0x36 + sysIPV6_ESP_NETWORK_LEVEL = 0x37 + sysIPSEC6_OUTSA = 0x38 + sysIPV6_RECVTCLASS = 0x39 + + sysIPV6_AUTOFLOWLABEL = 0x3b + sysIPV6_IPCOMP_LEVEL = 0x3c + + sysIPV6_TCLASS = 0x3d + sysIPV6_DONTFRAG = 0x3e + sysIPV6_PIPEX = 0x3f + + sysIPV6_RTABLE = 0x1021 + + sysIPV6_PORTRANGE_DEFAULT = 0x0 + sysIPV6_PORTRANGE_HIGH = 0x1 + sysIPV6_PORTRANGE_LOW = 0x2 + + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + + sysSizeofIPv6Mreq = 0x14 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrInet6 struct { + Len uint8 + Family uint8 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysICMPv6Filter struct { + Filt [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_solaris.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_solaris.go new file mode 100644 index 00000000..cdf00c25 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/ipv6/zsys_solaris.go @@ -0,0 +1,105 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_solaris.go + +// +build solaris + +package ipv6 + +const ( + sysIPV6_UNICAST_HOPS = 0x5 + sysIPV6_MULTICAST_IF = 0x6 + sysIPV6_MULTICAST_HOPS = 0x7 + sysIPV6_MULTICAST_LOOP = 0x8 + sysIPV6_JOIN_GROUP = 0x9 + sysIPV6_LEAVE_GROUP = 0xa + + sysIPV6_PKTINFO = 0xb + + sysIPV6_HOPLIMIT = 0xc + sysIPV6_NEXTHOP = 0xd + sysIPV6_HOPOPTS = 0xe + sysIPV6_DSTOPTS = 0xf + + sysIPV6_RTHDR = 0x10 + sysIPV6_RTHDRDSTOPTS = 0x11 + + sysIPV6_RECVPKTINFO = 0x12 + sysIPV6_RECVHOPLIMIT = 0x13 + sysIPV6_RECVHOPOPTS = 0x14 + + sysIPV6_RECVRTHDR = 0x16 + + sysIPV6_RECVRTHDRDSTOPTS = 0x17 + + sysIPV6_CHECKSUM = 0x18 + sysIPV6_RECVTCLASS = 0x19 + sysIPV6_USE_MIN_MTU = 0x20 + sysIPV6_DONTFRAG = 0x21 + sysIPV6_SEC_OPT = 0x22 + sysIPV6_SRC_PREFERENCES = 0x23 + sysIPV6_RECVPATHMTU = 0x24 + sysIPV6_PATHMTU = 0x25 + sysIPV6_TCLASS = 0x26 + sysIPV6_V6ONLY = 0x27 + + sysIPV6_RECVDSTOPTS = 0x28 + + sysIPV6_PREFER_SRC_HOME = 0x1 + sysIPV6_PREFER_SRC_COA = 0x2 + sysIPV6_PREFER_SRC_PUBLIC = 0x4 + sysIPV6_PREFER_SRC_TMP = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x10 + sysIPV6_PREFER_SRC_CGA = 0x20 + + sysIPV6_PREFER_SRC_MIPMASK = 0x3 + sysIPV6_PREFER_SRC_MIPDEFAULT = 0x1 + sysIPV6_PREFER_SRC_TMPMASK = 0xc + sysIPV6_PREFER_SRC_TMPDEFAULT = 0x4 + sysIPV6_PREFER_SRC_CGAMASK = 0x30 + sysIPV6_PREFER_SRC_CGADEFAULT = 0x10 + + sysIPV6_PREFER_SRC_MASK = 0x3f + + sysIPV6_PREFER_SRC_DEFAULT = 0x15 + + sysIPV6_BOUND_IF = 0x41 + sysIPV6_UNSPEC_SRC = 0x42 + + sysICMP6_FILTER = 0x1 + + sysSizeofSockaddrInet6 = 0x20 + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x24 + + sysSizeofIPv6Mreq = 0x14 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 + X__sin6_src_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex uint32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Interface uint32 +} + +type sysICMPv6Filter struct { + X__icmp6_filt [8]uint32 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/netutil/listen.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/netutil/listen.go new file mode 100644 index 00000000..b317ba2e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/netutil/listen.go @@ -0,0 +1,48 @@ +// 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 netutil provides network utility functions, complementing the more +// common ones in the net package. +package netutil // import "golang.org/x/net/netutil" + +import ( + "net" + "sync" +) + +// LimitListener returns a Listener that accepts at most n simultaneous +// connections from the provided Listener. +func LimitListener(l net.Listener, n int) net.Listener { + return &limitListener{l, make(chan struct{}, n)} +} + +type limitListener struct { + net.Listener + sem chan struct{} +} + +func (l *limitListener) acquire() { l.sem <- struct{}{} } +func (l *limitListener) release() { <-l.sem } + +func (l *limitListener) Accept() (net.Conn, error) { + l.acquire() + c, err := l.Listener.Accept() + if err != nil { + l.release() + return nil, err + } + return &limitListenerConn{Conn: c, release: l.release}, nil +} + +type limitListenerConn struct { + net.Conn + releaseOnce sync.Once + release func() +} + +func (l *limitListenerConn) Close() error { + err := l.Conn.Close() + l.releaseOnce.Do(l.release) + return err +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/netutil/listen_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/netutil/listen_test.go new file mode 100644 index 00000000..c1a3d552 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/netutil/listen_test.go @@ -0,0 +1,101 @@ +// 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 netutil + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + "net" + "net/http" + "sync" + "sync/atomic" + "testing" + "time" + + "golang.org/x/net/internal/nettest" +) + +func TestLimitListener(t *testing.T) { + const max = 5 + attempts := (nettest.MaxOpenFiles() - max) / 2 + if attempts > 256 { // maximum length of accept queue is 128 by default + attempts = 256 + } + + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatal(err) + } + defer l.Close() + l = LimitListener(l, max) + + var open int32 + go http.Serve(l, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if n := atomic.AddInt32(&open, 1); n > max { + t.Errorf("%d open connections, want <= %d", n, max) + } + defer atomic.AddInt32(&open, -1) + time.Sleep(10 * time.Millisecond) + fmt.Fprint(w, "some body") + })) + + var wg sync.WaitGroup + var failed int32 + for i := 0; i < attempts; i++ { + wg.Add(1) + go func() { + defer wg.Done() + c := http.Client{Timeout: 3 * time.Second} + r, err := c.Get("http://" + l.Addr().String()) + if err != nil { + t.Log(err) + atomic.AddInt32(&failed, 1) + return + } + defer r.Body.Close() + io.Copy(ioutil.Discard, r.Body) + }() + } + wg.Wait() + + // We expect some Gets to fail as the kernel's accept queue is filled, + // but most should succeed. + if int(failed) >= attempts/2 { + t.Errorf("%d requests failed within %d attempts", failed, attempts) + } +} + +type errorListener struct { + net.Listener +} + +func (errorListener) Accept() (net.Conn, error) { + return nil, errFake +} + +var errFake = errors.New("fake error from errorListener") + +// This used to hang. +func TestLimitListenerError(t *testing.T) { + donec := make(chan bool, 1) + go func() { + const n = 2 + ll := LimitListener(errorListener{}, n) + for i := 0; i < n+1; i++ { + _, err := ll.Accept() + if err != errFake { + t.Fatalf("Accept error = %v; want errFake", err) + } + } + donec <- true + }() + select { + case <-donec: + case <-time.After(5 * time.Second): + t.Fatal("timeout. deadlock?") + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/direct.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/direct.go new file mode 100644 index 00000000..4c5ad88b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/direct.go @@ -0,0 +1,18 @@ +// 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 proxy + +import ( + "net" +) + +type direct struct{} + +// Direct is a direct proxy: one that makes network connections directly. +var Direct = direct{} + +func (direct) Dial(network, addr string) (net.Conn, error) { + return net.Dial(network, addr) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/per_host.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/per_host.go new file mode 100644 index 00000000..f540b196 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/per_host.go @@ -0,0 +1,140 @@ +// 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 proxy + +import ( + "net" + "strings" +) + +// A PerHost directs connections to a default Dialer unless the hostname +// requested matches one of a number of exceptions. +type PerHost struct { + def, bypass Dialer + + bypassNetworks []*net.IPNet + bypassIPs []net.IP + bypassZones []string + bypassHosts []string +} + +// NewPerHost returns a PerHost Dialer that directs connections to either +// defaultDialer or bypass, depending on whether the connection matches one of +// the configured rules. +func NewPerHost(defaultDialer, bypass Dialer) *PerHost { + return &PerHost{ + def: defaultDialer, + bypass: bypass, + } +} + +// Dial connects to the address addr on the given network through either +// defaultDialer or bypass. +func (p *PerHost) Dial(network, addr string) (c net.Conn, err error) { + host, _, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + return p.dialerForRequest(host).Dial(network, addr) +} + +func (p *PerHost) dialerForRequest(host string) Dialer { + if ip := net.ParseIP(host); ip != nil { + for _, net := range p.bypassNetworks { + if net.Contains(ip) { + return p.bypass + } + } + for _, bypassIP := range p.bypassIPs { + if bypassIP.Equal(ip) { + return p.bypass + } + } + return p.def + } + + for _, zone := range p.bypassZones { + if strings.HasSuffix(host, zone) { + return p.bypass + } + if host == zone[1:] { + // For a zone "example.com", we match "example.com" + // too. + return p.bypass + } + } + for _, bypassHost := range p.bypassHosts { + if bypassHost == host { + return p.bypass + } + } + return p.def +} + +// AddFromString parses a string that contains comma-separated values +// specifying hosts that should use the bypass proxy. Each value is either an +// IP address, a CIDR range, a zone (*.example.com) or a hostname +// (localhost). A best effort is made to parse the string and errors are +// ignored. +func (p *PerHost) AddFromString(s string) { + hosts := strings.Split(s, ",") + for _, host := range hosts { + host = strings.TrimSpace(host) + if len(host) == 0 { + continue + } + if strings.Contains(host, "/") { + // We assume that it's a CIDR address like 127.0.0.0/8 + if _, net, err := net.ParseCIDR(host); err == nil { + p.AddNetwork(net) + } + continue + } + if ip := net.ParseIP(host); ip != nil { + p.AddIP(ip) + continue + } + if strings.HasPrefix(host, "*.") { + p.AddZone(host[1:]) + continue + } + p.AddHost(host) + } +} + +// AddIP specifies an IP address that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match an IP. +func (p *PerHost) AddIP(ip net.IP) { + p.bypassIPs = append(p.bypassIPs, ip) +} + +// AddNetwork specifies an IP range that will use the bypass proxy. Note that +// this will only take effect if a literal IP address is dialed. A connection +// to a named host will never match. +func (p *PerHost) AddNetwork(net *net.IPNet) { + p.bypassNetworks = append(p.bypassNetworks, net) +} + +// AddZone specifies a DNS suffix that will use the bypass proxy. A zone of +// "example.com" matches "example.com" and all of its subdomains. +func (p *PerHost) AddZone(zone string) { + if strings.HasSuffix(zone, ".") { + zone = zone[:len(zone)-1] + } + if !strings.HasPrefix(zone, ".") { + zone = "." + zone + } + p.bypassZones = append(p.bypassZones, zone) +} + +// AddHost specifies a hostname that will use the bypass proxy. +func (p *PerHost) AddHost(host string) { + if strings.HasSuffix(host, ".") { + host = host[:len(host)-1] + } + p.bypassHosts = append(p.bypassHosts, host) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/per_host_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/per_host_test.go new file mode 100644 index 00000000..a7d80957 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/per_host_test.go @@ -0,0 +1,55 @@ +// 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 proxy + +import ( + "errors" + "net" + "reflect" + "testing" +) + +type recordingProxy struct { + addrs []string +} + +func (r *recordingProxy) Dial(network, addr string) (net.Conn, error) { + r.addrs = append(r.addrs, addr) + return nil, errors.New("recordingProxy") +} + +func TestPerHost(t *testing.T) { + var def, bypass recordingProxy + perHost := NewPerHost(&def, &bypass) + perHost.AddFromString("localhost,*.zone,127.0.0.1,10.0.0.1/8,1000::/16") + + expectedDef := []string{ + "example.com:123", + "1.2.3.4:123", + "[1001::]:123", + } + expectedBypass := []string{ + "localhost:123", + "zone:123", + "foo.zone:123", + "127.0.0.1:123", + "10.1.2.3:123", + "[1000::]:123", + } + + for _, addr := range expectedDef { + perHost.Dial("tcp", addr) + } + for _, addr := range expectedBypass { + perHost.Dial("tcp", addr) + } + + if !reflect.DeepEqual(expectedDef, def.addrs) { + t.Errorf("Hosts which went to the default proxy didn't match. Got %v, want %v", def.addrs, expectedDef) + } + if !reflect.DeepEqual(expectedBypass, bypass.addrs) { + t.Errorf("Hosts which went to the bypass proxy didn't match. Got %v, want %v", bypass.addrs, expectedBypass) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/proxy.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/proxy.go new file mode 100644 index 00000000..78a8b7be --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/proxy.go @@ -0,0 +1,94 @@ +// 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 proxy provides support for a variety of protocols to proxy network +// data. +package proxy // import "golang.org/x/net/proxy" + +import ( + "errors" + "net" + "net/url" + "os" +) + +// A Dialer is a means to establish a connection. +type Dialer interface { + // Dial connects to the given address via the proxy. + Dial(network, addr string) (c net.Conn, err error) +} + +// Auth contains authentication parameters that specific Dialers may require. +type Auth struct { + User, Password string +} + +// FromEnvironment returns the dialer specified by the proxy related variables in +// the environment. +func FromEnvironment() Dialer { + allProxy := os.Getenv("all_proxy") + if len(allProxy) == 0 { + return Direct + } + + proxyURL, err := url.Parse(allProxy) + if err != nil { + return Direct + } + proxy, err := FromURL(proxyURL, Direct) + if err != nil { + return Direct + } + + noProxy := os.Getenv("no_proxy") + if len(noProxy) == 0 { + return proxy + } + + perHost := NewPerHost(proxy, Direct) + perHost.AddFromString(noProxy) + return perHost +} + +// proxySchemes is a map from URL schemes to a function that creates a Dialer +// from a URL with such a scheme. +var proxySchemes map[string]func(*url.URL, Dialer) (Dialer, error) + +// RegisterDialerType takes a URL scheme and a function to generate Dialers from +// a URL with that scheme and a forwarding Dialer. Registered schemes are used +// by FromURL. +func RegisterDialerType(scheme string, f func(*url.URL, Dialer) (Dialer, error)) { + if proxySchemes == nil { + proxySchemes = make(map[string]func(*url.URL, Dialer) (Dialer, error)) + } + proxySchemes[scheme] = f +} + +// FromURL returns a Dialer given a URL specification and an underlying +// Dialer for it to make network requests. +func FromURL(u *url.URL, forward Dialer) (Dialer, error) { + var auth *Auth + if u.User != nil { + auth = new(Auth) + auth.User = u.User.Username() + if p, ok := u.User.Password(); ok { + auth.Password = p + } + } + + switch u.Scheme { + case "socks5": + return SOCKS5("tcp", u.Host, auth, forward) + } + + // If the scheme doesn't match any of the built-in schemes, see if it + // was registered by another package. + if proxySchemes != nil { + if f, ok := proxySchemes[u.Scheme]; ok { + return f(u, forward) + } + } + + return nil, errors.New("proxy: unknown scheme: " + u.Scheme) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/proxy_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/proxy_test.go new file mode 100644 index 00000000..c19a5c06 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/proxy_test.go @@ -0,0 +1,142 @@ +// 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 proxy + +import ( + "io" + "net" + "net/url" + "strconv" + "sync" + "testing" +) + +func TestFromURL(t *testing.T) { + endSystem, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("net.Listen failed: %v", err) + } + defer endSystem.Close() + gateway, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("net.Listen failed: %v", err) + } + defer gateway.Close() + + var wg sync.WaitGroup + wg.Add(1) + go socks5Gateway(t, gateway, endSystem, socks5Domain, &wg) + + url, err := url.Parse("socks5://user:password@" + gateway.Addr().String()) + if err != nil { + t.Fatalf("url.Parse failed: %v", err) + } + proxy, err := FromURL(url, Direct) + if err != nil { + t.Fatalf("FromURL failed: %v", err) + } + _, port, err := net.SplitHostPort(endSystem.Addr().String()) + if err != nil { + t.Fatalf("net.SplitHostPort failed: %v", err) + } + if c, err := proxy.Dial("tcp", "localhost:"+port); err != nil { + t.Fatalf("FromURL.Dial failed: %v", err) + } else { + c.Close() + } + + wg.Wait() +} + +func TestSOCKS5(t *testing.T) { + endSystem, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("net.Listen failed: %v", err) + } + defer endSystem.Close() + gateway, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("net.Listen failed: %v", err) + } + defer gateway.Close() + + var wg sync.WaitGroup + wg.Add(1) + go socks5Gateway(t, gateway, endSystem, socks5IP4, &wg) + + proxy, err := SOCKS5("tcp", gateway.Addr().String(), nil, Direct) + if err != nil { + t.Fatalf("SOCKS5 failed: %v", err) + } + if c, err := proxy.Dial("tcp", endSystem.Addr().String()); err != nil { + t.Fatalf("SOCKS5.Dial failed: %v", err) + } else { + c.Close() + } + + wg.Wait() +} + +func socks5Gateway(t *testing.T, gateway, endSystem net.Listener, typ byte, wg *sync.WaitGroup) { + defer wg.Done() + + c, err := gateway.Accept() + if err != nil { + t.Errorf("net.Listener.Accept failed: %v", err) + return + } + defer c.Close() + + b := make([]byte, 32) + var n int + if typ == socks5Domain { + n = 4 + } else { + n = 3 + } + if _, err := io.ReadFull(c, b[:n]); err != nil { + t.Errorf("io.ReadFull failed: %v", err) + return + } + if _, err := c.Write([]byte{socks5Version, socks5AuthNone}); err != nil { + t.Errorf("net.Conn.Write failed: %v", err) + return + } + if typ == socks5Domain { + n = 16 + } else { + n = 10 + } + if _, err := io.ReadFull(c, b[:n]); err != nil { + t.Errorf("io.ReadFull failed: %v", err) + return + } + if b[0] != socks5Version || b[1] != socks5Connect || b[2] != 0x00 || b[3] != typ { + t.Errorf("got an unexpected packet: %#02x %#02x %#02x %#02x", b[0], b[1], b[2], b[3]) + return + } + if typ == socks5Domain { + copy(b[:5], []byte{socks5Version, 0x00, 0x00, socks5Domain, 9}) + b = append(b, []byte("localhost")...) + } else { + copy(b[:4], []byte{socks5Version, 0x00, 0x00, socks5IP4}) + } + host, port, err := net.SplitHostPort(endSystem.Addr().String()) + if err != nil { + t.Errorf("net.SplitHostPort failed: %v", err) + return + } + b = append(b, []byte(net.ParseIP(host).To4())...) + p, err := strconv.Atoi(port) + if err != nil { + t.Errorf("strconv.Atoi failed: %v", err) + return + } + b = append(b, []byte{byte(p >> 8), byte(p)}...) + if _, err := c.Write(b); err != nil { + t.Errorf("net.Conn.Write failed: %v", err) + return + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/socks5.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/socks5.go new file mode 100644 index 00000000..9b962823 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/proxy/socks5.go @@ -0,0 +1,210 @@ +// 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 proxy + +import ( + "errors" + "io" + "net" + "strconv" +) + +// SOCKS5 returns a Dialer that makes SOCKSv5 connections to the given address +// with an optional username and password. See RFC 1928. +func SOCKS5(network, addr string, auth *Auth, forward Dialer) (Dialer, error) { + s := &socks5{ + network: network, + addr: addr, + forward: forward, + } + if auth != nil { + s.user = auth.User + s.password = auth.Password + } + + return s, nil +} + +type socks5 struct { + user, password string + network, addr string + forward Dialer +} + +const socks5Version = 5 + +const ( + socks5AuthNone = 0 + socks5AuthPassword = 2 +) + +const socks5Connect = 1 + +const ( + socks5IP4 = 1 + socks5Domain = 3 + socks5IP6 = 4 +) + +var socks5Errors = []string{ + "", + "general failure", + "connection forbidden", + "network unreachable", + "host unreachable", + "connection refused", + "TTL expired", + "command not supported", + "address type not supported", +} + +// Dial connects to the address addr on the network net via the SOCKS5 proxy. +func (s *socks5) Dial(network, addr string) (net.Conn, error) { + switch network { + case "tcp", "tcp6", "tcp4": + default: + return nil, errors.New("proxy: no support for SOCKS5 proxy connections of type " + network) + } + + conn, err := s.forward.Dial(s.network, s.addr) + if err != nil { + return nil, err + } + closeConn := &conn + defer func() { + if closeConn != nil { + (*closeConn).Close() + } + }() + + host, portStr, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + port, err := strconv.Atoi(portStr) + if err != nil { + return nil, errors.New("proxy: failed to parse port number: " + portStr) + } + if port < 1 || port > 0xffff { + return nil, errors.New("proxy: port number out of range: " + portStr) + } + + // the size here is just an estimate + buf := make([]byte, 0, 6+len(host)) + + buf = append(buf, socks5Version) + if len(s.user) > 0 && len(s.user) < 256 && len(s.password) < 256 { + buf = append(buf, 2 /* num auth methods */, socks5AuthNone, socks5AuthPassword) + } else { + buf = append(buf, 1 /* num auth methods */, socks5AuthNone) + } + + if _, err := conn.Write(buf); err != nil { + return nil, errors.New("proxy: failed to write greeting to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return nil, errors.New("proxy: failed to read greeting from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + if buf[0] != 5 { + return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " has unexpected version " + strconv.Itoa(int(buf[0]))) + } + if buf[1] == 0xff { + return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " requires authentication") + } + + if buf[1] == socks5AuthPassword { + buf = buf[:0] + buf = append(buf, 1 /* password protocol version */) + buf = append(buf, uint8(len(s.user))) + buf = append(buf, s.user...) + buf = append(buf, uint8(len(s.password))) + buf = append(buf, s.password...) + + if _, err := conn.Write(buf); err != nil { + return nil, errors.New("proxy: failed to write authentication request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return nil, errors.New("proxy: failed to read authentication reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if buf[1] != 0 { + return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " rejected username/password") + } + } + + buf = buf[:0] + buf = append(buf, socks5Version, socks5Connect, 0 /* reserved */) + + if ip := net.ParseIP(host); ip != nil { + if ip4 := ip.To4(); ip4 != nil { + buf = append(buf, socks5IP4) + ip = ip4 + } else { + buf = append(buf, socks5IP6) + } + buf = append(buf, ip...) + } else { + if len(host) > 255 { + return nil, errors.New("proxy: destination hostname too long: " + host) + } + buf = append(buf, socks5Domain) + buf = append(buf, byte(len(host))) + buf = append(buf, host...) + } + buf = append(buf, byte(port>>8), byte(port)) + + if _, err := conn.Write(buf); err != nil { + return nil, errors.New("proxy: failed to write connect request to SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + if _, err := io.ReadFull(conn, buf[:4]); err != nil { + return nil, errors.New("proxy: failed to read connect reply from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + failure := "unknown error" + if int(buf[1]) < len(socks5Errors) { + failure = socks5Errors[buf[1]] + } + + if len(failure) > 0 { + return nil, errors.New("proxy: SOCKS5 proxy at " + s.addr + " failed to connect: " + failure) + } + + bytesToDiscard := 0 + switch buf[3] { + case socks5IP4: + bytesToDiscard = net.IPv4len + case socks5IP6: + bytesToDiscard = net.IPv6len + case socks5Domain: + _, err := io.ReadFull(conn, buf[:1]) + if err != nil { + return nil, errors.New("proxy: failed to read domain length from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + bytesToDiscard = int(buf[0]) + default: + return nil, errors.New("proxy: got unknown address type " + strconv.Itoa(int(buf[3])) + " from SOCKS5 proxy at " + s.addr) + } + + if cap(buf) < bytesToDiscard { + buf = make([]byte, bytesToDiscard) + } else { + buf = buf[:bytesToDiscard] + } + if _, err := io.ReadFull(conn, buf); err != nil { + return nil, errors.New("proxy: failed to read address from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + // Also need to discard the port number + if _, err := io.ReadFull(conn, buf[:2]); err != nil { + return nil, errors.New("proxy: failed to read port from SOCKS5 proxy at " + s.addr + ": " + err.Error()) + } + + closeConn = nil + return conn, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/gen.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/gen.go new file mode 100644 index 00000000..ee2598c3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/gen.go @@ -0,0 +1,608 @@ +// 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 ignore + +package main + +// This program generates table.go and table_test.go. +// Invoke as: +// +// go run gen.go -version "xxx" >table.go +// go run gen.go -version "xxx" -test >table_test.go +// +// The version is derived from information found at +// https://github.com/publicsuffix/list/commits/master/public_suffix_list.dat +// +// To fetch a particular git revision, such as 5c70ccd250, pass +// -url "https://raw.githubusercontent.com/publicsuffix/list/5c70ccd250/public_suffix_list.dat" + +import ( + "bufio" + "bytes" + "flag" + "fmt" + "go/format" + "io" + "net/http" + "os" + "regexp" + "sort" + "strings" + + "golang.org/x/net/idna" +) + +const ( + nodesBitsChildren = 9 + nodesBitsICANN = 1 + nodesBitsTextOffset = 15 + nodesBitsTextLength = 6 + + childrenBitsWildcard = 1 + childrenBitsNodeType = 2 + childrenBitsHi = 14 + childrenBitsLo = 14 +) + +var ( + maxChildren int + maxTextOffset int + maxTextLength int + maxHi uint32 + maxLo uint32 +) + +func max(a, b int) int { + if a < b { + return b + } + return a +} + +func u32max(a, b uint32) uint32 { + if a < b { + return b + } + return a +} + +const ( + nodeTypeNormal = 0 + nodeTypeException = 1 + nodeTypeParentOnly = 2 + numNodeType = 3 +) + +func nodeTypeStr(n int) string { + switch n { + case nodeTypeNormal: + return "+" + case nodeTypeException: + return "!" + case nodeTypeParentOnly: + return "o" + } + panic("unreachable") +} + +var ( + labelEncoding = map[string]uint32{} + labelsList = []string{} + labelsMap = map[string]bool{} + rules = []string{} + + // validSuffix is used to check that the entries in the public suffix list + // are in canonical form (after Punycode encoding). Specifically, capital + // letters are not allowed. + validSuffix = regexp.MustCompile(`^[a-z0-9_\!\*\-\.]+$`) + + crush = flag.Bool("crush", true, "make the generated node text as small as possible") + subset = flag.Bool("subset", false, "generate only a subset of the full table, for debugging") + url = flag.String("url", + "https://publicsuffix.org/list/effective_tld_names.dat", + "URL of the publicsuffix.org list. If empty, stdin is read instead") + v = flag.Bool("v", false, "verbose output (to stderr)") + version = flag.String("version", "", "the effective_tld_names.dat version") + test = flag.Bool("test", false, "generate table_test.go") +) + +func main() { + if err := main1(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func main1() error { + flag.Parse() + if nodesBitsTextLength+nodesBitsTextOffset+nodesBitsICANN+nodesBitsChildren > 32 { + return fmt.Errorf("not enough bits to encode the nodes table") + } + if childrenBitsLo+childrenBitsHi+childrenBitsNodeType+childrenBitsWildcard > 32 { + return fmt.Errorf("not enough bits to encode the children table") + } + if *version == "" { + return fmt.Errorf("-version was not specified") + } + var r io.Reader = os.Stdin + if *url != "" { + res, err := http.Get(*url) + if err != nil { + return err + } + if res.StatusCode != http.StatusOK { + return fmt.Errorf("bad GET status for %s: %d", *url, res.Status) + } + r = res.Body + defer res.Body.Close() + } + + var root node + icann := false + buf := new(bytes.Buffer) + br := bufio.NewReader(r) + for { + s, err := br.ReadString('\n') + if err != nil { + if err == io.EOF { + break + } + return err + } + s = strings.TrimSpace(s) + if strings.Contains(s, "BEGIN ICANN DOMAINS") { + icann = true + continue + } + if strings.Contains(s, "END ICANN DOMAINS") { + icann = false + continue + } + if s == "" || strings.HasPrefix(s, "//") { + continue + } + s, err = idna.ToASCII(s) + if err != nil { + return err + } + if !validSuffix.MatchString(s) { + return fmt.Errorf("bad publicsuffix.org list data: %q", s) + } + + if *subset { + switch { + case s == "ac.jp" || strings.HasSuffix(s, ".ac.jp"): + case s == "ak.us" || strings.HasSuffix(s, ".ak.us"): + case s == "ao" || strings.HasSuffix(s, ".ao"): + case s == "ar" || strings.HasSuffix(s, ".ar"): + case s == "arpa" || strings.HasSuffix(s, ".arpa"): + case s == "cy" || strings.HasSuffix(s, ".cy"): + case s == "dyndns.org" || strings.HasSuffix(s, ".dyndns.org"): + case s == "jp": + case s == "kobe.jp" || strings.HasSuffix(s, ".kobe.jp"): + case s == "kyoto.jp" || strings.HasSuffix(s, ".kyoto.jp"): + case s == "om" || strings.HasSuffix(s, ".om"): + case s == "uk" || strings.HasSuffix(s, ".uk"): + case s == "uk.com" || strings.HasSuffix(s, ".uk.com"): + case s == "tw" || strings.HasSuffix(s, ".tw"): + case s == "zw" || strings.HasSuffix(s, ".zw"): + case s == "xn--p1ai" || strings.HasSuffix(s, ".xn--p1ai"): + // xn--p1ai is Russian-Cyrillic "рф". + default: + continue + } + } + + rules = append(rules, s) + + nt, wildcard := nodeTypeNormal, false + switch { + case strings.HasPrefix(s, "*."): + s, nt = s[2:], nodeTypeParentOnly + wildcard = true + case strings.HasPrefix(s, "!"): + s, nt = s[1:], nodeTypeException + } + labels := strings.Split(s, ".") + for n, i := &root, len(labels)-1; i >= 0; i-- { + label := labels[i] + n = n.child(label) + if i == 0 { + if nt != nodeTypeParentOnly && n.nodeType == nodeTypeParentOnly { + n.nodeType = nt + } + n.icann = n.icann && icann + n.wildcard = n.wildcard || wildcard + } + labelsMap[label] = true + } + } + labelsList = make([]string, 0, len(labelsMap)) + for label := range labelsMap { + labelsList = append(labelsList, label) + } + sort.Strings(labelsList) + + p := printReal + if *test { + p = printTest + } + if err := p(buf, &root); err != nil { + return err + } + + b, err := format.Source(buf.Bytes()) + if err != nil { + return err + } + _, err = os.Stdout.Write(b) + return err +} + +func printTest(w io.Writer, n *node) error { + fmt.Fprintf(w, "// generated by go run gen.go; DO NOT EDIT\n\n") + fmt.Fprintf(w, "package publicsuffix\n\nvar rules = [...]string{\n") + for _, rule := range rules { + fmt.Fprintf(w, "%q,\n", rule) + } + fmt.Fprintf(w, "}\n\nvar nodeLabels = [...]string{\n") + if err := n.walk(w, printNodeLabel); err != nil { + return err + } + fmt.Fprintf(w, "}\n") + return nil +} + +func printReal(w io.Writer, n *node) error { + const header = `// generated by go run gen.go; DO NOT EDIT + +package publicsuffix + +const version = %q + +const ( + nodesBitsChildren = %d + nodesBitsICANN = %d + nodesBitsTextOffset = %d + nodesBitsTextLength = %d + + childrenBitsWildcard = %d + childrenBitsNodeType = %d + childrenBitsHi = %d + childrenBitsLo = %d +) + +const ( + nodeTypeNormal = %d + nodeTypeException = %d + nodeTypeParentOnly = %d +) + +// numTLD is the number of top level domains. +const numTLD = %d + +` + fmt.Fprintf(w, header, *version, + nodesBitsChildren, nodesBitsICANN, nodesBitsTextOffset, nodesBitsTextLength, + childrenBitsWildcard, childrenBitsNodeType, childrenBitsHi, childrenBitsLo, + nodeTypeNormal, nodeTypeException, nodeTypeParentOnly, len(n.children)) + + text := makeText() + if text == "" { + return fmt.Errorf("internal error: makeText returned no text") + } + for _, label := range labelsList { + offset, length := strings.Index(text, label), len(label) + if offset < 0 { + return fmt.Errorf("internal error: could not find %q in text %q", label, text) + } + maxTextOffset, maxTextLength = max(maxTextOffset, offset), max(maxTextLength, length) + if offset >= 1<= 1< 64 { + n, plus = 64, " +" + } + fmt.Fprintf(w, "%q%s\n", text[:n], plus) + text = text[n:] + } + + n.walk(w, assignIndexes) + + fmt.Fprintf(w, ` + +// nodes is the list of nodes. Each node is represented as a uint32, which +// encodes the node's children, wildcard bit and node type (as an index into +// the children array), ICANN bit and text. +// +// In the //-comment after each node's data, the nodes indexes of the children +// are formatted as (n0x1234-n0x1256), with * denoting the wildcard bit. The +// nodeType is printed as + for normal, ! for exception, and o for parent-only +// nodes that have children but don't match a domain label in their own right. +// An I denotes an ICANN domain. +// +// The layout within the uint32, from MSB to LSB, is: +// [%2d bits] unused +// [%2d bits] children index +// [%2d bits] ICANN bit +// [%2d bits] text index +// [%2d bits] text length +var nodes = [...]uint32{ +`, + 32-nodesBitsChildren-nodesBitsICANN-nodesBitsTextOffset-nodesBitsTextLength, + nodesBitsChildren, nodesBitsICANN, nodesBitsTextOffset, nodesBitsTextLength) + if err := n.walk(w, printNode); err != nil { + return err + } + fmt.Fprintf(w, `} + +// children is the list of nodes' children, the parent's wildcard bit and the +// parent's node type. If a node has no children then their children index +// will be in the range [0, 6), depending on the wildcard bit and node type. +// +// The layout within the uint32, from MSB to LSB, is: +// [%2d bits] unused +// [%2d bits] wildcard bit +// [%2d bits] node type +// [%2d bits] high nodes index (exclusive) of children +// [%2d bits] low nodes index (inclusive) of children +var children=[...]uint32{ +`, + 32-childrenBitsWildcard-childrenBitsNodeType-childrenBitsHi-childrenBitsLo, + childrenBitsWildcard, childrenBitsNodeType, childrenBitsHi, childrenBitsLo) + for i, c := range childrenEncoding { + s := "---------------" + lo := c & (1<> childrenBitsLo) & (1<>(childrenBitsLo+childrenBitsHi)) & (1<>(childrenBitsLo+childrenBitsHi+childrenBitsNodeType) != 0 + fmt.Fprintf(w, "0x%08x, // c0x%04x (%s)%s %s\n", + c, i, s, wildcardStr(wildcard), nodeTypeStr(nodeType)) + } + fmt.Fprintf(w, "}\n\n") + fmt.Fprintf(w, "// max children %d (capacity %d)\n", maxChildren, 1<= 1<= 1<= 1< 0 && ss[0] == "" { + ss = ss[1:] + } + + // Join strings where one suffix matches another prefix. + for { + // Find best i, j, k such that ss[i][len-k:] == ss[j][:k], + // maximizing overlap length k. + besti := -1 + bestj := -1 + bestk := 0 + for i, s := range ss { + if s == "" { + continue + } + for j, t := range ss { + if i == j { + continue + } + for k := bestk + 1; k <= len(s) && k <= len(t); k++ { + if s[len(s)-k:] == t[:k] { + besti = i + bestj = j + bestk = k + } + } + } + } + if bestk > 0 { + if *v { + fmt.Fprintf(os.Stderr, "%d-length overlap at (%4d,%4d) out of (%4d,%4d): %q and %q\n", + bestk, besti, bestj, len(ss), len(ss), ss[besti], ss[bestj]) + } + ss[besti] += ss[bestj][bestk:] + ss[bestj] = "" + continue + } + break + } + + text := strings.Join(ss, "") + if *v { + fmt.Fprintf(os.Stderr, "crushed %d bytes to become %d bytes\n", beforeLength, len(text)) + } + return text +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/list.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/list.go new file mode 100644 index 00000000..9419ca99 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/list.go @@ -0,0 +1,133 @@ +// 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 publicsuffix provides a public suffix list based on data from +// http://publicsuffix.org/. A public suffix is one under which Internet users +// can directly register names. +package publicsuffix // import "golang.org/x/net/publicsuffix" + +// TODO: specify case sensitivity and leading/trailing dot behavior for +// func PublicSuffix and func EffectiveTLDPlusOne. + +import ( + "fmt" + "net/http/cookiejar" + "strings" +) + +// List implements the cookiejar.PublicSuffixList interface by calling the +// PublicSuffix function. +var List cookiejar.PublicSuffixList = list{} + +type list struct{} + +func (list) PublicSuffix(domain string) string { + ps, _ := PublicSuffix(domain) + return ps +} + +func (list) String() string { + return version +} + +// PublicSuffix returns the public suffix of the domain using a copy of the +// publicsuffix.org database compiled into the library. +// +// icann is whether the public suffix is managed by the Internet Corporation +// for Assigned Names and Numbers. If not, the public suffix is privately +// managed. For example, foo.org and foo.co.uk are ICANN domains, +// foo.dyndns.org and foo.blogspot.co.uk are private domains. +// +// Use cases for distinguishing ICANN domains like foo.com from private +// domains like foo.appspot.com can be found at +// https://wiki.mozilla.org/Public_Suffix_List/Use_Cases +func PublicSuffix(domain string) (publicSuffix string, icann bool) { + lo, hi := uint32(0), uint32(numTLD) + s, suffix, wildcard := domain, len(domain), false +loop: + for { + dot := strings.LastIndex(s, ".") + if wildcard { + suffix = 1 + dot + } + if lo == hi { + break + } + f := find(s[1+dot:], lo, hi) + if f == notFound { + break + } + + u := nodes[f] >> (nodesBitsTextOffset + nodesBitsTextLength) + icann = u&(1<>= nodesBitsICANN + u = children[u&(1<>= childrenBitsLo + hi = u & (1<>= childrenBitsHi + switch u & (1<>= childrenBitsNodeType + wildcard = u&(1<>= nodesBitsTextLength + offset := x & (1< len(b[j]) +} + +// eTLDPlusOneTestCases come from +// https://github.com/publicsuffix/list/blob/master/tests/test_psl.txt +var eTLDPlusOneTestCases = []struct { + domain, want string +}{ + // Empty input. + {"", ""}, + // Unlisted TLD. + {"example", ""}, + {"example.example", "example.example"}, + {"b.example.example", "example.example"}, + {"a.b.example.example", "example.example"}, + // TLD with only 1 rule. + {"biz", ""}, + {"domain.biz", "domain.biz"}, + {"b.domain.biz", "domain.biz"}, + {"a.b.domain.biz", "domain.biz"}, + // TLD with some 2-level rules. + {"com", ""}, + {"example.com", "example.com"}, + {"b.example.com", "example.com"}, + {"a.b.example.com", "example.com"}, + {"uk.com", ""}, + {"example.uk.com", "example.uk.com"}, + {"b.example.uk.com", "example.uk.com"}, + {"a.b.example.uk.com", "example.uk.com"}, + {"test.ac", "test.ac"}, + // TLD with only 1 (wildcard) rule. + {"mm", ""}, + {"c.mm", ""}, + {"b.c.mm", "b.c.mm"}, + {"a.b.c.mm", "b.c.mm"}, + // More complex TLD. + {"jp", ""}, + {"test.jp", "test.jp"}, + {"www.test.jp", "test.jp"}, + {"ac.jp", ""}, + {"test.ac.jp", "test.ac.jp"}, + {"www.test.ac.jp", "test.ac.jp"}, + {"kyoto.jp", ""}, + {"test.kyoto.jp", "test.kyoto.jp"}, + {"ide.kyoto.jp", ""}, + {"b.ide.kyoto.jp", "b.ide.kyoto.jp"}, + {"a.b.ide.kyoto.jp", "b.ide.kyoto.jp"}, + {"c.kobe.jp", ""}, + {"b.c.kobe.jp", "b.c.kobe.jp"}, + {"a.b.c.kobe.jp", "b.c.kobe.jp"}, + {"city.kobe.jp", "city.kobe.jp"}, + {"www.city.kobe.jp", "city.kobe.jp"}, + // TLD with a wildcard rule and exceptions. + {"ck", ""}, + {"test.ck", ""}, + {"b.test.ck", "b.test.ck"}, + {"a.b.test.ck", "b.test.ck"}, + {"www.ck", "www.ck"}, + {"www.www.ck", "www.ck"}, + // US K12. + {"us", ""}, + {"test.us", "test.us"}, + {"www.test.us", "test.us"}, + {"ak.us", ""}, + {"test.ak.us", "test.ak.us"}, + {"www.test.ak.us", "test.ak.us"}, + {"k12.ak.us", ""}, + {"test.k12.ak.us", "test.k12.ak.us"}, + {"www.test.k12.ak.us", "test.k12.ak.us"}, + // Punycoded IDN labels + {"xn--85x722f.com.cn", "xn--85x722f.com.cn"}, + {"xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"}, + {"www.xn--85x722f.xn--55qx5d.cn", "xn--85x722f.xn--55qx5d.cn"}, + {"shishi.xn--55qx5d.cn", "shishi.xn--55qx5d.cn"}, + {"xn--55qx5d.cn", ""}, + {"xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"}, + {"www.xn--85x722f.xn--fiqs8s", "xn--85x722f.xn--fiqs8s"}, + {"shishi.xn--fiqs8s", "shishi.xn--fiqs8s"}, + {"xn--fiqs8s", ""}, +} + +func TestEffectiveTLDPlusOne(t *testing.T) { + for _, tc := range eTLDPlusOneTestCases { + got, _ := EffectiveTLDPlusOne(tc.domain) + if got != tc.want { + t.Errorf("%q: got %q, want %q", tc.domain, got, tc.want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/table.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/table.go new file mode 100644 index 00000000..8f11c73e --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/table.go @@ -0,0 +1,8763 @@ +// generated by go run gen.go; DO NOT EDIT + +package publicsuffix + +const version = "publicsuffix.org's public_suffix_list.dat, git revision 24caf4f (2016-01-30)" + +const ( + nodesBitsChildren = 9 + nodesBitsICANN = 1 + nodesBitsTextOffset = 15 + nodesBitsTextLength = 6 + + childrenBitsWildcard = 1 + childrenBitsNodeType = 2 + childrenBitsHi = 14 + childrenBitsLo = 14 +) + +const ( + nodeTypeNormal = 0 + nodeTypeException = 1 + nodeTypeParentOnly = 2 +) + +// numTLD is the number of top level domains. +const numTLD = 1543 + +// Text is the combined text of all labels. +const text = "bieszczadygeyachimataipeigersundurbanamexeterbievatmallorcadaque" + + "sanjotateshinanomachintaijinfinitinfoggiabifukagawalmartateyamab" + + "ihorologyusuharabikedagestangebilbaogakievenesannanikkoebenhavni" + + "kolaeverbankashiwazakiyokawarabillustrationikonantanangerbiomuta" + + "shinainuyamanouchikuhokuryugasakitashiobarabirdartcenterprisesak" + + "ikonaircraftraeumtgeradealstahaugesundurhamburgliwicebirkenesodd" + + "tangenovaravennaharimalvikasukabedzin-the-bandaioirasebastopolog" + + "yeongnamegawakembuchikumagayagawakkanaibetsubamericanfamilydsclo" + + "udappspotenzachpomorskienebakkeshibechambagriculturennebudapest-" + + "a-la-masioninohelplfinancialinzainvestmentsannohelsinkitahiroshi" + + "marshallstatebankasumigaurawa-mazowszextraspace-to-rentalstomako" + + "maibarabirthplacebjarkoyusuisservicesanokasuyakutiabjerkreimmobi" + + "lieninomiyakonojoshkar-olayangroupaleostrowiecartoonartdecoffeed" + + "backaszubyuudmurtiabjugnirasakis-a-candidateblockbusternidvrdnsa" + + "ntabarbarabloombergbauernrtatsunostrowwlkpmglobalashovhachinoheg" + + "uris-a-catererbluedatingloboehringerikebmoattachmentsantacruzsan" + + "tafedexhibitionishiazais-a-celticsfanishigotpantheonishiharabmsa" + + "nukis-a-chefarsundwglogowegroweibolzanore-og-uvdalipetskatowiceb" + + "mweirbnpparibaselburgloppenzaogashimadachicagobododgemologically" + + "ngenglandyndns-homednsaotomeldalivornobomloansapodhalewismillerb" + + "ondyndns-ip6bonnishiizunazukis-a-conservativefsncfailomzansimagi" + + "casadelamonedavvesiidazaifudaigodoesntexistanbullensakerbookingm" + + "inakamichigangwonishikatakazakis-a-cpadoval-daostavalleyuzawaboo" + + "tsapporoboschaefflerdalorenskogmodenakatombetsumidatlanticaseihi" + + "chisobetsuitairabostikatsushikabeeldengeluidyndns-mailotenkawabo" + + "stonakijinsekikogentingmxboxenishikatsuragivestbytomaritimekeepi" + + "ngretakamoriokamchatkameokameyamashinatsukigatakanabeatsaratoval" + + "leaostavernishikawazukanazawabotanicalgardenishimerabotanicgarde" + + "nishinomiyashironobotanyuzhno-sakhalinskatsuyamasfjordenishinoom" + + "otegotsukisosakitagatakamatsukawaboutiquebecngrimstadyndns-offic" + + "e-on-the-webcambridgestonewspaperbozentsujiiebradescorporationis" + + "hinoshimatta-varjjatattoolsztynsettlersardegnamsskoganeis-a-cubi" + + "cle-slavellinowtvalled-aostavropolicebrandywinevalleybrasiljan-m" + + "ayenishiokoppegardyndns-picsardiniabresciabrindisibenikebristolg" + + "alsacebritishcolumbialowiezagannakadomari-elasticbeanstalkaufeni" + + "shitosashimizunaminamiashigarabroadcastlebtimnetzgorabroadwaybro" + + "ke-itaxihuanishiwakis-a-democratgorybrokerrypropertiesarlottebro" + + "nnoysundyndns-remotegildeskalmykiabrothermesaverdefensejnybrumun" + + "ddalottokigawabrunelblagdenesnaaseralingenkainanaejrietisalatina" + + "benogatachikawakayamagadancebetsukubabia-goracleaningatlantagajo" + + "bojis-a-designerbrusselsarpsborgripebruxellesarufutsunomiyawakas" + + "aikaitakoelnissandoybryanskjakdnepropetrovskiervaapsteiermarkaut" + + "okeinobryneustarhubalestrandabergamoarekembroideryonabaruconnect" + + "arnobrzegjesdalimanowarudasnesoddenmarkets3-eu-central-1buskerud" + + "inewhampshirecipesaro-urbino-pesarourbinopesaromaniwakuratelekom" + + "munikationissayokoshibahikariwanumataketomisatokuyamatteledataba" + + "seballooningriwataraidyndns-serverbaniabuzenissedalouvrepbodyndn" + + "s-blogdnsasayamabuzzgorzeleccollegersundyndns-weberlincolnisshin" + + "guernseybwfashioniyodogawabzhitomirkutskjervoyagecloudfunctionsb" + + "schokoladencntjxn--0trq7p7nncolognewmexicoldwarmiamiastapleschol" + + "arshipschooluroycolonialwilliamsburgujolstercoloradoplateaudioco" + + "lumbusheycommunitysneschulezajskfhskhabarovskhakassiacomobaracom" + + "paremarkerryhotelschwarzgwangjuifminamibosogndalutskharkivguccip" + + "rianiigataitogitsuldaluxembourgulencompute-1computerhistoryofsci" + + "ence-fictioncomsecuritysvardoharuhrcondoshichinohedmarkhangelsky" + + "pescaravantaaconferenceconstructionconsuladollschweizgradconsult" + + "anthropologyconsultingvolluxurycontactkmaxxn--11b4c3dcontemporar" + + "yarteducationalchikugojomedicaltanissettaiwanairguardcontractors" + + "kenconventureshinodesashibetsuikimobetsuliguriacookingchannelver" + + "uminamidaitomangotembaixadacoolkuszippodlasiellakasamatsudoosand" + + "iegokaseljordcoopocznorthwesternmutualuzerncopenhagencyclopedica" + + "tholicasertaishinomakikuchikuseikarugapartmentsaseboknowsitallov" + + "egaskimitsubatamicabbottjeldsundyndns-wikindlegnicamerakershus-e" + + "ast-1corsicagliaridagawarszawashingtondclkharkovalledaostakkofue" + + "lvivano-frankivskhersoncorvettemasekhmelnitskiyamashikecosenzama" + + "mibuildersciencecentersciencehistorycostumedio-campidano-medioca" + + "mpidanomediocouncilcouponscientistor-elvdalcoursescjohnsoncq-acr" + + "anbrookuwanalyticscrapper-sitecreditcardcreditunioncremonashorok" + + "anaiecrewiiheyaizuwakamatsubushikusakadogawacricketrzyncrimeacro" + + "tonewportlligatewaycrowncrscrappingunmarriottmpalmspringsakercru" + + "isesettsurfastlycuisinellajollamericanexpressexyzjcbnlculturalce" + + "ntertainmentoyokawacuneocupcakecxn--1ck2e1balsanagochihayaakasak" + + "awaharaumakeupowiathletajimabariakepnordkappgjovikaruizawastrono" + + "mydstvedestrandgcahcesuolocalhistoryazannefrankfurtargets-itargi" + + "234cymruovatoyonakagyokutoshimacyouthdfcbankhmelnytskyivallee-ao" + + "steroyfilminamifuranofinalfinancefineartsfranziskanerimamateramo" + + "chizukirafinlandfinnoyfirebaseappamperedchefauskedsmokorsetagaya" + + "sells-for-lessevastopolefirenzefirestonextdirectoryfirmdalegolfe" + + "djejuegoshikiminokamoenairlinebraskaunbieidsvollfishingonohejis-" + + "a-geekhvalleeaosteigenfitjarqhachiojiyahikobeautydalfitnessettle" + + "mentoyonofjalerflickragerotikalugansklabudhabikinokawabarthachir" + + "ogatakanezawaflightshangrilangevagrarboretumbriaflirumansionshar" + + "is-a-greenfloguchikuzenfloraflorencefloridafloristanohatakaharus" + + "siafloromskogxn--1ctwolominamatamayukis-a-gurulsandvikcoromantov" + + "alle-daostavangerflowersharpanamaflsmidthruhereggiocalabriaflynn" + + "hubalsfjordiskstationaval-d-aosta-valleyonagoyaugustowadaegubs3-" + + "eu-west-1fndfolldalfoodnetworkangerfor-better-thandafor-ourfor-s" + + "omedizinhistorischeshawaiijimarylandfor-theaterforexrothadanotog" + + "awaforgotdnshellaspeziaforli-cesena-forlicesenaforlikes-piedmont" + + "blancomeereshimokawaforsaleikangerforsandasuolodingenfortmissoul" + + "an-udell-ogliastrakhanawawilliamhillfortworthadselfipirangaforum" + + "inamiiselectoyookarasjohkaminoyamatsuris-a-hard-workerfosneshimo" + + "kitayamafotoyosatotalfoxn--1lqs03nfreiburgzlgfreightcmwinbaltimo" + + "re-og-romsdalimitedunetflixilimoliserniaukraanghke164freseniusde" + + "corativeartshimonitayanagivingfribourgfriuli-v-giuliafriuli-ve-g" + + "iuliafriuli-vegiuliafriuli-venezia-giuliafriuli-veneziagiuliafri" + + "uli-vgiuliafriuliv-giuliafriulive-giuliafriulivegiuliafriulivene" + + "zia-giuliafriuliveneziagiuliafriulivgiuliafrlfroganshimonosekika" + + "wafrognfrolandfrom-akrehamnfrom-alfrom-arfrom-azpanasonicdn77-ss" + + "lattumetlifeinsurancefrom-canonoichikawamisatodayfrom-collection" + + "from-ctoyotaris-a-hunterfrom-dcheltenham-radio-operaunitelemarka" + + "zimierz-dolnyfrom-dellogliastraderfrom-flandershimosuwalkis-a-kn" + + "ightoyotomiyazakis-a-landscaperugiafrom-gaulardalfrom-higashiaga" + + "tsumagoirmitakeharafrom-iafrom-idfrom-ilfrom-incheonfrom-kshimot" + + "sukefrom-kyknetoyotsukaidovre-eikerfrom-lanbibaidarfrom-manxn--1" + + "lqs71dfrom-mdfrom-meetoyourafrom-microsoftbankmpspbambleborkarum" + + "aifarmsteadivtasvuodnakaiwamizawaurskog-holandroverhalla-speziae" + + "tnagahamaroygardendoftheinternetcimdbalatinordre-landds3-ap-sout" + + "heast-1kappleangaviikadenaamesjevuemielnoboribetsucks3-ap-northe" + + "ast-1from-mnfrom-modalenfrom-mshimotsumafrom-mtnfrom-nchelyabins" + + "kodjeffersonrwhalingrongausdalucaniafrom-ndfrom-nexusgardenfrom-" + + "nhktoystre-slidrettozawafrom-njcparaglidingfrom-nminamiizukamito" + + "ndabayashiogamagoriziafrom-nvanylvenicefrom-nyfrom-ohkurafrom-ok" + + "etogurafrom-orfrom-paderbornfrom-pratohmaoris-a-lawyerfrom-ris-a" + + "-liberalfrom-schoenbrunnfrom-sdnipropetrovskmshinichinanfrom-tnf" + + "rom-txn--1qqw23afrom-utazuerichardlikescandyndns-at-homedepotaru" + + "is-a-libertarianfrom-vadsochildrensgardenfrom-vtozsdefrom-wafrom" + + "-wielunnerfrom-wvaolbia-tempio-olbiatempioolbialystokkemerovodka" + + "goshimaintenancefrom-wyfrosinonefrostalowa-wolawafroyahabadajozo" + + "rahkkeravjudygarlandfstcgrouparisor-fronfujiiderafujikawaguchiko" + + "nefujiminohtawaramotoineppugliafujinomiyadafujiokayamarburgfujis" + + "atoshonairportland-4-salernogiessengerdalaskanittedallasalleasee" + + "klogesquarezzoologyfujisawafujishiroishidakabiratoridelmenhorsta" + + "lbanshinjournalismailillehammerfest-mon-blogueurovisionfujitsuru" + + "gashimarinefujixeroxn--2m4a15efujiyoshidafukayabeardubaiduckdnsd" + + "ojoburgfukuchiyamadafukudominichernigovernmentjmaxxxfinityfukuis" + + "-a-linux-useranishiaritabashikaoizumizakitaurayasudafukumitsubis" + + "higakirkeneshinjukumanofukuokazakirovogradoyfukuroishikarikaturi" + + "ndalfukusakiryuohaebaruminamimakis-a-llamarylhursteinkjerusalemb" + + "etsukuis-a-musicianfukuyamagatakahashimamakisarazure-mobileirfjo" + + "rdfunabashiriuchinadafunagatakahatakaishimoichinosekigaharafunah" + + "ashikamiamakusatsumasendaisennangoodyearthagakhanamigawafundacio" + + "fuoiskujukuriyamarcheaparliamentranbyfuosskoczowindmillfurniture" + + "ggioemiliaromagnakasatsunairtelecityeatshinkamigotoyohashimotomo" + + "bellunordreisa-geekokonoefurubiraquarelleasingleshinshinotsurgeo" + + "nshalloffamelhustkamisunagawafurudonostiafurukawairtraffichernih" + + "ivanovosibirskydivingrossetouchijiwadeltajimicrolightingroundhan" + + "dlingroznyfusodegaurafussaikishiwadafutabayamaguchinomigawafutbo" + + "ldlygoingnowhere-for-moregontrailroadfuttsurugiminamiminowafvgfy" + + "is-a-nascarfanfylkesbiblackfridayfyresdalhannovareserveftparoche" + + "rkasyzrankoshigayaltaikis-a-painteractivegarsheis-a-patsfanhanyu" + + "zenhapmirhappoulvikomaganehareidsbergenharstadharvestcelebration" + + "hasamarahasaminami-alpssells-for-unzenhashbanghasudahasvikomakiy" + + "osatokamachippubetsubetsugaruhatogayahoooshikamaishimofusartshin" + + "tokushimahatoyamazakitahatakaokamikitayamatotakadahatsukaichihar" + + "ahattfjelldalhayashimamotobuildinghazuminobusells-itrani-andria-" + + "barletta-trani-andriahbofagehembygdsforbundhemneshintomikasahara" + + "hemsedalherokussldheroyhgtvarggatraniandriabarlettatraniandriahi" + + "gashichichibungotakadatsunanjoetsuwanouchikujogaszkoladbrokesenn" + + "umamurogawalterhigashihiroshimanehigashiizumozakitakamiizumisano" + + "fiatranoyhigashikagawahigashikagurasoedahigashikawakitaaikitakat" + + "akarazukamikoaniikappulawyhigashikurumeguroroskoleitungsenhigash" + + "imatsushimarugame-hostinghigashimatsuyamakitaakitadaitoigawahiga" + + "shimurayamalatvuopmidoris-a-personaltrainerhigashinarusellsyourh" + + "omegoodshinyoshitomiokaniepcehigashinehigashiomihachimanchesterh" + + "igashiosakasayamamotorcycleshiojirishirifujiedahigashishirakawam" + + "atakasagooglecodespotransportrapaniimimatakatoris-a-photographer" + + "okuapparshioyameloyalistockholmestrandhigashisumiyoshikawaminami" + + "aikitakyushuaiahigashitsunowruzhgorodoyhigashiurausukitamidsundh" + + "igashiyamatokoriyamanakakogawahigashiyodogawahigashiyoshinogaris" + + "-a-playerhiraizumisatohnoshoohirakatashinagawahiranais-a-republi" + + "cancerresearchaeologicaliforniahirarahiratsukagawahirayaitakasak" + + "itamotosumitakaginankokubunjis-a-rockstarachowicehisayamanashiib" + + "aghdadultravelchannelhistorichouseshirahamatonbetsurgeryhitachio" + + "miyaginowaniihamatamakawajimaritimodellinghitachiotagopartis-a-s" + + "ocialistmeindianapolis-a-bloggerhitoyoshimifunehitradinghjartdal" + + "hjelmelandholeckobierzyceholidayhomeipartnershirakoenighomelinux" + + "n--30rr7yhomesensembokukitanakagusukumoduminamiogunicomcastresis" + + "tancehomeunixn--32vp30hagebostadhondahonefosshiranukanmakiwakuni" + + "gamihamadahoneywellhongorgehonjyoitakashimarumorimachidahorninda" + + "lhorseminehortendofinternetravelersinsurancehoteleshiraois-a-sox" + + "fanhotmailhoyangerhoylandetroitskomatsushimashikiyosemitehumanit" + + "ieshiraokannamiharuhurdalhurumajis-a-studentalhyllestadhyogoris-" + + "a-teacherkassymantechnologyhyugawarahyundaiwafunejgorajlchiryuky" + + "uragifuefukihaborokunohealthcareersaskatchewanggouvicenzajlljmpa" + + "rtshizukuishimogosenjnjelenia-gorajoyokaichibahcavuotnagaraholta" + + "lenjpmorganichitachinakagawatchandclockazojpnchitosetogakushimot" + + "oganewjerseyjprshizuokanoyakagejuniperjurkristiansandcatshoujis-" + + "bykristiansundkrodsheradkrokstadelvaldaostarostwodzislawinnersho" + + "wakryminamitanekumatorinokumejimasudakumenanyokkaichirurgiens-de" + + "ntisteshowtimemerckomonokunisakis-certifiedekakegawakunitachiara" + + "ilwaykunitomigusukumamotoyamassa-carrara-massacarraramassabunkyo" + + "nanaoshimageandsoundandvisionkunneppupartykunstsammlungkunstundd" + + "esignkuokgroupasadenamsosnowiechloekurepairbusantiquest-a-la-mai" + + "sondre-landebusinessebykleclerchocolatelevisionkurgankurobelaudi" + + "blebesbyglandkurogimilitarykuroisoftwarendalenugkuromatsunais-fo" + + "undationkurotakikawasakis-gonekurskomorotsukamishihoronobeokamin" + + "okawanishiaizubangekushirogawakustanais-into-animeiwamaseratis-a" + + "n-actorkusupersportrentino-stirolkutchanelkutnokuzbassnillfjordk" + + "uzumakis-into-carshisognekvafjordkvalsundkvamlidlugolekagaminord" + + "-aurdalvdalipayufuchukotkafjordkvanangenkvinesdalkvinnheradkvite" + + "seidskogkvitsoykwpspjelkavikomvuxn--3bst00minamisanrikubetsupply" + + "kyotobetsupplieshriramsterdambulanceokyowariasahikawamishimatsum" + + "otofukemissilelmisugitokonamegatakayamatsunomitourismolanciamito" + + "yoakemiuramiyazurewebsiteshikagamiishibukawamiyotamanomjondalenm" + + "lbarclaycards3-us-west-2monmouthaibarakitagawamonstermonticellol" + + "montrealestatefarmequipmentrentino-sud-tirolmonza-brianzaporizhz" + + "hekinannestadmonza-e-della-brianzaporizhzhiamonzabrianzapposlomb" + + "ardiamondsigdalmonzaebrianzaramonzaedellabrianzamoparachutingmor" + + "doviajessheiminamiuonumatsumaebashimodatemoriyamatsusakahoginoza" + + "waonsenmoriyoshiokamitsuemormoneymoroyamatsushigemortgagemoscowi" + + "ostrolekaneyamaxunjargamoseushistorymosjoenmoskenesimbirskongsvi" + + "ngermossimple-urlmosvikoninjamisonmoviemovistargardmtpccwitdkons" + + "kowolancashireisenmtranakayamatsuuramuenstermugithubusercontentr" + + "entino-sudtirolmuikamogawamukochikushinonsenergymulhouservebbsir" + + "dalmultichoicemunakatanemuncieszynmuosattemupassagenslingmurmans" + + "konsulatrobeermurotorcraftrentino-sued-tirolmusashimurayamatsuza" + + "kis-lostre-toteneis-an-actresshishikuis-an-accountantshiratakaha" + + "gis-a-techietis-a-therapistoiamusashinoharamuseetrentino-suedtir" + + "olmuseumverenigingmutsuzawamutuellevangermyokohamamatsudamypetsl" + + "upskonyveloftrentino-altoadigemyphotoshibahccavuotnagareyamaizur" + + "ubtsovskiptveterinairebungoonomichinomiyakemytis-a-bookkeepermin" + + "amiyamashirokawanabelgorodeophiladelphiaareadmyblogsitephilately" + + "philipsyphoenixn--3ds443gphotographysiopiagetmyipassenger-associ" + + "ationpictetrentinoa-adigepicturesnzpiemontepilotsokanrapinkoperv" + + "ikommunalforbundpioneerpippupiszpittsburghofermobilypiwatepizzap" + + "koryolasiteplanetariuminanoplantationplantsokndalplatformincommb" + + "ankongsbergplaystationplazaplchofunatorientexpressassaris-a-fina" + + "ncialadvisor-aurdaluccapebretonamiasakuchinotsuchiurakawassamuka" + + "wataricohdavvenjargamvikazunoplombardyndns-at-workinggroupavianc" + + "apetownplumbingotvbarclaysakuraibigawaustinnaturalsciencesnature" + + "lles3-external-1plusterpmnpodzonepohlpokerpokrovskosaigawapoliti" + + "endapolkowicepoltavalle-aostathellexuslivinghistorypomorzeszowit" + + "hgoogleapisa-hockeynutrentinoaadigepordenonepornporsangerporsang" + + "ugeporsgrunnanpoznanpraxis-a-bruinsfansolarssonprdpreservationpr" + + "esidioprgmrprimelbourneprincipeprivneprochowiceproductionsologne" + + "proferraraprogressivenneslaskerrylogisticsolundbeckosakaerodrome" + + "gallupinbarcelonagasakijobservercellierneues3-us-west-1projectre" + + "ntinoalto-adigepromombetsupportrentinoaltoadigepropertyprotectio" + + "nprudentialpruszkowithyoutubeneventochiokinoshimalselvendrellprz" + + "eworskogptzpvtrentinos-tirolpwchonanbugattipschmidtre-gauldaluce" + + "rnepzqldqponqslgbtrentinostirolqvchoseiroumuenchenstudiostudyndn" + + "s-freemasonryokamikawanehonbetsurutaharastuff-4-salestuttgartren" + + "tinosued-tirolsurnadalsurreysusakis-uberleetrentino-a-adigesuson" + + "osuzakanumazurysuzukanzakiwiensuzukis-very-badaddjamalborkdalsva" + + "lbardudinkakamigaharasveiosvelvikosherbrookegawasvizzeraswedensw" + + "idnicapitalonewhollandswiebodzindianmarketingswiftcoverisignswin" + + "oujscienceandhistoryswisshikis-very-evillagesxn--3e0b707etunesoo" + + "turystykarasjoksnesopotrentinosud-tiroltuscanytushuissier-justic" + + "etuvalle-d-aostatoilvestnesor-varangervestre-slidreamhostersorfo" + + "ldvestre-totennishiawakuravestvagoyvevelstadvibo-valentiaviboval" + + "entiavideovillaskoyabearalvahkihokumakogeniwaizumiotsukumiyamazo" + + "nawsabaerobaticketsorreisahayakawakamiichikaiseis-slickomforbana" + + "narepublicargodaddynathomebuiltarumizusawaustevollavangenaturalh" + + "istorymuseumcenterhcloudcontrolledigitalaziobiragroks-thisamitsu" + + "keisenbahnativeamericanantiques3-ap-southeast-2vinnicarbonia-igl" + + "esias-carboniaiglesiascarboniavinnytsiavipsinaappfizervirginiavi" + + "rtualvirtuelvisakatakinouevistaprintuitrentottoris-very-goodhand" + + "sonviterboltrevisohughesolutionsomavivoldavladikavkazanvladimirv" + + "ladivostokaizukarasuyamazoevlogvolkenkunderseaportroandinosaurep" + + "ortrentinosuedtirolvolkswagentsortlandvologdanskoshunantokashiki" + + "zunokunimilanovolvolgogradvolyngdalvoronezhytomyrvossevangenvote" + + "votingvotoursoruminnesotaketakatsukis-into-cartoonshisuifuettert" + + "dasnetzwindowshitaramavrnworse-thangglidingwowiwatsukiyonowrites" + + "thisblogspotrogstadwroclawloclawekostromahachijorpelandwtchoshib" + + "uyachiyodawtferrarittogoldpointelligencewuozuwwworldwzmiuwajimax" + + "n--4gbriminingxn--4gq48lf9jeonnamerikawauexn--4it168dxn--4it797k" + + "otohiradomainsureitrentino-s-tirollagrigentomologyeonggiehtavuoa" + + "tnagaivuotnagaokakyotambabydgoszczecinemailxn--4pvxsouthcarolina" + + "zawaxn--54b7fta0cchromediaxn--55qw42gxn--55qx5dxn--5js045dxn--5r" + + "tp49chryslerxn--5rtq34kotouraxn--5su34j936bgsgxn--5tzm5gxn--6btw" + + "5axn--6frz82gxn--6orx2rxn--6qq986b3xlxn--7t0a264chtrainingrpaler" + + "momasvuotnakatsugawaxn--80adxhksouthwestfalenxn--80ao21axn--80aq" + + "ecdr1axn--80asehdbarefootballangenoamishirasatobishimalopolskanl" + + "andivttasvuotnakamagayachtsakyotanabellevuelosangelesjaguarchite" + + "cturealtychyattorneyagawalbrzycharternopilawalesundiyonagunivers" + + "ityoriikasaokamiokamiminersalangenavigationavuotnakhodkanagawaus" + + "traliaisondriodejaneirochesterxn--80aswgxn--80audnedalnxn--8ltr6" + + "2kouhokutamakis-an-engineeringxn--8pvr4uxn--8y0a063axn--90a3acad" + + "emydroboatsaritsynologyeongbukounosunndalxn--90aishobaraomoriguc" + + "hiharagusaarlandxn--90azhair-surveillancexn--9dbhblg6diethnology" + + "xn--9dbq2axn--9et52uxn--9krt00axn--andy-iraxn--aroport-byanagawa" + + "xn--asky-iraxn--aurskog-hland-jnbargainstitutelefonicafederation" + + "ayoroceanographicsalondonetskashibatakasugaibmdnpalacemergencybe" + + "rlevagangaviikanonjiinetatamotorsaltdalindasiaustrheimatunduhren" + + "nesoyekaterinburgjemnes3-external-2xn--avery-yuasakegawaxn--b-5g" + + "axn--b4w605ferdxn--bck1b9a5dre4chungbukchristiansburgruexn--bddd" + + "j-mrabdxn--bearalvhki-y4axn--berlevg-jxaxn--bhcavuotna-s4axn--bh" + + "ccavuotna-k7axn--bidr-5nachikatsuuraxn--bievt-0qa2xn--bjarky-fya" + + "naizuxn--bjddar-ptamboversaillesor-odalxn--blt-elaborxn--bmlo-gr" + + "aingerxn--bod-2naroyxn--brnny-wuaccident-investigationjukudoyama" + + "ceratabuseat-band-campaniamallamadridvagsoyericssonlineat-urlxn-" + + "-brnnysund-m8accident-preventionxn--brum-voagatromsakakinokiaxn-" + + "-btsfjord-9zaxn--c1avgxn--c2br7gxn--c3s14minternationalfirearmsi" + + "enarashinoxn--cck2b3barreauctionflatangerxn--cg4bkis-very-nicexn" + + "--ciqpnxn--clchc0ea0b2g2a9gcdn77-securecreationxn--comunicaes-v6" + + "a2oxn--correios-e-telecomunicaes-ghc29axn--czr694barrel-of-knowl" + + "edgeometre-experts-comptablesalvadordalibabaikaliszczytnordlandr" + + "angedalindesnesalzburgladeloittenrightathomeftpaccessamegawautho" + + "rdalandroidiscountyumenaturbruksgymnaturhistorisches3-fips-us-go" + + "v-west-1xn--czrs0tromsojavald-aostarnbergxn--czru2dxn--czrw28bar" + + "rell-of-knowledgeorgeorgiautomotivecodyn-o-saurlandes3-sa-east-1" + + "xn--d1acj3bashkiriautoscanadaejeonbukariyakumoldebinagisoccertif" + + "icationatuurwetenschappenaumburgjerdrumckinseyokosukareliancebin" + + "osegawakunedre-eikereviewskrakowebhopagefrontappagespeedmobilize" + + "robihirosakikamijimaeroportalabamagasakishimabarackmaze-burggfar" + + "merseinewyorkshireggio-emilia-romagnakanotoddenasushiobarabruzzo" + + "ologicalvinklein-addrammenuernbergdyniabogadocscbg12000xn--d1alf" + + "aromeoxn--d1atrusteexn--d5qv7z876chungnamdalseidfjordyroyrviking" + + "uideventsaudaxn--davvenjrga-y4axn--djrs72d6uyxn--djty4kouyamashi" + + "kokuchuoxn--dnna-grajewolterskluwerxn--drbak-wuaxn--dyry-iraxn--" + + "eckvdtc9dxn--efvn9sowaxn--efvy88hakatanotteroyxn--ehqz56nxn--elq" + + "q16hakodatevaksdalxn--estv75gxn--eveni-0qa01gaxn--f6qx53axn--fct" + + "429kouzushimasoyxn--fhbeiarnxn--finny-yuaxn--fiq228c5hspreadbett" + + "ingxn--fiq64basilicataniaveroykenvironmentalconservationaustdali" + + "llesandefjordiscoveryggeelvinckarlsoyokotebizenakaniikawatanagur" + + "amusementarantomsk-uralsk12xn--fiqs8spydebergxn--fiqz9srlxn--fjo" + + "rd-lraxn--fjq720axn--fl-ziaxn--flor-jraxn--flw351exn--fpcrj9c3dx" + + "n--frde-grandrapidsrtrentinosudtirolxn--frna-woaraisaijosoyrovig" + + "orlicexn--frya-hraxn--fzc2c9e2churchaseljeepilepsydneyxn--fzys8d" + + "69uvgmailxn--g2xx48chuvashiaxn--gckr3f0ferreroticampobassociates" + + "evenassisicilyxn--gecrj9circlegallocuscountryestateofdelawaredum" + + "brellahppiacenzakopanerairforcechirealtorlandxn--ggaviika-8ya47h" + + "akonexn--gildeskl-g0axn--givuotna-8yandexn--3oq18vl8pn36axn--gjv" + + "ik-wuaxn--gk3at1exn--gls-elacaixaxn--gmq050is-very-sweetrentino-" + + "aadigexn--gmqw5axn--h-2fairwindsrvdonskoseis-an-artistjohnxn--h1" + + "aeghakubankolobrzegyptianpachigasakidsmynasperschlesischesurance" + + "xn--h2brj9circuscultureggio-calabriaxn--hbmer-xqaxn--hcesuolo-7y" + + "a35basketballfinanz-2xn--hery-iraxn--hgebostad-g3axn--hmmrfeasta" + + "-s4acoachampionshiphopenair-traffic-controlleyxn--hnefoss-q1axn-" + + "-hobl-iraxn--holtlen-hxaxn--hpmir-xqaxn--hxt814exn--hyanger-q1ax" + + "n--hylandet-54axn--i1b6b1a6a2exn--imr513nxn--indery-fyaotsurguts" + + "iracusaitokyotangovtrverranzanxn--io0a7is-with-thebandoomdnsalia" + + "scolipicenord-odalxn--j1aefetsundxn--j1amhakuis-a-nurseoullensva" + + "nguardxn--j6w193gxn--jlq61u9w7batochigiftsamnangerxn--jlster-bya" + + "roslavlaanderenxn--jrpeland-54axn--jvr189misakis-into-gamessinas" + + "hikitchenxn--k7yn95exn--karmy-yuaxn--kbrq7oxn--kcrx77d1x4axn--kf" + + "jord-iuaxn--klbu-woaxn--klt787dxn--kltp7dxn--kltx9axn--klty5xn--" + + "3pxu8kosugexn--koluokta-7ya57hakusandnessjoenxn--kprw13dxn--kpry" + + "57dxn--kpu716fguovdageaidnulminamiechizenxn--kput3isleofmandalxn" + + "--krager-gyasakaiminatoyakokamisatohobby-sitexasdaburyatiaarphar" + + "maciensmolenskooris-an-anarchistoricalsocietyxn--kranghke-b0axn-" + + "-krdsherad-m8axn--krehamn-dxaxn--krjohka-hwab49jetztrentino-alto" + + "-adigexn--ksnes-uuaxn--kvfjord-nxaxn--kvitsy-fyasugissmarterthan" + + "youxn--kvnangen-k0axn--l-1faitheguardianquanconagawakuyabukicks-" + + "assedicitadeliverybnikahokutogliattiresauheradxn--l1accenturekla" + + "mborghiniizaxn--laheadju-7yasuokaratexn--langevg-jxaxn--lcvr32dx" + + "n--ldingen-q1axn--leagaviika-52batsfjordrivelandrobaknoluoktaina" + + "ikawachinaganoharamcoalaheadjudaicaaarborteaches-yogasawaracingr" + + "oks-theatreemersongdalenviknakanojohanamakinoharavocatanzarowedd" + + "ingjerstadotsuruokamakurazakisofukushimarnardalillyokozehimejibe" + + "stadishakotankarmoyomitanobninskarpaczeladz-1xn--lesund-huaxn--l" + + "gbbat1ad8jevnakerxn--lgrd-poaciticasinorfolkebiblefrakkestadyndn" + + "s-workshoppdalowiczest-le-patrondheimperiaxn--lhppi-xqaxn--linds" + + "-pramericanartrysilkoshimizumakiyosumykolaivaroyxn--lns-qlanxess" + + "toragexn--loabt-0qaxn--lrdal-sraxn--lrenskog-54axn--lt-liacivila" + + "viationxn--lten-granexn--lury-iraxn--mely-iraxn--merker-kuaxn--m" + + "gb2ddestordalxn--mgb9awbfidelityxn--mgba3a3ejtulansomnaritakuras" + + "hikis-saveducatorahimeshimakanegasakinkobayashikshacknetnedalxn-" + + "-mgba3a4f16axn--mgba3a4franamizuholdingsmileirvikozagawaxn--mgba" + + "7c0bbn0axn--mgbaakc7dvfidonnakamuratakahamannortonsbergushikamif" + + "uranotairesewildlifestylexn--mgbaam7a8haldenxn--mgbab2bdxn--mgba" + + "i9a5eva00bauhausposts-and-telecommunicationsnasadoes-itveronagas" + + "ukemrxn--mgbai9azgqp6jewelryxn--mgbayh7gpaduaxn--mgbb9fbpobanaza" + + "waxn--mgbbh1a71exn--mgbc0a9azcgxn--mgbca7dzdownloadxn--mgberp4a5" + + "d4a87gxn--mgberp4a5d4arxn--mgbi4ecexposedxn--mgbpl2fhvalerxn--mg" + + "bqly7c0a67fbcivilisationxn--mgbqly7cvafredrikstadtvstorenburgxn-" + + "-mgbt3dhdxn--mgbtf8flekkefjordxn--mgbtx2bbcarrierxn--mgbx4cd0abb" + + "vieeexn--mix082fieldxn--mix891figuerestaurantoyonezawaxn--mjndal" + + "en-64axn--mk0axindustriesteamfamberkeleyxn--mk1bu44civilizationx" + + "n--mkru45iwchernovtsykkylvenetoeiheijis-a-doctorayxn--mlatvuopmi" + + "-s4axn--mli-tlapyatigorskozakis-an-entertainerxn--mlselv-iuaxn--" + + "moreke-juaxn--mori-qsakuhokkaidontexisteingeekpnxn--mosjen-eyato" + + "minamiawajikixn--mot-tlaquilancasterxn--mre-og-romsdal-qqbbtatar" + + "stanfshostrodawaravoues3-us-gov-west-1xn--msy-ula0halsaintlouis-" + + "a-anarchistoirehabmerxn--mtta-vrjjat-k7afamilycompanycivilwarman" + + "agementjomemorialukowhoswhokksundxn--muost-0qaxn--mxtq1misasagur" + + "is-leetrdxn--ngbc5azdxn--ngbe9e0axn--ngbrxn--42c2d9axn--nit225kp" + + "pspiegelxn--nmesjevuemie-tcbajddarchaeologyxn--nnx388axn--nodess" + + "akuragawaxn--nqv7fs00emaxn--nry-yla5gxn--ntso0iqx3axn--ntsq17gxn" + + "--nttery-byaeservegame-serverdalxn--nvuotna-hwaxn--nyqy26axn--o1" + + "achattanooganorilskleppharmacysnoasaitamatsukuris-not-certifiedo" + + "gawarabikomaezakirunoshiroomuraxn--o3cw4hammarfeastafricamagiche" + + "rnivtsiciliaxn--od0algxn--od0aq3bbvacationswatch-and-clockerxn--" + + "ogbpf8flesbergxn--oppegrd-ixaxn--ostery-fyatsukaratsuginamikatag" + + "amihoboleslawieclaimsavannahgaxn--osyro-wuaxn--p1acfdxn--p1aixn-" + + "-pbt977clickddielddanuorrikuzentakatajirissagaeroclubmedecincinn" + + "ationwidealerimo-i-ranadexchangeiseiyoichiropracticbcn-north-1xn" + + "--pgbs0dhlxn--porsgu-sta26filateliaxn--pssu33lxn--pssy2uxn--q9jy" + + "b4clinicateringebudejjuedischesapeakebayernurembergrondarxn--qck" + + "a1pmcdonaldstorfjordxn--qqqt11misawaxn--qxamurskinderoyxn--rady-" + + "iraxn--rdal-poaxn--rde-ularvikrasnodarxn--rdy-0nabarixn--rennesy" + + "-v1axn--rhkkervju-01aflakstadaokagakibichuoxn--rholt-mragowoodsi" + + "dexn--rhqv96gxn--rht27zxn--rht3dxn--rht61exn--risa-5narusawaxn--" + + "risr-iraxn--rland-uuaxn--rlingen-mxaxn--rmskog-byatsushiroxn--rn" + + "y31hamurakamigoriginshinshiroxn--rovu88bentleyukuhashimojiitateb" + + "ayashijonawatextileksvikashiharaxasmatartanddesignieznorddalavag" + + "iske12xn--rros-granvindafjordxn--rskog-uuaxn--rst-0narutokorozaw" + + "axn--rsta-francaiseharaxn--ryken-vuaxn--ryrvik-byawaraxn--s-1far" + + "eastcoastaldefencexn--s9brj9cliniquenoharaxn--sandnessjen-ogbizh" + + "evskrasnoyarskommunexn--sandy-yuaxn--seral-lraxn--ses554gxn--sgn" + + "e-gratangenxn--skierv-utazaskvolloabathsbclintonoshoesaves-the-w" + + "halessandria-trani-barletta-andriatranibarlettaandriaxn--skjervy" + + "-v1axn--skjk-soaxn--sknit-yqaxn--sknland-fxaxn--slat-5narviikana" + + "nporovnoxn--slt-elabourxn--smla-hraxn--smna-gratis-a-bulls-fanxn" + + "--snase-nraxn--sndre-land-0cbremangerxn--snes-poaxn--snsa-roaxn-" + + "-sr-aurdal-l8axn--sr-fron-q1axn--sr-odal-q1axn--sr-varanger-ggbe" + + "ppubolognagatorockartuzyurihonjournalistjordalshalsenhsamsclubin" + + "dalinkashiwaraxn--srfold-byawatahamaxn--srreisa-q1axn--srum-graz" + + "xn--stfold-9xaxn--stjrdal-s1axn--stjrdalshalsen-sqberndunloppaci" + + "ficartierxn--stre-toten-zcbstpetersburgxn--t60b56axn--tckweather" + + "channelxn--tiq49xqyjewishartgalleryxn--tjme-hraxn--tn0agrinetban" + + "kzxn--tnsberg-q1axn--tor131oxn--trany-yuaxn--trgstad-r1axn--trna" + + "-woaxn--troms-zuaxn--tysvr-vraxn--uc0atversicherungxn--uc0ay4axn" + + "--uist22hangoutsystemscloudcontrolapparmaxn--uisz3gxn--unjrga-rt" + + "aobaokinawashirosatobamagazinemurorangeologyxn--unup4yxn--uuwu58" + + "axn--vads-jraxn--vard-jraxn--vegrshei-c0axn--vermgensberater-ctb" + + "eskidynaliascoli-picenord-frontierxn--vermgensberatung-pwbestbuy" + + "shousesamsunglassassinationalheritagematsubarakawagoepostfoldnav" + + "yatkakudamatsuepsonyoursidegreevje-og-hornnesanfranciscotlanduns" + + "agamiharaxn--vestvgy-ixa6oxn--vg-yiabcgxn--vgan-qoaxn--vgsy-qoa0" + + "jfkomitamamuraxn--vgu402clothinguitarsavonaplesaxoxn--vhquvestfo" + + "ldxn--vler-qoaxn--vre-eiker-k8axn--vrggt-xqadxn--vry-yla5gxn--vu" + + "q861betainaboxfordeatnuorogersvpalanaklodzkodairaxn--w4r85el8fhu" + + "5dnraxn--w4rs40lxn--wcvs22dxn--wgbh1cloudfrontdoorxn--wgbl6axn--" + + "xhq521bhartiffanynysafetysfjordupontarioceanographiquexn--xkc2al" + + "3hye2axn--xkc2dl3a5ee0hannanmokuizumodernxn--y9a3aquariumisconfu" + + "sedxn--yer-znarvikredstonexn--yfro4i67oxn--ygarden-p1axn--ygbi2a" + + "mmxn--45brj9choyodobashichikashukujitawaraxn--ystre-slidre-ujbie" + + "lawallonieruchomoscienceandindustrynikiiyamanobeauxartsandcrafts" + + "angoddaxn--zbx025dxn--zf0ao64axn--zf0avxn--45q11christmasakikuga" + + "watchesatxjaworznoxn--zfr164biellaakesvuemieleccexperiaxz" + +// nodes is the list of nodes. Each node is represented as a uint32, which +// encodes the node's children, wildcard bit and node type (as an index into +// the children array), ICANN bit and text. +// +// In the //-comment after each node's data, the nodes indexes of the children +// are formatted as (n0x1234-n0x1256), with * denoting the wildcard bit. The +// nodeType is printed as + for normal, ! for exception, and o for parent-only +// nodes that have children but don't match a domain label in their own right. +// An I denotes an ICANN domain. +// +// The layout within the uint32, from MSB to LSB, is: +// [ 1 bits] unused +// [ 9 bits] children index +// [ 1 bits] ICANN bit +// [15 bits] text index +// [ 6 bits] text length +var nodes = [...]uint32{ + 0x00352883, // n0x0000 c0x0000 (---------------) + I aaa + 0x0034ae44, // n0x0001 c0x0000 (---------------) + I aarp + 0x00250d46, // n0x0002 c0x0000 (---------------) + I abarth + 0x0023e483, // n0x0003 c0x0000 (---------------) + I abb + 0x0023e486, // n0x0004 c0x0000 (---------------) + I abbott + 0x00365f46, // n0x0005 c0x0000 (---------------) + I abbvie + 0x0039a8c3, // n0x0006 c0x0000 (---------------) + I abc + 0x0031f604, // n0x0007 c0x0000 (---------------) + I able + 0x00329987, // n0x0008 c0x0000 (---------------) + I abogado + 0x00250988, // n0x0009 c0x0000 (---------------) + I abudhabi + 0x01a00342, // n0x000a c0x0006 (n0x0607-n0x060d) + I ac + 0x0030cf07, // n0x000b c0x0000 (---------------) + I academy + 0x0034fd09, // n0x000c c0x0000 (---------------) + I accenture + 0x002cfaca, // n0x000d c0x0000 (---------------) + I accountant + 0x002cfacb, // n0x000e c0x0000 (---------------) + I accountants + 0x00233d03, // n0x000f c0x0000 (---------------) + I aco + 0x0028c8c6, // n0x0010 c0x0000 (---------------) + I active + 0x00239e85, // n0x0011 c0x0000 (---------------) + I actor + 0x01e001c2, // n0x0012 c0x0007 (n0x060d-n0x060e) + I ad + 0x00212904, // n0x0013 c0x0000 (---------------) + I adac + 0x0025ab43, // n0x0014 c0x0000 (---------------) + I ads + 0x002a3105, // n0x0015 c0x0000 (---------------) + I adult + 0x022030c2, // n0x0016 c0x0008 (n0x060e-n0x0616) + I ae + 0x00255e03, // n0x0017 c0x0000 (---------------) + I aeg + 0x026e2dc4, // n0x0018 c0x0009 (n0x0616-n0x066d) + I aero + 0x0026af85, // n0x0019 c0x0000 (---------------) + I aetna + 0x02a05242, // n0x001a c0x000a (n0x066d-n0x0672) + I af + 0x0036d9ce, // n0x001b c0x0000 (---------------) + I afamilycompany + 0x00251303, // n0x001c c0x0000 (---------------) + I afl + 0x00374cc6, // n0x001d c0x0000 (---------------) + I africa + 0x00374ccb, // n0x001e c0x0000 (---------------) + I africamagic + 0x02e01b82, // n0x001f c0x000b (n0x0672-n0x0677) + I ag + 0x00283a87, // n0x0020 c0x0000 (---------------) + I agakhan + 0x0023cc46, // n0x0021 c0x0000 (---------------) + I agency + 0x03200502, // n0x0022 c0x000c (n0x0677-n0x067b) + I ai + 0x00215703, // n0x0023 c0x0000 (---------------) + I aig + 0x00215704, // n0x0024 c0x0000 (---------------) + I aigo + 0x002b7a06, // n0x0025 c0x0000 (---------------) + I airbus + 0x003385c8, // n0x0026 c0x0000 (---------------) + I airforce + 0x00285646, // n0x0027 c0x0000 (---------------) + I airtel + 0x00229704, // n0x0028 c0x0000 (---------------) + I akdn + 0x03600d02, // n0x0029 c0x000d (n0x067b-n0x0682) + I al + 0x00329f49, // n0x002a c0x0000 (---------------) + I alfaromeo + 0x0031f947, // n0x002b c0x0000 (---------------) + I alibaba + 0x002be246, // n0x002c c0x0000 (---------------) + I alipay + 0x0033e289, // n0x002d c0x0000 (---------------) + I allfinanz + 0x0020a148, // n0x002e c0x0000 (---------------) + I allstate + 0x00212f04, // n0x002f c0x0000 (---------------) + I ally + 0x00222006, // n0x0030 c0x0000 (---------------) + I alsace + 0x0020adc6, // n0x0031 c0x0000 (---------------) + I alstom + 0x03a00942, // n0x0032 c0x000e (n0x0682-n0x0683) + I am + 0x0024678f, // n0x0033 c0x0000 (---------------) + I americanexpress + 0x00207b4e, // n0x0034 c0x0000 (---------------) + I americanfamily + 0x00200944, // n0x0035 c0x0000 (---------------) + I amex + 0x003676c5, // n0x0036 c0x0000 (---------------) + I amfam + 0x0023e385, // n0x0037 c0x0000 (---------------) + I amica + 0x002c0509, // n0x0038 c0x0000 (---------------) + I amsterdam + 0x00243249, // n0x0039 c0x0000 (---------------) + I analytics + 0x00321107, // n0x003a c0x0000 (---------------) + I android + 0x0034e986, // n0x003b c0x0000 (---------------) + I anquan + 0x0024bac3, // n0x003c c0x0000 (---------------) + I anz + 0x03e02882, // n0x003d c0x000f (n0x0683-n0x0689) + I ao + 0x00275443, // n0x003e c0x0000 (---------------) + I aol + 0x0023d94a, // n0x003f c0x0000 (---------------) + I apartments + 0x00208083, // n0x0040 c0x0000 (---------------) + I app + 0x0026c205, // n0x0041 c0x0000 (---------------) + I apple + 0x00200f02, // n0x0042 c0x0000 (---------------) + I aq + 0x00286809, // n0x0043 c0x0000 (---------------) + I aquarelle + 0x04201d42, // n0x0044 c0x0010 (n0x0689-n0x0692) + I ar + 0x00202344, // n0x0045 c0x0000 (---------------) + I arab + 0x003523c6, // n0x0046 c0x0000 (---------------) + I aramco + 0x00308e45, // n0x0047 c0x0000 (---------------) + I archi + 0x00346644, // n0x0048 c0x0000 (---------------) + I army + 0x04a54644, // n0x0049 c0x0012 (n0x0693-n0x0699) + I arpa + 0x00239044, // n0x004a c0x0000 (---------------) + I arte + 0x04e03302, // n0x004b c0x0013 (n0x0699-n0x069a) + I as + 0x0034ab84, // n0x004c c0x0000 (---------------) + I asda + 0x00312a84, // n0x004d c0x0000 (---------------) + I asia + 0x00336d8a, // n0x004e c0x0000 (---------------) + I associates + 0x05200482, // n0x004f c0x0014 (n0x069a-n0x06a1) + I at + 0x00248447, // n0x0050 c0x0000 (---------------) + I athleta + 0x00309308, // n0x0051 c0x0000 (---------------) + I attorney + 0x05a05782, // n0x0052 c0x0016 (n0x06a2-n0x06b4) + I au + 0x0031c647, // n0x0053 c0x0000 (---------------) + I auction + 0x00232e44, // n0x0054 c0x0000 (---------------) + I audi + 0x002b8f07, // n0x0055 c0x0000 (---------------) + I audible + 0x00232e45, // n0x0056 c0x0000 (---------------) + I audio + 0x00360347, // n0x0057 c0x0000 (---------------) + I auspost + 0x00320ec6, // n0x0058 c0x0000 (---------------) + I author + 0x00229f44, // n0x0059 c0x0000 (---------------) + I auto + 0x00324485, // n0x005a c0x0000 (---------------) + I autos + 0x002dbe87, // n0x005b c0x0000 (---------------) + I avianca + 0x06a01c02, // n0x005c c0x001a (n0x06c2-n0x06c3) + I aw + 0x002f2043, // n0x005d c0x0000 (---------------) + I aws + 0x00224142, // n0x005e c0x0000 (---------------) + I ax + 0x003827c3, // n0x005f c0x0000 (---------------) + I axa + 0x06e03442, // n0x0060 c0x001b (n0x06c3-n0x06cf) + I az + 0x00281bc5, // n0x0061 c0x0000 (---------------) + I azure + 0x07200882, // n0x0062 c0x001c (n0x06cf-n0x06da) + I ba + 0x003025c4, // n0x0063 c0x0000 (---------------) + I baby + 0x0027cd45, // n0x0064 c0x0000 (---------------) + I baidu + 0x00200887, // n0x0065 c0x0000 (---------------) + I banamex + 0x002f2f0e, // n0x0066 c0x0000 (---------------) + I bananarepublic + 0x00206a84, // n0x0067 c0x0000 (---------------) + I band + 0x00203204, // n0x0068 c0x0000 (---------------) + I bank + 0x002049c3, // n0x0069 c0x0000 (---------------) + I bar + 0x002e3209, // n0x006a c0x0000 (---------------) + I barcelona + 0x002c304b, // n0x006b c0x0000 (---------------) + I barclaycard + 0x002dc488, // n0x006c c0x0000 (---------------) + I barclays + 0x00307448, // n0x006d c0x0000 (---------------) + I barefoot + 0x00310808, // n0x006e c0x0000 (---------------) + I bargains + 0x0022df88, // n0x006f c0x0000 (---------------) + I baseball + 0x0033e0ca, // n0x0070 c0x0000 (---------------) + I basketball + 0x00360247, // n0x0071 c0x0000 (---------------) + I bauhaus + 0x0037b946, // n0x0072 c0x0000 (---------------) + I bayern + 0x0763e4c2, // n0x0073 c0x001d (n0x06da-n0x06e4) + I bb + 0x00365a03, // n0x0074 c0x0000 (---------------) + I bbc + 0x0036be43, // n0x0075 c0x0000 (---------------) + I bbt + 0x00375804, // n0x0076 c0x0000 (---------------) + I bbva + 0x0039a903, // n0x0077 c0x0000 (---------------) + I bcg + 0x00379cc3, // n0x0078 c0x0000 (---------------) + I bcn + 0x01714f02, // n0x0079 c0x0005 (---------------)* o I bd + 0x07a02e02, // n0x007a c0x001e (n0x06e4-n0x06e6) + I be + 0x0021acc5, // n0x007b c0x0000 (---------------) + I beats + 0x0024fac6, // n0x007c c0x0000 (---------------) + I beauty + 0x002ce284, // n0x007d c0x0000 (---------------) + I beer + 0x003819c7, // n0x007e c0x0000 (---------------) + I bentley + 0x0022fc06, // n0x007f c0x0000 (---------------) + I berlin + 0x00354f84, // n0x0080 c0x0000 (---------------) + I best + 0x00397e47, // n0x0081 c0x0000 (---------------) + I bestbuy + 0x002079c3, // n0x0082 c0x0000 (---------------) + I bet + 0x07f5b5c2, // n0x0083 c0x001f (n0x06e6-n0x06e7) + I bf + 0x08304a82, // n0x0084 c0x0020 (n0x06e7-n0x070c) + I bg + 0x0870ebc2, // n0x0085 c0x0021 (n0x070c-n0x0711) + I bh + 0x0039f186, // n0x0086 c0x0000 (---------------) + I bharti + 0x08a00002, // n0x0087 c0x0022 (n0x0711-n0x0716) + I bi + 0x00356b45, // n0x0088 c0x0000 (---------------) + I bible + 0x00316443, // n0x0089 c0x0000 (---------------) + I bid + 0x00202404, // n0x008a c0x0000 (---------------) + I bike + 0x002dc2c4, // n0x008b c0x0000 (---------------) + I bing + 0x002dc2c5, // n0x008c c0x0000 (---------------) + I bingo + 0x00203e43, // n0x008d c0x0000 (---------------) + I bio + 0x08f31a83, // n0x008e c0x0023 (n0x0716-n0x071e) + I biz + 0x0920b442, // n0x008f c0x0024 (n0x071e-n0x0722) + I bj + 0x0028b585, // n0x0090 c0x0000 (---------------) + I black + 0x0028b58b, // n0x0091 c0x0000 (---------------) + I blackfriday + 0x00259006, // n0x0092 c0x0000 (---------------) + I blanco + 0x0020db0b, // n0x0093 c0x0000 (---------------) + I blockbuster + 0x0022f084, // n0x0094 c0x0000 (---------------) + I blog + 0x0020e289, // n0x0095 c0x0000 (---------------) + I bloomberg + 0x0020f384, // n0x0096 c0x0000 (---------------) + I blue + 0x0960f9c2, // n0x0097 c0x0025 (n0x0722-n0x0727) + I bm + 0x00210f03, // n0x0098 c0x0000 (---------------) + I bms + 0x00211fc3, // n0x0099 c0x0000 (---------------) + I bmw + 0x01612142, // n0x009a c0x0005 (---------------)* o I bn + 0x00246cc3, // n0x009b c0x0000 (---------------) + I bnl + 0x0021214a, // n0x009c c0x0000 (---------------) + I bnpparibas + 0x09a0f682, // n0x009d c0x0026 (n0x0727-n0x0730) + I bo + 0x0030d185, // n0x009e c0x0000 (---------------) + I boats + 0x0020f68a, // n0x009f c0x0000 (---------------) + I boehringer + 0x00292584, // n0x00a0 c0x0000 (---------------) + I bofa + 0x00213983, // n0x00a1 c0x0000 (---------------) + I bom + 0x00213fc4, // n0x00a2 c0x0000 (---------------) + I bond + 0x00215e03, // n0x00a3 c0x0000 (---------------) + I boo + 0x00215e04, // n0x00a4 c0x0000 (---------------) + I book + 0x00215e07, // n0x00a5 c0x0000 (---------------) + I booking + 0x00216f45, // n0x00a6 c0x0000 (---------------) + I boots + 0x00217205, // n0x00a7 c0x0000 (---------------) + I bosch + 0x00218406, // n0x00a8 c0x0000 (---------------) + I bostik + 0x00218f86, // n0x00a9 c0x0000 (---------------) + I boston + 0x0021b743, // n0x00aa c0x0000 (---------------) + I bot + 0x0021d848, // n0x00ab c0x0000 (---------------) + I boutique + 0x00219643, // n0x00ac c0x0000 (---------------) + I box + 0x09e1e3c2, // n0x00ad c0x0027 (n0x0730-n0x0776) + I br + 0x0021eb48, // n0x00ae c0x0000 (---------------) + I bradesco + 0x0021e3cb, // n0x00af c0x0000 (---------------) + I bridgestone + 0x00223d48, // n0x00b0 c0x0000 (---------------) + I broadway + 0x00224906, // n0x00b1 c0x0000 (---------------) + I broker + 0x00225887, // n0x00b2 c0x0000 (---------------) + I brother + 0x00228408, // n0x00b3 c0x0000 (---------------) + I brussels + 0x0a630fc2, // n0x00b4 c0x0029 (n0x0777-n0x077c) + I bs + 0x0aa23a42, // n0x00b5 c0x002a (n0x077c-n0x0781) + I bt + 0x00208dc8, // n0x00b6 c0x0000 (---------------) + I budapest + 0x002e6907, // n0x00b7 c0x0000 (---------------) + I bugatti + 0x00241085, // n0x00b8 c0x0000 (---------------) + I build + 0x00241088, // n0x00b9 c0x0000 (---------------) + I builders + 0x002b8308, // n0x00ba c0x0000 (---------------) + I business + 0x002fefc3, // n0x00bb c0x0000 (---------------) + I buy + 0x0022f404, // n0x00bc c0x0000 (---------------) + I buzz + 0x00365fc2, // n0x00bd c0x0000 (---------------) + I bv + 0x0ae30202, // n0x00be c0x002b (n0x0781-n0x0783) + I bw + 0x0b20d202, // n0x00bf c0x002c (n0x0783-n0x0787) + I by + 0x0ba30682, // n0x00c0 c0x002e (n0x0788-n0x078e) + I bz + 0x00230683, // n0x00c1 c0x0000 (---------------) + I bzh + 0x0be00e42, // n0x00c2 c0x002f (n0x078e-n0x079f) + I ca + 0x0023e443, // n0x00c3 c0x0000 (---------------) + I cab + 0x00310d04, // n0x00c4 c0x0000 (---------------) + I cafe + 0x00212ec3, // n0x00c5 c0x0000 (---------------) + I cal + 0x00212ec4, // n0x00c6 c0x0000 (---------------) + I call + 0x0032914b, // n0x00c7 c0x0000 (---------------) + I calvinklein + 0x0023ec46, // n0x00c8 c0x0000 (---------------) + I camera + 0x00241bc4, // n0x00c9 c0x0000 (---------------) + I camp + 0x002a100e, // n0x00ca c0x0000 (---------------) + I cancerresearch + 0x00263685, // n0x00cb c0x0000 (---------------) + I canon + 0x002dbfc8, // n0x00cc c0x0000 (---------------) + I capetown + 0x002ec107, // n0x00cd c0x0000 (---------------) + I capital + 0x002ec10a, // n0x00ce c0x0000 (---------------) + I capitalone + 0x0020cb43, // n0x00cf c0x0000 (---------------) + I car + 0x002370c7, // n0x00d0 c0x0000 (---------------) + I caravan + 0x002c3205, // n0x00d1 c0x0000 (---------------) + I cards + 0x002ae704, // n0x00d2 c0x0000 (---------------) + I care + 0x002ae706, // n0x00d3 c0x0000 (---------------) + I career + 0x002ae707, // n0x00d4 c0x0000 (---------------) + I careers + 0x002bd384, // n0x00d5 c0x0000 (---------------) + I cars + 0x00390087, // n0x00d6 c0x0000 (---------------) + I cartier + 0x00215004, // n0x00d7 c0x0000 (---------------) + I casa + 0x00217e44, // n0x00d8 c0x0000 (---------------) + I case + 0x00217e46, // n0x00d9 c0x0000 (---------------) + I caseih + 0x002cb1c4, // n0x00da c0x0000 (---------------) + I cash + 0x00356846, // n0x00db c0x0000 (---------------) + I casino + 0x0020f1c3, // n0x00dc c0x0000 (---------------) + I cat + 0x0037b1c8, // n0x00dd c0x0000 (---------------) + I catering + 0x0023cf88, // n0x00de c0x0000 (---------------) + I catholic + 0x0024a9c3, // n0x00df c0x0000 (---------------) + I cba + 0x00246c83, // n0x00e0 c0x0000 (---------------) + I cbn + 0x0038b6c4, // n0x00e1 c0x0000 (---------------) + I cbre + 0x00390643, // n0x00e2 c0x0000 (---------------) + I cbs + 0x0c22f6c2, // n0x00e3 c0x0030 (n0x079f-n0x07a3) + I cc + 0x0c662e02, // n0x00e4 c0x0031 (n0x07a3-n0x07a4) + I cd + 0x00205cc3, // n0x00e5 c0x0000 (---------------) + I ceb + 0x00204c86, // n0x00e6 c0x0000 (---------------) + I center + 0x002c0883, // n0x00e7 c0x0000 (---------------) + I ceo + 0x002e6f84, // n0x00e8 c0x0000 (---------------) + I cern + 0x0ca14c02, // n0x00e9 c0x0032 (n0x07a4-n0x07a5) + I cf + 0x00214c03, // n0x00ea c0x0000 (---------------) + I cfa + 0x00377c83, // n0x00eb c0x0000 (---------------) + I cfd + 0x0021be82, // n0x00ec c0x0000 (---------------) + I cg + 0x0ce00382, // n0x00ed c0x0033 (n0x07a5-n0x07a6) + I ch + 0x002bc906, // n0x00ee c0x0000 (---------------) + I chanel + 0x0023ad87, // n0x00ef c0x0000 (---------------) + I channel + 0x00335885, // n0x00f0 c0x0000 (---------------) + I chase + 0x0021a404, // n0x00f1 c0x0000 (---------------) + I chat + 0x00284485, // n0x00f2 c0x0000 (---------------) + I cheap + 0x00201487, // n0x00f3 c0x0000 (---------------) + I chintai + 0x002b7785, // n0x00f4 c0x0000 (---------------) + I chloe + 0x003a4c09, // n0x00f5 c0x0000 (---------------) + I christmas + 0x00303446, // n0x00f6 c0x0000 (---------------) + I chrome + 0x00304108, // n0x00f7 c0x0000 (---------------) + I chrysler + 0x00335786, // n0x00f8 c0x0000 (---------------) + I church + 0x0d209602, // n0x00f9 c0x0034 (n0x07a6-n0x07b5) + I ci + 0x00234f48, // n0x00fa c0x0000 (---------------) + I cipriani + 0x00337606, // n0x00fb c0x0000 (---------------) + I circle + 0x00399cc5, // n0x00fc c0x0000 (---------------) + I cisco + 0x0034f187, // n0x00fd c0x0000 (---------------) + I citadel + 0x00356744, // n0x00fe c0x0000 (---------------) + I citi + 0x00356745, // n0x00ff c0x0000 (---------------) + I citic + 0x00285804, // n0x0100 c0x0000 (---------------) + I city + 0x00285808, // n0x0101 c0x0000 (---------------) + I cityeats + 0x0d60d082, // n0x0102 c0x0035 (n0x07b5-n0x07b6)* o I ck + 0x0da07f42, // n0x0103 c0x0036 (n0x07b6-n0x07bb) + I cl + 0x003773c6, // n0x0104 c0x0000 (---------------) + I claims + 0x00227b48, // n0x0105 c0x0000 (---------------) + I cleaning + 0x003781c5, // n0x0106 c0x0000 (---------------) + I click + 0x0037b086, // n0x0107 c0x0000 (---------------) + I clinic + 0x00385708, // n0x0108 c0x0000 (---------------) + I clinique + 0x0039b608, // n0x0109 c0x0000 (---------------) + I clothing + 0x00207f45, // n0x010a c0x0000 (---------------) + I cloud + 0x00378c44, // n0x010b c0x0000 (---------------) + I club + 0x00378c47, // n0x010c c0x0000 (---------------) + I clubmed + 0x0de5cd02, // n0x010d c0x0037 (n0x07bb-n0x07bf) + I cm + 0x0e21dac2, // n0x010e c0x0038 (n0x07bf-n0x07ec) + I cn + 0x0fa0ce42, // n0x010f c0x003e (n0x07f1-n0x07fe) + I co + 0x0033f105, // n0x0110 c0x0000 (---------------) + I coach + 0x0029c345, // n0x0111 c0x0000 (---------------) + I codes + 0x0020ce46, // n0x0112 c0x0000 (---------------) + I coffee + 0x0022f707, // n0x0113 c0x0000 (---------------) + I college + 0x00231707, // n0x0114 c0x0000 (---------------) + I cologne + 0x10233243, // n0x0115 c0x0040 (n0x07ff-n0x08d1) + I com + 0x002a7d07, // n0x0116 c0x0000 (---------------) + I comcast + 0x002d8ec8, // n0x0117 c0x0000 (---------------) + I commbank + 0x00233249, // n0x0118 c0x0000 (---------------) + I community + 0x0036db87, // n0x0119 c0x0000 (---------------) + I company + 0x00233f47, // n0x011a c0x0000 (---------------) + I compare + 0x00235b08, // n0x011b c0x0000 (---------------) + I computer + 0x00236306, // n0x011c c0x0000 (---------------) + I comsec + 0x002368c6, // n0x011d c0x0000 (---------------) + I condos + 0x002375cc, // n0x011e c0x0000 (---------------) + I construction + 0x0023830a, // n0x011f c0x0000 (---------------) + I consulting + 0x002387c7, // n0x0120 c0x0000 (---------------) + I contact + 0x00239d4b, // n0x0121 c0x0000 (---------------) + I contractors + 0x0023abc7, // n0x0122 c0x0000 (---------------) + I cooking + 0x0023abce, // n0x0123 c0x0000 (---------------) + I cookingchannel + 0x0023b6c4, // n0x0124 c0x0000 (---------------) + I cool + 0x0023c344, // n0x0125 c0x0000 (---------------) + I coop + 0x0023f147, // n0x0126 c0x0000 (---------------) + I corsica + 0x00337987, // n0x0127 c0x0000 (---------------) + I country + 0x002424c6, // n0x0128 c0x0000 (---------------) + I coupon + 0x002424c7, // n0x0129 c0x0000 (---------------) + I coupons + 0x00242ac7, // n0x012a c0x0000 (---------------) + I courses + 0x11a051c2, // n0x012b c0x0046 (n0x08f0-n0x08f7) + I cr + 0x00243786, // n0x012c c0x0000 (---------------) + I credit + 0x0024378a, // n0x012d c0x0000 (---------------) + I creditcard + 0x00243a0b, // n0x012e c0x0000 (---------------) + I creditunion + 0x00244b07, // n0x012f c0x0000 (---------------) + I cricket + 0x002454c5, // n0x0130 c0x0000 (---------------) + I crown + 0x00245603, // n0x0131 c0x0000 (---------------) + I crs + 0x00245f46, // n0x0132 c0x0000 (---------------) + I cruise + 0x00245f47, // n0x0133 c0x0000 (---------------) + I cruises + 0x00243403, // n0x0134 c0x0000 (---------------) + I csc + 0x11e08b42, // n0x0135 c0x0047 (n0x08f7-n0x08fd) + I cu + 0x0024640a, // n0x0136 c0x0000 (---------------) + I cuisinella + 0x12350e42, // n0x0137 c0x0048 (n0x08fd-n0x08fe) + I cv + 0x126cadc2, // n0x0138 c0x0049 (n0x08fe-n0x0902) + I cw + 0x12a477c2, // n0x0139 c0x004a (n0x0902-n0x0904) + I cx + 0x12e3cd42, // n0x013a c0x004b (n0x0904-n0x0911) o I cy + 0x0024a0c5, // n0x013b c0x0000 (---------------) + I cymru + 0x0024a7c4, // n0x013c c0x0000 (---------------) + I cyou + 0x13600142, // n0x013d c0x004d (n0x0912-n0x0914) + I cz + 0x0034ac05, // n0x013e c0x0000 (---------------) + I dabur + 0x002a30c3, // n0x013f c0x0000 (---------------) + I dad + 0x002275c5, // n0x0140 c0x0000 (---------------) + I dance + 0x0020da04, // n0x0141 c0x0000 (---------------) + I date + 0x0020f486, // n0x0142 c0x0000 (---------------) + I dating + 0x00294506, // n0x0143 c0x0000 (---------------) + I datsun + 0x00263b83, // n0x0144 c0x0000 (---------------) + I day + 0x0023f984, // n0x0145 c0x0000 (---------------) + I dclk + 0x0026bd03, // n0x0146 c0x0000 (---------------) + I dds + 0x13a05582, // n0x0147 c0x004e (n0x0914-n0x091c) + I de + 0x00205584, // n0x0148 c0x0000 (---------------) + I deal + 0x003791c6, // n0x0149 c0x0000 (---------------) + I dealer + 0x00205585, // n0x014a c0x0000 (---------------) + I deals + 0x00399646, // n0x014b c0x0000 (---------------) + I degree + 0x0034f288, // n0x014c c0x0000 (---------------) + I delivery + 0x0025a104, // n0x014d c0x0000 (---------------) + I dell + 0x00320608, // n0x014e c0x0000 (---------------) + I deloitte + 0x00288905, // n0x014f c0x0000 (---------------) + I delta + 0x00224608, // n0x0150 c0x0000 (---------------) + I democrat + 0x002aca06, // n0x0151 c0x0000 (---------------) + I dental + 0x002b3f87, // n0x0152 c0x0000 (---------------) + I dentist + 0x00228204, // n0x0153 c0x0000 (---------------) + I desi + 0x00228206, // n0x0154 c0x0000 (---------------) + I design + 0x0032b083, // n0x0155 c0x0000 (---------------) + I dev + 0x0037a1c3, // n0x0156 c0x0000 (---------------) + I dhl + 0x002c6088, // n0x0157 c0x0000 (---------------) + I diamonds + 0x0030ed44, // n0x0158 c0x0000 (---------------) + I diet + 0x002f4847, // n0x0159 c0x0000 (---------------) + I digital + 0x0024da86, // n0x015a c0x0000 (---------------) + I direct + 0x0024da89, // n0x015b c0x0000 (---------------) + I directory + 0x00321288, // n0x015c c0x0000 (---------------) + I discount + 0x00331308, // n0x015d c0x0000 (---------------) + I discover + 0x003550c4, // n0x015e c0x0000 (---------------) + I dish + 0x00309c83, // n0x015f c0x0000 (---------------) + I diy + 0x0024e002, // n0x0160 c0x0000 (---------------) + I dj + 0x13e489c2, // n0x0161 c0x004f (n0x091c-n0x091d) + I dk + 0x1420d302, // n0x0162 c0x0050 (n0x091d-n0x0922) + I dm + 0x00311b83, // n0x0163 c0x0000 (---------------) + I dnp + 0x14612c02, // n0x0164 c0x0051 (n0x0922-n0x092c) + I do + 0x00329ac4, // n0x0165 c0x0000 (---------------) + I docs + 0x00212c05, // n0x0166 c0x0000 (---------------) + I dodge + 0x00230503, // n0x0167 c0x0000 (---------------) + I dog + 0x002366c4, // n0x0168 c0x0000 (---------------) + I doha + 0x003011c7, // n0x0169 c0x0000 (---------------) + I domains + 0x0023be46, // n0x016a c0x0000 (---------------) + I doosan + 0x00354243, // n0x016b c0x0000 (---------------) + I dot + 0x00362ac8, // n0x016c c0x0000 (---------------) + I download + 0x003519c5, // n0x016d c0x0000 (---------------) + I drive + 0x00249084, // n0x016e c0x0000 (---------------) + I dstv + 0x00364c03, // n0x016f c0x0000 (---------------) + I dtv + 0x0027ccc5, // n0x0170 c0x0000 (---------------) + I dubai + 0x0027ce04, // n0x0171 c0x0000 (---------------) + I duck + 0x0038fd86, // n0x0172 c0x0000 (---------------) + I dunlop + 0x00399f04, // n0x0173 c0x0000 (---------------) + I duns + 0x0039f786, // n0x0174 c0x0000 (---------------) + I dupont + 0x002007c6, // n0x0175 c0x0000 (---------------) + I durban + 0x00319904, // n0x0176 c0x0000 (---------------) + I dvag + 0x00211443, // n0x0177 c0x0000 (---------------) + I dwg + 0x14a06842, // n0x0178 c0x0052 (n0x092c-n0x0934) + I dz + 0x00283945, // n0x0179 c0x0000 (---------------) + I earth + 0x0021ad03, // n0x017a c0x0000 (---------------) + I eat + 0x14e088c2, // n0x017b c0x0053 (n0x0934-n0x0940) + I ec + 0x002b4a45, // n0x017c c0x0000 (---------------) + I edeka + 0x00239103, // n0x017d c0x0000 (---------------) + I edu + 0x00239109, // n0x017e c0x0000 (---------------) + I education + 0x1520cf42, // n0x017f c0x0054 (n0x0940-n0x094a) + I ee + 0x15a07202, // n0x0180 c0x0056 (n0x094b-n0x0954) + I eg + 0x00302985, // n0x0181 c0x0000 (---------------) + I email + 0x002b4346, // n0x0182 c0x0000 (---------------) + I emerck + 0x003532c7, // n0x0183 c0x0000 (---------------) + I emerson + 0x002cca86, // n0x0184 c0x0000 (---------------) + I energy + 0x0030c4c8, // n0x0185 c0x0000 (---------------) + I engineer + 0x0030c4cb, // n0x0186 c0x0000 (---------------) + I engineering + 0x00204ccb, // n0x0187 c0x0000 (---------------) + I enterprises + 0x00398d05, // n0x0188 c0x0000 (---------------) + I epost + 0x00399385, // n0x0189 c0x0000 (---------------) + I epson + 0x002c4489, // n0x018a c0x0000 (---------------) + I equipment + 0x01600682, // n0x018b c0x0005 (---------------)* o I er + 0x00319ac8, // n0x018c c0x0000 (---------------) + I ericsson + 0x0020dd44, // n0x018d c0x0000 (---------------) + I erni + 0x16200082, // n0x018e c0x0058 (n0x0955-n0x095a) + I es + 0x0027a103, // n0x018f c0x0000 (---------------) + I esq + 0x002c4206, // n0x0190 c0x0000 (---------------) + I estate + 0x0033ce08, // n0x0191 c0x0000 (---------------) + I esurance + 0x16a00a42, // n0x0192 c0x005a (n0x095b-n0x0963) + I et + 0x00226d48, // n0x0193 c0x0000 (---------------) + I etisalat + 0x00205382, // n0x0194 c0x0000 (---------------) + I eu + 0x0027bb4a, // n0x0195 c0x0000 (---------------) + I eurovision + 0x0022a283, // n0x0196 c0x0000 (---------------) + I eus + 0x0032b0c6, // n0x0197 c0x0000 (---------------) + I events + 0x00203108, // n0x0198 c0x0000 (---------------) + I everbank + 0x00379608, // n0x0199 c0x0000 (---------------) + I exchange + 0x0031f2c6, // n0x019a c0x0000 (---------------) + I expert + 0x00363887, // n0x019b c0x0000 (---------------) + I exposed + 0x00246987, // n0x019c c0x0000 (---------------) + I express + 0x0020a94a, // n0x019d c0x0000 (---------------) + I extraspace + 0x00292604, // n0x019e c0x0000 (---------------) + I fage + 0x00214c44, // n0x019f c0x0000 (---------------) + I fail + 0x0033b5c9, // n0x01a0 c0x0000 (---------------) + I fairwinds + 0x0034e685, // n0x01a1 c0x0000 (---------------) + I faith + 0x00207d46, // n0x01a2 c0x0000 (---------------) + I family + 0x00210883, // n0x01a3 c0x0000 (---------------) + I fan + 0x002e08c4, // n0x01a4 c0x0000 (---------------) + I fans + 0x0026a084, // n0x01a5 c0x0000 (---------------) + I farm + 0x00327f47, // n0x01a6 c0x0000 (---------------) + I farmers + 0x00230287, // n0x01a7 c0x0000 (---------------) + I fashion + 0x00246284, // n0x01a8 c0x0000 (---------------) + I fast + 0x00210085, // n0x01a9 c0x0000 (---------------) + I fedex + 0x0020cf08, // n0x01aa c0x0000 (---------------) + I feedback + 0x002ff307, // n0x01ab c0x0000 (---------------) + I ferrari + 0x003369c7, // n0x01ac c0x0000 (---------------) + I ferrero + 0x16e01702, // n0x01ad c0x005b (n0x0963-n0x0966) + I fi + 0x00296004, // n0x01ae c0x0000 (---------------) + I fiat + 0x0035b608, // n0x01af c0x0000 (---------------) + I fidelity + 0x0035e584, // n0x01b0 c0x0000 (---------------) + I fido + 0x0024b184, // n0x01b1 c0x0000 (---------------) + I film + 0x0024b545, // n0x01b2 c0x0000 (---------------) + I final + 0x0024b687, // n0x01b3 c0x0000 (---------------) + I finance + 0x002094c9, // n0x01b4 c0x0000 (---------------) + I financial + 0x0024c584, // n0x01b5 c0x0000 (---------------) + I fire + 0x0024d7c9, // n0x01b6 c0x0000 (---------------) + I firestone + 0x0024dcc8, // n0x01b7 c0x0000 (---------------) + I firmdale + 0x0024ec04, // n0x01b8 c0x0000 (---------------) + I fish + 0x0024ec07, // n0x01b9 c0x0000 (---------------) + I fishing + 0x0024f583, // n0x01ba c0x0000 (---------------) + I fit + 0x0024fd07, // n0x01bb c0x0000 (---------------) + I fitness + 0x0161cc42, // n0x01bc c0x0005 (---------------)* o I fj + 0x0179b042, // n0x01bd c0x0005 (---------------)* o I fk + 0x002503c6, // n0x01be c0x0000 (---------------) + I flickr + 0x00251347, // n0x01bf c0x0000 (---------------) + I flights + 0x00251c04, // n0x01c0 c0x0000 (---------------) + I flir + 0x00252ac7, // n0x01c1 c0x0000 (---------------) + I florist + 0x00254447, // n0x01c2 c0x0000 (---------------) + I flowers + 0x00254848, // n0x01c3 c0x0000 (---------------) + I flsmidth + 0x00254ec3, // n0x01c4 c0x0000 (---------------) + I fly + 0x00234802, // n0x01c5 c0x0000 (---------------) + I fm + 0x002018c2, // n0x01c6 c0x0000 (---------------) + I fo + 0x002564c3, // n0x01c7 c0x0000 (---------------) + I foo + 0x002564cb, // n0x01c8 c0x0000 (---------------) + I foodnetwork + 0x00307548, // n0x01c9 c0x0000 (---------------) + I football + 0x0039d384, // n0x01ca c0x0000 (---------------) + I ford + 0x00257bc5, // n0x01cb c0x0000 (---------------) + I forex + 0x00259507, // n0x01cc c0x0000 (---------------) + I forsale + 0x0025aec5, // n0x01cd c0x0000 (---------------) + I forum + 0x002b9f8a, // n0x01ce c0x0000 (---------------) + I foundation + 0x0025c543, // n0x01cf c0x0000 (---------------) + I fox + 0x17240202, // n0x01d0 c0x005c (n0x0966-n0x097e) + I fr + 0x002e8084, // n0x01d1 c0x0000 (---------------) + I free + 0x0025dd49, // n0x01d2 c0x0000 (---------------) + I fresenius + 0x00261a83, // n0x01d3 c0x0000 (---------------) + I frl + 0x00261b47, // n0x01d4 c0x0000 (---------------) + I frogans + 0x0039ea49, // n0x01d5 c0x0000 (---------------) + I frontdoor + 0x00397688, // n0x01d6 c0x0000 (---------------) + I frontier + 0x00205283, // n0x01d7 c0x0000 (---------------) + I ftr + 0x0027bdc7, // n0x01d8 c0x0000 (---------------) + I fujitsu + 0x0027c2c9, // n0x01d9 c0x0000 (---------------) + I fujixerox + 0x00283e04, // n0x01da c0x0000 (---------------) + I fund + 0x00284dc9, // n0x01db c0x0000 (---------------) + I furniture + 0x00289ec6, // n0x01dc c0x0000 (---------------) + I futbol + 0x0028af83, // n0x01dd c0x0000 (---------------) + I fyi + 0x00201bc2, // n0x01de c0x0000 (---------------) + I ga + 0x00221fc3, // n0x01df c0x0000 (---------------) + I gal + 0x00391707, // n0x01e0 c0x0000 (---------------) + I gallery + 0x00337785, // n0x01e1 c0x0000 (---------------) + I gallo + 0x002e3006, // n0x01e2 c0x0000 (---------------) + I gallup + 0x00298344, // n0x01e3 c0x0000 (---------------) + I game + 0x00345d85, // n0x01e4 c0x0000 (---------------) + I games + 0x0023d903, // n0x01e5 c0x0000 (---------------) + I gap + 0x0021b986, // n0x01e6 c0x0000 (---------------) + I garden + 0x0020e482, // n0x01e7 c0x0000 (---------------) + I gb + 0x00385ec4, // n0x01e8 c0x0000 (---------------) + I gbiz + 0x002265c2, // n0x01e9 c0x0000 (---------------) + I gd + 0x0022f143, // n0x01ea c0x0000 (---------------) + I gdn + 0x17600282, // n0x01eb c0x005d (n0x097e-n0x0985) + I ge + 0x002b6283, // n0x01ec c0x0000 (---------------) + I gea + 0x00219404, // n0x01ed c0x0000 (---------------) + I gent + 0x00219407, // n0x01ee c0x0000 (---------------) + I genting + 0x003233c6, // n0x01ef c0x0000 (---------------) + I george + 0x0025cb02, // n0x01f0 c0x0000 (---------------) + I gf + 0x17a01942, // n0x01f1 c0x005e (n0x0985-n0x0988) + I gg + 0x00331544, // n0x01f2 c0x0000 (---------------) + I ggee + 0x17e51402, // n0x01f3 c0x005f (n0x0988-n0x098d) + I gh + 0x18201982, // n0x01f4 c0x0060 (n0x098d-n0x0993) + I gi + 0x00344944, // n0x01f5 c0x0000 (---------------) + I gift + 0x00344945, // n0x01f6 c0x0000 (---------------) + I gifts + 0x00219a45, // n0x01f7 c0x0000 (---------------) + I gives + 0x0025e606, // n0x01f8 c0x0000 (---------------) + I giving + 0x18605b82, // n0x01f9 c0x0061 (n0x0993-n0x0998) + I gl + 0x00320545, // n0x01fa c0x0000 (---------------) + I glade + 0x00398305, // n0x01fb c0x0000 (---------------) + I glass + 0x00286b43, // n0x01fc c0x0000 (---------------) + I gle + 0x0020eac6, // n0x01fd c0x0000 (---------------) + I global + 0x0020f5c5, // n0x01fe c0x0000 (---------------) + I globo + 0x00215f82, // n0x01ff c0x0000 (---------------) + I gm + 0x00336105, // n0x0200 c0x0000 (---------------) + I gmail + 0x00217783, // n0x0201 c0x0000 (---------------) + I gmo + 0x00219583, // n0x0202 c0x0000 (---------------) + I gmx + 0x18a07102, // n0x0203 c0x0062 (n0x0998-n0x099e) + I gn + 0x002f3307, // n0x0204 c0x0000 (---------------) + I godaddy + 0x002ff584, // n0x0205 c0x0000 (---------------) + I gold + 0x002ff589, // n0x0206 c0x0000 (---------------) + I goldpoint + 0x0024dec4, // n0x0207 c0x0000 (---------------) + I golf + 0x00283803, // n0x0208 c0x0000 (---------------) + I goo + 0x002f7e09, // n0x0209 c0x0000 (---------------) + I goodhands + 0x00283808, // n0x020a c0x0000 (---------------) + I goodyear + 0x0029c1c4, // n0x020b c0x0000 (---------------) + I goog + 0x0029c1c6, // n0x020c c0x0000 (---------------) + I google + 0x002a4d03, // n0x020d c0x0000 (---------------) + I gop + 0x00210a43, // n0x020e c0x0000 (---------------) + I got + 0x002dc384, // n0x020f c0x0000 (---------------) + I gotv + 0x0027d903, // n0x0210 c0x0000 (---------------) + I gov + 0x18ed5602, // n0x0211 c0x0063 (n0x099e-n0x09a4) + I gp + 0x003004c2, // n0x0212 c0x0000 (---------------) + I gq + 0x19208a82, // n0x0213 c0x0064 (n0x09a4-n0x09aa) + I gr + 0x00317f88, // n0x0214 c0x0000 (---------------) + I grainger + 0x00311288, // n0x0215 c0x0000 (---------------) + I graphics + 0x0038ab06, // n0x0216 c0x0000 (---------------) + I gratis + 0x00252145, // n0x0217 c0x0000 (---------------) + I green + 0x002287c5, // n0x0218 c0x0000 (---------------) + I gripe + 0x0020c745, // n0x0219 c0x0000 (---------------) + I group + 0x00245dc2, // n0x021a c0x0000 (---------------) + I gs + 0x1963f882, // n0x021b c0x0065 (n0x09aa-n0x09b1) + I gt + 0x0160efc2, // n0x021c c0x0005 (---------------)* o I gu + 0x0034e808, // n0x021d c0x0000 (---------------) + I guardian + 0x00234e85, // n0x021e c0x0000 (---------------) + I gucci + 0x002dffc4, // n0x021f c0x0000 (---------------) + I guge + 0x0032afc5, // n0x0220 c0x0000 (---------------) + I guide + 0x0039b7c7, // n0x0221 c0x0000 (---------------) + I guitars + 0x00253a84, // n0x0222 c0x0000 (---------------) + I guru + 0x00216342, // n0x0223 c0x0000 (---------------) + I gw + 0x19a021c2, // n0x0224 c0x0066 (n0x09b1-n0x09b7) + I gy + 0x0030e604, // n0x0225 c0x0000 (---------------) + I hair + 0x00205a07, // n0x0226 c0x0000 (---------------) + I hamburg + 0x00394207, // n0x0227 c0x0000 (---------------) + I hangout + 0x00360304, // n0x0228 c0x0000 (---------------) + I haus + 0x00292543, // n0x0229 c0x0000 (---------------) + I hbo + 0x0024a904, // n0x022a c0x0000 (---------------) + I hdfc + 0x0024a908, // n0x022b c0x0000 (---------------) + I hdfcbank + 0x002ae586, // n0x022c c0x0000 (---------------) + I health + 0x002ae58a, // n0x022d c0x0000 (---------------) + I healthcare + 0x00209384, // n0x022e c0x0000 (---------------) + I help + 0x00209bc8, // n0x022f c0x0000 (---------------) + I helsinki + 0x00254ac4, // n0x0230 c0x0000 (---------------) + I here + 0x00225986, // n0x0231 c0x0000 (---------------) + I hermes + 0x002935c4, // n0x0232 c0x0000 (---------------) + I hgtv + 0x0033f406, // n0x0233 c0x0000 (---------------) + I hiphop + 0x002f4dc9, // n0x0234 c0x0000 (---------------) + I hisamitsu + 0x002a3e07, // n0x0235 c0x0000 (---------------) + I hitachi + 0x00287fc3, // n0x0236 c0x0000 (---------------) + I hiv + 0x19e0c482, // n0x0237 c0x0067 (n0x09b7-n0x09cf) + I hk + 0x0026f043, // n0x0238 c0x0000 (---------------) + I hkt + 0x0020fbc2, // n0x0239 c0x0000 (---------------) + I hm + 0x1a21c682, // n0x023a c0x0068 (n0x09cf-n0x09d5) + I hn + 0x002df346, // n0x023b c0x0000 (---------------) + I hockey + 0x0035d808, // n0x023c c0x0000 (---------------) + I holdings + 0x002a6647, // n0x023d c0x0000 (---------------) + I holiday + 0x00273d09, // n0x023e c0x0000 (---------------) + I homedepot + 0x00299fc9, // n0x023f c0x0000 (---------------) + I homegoods + 0x002a7245, // n0x0240 c0x0000 (---------------) + I homes + 0x002a7249, // n0x0241 c0x0000 (---------------) + I homesense + 0x002a8805, // n0x0242 c0x0000 (---------------) + I honda + 0x002a9289, // n0x0243 c0x0000 (---------------) + I honeywell + 0x002aa045, // n0x0244 c0x0000 (---------------) + I horse + 0x00298484, // n0x0245 c0x0000 (---------------) + I host + 0x00298487, // n0x0246 c0x0000 (---------------) + I hosting + 0x00234303, // n0x0247 c0x0000 (---------------) + I hot + 0x002aab07, // n0x0248 c0x0000 (---------------) + I hoteles + 0x002ab0c7, // n0x0249 c0x0000 (---------------) + I hotmail + 0x002a3745, // n0x024a c0x0000 (---------------) + I house + 0x002a2ac3, // n0x024b c0x0000 (---------------) + I how + 0x1a60f742, // n0x024c c0x0069 (n0x09d5-n0x09da) + I hr + 0x00387984, // n0x024d c0x0000 (---------------) + I hsbc + 0x1aa51442, // n0x024e c0x006a (n0x09da-n0x09eb) + I ht + 0x0025cc83, // n0x024f c0x0000 (---------------) + I htc + 0x1ae24202, // n0x0250 c0x006b (n0x09eb-n0x0a0b) + I hu + 0x002f8486, // n0x0251 c0x0000 (---------------) + I hughes + 0x00309285, // n0x0252 c0x0000 (---------------) + I hyatt + 0x002ad907, // n0x0253 c0x0000 (---------------) + I hyundai + 0x00311ac3, // n0x0254 c0x0000 (---------------) + I ibm + 0x00379c44, // n0x0255 c0x0000 (---------------) + I icbc + 0x00205c83, // n0x0256 c0x0000 (---------------) + I ice + 0x00208b03, // n0x0257 c0x0000 (---------------) + I icu + 0x1b20d9c2, // n0x0258 c0x006c (n0x0a0b-n0x0a16) + I id + 0x1ba00042, // n0x0259 c0x006e (n0x0a17-n0x0a19) + I ie + 0x00366044, // n0x025a c0x0000 (---------------) + I ieee + 0x002347c3, // n0x025b c0x0000 (---------------) + I ifm + 0x003124c5, // n0x025c c0x0000 (---------------) + I iinet + 0x00312305, // n0x025d c0x0000 (---------------) + I ikano + 0x1be027c2, // n0x025e c0x006f (n0x0a19-n0x0a21) + I il + 0x1c600402, // n0x025f c0x0071 (n0x0a22-n0x0a29) + I im + 0x0024bd46, // n0x0260 c0x0000 (---------------) + I imamat + 0x0026b844, // n0x0261 c0x0000 (---------------) + I imdb + 0x0020be84, // n0x0262 c0x0000 (---------------) + I immo + 0x0020be8a, // n0x0263 c0x0000 (---------------) + I immobilien + 0x1ce012c2, // n0x0264 c0x0073 (n0x0a2b-n0x0a38) + I in + 0x003673ca, // n0x0265 c0x0000 (---------------) + I industries + 0x00201688, // n0x0266 c0x0000 (---------------) + I infiniti + 0x1d201844, // n0x0267 c0x0074 (n0x0a38-n0x0a42) + I info + 0x0020f543, // n0x0268 c0x0000 (---------------) + I ing + 0x00209cc3, // n0x0269 c0x0000 (---------------) + I ink + 0x00310949, // n0x026a c0x0000 (---------------) + I institute + 0x00263309, // n0x026b c0x0000 (---------------) + I insurance + 0x003012c6, // n0x026c c0x0000 (---------------) + I insure + 0x1d601503, // n0x026d c0x0075 (n0x0a42-n0x0a43) + I int + 0x002ff705, // n0x026e c0x0000 (---------------) + I intel + 0x0031ba8d, // n0x026f c0x0000 (---------------) + I international + 0x002f7846, // n0x0270 c0x0000 (---------------) + I intuit + 0x0020980b, // n0x0271 c0x0000 (---------------) + I investments + 0x1da03a02, // n0x0272 c0x0076 (n0x0a43-n0x0a49) + I io + 0x0025acc8, // n0x0273 c0x0000 (---------------) + I ipiranga + 0x1de1d942, // n0x0274 c0x0077 (n0x0a49-n0x0a4f) + I iq + 0x1e204b02, // n0x0275 c0x0078 (n0x0a4f-n0x0a58) + I ir + 0x0029b805, // n0x0276 c0x0000 (---------------) + I irish + 0x1e604e82, // n0x0277 c0x0079 (n0x0a58-n0x0a60) + I is + 0x0025b147, // n0x0278 c0x0000 (---------------) + I iselect + 0x0027b3c7, // n0x0279 c0x0000 (---------------) + I ismaili + 0x00215a03, // n0x027a c0x0000 (---------------) + I ist + 0x00215a08, // n0x027b c0x0000 (---------------) + I istanbul + 0x1ea017c2, // n0x027c c0x007a (n0x0a60-n0x0bd1) + I it + 0x0027ea04, // n0x027d c0x0000 (---------------) + I itau + 0x00360d43, // n0x027e c0x0000 (---------------) + I itv + 0x00323805, // n0x027f c0x0000 (---------------) + I iveco + 0x00368243, // n0x0280 c0x0000 (---------------) + I iwc + 0x00308d46, // n0x0281 c0x0000 (---------------) + I jaguar + 0x003225c4, // n0x0282 c0x0000 (---------------) + I java + 0x00246c43, // n0x0283 c0x0000 (---------------) + I jcb + 0x0026f783, // n0x0284 c0x0000 (---------------) + I jcp + 0x1ee0bd02, // n0x0285 c0x007b (n0x0bd1-n0x0bd4) + I je + 0x00335a04, // n0x0286 c0x0000 (---------------) + I jeep + 0x0034cbc5, // n0x0287 c0x0000 (---------------) + I jetzt + 0x00361547, // n0x0288 c0x0000 (---------------) + I jewelry + 0x00278b43, // n0x0289 c0x0000 (---------------) + I jio + 0x002add83, // n0x028a c0x0000 (---------------) + I jlc + 0x002aee43, // n0x028b c0x0000 (---------------) + I jll + 0x0167db82, // n0x028c c0x0005 (---------------)* o I jm + 0x002aef03, // n0x028d c0x0000 (---------------) + I jmp + 0x002af503, // n0x028e c0x0000 (---------------) + I jnj + 0x1f2010c2, // n0x028f c0x007c (n0x0bd4-n0x0bdc) + I jo + 0x002e35c4, // n0x0290 c0x0000 (---------------) + I jobs + 0x0027d046, // n0x0291 c0x0000 (---------------) + I joburg + 0x002010c3, // n0x0292 c0x0000 (---------------) + I jot + 0x002af883, // n0x0293 c0x0000 (---------------) + I joy + 0x1f6b00c2, // n0x0294 c0x007d (n0x0bdc-n0x0c4b) + I jp + 0x002b00c8, // n0x0295 c0x0000 (---------------) + I jpmorgan + 0x002b1304, // n0x0296 c0x0000 (---------------) + I jprs + 0x0024e0c6, // n0x0297 c0x0000 (---------------) + I juegos + 0x002b17c7, // n0x0298 c0x0000 (---------------) + I juniper + 0x00222e46, // n0x0299 c0x0000 (---------------) + I kaufen + 0x003782c4, // n0x029a c0x0000 (---------------) + I kddi + 0x2d202482, // n0x029b c0x00b4 (n0x12df-n0x12e0)* o I ke + 0x002341cb, // n0x029c c0x0000 (---------------) + I kerryhotels + 0x002e270e, // n0x029d c0x0000 (---------------) + I kerrylogistics + 0x002249cf, // n0x029e c0x0000 (---------------) + I kerryproperties + 0x002337c3, // n0x029f c0x0000 (---------------) + I kfh + 0x2dab7202, // n0x02a0 c0x00b6 (n0x12e1-n0x12e7) + I kg + 0x0161c802, // n0x02a1 c0x0005 (---------------)* o I kh + 0x2de02982, // n0x02a2 c0x00b7 (n0x12e7-n0x12ee) + I ki + 0x002257c3, // n0x02a3 c0x0000 (---------------) + I kia + 0x0023a7c3, // n0x02a4 c0x0000 (---------------) + I kim + 0x0037cbc6, // n0x02a5 c0x0000 (---------------) + I kinder + 0x0023ea06, // n0x02a6 c0x0000 (---------------) + I kindle + 0x00346087, // n0x02a7 c0x0000 (---------------) + I kitchen + 0x002ea604, // n0x02a8 c0x0000 (---------------) + I kiwi + 0x2e238982, // n0x02a9 c0x00b8 (n0x12ee-n0x12ff) + I km + 0x2e63dd02, // n0x02aa c0x00b9 (n0x12ff-n0x1303) + I kn + 0x002291c5, // n0x02ab c0x0000 (---------------) + I koeln + 0x002ab807, // n0x02ac c0x0000 (---------------) + I komatsu + 0x002eb806, // n0x02ad c0x0000 (---------------) + I kosher + 0x2ea0ea02, // n0x02ae c0x00ba (n0x1303-n0x1309) + I kp + 0x0020ea04, // n0x02af c0x0000 (---------------) + I kpmg + 0x0036ab43, // n0x02b0 c0x0000 (---------------) + I kpn + 0x2ee0bdc2, // n0x02b1 c0x00bb (n0x1309-n0x1327) + I kr + 0x0034c043, // n0x02b2 c0x0000 (---------------) + I krd + 0x003a1444, // n0x02b3 c0x0000 (---------------) + I kred + 0x002b7149, // n0x02b4 c0x0000 (---------------) + I kuokgroup + 0x016bf3c2, // n0x02b5 c0x0005 (---------------)* o I kw + 0x2f236f82, // n0x02b6 c0x00bc (n0x1327-n0x132c) + I ky + 0x00268246, // n0x02b7 c0x0000 (---------------) + I kyknet + 0x002c0005, // n0x02b8 c0x0000 (---------------) + I kyoto + 0x2f792002, // n0x02b9 c0x00bd (n0x132c-n0x1332) + I kz + 0x2fa03082, // n0x02ba c0x00be (n0x1332-n0x133b) + I la + 0x0033a687, // n0x02bb c0x0000 (---------------) + I lacaixa + 0x00294d09, // n0x02bc c0x0000 (---------------) + I ladbrokes + 0x0034ff8b, // n0x02bd c0x0000 (---------------) + I lamborghini + 0x00246745, // n0x02be c0x0000 (---------------) + I lamer + 0x0036b6c9, // n0x02bf c0x0000 (---------------) + I lancaster + 0x002c1d86, // n0x02c0 c0x0000 (---------------) + I lancia + 0x00259047, // n0x02c1 c0x0000 (---------------) + I lancome + 0x00213144, // n0x02c2 c0x0000 (---------------) + I land + 0x0026aa89, // n0x02c3 c0x0000 (---------------) + I landrover + 0x00358e47, // n0x02c4 c0x0000 (---------------) + I lanxess + 0x00279d47, // n0x02c5 c0x0000 (---------------) + I lasalle + 0x00226e83, // n0x02c6 c0x0000 (---------------) + I lat + 0x0026b986, // n0x02c7 c0x0000 (---------------) + I latino + 0x002ce147, // n0x02c8 c0x0000 (---------------) + I latrobe + 0x00271c03, // n0x02c9 c0x0000 (---------------) + I law + 0x00271c06, // n0x02ca c0x0000 (---------------) + I lawyer + 0x2fe02802, // n0x02cb c0x00bf (n0x133b-n0x1340) + I lb + 0x30239382, // n0x02cc c0x00c0 (n0x1340-n0x1346) + I lc + 0x0023e683, // n0x02cd c0x0000 (---------------) + I lds + 0x00279e85, // n0x02ce c0x0000 (---------------) + I lease + 0x002b8607, // n0x02cf c0x0000 (---------------) + I leclerc + 0x00356c06, // n0x02d0 c0x0000 (---------------) + I lefrak + 0x00337705, // n0x02d1 c0x0000 (---------------) + I legal + 0x0024de44, // n0x02d2 c0x0000 (---------------) + I lego + 0x002de845, // n0x02d3 c0x0000 (---------------) + I lexus + 0x002e7384, // n0x02d4 c0x0000 (---------------) + I lgbt + 0x30605bc2, // n0x02d5 c0x00c1 (n0x1346-n0x1347) + I li + 0x0030b0c7, // n0x02d6 c0x0000 (---------------) + I liaison + 0x002bdb44, // n0x02d7 c0x0000 (---------------) + I lidl + 0x00263204, // n0x02d8 c0x0000 (---------------) + I life + 0x0026320d, // n0x02d9 c0x0000 (---------------) + I lifeinsurance + 0x0035f409, // n0x02da c0x0000 (---------------) + I lifestyle + 0x00288c08, // n0x02db c0x0000 (---------------) + I lighting + 0x00258c84, // n0x02dc c0x0000 (---------------) + I like + 0x00354b85, // n0x02dd c0x0000 (---------------) + I lilly + 0x0025d307, // n0x02de c0x0000 (---------------) + I limited + 0x0025d704, // n0x02df c0x0000 (---------------) + I limo + 0x0022fcc7, // n0x02e0 c0x0000 (---------------) + I lincoln + 0x00320185, // n0x02e1 c0x0000 (---------------) + I linde + 0x0038e084, // n0x02e2 c0x0000 (---------------) + I link + 0x002d50c5, // n0x02e3 c0x0000 (---------------) + I lipsy + 0x00260744, // n0x02e4 c0x0000 (---------------) + I live + 0x002de986, // n0x02e5 c0x0000 (---------------) + I living + 0x0025d605, // n0x02e6 c0x0000 (---------------) + I lixil + 0x30a0e9c2, // n0x02e7 c0x00c2 (n0x1347-n0x1356) + I lk + 0x00213a44, // n0x02e8 c0x0000 (---------------) + I loan + 0x00213a45, // n0x02e9 c0x0000 (---------------) + I loans + 0x00375d86, // n0x02ea c0x0000 (---------------) + I locker + 0x00337845, // n0x02eb c0x0000 (---------------) + I locus + 0x002d2244, // n0x02ec c0x0000 (---------------) + I loft + 0x002c3f43, // n0x02ed c0x0000 (---------------) + I lol + 0x003114c6, // n0x02ee c0x0000 (---------------) + I london + 0x00224e05, // n0x02ef c0x0000 (---------------) + I lotte + 0x002260c5, // n0x02f0 c0x0000 (---------------) + I lotto + 0x0023df44, // n0x02f1 c0x0000 (---------------) + I love + 0x00209403, // n0x02f2 c0x0000 (---------------) + I lpl + 0x0020940c, // n0x02f3 c0x0000 (---------------) + I lplfinancial + 0x30e8a802, // n0x02f4 c0x00c3 (n0x1356-n0x135b) + I lr + 0x31205642, // n0x02f5 c0x00c4 (n0x135b-n0x135d) + I ls + 0x31608bc2, // n0x02f6 c0x00c5 (n0x135d-n0x135f) + I lt + 0x00312883, // n0x02f7 c0x0000 (---------------) + I ltd + 0x00312884, // n0x02f8 c0x0000 (---------------) + I ltda + 0x31a03842, // n0x02f9 c0x00c6 (n0x135f-n0x1360) + I lu + 0x002e2ac8, // n0x02fa c0x0000 (---------------) + I lundbeck + 0x002e30c5, // n0x02fb c0x0000 (---------------) + I lupin + 0x00235544, // n0x02fc c0x0000 (---------------) + I luxe + 0x00238646, // n0x02fd c0x0000 (---------------) + I luxury + 0x31e06582, // n0x02fe c0x00c7 (n0x1360-n0x1369) + I lv + 0x32207e42, // n0x02ff c0x00c8 (n0x1369-n0x1372) + I ly + 0x32600442, // n0x0300 c0x00c9 (n0x1372-n0x1378) + I ma + 0x00373685, // n0x0301 c0x0000 (---------------) + I macys + 0x003197c6, // n0x0302 c0x0000 (---------------) + I madrid + 0x00269fc4, // n0x0303 c0x0000 (---------------) + I maif + 0x002b7f46, // n0x0304 c0x0000 (---------------) + I maison + 0x00248206, // n0x0305 c0x0000 (---------------) + I makeup + 0x00204283, // n0x0306 c0x0000 (---------------) + I man + 0x0036df4a, // n0x0307 c0x0000 (---------------) + I management + 0x0023b305, // n0x0308 c0x0000 (---------------) + I mango + 0x0022b8c6, // n0x0309 c0x0000 (---------------) + I market + 0x002ec909, // n0x030a c0x0000 (---------------) + I marketing + 0x0022b8c7, // n0x030b c0x0000 (---------------) + I markets + 0x00245948, // n0x030c c0x0000 (---------------) + I marriott + 0x0020a009, // n0x030d c0x0000 (---------------) + I marshalls + 0x002bbd48, // n0x030e c0x0000 (---------------) + I maserati + 0x0022dcc6, // n0x030f c0x0000 (---------------) + I mattel + 0x002089c3, // n0x0310 c0x0000 (---------------) + I mba + 0x32a1a3c2, // n0x0311 c0x00ca (n0x1378-n0x137a) + I mc + 0x0037c0c3, // n0x0312 c0x0000 (---------------) + I mcd + 0x0037c0c9, // n0x0313 c0x0000 (---------------) + I mcdonalds + 0x00325988, // n0x0314 c0x0000 (---------------) + I mckinsey + 0x32e4dd82, // n0x0315 c0x00cb (n0x137a-n0x137b) + I md + 0x33200982, // n0x0316 c0x00cc (n0x137b-n0x1388) + I me + 0x00213443, // n0x0317 c0x0000 (---------------) + I med + 0x00303545, // n0x0318 c0x0000 (---------------) + I media + 0x00269484, // n0x0319 c0x0000 (---------------) + I meet + 0x002e1389, // n0x031a c0x0000 (---------------) + I melbourne + 0x002b4304, // n0x031b c0x0000 (---------------) + I meme + 0x0036e248, // n0x031c c0x0000 (---------------) + I memorial + 0x00209983, // n0x031d c0x0000 (---------------) + I men + 0x003295c4, // n0x031e c0x0000 (---------------) + I menu + 0x0021a583, // n0x031f c0x0000 (---------------) + I meo + 0x00263147, // n0x0320 c0x0000 (---------------) + I metlife + 0x3360ea82, // n0x0321 c0x00cd (n0x1388-n0x1391) + I mg + 0x0025a7c2, // n0x0322 c0x0000 (---------------) + I mh + 0x00231bc5, // n0x0323 c0x0000 (---------------) + I miami + 0x00269849, // n0x0324 c0x0000 (---------------) + I microsoft + 0x00207dc3, // n0x0325 c0x0000 (---------------) + I mil + 0x0027d684, // n0x0326 c0x0000 (---------------) + I mini + 0x0031ba44, // n0x0327 c0x0000 (---------------) + I mint + 0x0023e183, // n0x0328 c0x0000 (---------------) + I mit + 0x0027ee0a, // n0x0329 c0x0000 (---------------) + I mitsubishi + 0x33b67282, // n0x032a c0x00ce (n0x1391-n0x1399) + I mk + 0x33e13a02, // n0x032b c0x00cf (n0x1399-n0x13a0) + I ml + 0x002c2fc3, // n0x032c c0x0000 (---------------) + I mlb + 0x00369c83, // n0x032d c0x0000 (---------------) + I mls + 0x0160bec2, // n0x032e c0x0005 (---------------)* o I mm + 0x00374a83, // n0x032f c0x0000 (---------------) + I mma + 0x34223b02, // n0x0330 c0x00d0 (n0x13a0-n0x13a4) + I mn + 0x00223b04, // n0x0331 c0x0000 (---------------) + I mnet + 0x34608442, // n0x0332 c0x00d1 (n0x13a4-n0x13a9) + I mo + 0x34a0bf04, // n0x0333 c0x00d2 (n0x13a9-n0x13aa) + I mobi + 0x002d7b86, // n0x0334 c0x0000 (---------------) + I mobily + 0x0026d444, // n0x0335 c0x0000 (---------------) + I moda + 0x0024e4c3, // n0x0336 c0x0000 (---------------) + I moe + 0x00282a43, // n0x0337 c0x0000 (---------------) + I moi + 0x002e4483, // n0x0338 c0x0000 (---------------) + I mom + 0x00243d86, // n0x0339 c0x0000 (---------------) + I monash + 0x002c8705, // n0x033a c0x0000 (---------------) + I money + 0x002c3b87, // n0x033b c0x0000 (---------------) + I monster + 0x00258f09, // n0x033c c0x0000 (---------------) + I montblanc + 0x002c6c05, // n0x033d c0x0000 (---------------) + I mopar + 0x002c8646, // n0x033e c0x0000 (---------------) + I mormon + 0x002c8c48, // n0x033f c0x0000 (---------------) + I mortgage + 0x002c8e46, // n0x0340 c0x0000 (---------------) + I moscow + 0x00278444, // n0x0341 c0x0000 (---------------) + I moto + 0x0029b44b, // n0x0342 c0x0000 (---------------) + I motorcycles + 0x002ca883, // n0x0343 c0x0000 (---------------) + I mov + 0x002ca885, // n0x0344 c0x0000 (---------------) + I movie + 0x002ca9c8, // n0x0345 c0x0000 (---------------) + I movistar + 0x0022c182, // n0x0346 c0x0000 (---------------) + I mp + 0x0033a982, // n0x0347 c0x0000 (---------------) + I mq + 0x34e4a142, // n0x0348 c0x00d3 (n0x13aa-n0x13ac) + I mr + 0x35210f42, // n0x0349 c0x00d4 (n0x13ac-n0x13b1) + I ms + 0x0025d203, // n0x034a c0x0000 (---------------) + I msd + 0x35605402, // n0x034b c0x00d5 (n0x13b1-n0x13b5) + I mt + 0x0026db43, // n0x034c c0x0000 (---------------) + I mtn + 0x002cacc4, // n0x034d c0x0000 (---------------) + I mtpc + 0x002cb483, // n0x034e c0x0000 (---------------) + I mtr + 0x35e03f02, // n0x034f c0x00d7 (n0x13b6-n0x13bd) + I mu + 0x002cd0cb, // n0x0350 c0x0000 (---------------) + I multichoice + 0x362d1086, // n0x0351 c0x00d8 (n0x13bd-n0x15e1) + I museum + 0x0023c806, // n0x0352 c0x0000 (---------------) + I mutual + 0x002d16c8, // n0x0353 c0x0000 (---------------) + I mutuelle + 0x366bf742, // n0x0354 c0x00d9 (n0x15e1-n0x15ef) + I mv + 0x36a12002, // n0x0355 c0x00da (n0x15ef-n0x15fa) + I mw + 0x36e195c2, // n0x0356 c0x00db (n0x15fa-n0x1600) + I mx + 0x37225742, // n0x0357 c0x00dc (n0x1600-n0x1608) + I my + 0x37614d82, // n0x0358 c0x00dd (n0x1608-n0x1609)* o I mz + 0x00214d8b, // n0x0359 c0x0000 (---------------) + I mzansimagic + 0x37a00902, // n0x035a c0x00de (n0x1609-n0x161a) + I na + 0x0021ac43, // n0x035b c0x0000 (---------------) + I nab + 0x00379545, // n0x035c c0x0000 (---------------) + I nadex + 0x00255a46, // n0x035d c0x0000 (---------------) + I nagoya + 0x37e00904, // n0x035e c0x00df (n0x161a-n0x161c) + I name + 0x0033ca07, // n0x035f c0x0000 (---------------) + I naspers + 0x00378fca, // n0x0360 c0x0000 (---------------) + I nationwide + 0x002dcac6, // n0x0361 c0x0000 (---------------) + I natura + 0x00398f44, // n0x0362 c0x0000 (---------------) + I navy + 0x0025ce03, // n0x0363 c0x0000 (---------------) + I nba + 0x38a095c2, // n0x0364 c0x00e2 (n0x161e-n0x161f) + I nc + 0x00202ac2, // n0x0365 c0x0000 (---------------) + I ne + 0x0022af03, // n0x0366 c0x0000 (---------------) + I nec + 0x38e23b43, // n0x0367 c0x00e3 (n0x161f-n0x1654) + I net + 0x00391e87, // n0x0368 c0x0000 (---------------) + I netbank + 0x0025d507, // n0x0369 c0x0000 (---------------) + I netflix + 0x002565c7, // n0x036a c0x0000 (---------------) + I network + 0x0022a247, // n0x036b c0x0000 (---------------) + I neustar + 0x0021e603, // n0x036c c0x0000 (---------------) + I new + 0x002ec30a, // n0x036d c0x0000 (---------------) + I newholland + 0x0021e604, // n0x036e c0x0000 (---------------) + I news + 0x0024d984, // n0x036f c0x0000 (---------------) + I next + 0x0024d98a, // n0x0370 c0x0000 (---------------) + I nextdirect + 0x0026ec05, // n0x0371 c0x0000 (---------------) + I nexus + 0x3a2016c2, // n0x0372 c0x00e8 (n0x165c-n0x1666) + I nf + 0x00252243, // n0x0373 c0x0000 (---------------) + I nfl + 0x3a6026c2, // n0x0374 c0x00e9 (n0x1666-n0x1670) + I ng + 0x0023b383, // n0x0375 c0x0000 (---------------) + I ngo + 0x0026f003, // n0x0376 c0x0000 (---------------) + I nhk + 0x3ae01782, // n0x0377 c0x00eb (n0x1671-n0x167f) o I ni + 0x002a7c84, // n0x0378 c0x0000 (---------------) + I nico + 0x00221d04, // n0x0379 c0x0000 (---------------) + I nike + 0x00203a85, // n0x037a c0x0000 (---------------) + I nikon + 0x002ca605, // n0x037b c0x0000 (---------------) + I ninja + 0x002292c6, // n0x037c c0x0000 (---------------) + I nissan + 0x0022d246, // n0x037d c0x0000 (---------------) + I nissay + 0x3b246d02, // n0x037e c0x00ec (n0x167f-n0x1682) + I nl + 0x3b601382, // n0x037f c0x00ed (n0x1682-n0x1958) + I no + 0x0031ae05, // n0x0380 c0x0000 (---------------) + I nokia + 0x0023c512, // n0x0381 c0x0000 (---------------) + I northwesternmutual + 0x0035eb06, // n0x0382 c0x0000 (---------------) + I norton + 0x00220303, // n0x0383 c0x0000 (---------------) + I now + 0x0029e646, // n0x0384 c0x0000 (---------------) + I nowruz + 0x00220305, // n0x0385 c0x0000 (---------------) + I nowtv + 0x01612182, // n0x0386 c0x0005 (---------------)* o I np + 0x43a0e602, // n0x0387 c0x010e (n0x1980-n0x1987) + I nr + 0x002d6d03, // n0x0388 c0x0000 (---------------) + I nra + 0x0026e2c3, // n0x0389 c0x0000 (---------------) + I nrw + 0x00372083, // n0x038a c0x0000 (---------------) + I ntt + 0x43e04182, // n0x038b c0x010f (n0x1987-n0x198a) + I nu + 0x0036dcc3, // n0x038c c0x0000 (---------------) + I nyc + 0x44208282, // n0x038d c0x0110 (n0x198a-n0x199a) + I nz + 0x0020bf43, // n0x038e c0x0000 (---------------) + I obi + 0x002e3608, // n0x038f c0x0000 (---------------) + I observer + 0x0020ce83, // n0x0390 c0x0000 (---------------) + I off + 0x0021dec6, // n0x0391 c0x0000 (---------------) + I office + 0x00395107, // n0x0392 c0x0000 (---------------) + I okinawa + 0x0020c5c6, // n0x0393 c0x0000 (---------------) + I olayan + 0x0020c5cb, // n0x0394 c0x0000 (---------------) + I olayangroup + 0x00398e87, // n0x0395 c0x0000 (---------------) + I oldnavy + 0x00387784, // n0x0396 c0x0000 (---------------) + I ollo + 0x44a013c2, // n0x0397 c0x0112 (n0x199b-n0x19a4) + I om + 0x002e2f45, // n0x0398 c0x0000 (---------------) + I omega + 0x00215243, // n0x0399 c0x0000 (---------------) + I one + 0x00207083, // n0x039a c0x0000 (---------------) + I ong + 0x00319c43, // n0x039b c0x0000 (---------------) + I onl + 0x00319c46, // n0x039c c0x0000 (---------------) + I online + 0x0039944a, // n0x039d c0x0000 (---------------) + I onyourside + 0x0028f983, // n0x039e c0x0000 (---------------) + I ooo + 0x0023cb04, // n0x039f c0x0000 (---------------) + I open + 0x00227a86, // n0x03a0 c0x0000 (---------------) + I oracle + 0x00395846, // n0x03a1 c0x0000 (---------------) + I orange + 0x44e28743, // n0x03a2 c0x0113 (n0x19a4-n0x19e1) + I org + 0x002b0187, // n0x03a3 c0x0000 (---------------) + I organic + 0x002d994d, // n0x03a4 c0x0000 (---------------) + I orientexpress + 0x00381387, // n0x03a5 c0x0000 (---------------) + I origins + 0x0029b185, // n0x03a6 c0x0000 (---------------) + I osaka + 0x00268446, // n0x03a7 c0x0000 (---------------) + I otsuka + 0x00224e43, // n0x03a8 c0x0000 (---------------) + I ott + 0x0020ed03, // n0x03a9 c0x0000 (---------------) + I ovh + 0x4660aac2, // n0x03aa c0x0119 (n0x1a1e-n0x1a29) + I pa + 0x00326904, // n0x03ab c0x0000 (---------------) + I page + 0x0024c80c, // n0x03ac c0x0000 (---------------) + I pamperedchef + 0x00262c09, // n0x03ad c0x0000 (---------------) + I panasonic + 0x00338487, // n0x03ae c0x0000 (---------------) + I panerai + 0x00277705, // n0x03af c0x0000 (---------------) + I paris + 0x0029d144, // n0x03b0 c0x0000 (---------------) + I pars + 0x002a6948, // n0x03b1 c0x0000 (---------------) + I partners + 0x002aef85, // n0x03b2 c0x0000 (---------------) + I parts + 0x002b6945, // n0x03b3 c0x0000 (---------------) + I party + 0x002cdb09, // n0x03b4 c0x0000 (---------------) + I passagens + 0x002be303, // n0x03b5 c0x0000 (---------------) + I pay + 0x002be304, // n0x03b6 c0x0000 (---------------) + I payu + 0x002cad44, // n0x03b7 c0x0000 (---------------) + I pccw + 0x46a00582, // n0x03b8 c0x011a (n0x1a29-n0x1a31) + I pe + 0x00211cc3, // n0x03b9 c0x0000 (---------------) + I pet + 0x46ef6c02, // n0x03ba c0x011b (n0x1a31-n0x1a34) + I pf + 0x002f6c06, // n0x03bb c0x0000 (---------------) + I pfizer + 0x01648ac2, // n0x03bc c0x0005 (---------------)* o I pg + 0x4729cd02, // n0x03bd c0x011c (n0x1a34-n0x1a3c) + I ph + 0x00373588, // n0x03be c0x0000 (---------------) + I pharmacy + 0x002d5007, // n0x03bf c0x0000 (---------------) + I philips + 0x0029cd05, // n0x03c0 c0x0000 (---------------) + I photo + 0x002d564b, // n0x03c1 c0x0000 (---------------) + I photography + 0x002d2806, // n0x03c2 c0x0000 (---------------) + I photos + 0x002d5846, // n0x03c3 c0x0000 (---------------) + I physio + 0x002d59c6, // n0x03c4 c0x0000 (---------------) + I piaget + 0x00221604, // n0x03c5 c0x0000 (---------------) + I pics + 0x002d6146, // n0x03c6 c0x0000 (---------------) + I pictet + 0x002d6648, // n0x03c7 c0x0000 (---------------) + I pictures + 0x00241c83, // n0x03c8 c0x0000 (---------------) + I pid + 0x00219f83, // n0x03c9 c0x0000 (---------------) + I pin + 0x00219f84, // n0x03ca c0x0000 (---------------) + I ping + 0x002d6dc4, // n0x03cb c0x0000 (---------------) + I pink + 0x002d7407, // n0x03cc c0x0000 (---------------) + I pioneer + 0x002d7e85, // n0x03cd c0x0000 (---------------) + I pizza + 0x476d7fc2, // n0x03ce c0x011d (n0x1a3c-n0x1a4a) + I pk + 0x47a09442, // n0x03cf c0x011e (n0x1a4a-n0x1aef) + I pl + 0x0020b305, // n0x03d0 c0x0000 (---------------) + I place + 0x002a00c4, // n0x03d1 c0x0000 (---------------) + I play + 0x002d92cb, // n0x03d2 c0x0000 (---------------) + I playstation + 0x002dc1c8, // n0x03d3 c0x0000 (---------------) + I plumbing + 0x002dd404, // n0x03d4 c0x0000 (---------------) + I plus + 0x0020ea42, // n0x03d5 c0x0000 (---------------) + I pm + 0x482488c2, // n0x03d6 c0x0120 (n0x1b1e-n0x1b23) + I pn + 0x002b0ac3, // n0x03d7 c0x0000 (---------------) + I pnc + 0x002dd844, // n0x03d8 c0x0000 (---------------) + I pohl + 0x002dd945, // n0x03d9 c0x0000 (---------------) + I poker + 0x002dde87, // n0x03da c0x0000 (---------------) + I politie + 0x002dfb04, // n0x03db c0x0000 (---------------) + I porn + 0x00360404, // n0x03dc c0x0000 (---------------) + I post + 0x48604e02, // n0x03dd c0x0121 (n0x1b23-n0x1b30) + I pr + 0x00358049, // n0x03de c0x0000 (---------------) + I pramerica + 0x002e0505, // n0x03df c0x0000 (---------------) + I praxi + 0x00246a05, // n0x03e0 c0x0000 (---------------) + I press + 0x002e12c5, // n0x03e1 c0x0000 (---------------) + I prime + 0x48a24b03, // n0x03e2 c0x0122 (n0x1b30-n0x1b37) + I pro + 0x002e1bc4, // n0x03e3 c0x0000 (---------------) + I prod + 0x002e1bcb, // n0x03e4 c0x0000 (---------------) + I productions + 0x002e2004, // n0x03e5 c0x0000 (---------------) + I prof + 0x002e228b, // n0x03e6 c0x0000 (---------------) + I progressive + 0x002e43c5, // n0x03e7 c0x0000 (---------------) + I promo + 0x00224b0a, // n0x03e8 c0x0000 (---------------) + I properties + 0x002e4bc8, // n0x03e9 c0x0000 (---------------) + I property + 0x002e4dca, // n0x03ea c0x0000 (---------------) + I protection + 0x002e5043, // n0x03eb c0x0000 (---------------) + I pru + 0x002e504a, // n0x03ec c0x0000 (---------------) + I prudential + 0x48e08102, // n0x03ed c0x0123 (n0x1b37-n0x1b3e) + I ps + 0x492d3242, // n0x03ee c0x0124 (n0x1b3e-n0x1b47) + I pt + 0x0028f343, // n0x03ef c0x0000 (---------------) + I pub + 0x496e6702, // n0x03f0 c0x0125 (n0x1b47-n0x1b4d) + I pw + 0x002e6703, // n0x03f1 c0x0000 (---------------) + I pwc + 0x49b32942, // n0x03f2 c0x0126 (n0x1b4d-n0x1b54) + I py + 0x49f16bc2, // n0x03f3 c0x0127 (n0x1b54-n0x1b5d) + I qa + 0x002e7204, // n0x03f4 c0x0000 (---------------) + I qpon + 0x0021d986, // n0x03f5 c0x0000 (---------------) + I quebec + 0x002b7c85, // n0x03f6 c0x0000 (---------------) + I quest + 0x002e77c3, // n0x03f7 c0x0000 (---------------) + I qvc + 0x00352e46, // n0x03f8 c0x0000 (---------------) + I racing + 0x0022e484, // n0x03f9 c0x0000 (---------------) + I raid + 0x4a208c82, // n0x03fa c0x0128 (n0x1b5d-n0x1b61) + I re + 0x002d4a44, // n0x03fb c0x0000 (---------------) + I read + 0x002c410a, // n0x03fc c0x0000 (---------------) + I realestate + 0x00338887, // n0x03fd c0x0000 (---------------) + I realtor + 0x003090c6, // n0x03fe c0x0000 (---------------) + I realty + 0x0022c2c7, // n0x03ff c0x0000 (---------------) + I recipes + 0x002437c3, // n0x0400 c0x0000 (---------------) + I red + 0x003a1488, // n0x0401 c0x0000 (---------------) + I redstone + 0x00337ecb, // n0x0402 c0x0000 (---------------) + I redumbrella + 0x0036d345, // n0x0403 c0x0000 (---------------) + I rehab + 0x002cb305, // n0x0404 c0x0000 (---------------) + I reise + 0x002cb306, // n0x0405 c0x0000 (---------------) + I reisen + 0x003013c4, // n0x0406 c0x0000 (---------------) + I reit + 0x00325d48, // n0x0407 c0x0000 (---------------) + I reliance + 0x00208c83, // n0x0408 c0x0000 (---------------) + I ren + 0x0020acc4, // n0x0409 c0x0000 (---------------) + I rent + 0x0020acc7, // n0x040a c0x0000 (---------------) + I rentals + 0x002b7946, // n0x040b c0x0000 (---------------) + I repair + 0x002f9f46, // n0x040c c0x0000 (---------------) + I report + 0x002a0e4a, // n0x040d c0x0000 (---------------) + I republican + 0x0024d844, // n0x040e c0x0000 (---------------) + I rest + 0x003668ca, // n0x040f c0x0000 (---------------) + I restaurant + 0x003264c6, // n0x0410 c0x0000 (---------------) + I review + 0x003264c7, // n0x0411 c0x0000 (---------------) + I reviews + 0x00257c47, // n0x0412 c0x0000 (---------------) + I rexroth + 0x002736c4, // n0x0413 c0x0000 (---------------) + I rich + 0x002736c9, // n0x0414 c0x0000 (---------------) + I richardli + 0x002db105, // n0x0415 c0x0000 (---------------) + I ricoh + 0x0032084b, // n0x0416 c0x0000 (---------------) + I rightathome + 0x00251603, // n0x0417 c0x0000 (---------------) + I ril + 0x0021a283, // n0x0418 c0x0000 (---------------) + I rio + 0x00228803, // n0x0419 c0x0000 (---------------) + I rip + 0x00267204, // n0x041a c0x0000 (---------------) + I rmit + 0x4a6020c2, // n0x041b c0x0129 (n0x1b61-n0x1b6d) + I ro + 0x0028bec6, // n0x041c c0x0000 (---------------) + I rocher + 0x002a2845, // n0x041d c0x0000 (---------------) + I rocks + 0x002d45c5, // n0x041e c0x0000 (---------------) + I rodeo + 0x0039d606, // n0x041f c0x0000 (---------------) + I rogers + 0x00374604, // n0x0420 c0x0000 (---------------) + I room + 0x4aa006c2, // n0x0421 c0x012a (n0x1b6d-n0x1b74) + I rs + 0x0039d704, // n0x0422 c0x0000 (---------------) + I rsvp + 0x4ae0fe82, // n0x0423 c0x012b (n0x1b74-n0x1bf7) + I ru + 0x002367c4, // n0x0424 c0x0000 (---------------) + I ruhr + 0x002263c3, // n0x0425 c0x0000 (---------------) + I run + 0x4b26e302, // n0x0426 c0x012c (n0x1bf7-n0x1c00) + I rw + 0x003252c3, // n0x0427 c0x0000 (---------------) + I rwe + 0x002adec6, // n0x0428 c0x0000 (---------------) + I ryukyu + 0x4b601002, // n0x0429 c0x012d (n0x1c00-n0x1c08) + I sa + 0x0030e208, // n0x042a c0x0000 (---------------) + I saarland + 0x0039f4c4, // n0x042b c0x0000 (---------------) + I safe + 0x0039f4c6, // n0x042c c0x0000 (---------------) + I safety + 0x002dc646, // n0x042d c0x0000 (---------------) + I sakura + 0x002595c4, // n0x042e c0x0000 (---------------) + I sale + 0x00311445, // n0x042f c0x0000 (---------------) + I salon + 0x0038dd88, // n0x0430 c0x0000 (---------------) + I samsclub + 0x00398187, // n0x0431 c0x0000 (---------------) + I samsung + 0x00253bc7, // n0x0432 c0x0000 (---------------) + I sandvik + 0x00253bcf, // n0x0433 c0x0000 (---------------) + I sandvikcoromant + 0x00295f06, // n0x0434 c0x0000 (---------------) + I sanofi + 0x00213b43, // n0x0435 c0x0000 (---------------) + I sap + 0x00213b44, // n0x0436 c0x0000 (---------------) + I sapo + 0x00224d44, // n0x0437 c0x0000 (---------------) + I sarl + 0x00223143, // n0x0438 c0x0000 (---------------) + I sas + 0x00225ac4, // n0x0439 c0x0000 (---------------) + I save + 0x0039bb84, // n0x043a c0x0000 (---------------) + I saxo + 0x4ba286c2, // n0x043b c0x012e (n0x1c08-n0x1c0d) + I sb + 0x0028b4c3, // n0x043c c0x0000 (---------------) + I sbi + 0x00230f83, // n0x043d c0x0000 (---------------) + I sbs + 0x4be07f02, // n0x043e c0x012f (n0x1c0d-n0x1c12) + I sc + 0x00237083, // n0x043f c0x0000 (---------------) + I sca + 0x00329b83, // n0x0440 c0x0000 (---------------) + I scb + 0x0021728a, // n0x0441 c0x0000 (---------------) + I schaeffler + 0x002e6b07, // n0x0442 c0x0000 (---------------) + I schmidt + 0x00231ecc, // n0x0443 c0x0000 (---------------) + I scholarships + 0x00232186, // n0x0444 c0x0000 (---------------) + I school + 0x00233546, // n0x0445 c0x0000 (---------------) + I schule + 0x00234447, // n0x0446 c0x0000 (---------------) + I schwarz + 0x00235f47, // n0x0447 c0x0000 (---------------) + I science + 0x00242c49, // n0x0448 c0x0000 (---------------) + I scjohnson + 0x0021ec84, // n0x0449 c0x0000 (---------------) + I scor + 0x00399d44, // n0x044a c0x0000 (---------------) + I scot + 0x4c22b2c2, // n0x044b c0x0130 (n0x1c12-n0x1c1a) + I sd + 0x4c604ec2, // n0x044c c0x0131 (n0x1c1a-n0x1c43) + I se + 0x00319204, // n0x044d c0x0000 (---------------) + I seat + 0x0031d846, // n0x044e c0x0000 (---------------) + I secure + 0x002363c8, // n0x044f c0x0000 (---------------) + I security + 0x00279f44, // n0x0450 c0x0000 (---------------) + I seek + 0x0025b186, // n0x0451 c0x0000 (---------------) + I select + 0x002cca45, // n0x0452 c0x0000 (---------------) + I sener + 0x0020b748, // n0x0453 c0x0000 (---------------) + I services + 0x00204ec3, // n0x0454 c0x0000 (---------------) + I ses + 0x00336fc5, // n0x0455 c0x0000 (---------------) + I seven + 0x0035f283, // n0x0456 c0x0000 (---------------) + I sew + 0x00246b03, // n0x0457 c0x0000 (---------------) + I sex + 0x00246b04, // n0x0458 c0x0000 (---------------) + I sexy + 0x0024ba03, // n0x0459 c0x0000 (---------------) + I sfr + 0x4ca6ed02, // n0x045a c0x0132 (n0x1c43-n0x1c4a) + I sg + 0x4ce01242, // n0x045b c0x0133 (n0x1c4a-n0x1c51) + I sh + 0x002514c9, // n0x045c c0x0000 (---------------) + I shangrila + 0x002545c5, // n0x045d c0x0000 (---------------) + I sharp + 0x002574c4, // n0x045e c0x0000 (---------------) + I shaw + 0x002582c5, // n0x045f c0x0000 (---------------) + I shell + 0x00210404, // n0x0460 c0x0000 (---------------) + I shia + 0x0035cb07, // n0x0461 c0x0000 (---------------) + I shiksha + 0x00387c45, // n0x0462 c0x0000 (---------------) + I shoes + 0x002b1e06, // n0x0463 c0x0000 (---------------) + I shouji + 0x002b2f44, // n0x0464 c0x0000 (---------------) + I show + 0x002b4188, // n0x0465 c0x0000 (---------------) + I showtime + 0x002c03c7, // n0x0466 c0x0000 (---------------) + I shriram + 0x4d2091c2, // n0x0467 c0x0134 (n0x1c51-n0x1c52) + I si + 0x00358404, // n0x0468 c0x0000 (---------------) + I silk + 0x002f6a84, // n0x0469 c0x0000 (---------------) + I sina + 0x00286a87, // n0x046a c0x0000 (---------------) + I singles + 0x00243684, // n0x046b c0x0000 (---------------) + I site + 0x0025b502, // n0x046c c0x0000 (---------------) + I sj + 0x4d608502, // n0x046d c0x0135 (n0x1c52-n0x1c53) + I sk + 0x00208503, // n0x046e c0x0000 (---------------) + I ski + 0x0037cb84, // n0x046f c0x0000 (---------------) + I skin + 0x00236f43, // n0x0470 c0x0000 (---------------) + I sky + 0x00236f45, // n0x0471 c0x0000 (---------------) + I skype + 0x4da20102, // n0x0472 c0x0136 (n0x1c53-n0x1c58) + I sl + 0x002cdd05, // n0x0473 c0x0000 (---------------) + I sling + 0x00213e02, // n0x0474 c0x0000 (---------------) + I sm + 0x0034dd45, // n0x0475 c0x0000 (---------------) + I smart + 0x0035d9c5, // n0x0476 c0x0000 (---------------) + I smile + 0x4de14b82, // n0x0477 c0x0137 (n0x1c58-n0x1c60) + I sn + 0x00214b84, // n0x0478 c0x0000 (---------------) + I sncf + 0x4e205f02, // n0x0479 c0x0138 (n0x1c60-n0x1c63) + I so + 0x00324dc6, // n0x047a c0x0000 (---------------) + I soccer + 0x002a4fc6, // n0x047b c0x0000 (---------------) + I social + 0x00269988, // n0x047c c0x0000 (---------------) + I softbank + 0x002b9808, // n0x047d c0x0000 (---------------) + I software + 0x002f8404, // n0x047e c0x0000 (---------------) + I sohu + 0x002e0985, // n0x047f c0x0000 (---------------) + I solar + 0x002f85c9, // n0x0480 c0x0000 (---------------) + I solutions + 0x003533c4, // n0x0481 c0x0000 (---------------) + I song + 0x00399404, // n0x0482 c0x0000 (---------------) + I sony + 0x002bf303, // n0x0483 c0x0000 (---------------) + I soy + 0x0020aa85, // n0x0484 c0x0000 (---------------) + I space + 0x00370047, // n0x0485 c0x0000 (---------------) + I spiegel + 0x00208144, // n0x0486 c0x0000 (---------------) + I spot + 0x0032fd8d, // n0x0487 c0x0000 (---------------) + I spreadbetting + 0x00332d82, // n0x0488 c0x0000 (---------------) + I sr + 0x00332d83, // n0x0489 c0x0000 (---------------) + I srl + 0x00334483, // n0x048a c0x0000 (---------------) + I srt + 0x4e602602, // n0x048b c0x0139 (n0x1c63-n0x1c6f) + I st + 0x0037e645, // n0x048c c0x0000 (---------------) + I stada + 0x00231d47, // n0x048d c0x0000 (---------------) + I staples + 0x0022a304, // n0x048e c0x0000 (---------------) + I star + 0x0022a307, // n0x048f c0x0000 (---------------) + I starhub + 0x0020a209, // n0x0490 c0x0000 (---------------) + I statebank + 0x002c4249, // n0x0491 c0x0000 (---------------) + I statefarm + 0x002ef347, // n0x0492 c0x0000 (---------------) + I statoil + 0x00277543, // n0x0493 c0x0000 (---------------) + I stc + 0x00277548, // n0x0494 c0x0000 (---------------) + I stcgroup + 0x0029d589, // n0x0495 c0x0000 (---------------) + I stockholm + 0x00358fc7, // n0x0496 c0x0000 (---------------) + I storage + 0x00364cc5, // n0x0497 c0x0000 (---------------) + I store + 0x002e7c86, // n0x0498 c0x0000 (---------------) + I studio + 0x002e7e05, // n0x0499 c0x0000 (---------------) + I study + 0x0035f505, // n0x049a c0x0000 (---------------) + I style + 0x4ea00702, // n0x049b c0x013a (n0x1c6f-n0x1c8f) + I su + 0x0026cc05, // n0x049c c0x0000 (---------------) + I sucks + 0x002bc24a, // n0x049d c0x0000 (---------------) + I supersport + 0x002c0208, // n0x049e c0x0000 (---------------) + I supplies + 0x002bfe86, // n0x049f c0x0000 (---------------) + I supply + 0x002e4607, // n0x04a0 c0x0000 (---------------) + I support + 0x002461c4, // n0x04a1 c0x0000 (---------------) + I surf + 0x002a3c47, // n0x04a2 c0x0000 (---------------) + I surgery + 0x002ea786, // n0x04a3 c0x0000 (---------------) + I suzuki + 0x4ee365c2, // n0x04a4 c0x013b (n0x1c8f-n0x1c94) + I sv + 0x00375a86, // n0x04a5 c0x0000 (---------------) + I swatch + 0x002ecb4a, // n0x04a6 c0x0000 (---------------) + I swiftcover + 0x002ed505, // n0x04a7 c0x0000 (---------------) + I swiss + 0x4f2edb02, // n0x04a8 c0x013c (n0x1c94-n0x1c95) + I sx + 0x4f68c0c2, // n0x04a9 c0x013d (n0x1c95-n0x1c9b) + I sy + 0x00335c06, // n0x04aa c0x0000 (---------------) + I sydney + 0x002ad308, // n0x04ab c0x0000 (---------------) + I symantec + 0x003943c7, // n0x04ac c0x0000 (---------------) + I systems + 0x4fa000c2, // n0x04ad c0x013e (n0x1c9b-n0x1c9e) + I sz + 0x0020e043, // n0x04ae c0x0000 (---------------) + I tab + 0x002004c6, // n0x04af c0x0000 (---------------) + I taipei + 0x00222d84, // n0x04b0 c0x0000 (---------------) + I talk + 0x00394fc6, // n0x04b1 c0x0000 (---------------) + I taobao + 0x00249c86, // n0x04b2 c0x0000 (---------------) + I target + 0x003125ca, // n0x04b3 c0x0000 (---------------) + I tatamotors + 0x0036bec5, // n0x04b4 c0x0000 (---------------) + I tatar + 0x0021f4c6, // n0x04b5 c0x0000 (---------------) + I tattoo + 0x00224103, // n0x04b6 c0x0000 (---------------) + I tax + 0x00224104, // n0x04b7 c0x0000 (---------------) + I taxi + 0x00204c42, // n0x04b8 c0x0000 (---------------) + I tc + 0x0026b7c3, // n0x04b9 c0x0000 (---------------) + I tci + 0x4fe0cd82, // n0x04ba c0x013f (n0x1c9e-n0x1c9f) + I td + 0x002cae83, // n0x04bb c0x0000 (---------------) + I tdk + 0x00367644, // n0x04bc c0x0000 (---------------) + I team + 0x002ad444, // n0x04bd c0x0000 (---------------) + I tech + 0x002ad44a, // n0x04be c0x0000 (---------------) + I technology + 0x0022ce43, // n0x04bf c0x0000 (---------------) + I tel + 0x00285708, // n0x04c0 c0x0000 (---------------) + I telecity + 0x00310b0a, // n0x04c1 c0x0000 (---------------) + I telefonica + 0x00240747, // n0x04c2 c0x0000 (---------------) + I temasek + 0x002f02c6, // n0x04c3 c0x0000 (---------------) + I tennis + 0x0032e244, // n0x04c4 c0x0000 (---------------) + I teva + 0x0025d582, // n0x04c5 c0x0000 (---------------) + I tf + 0x00205442, // n0x04c6 c0x0000 (---------------) + I tg + 0x50206982, // n0x04c7 c0x0140 (n0x1c9f-n0x1ca6) + I th + 0x0024a8c3, // n0x04c8 c0x0000 (---------------) + I thd + 0x00257a07, // n0x04c9 c0x0000 (---------------) + I theater + 0x00353107, // n0x04ca c0x0000 (---------------) + I theatre + 0x0034e74b, // n0x04cb c0x0000 (---------------) + I theguardian + 0x0034adc4, // n0x04cc c0x0000 (---------------) + I tiaa + 0x002f2307, // n0x04cd c0x0000 (---------------) + I tickets + 0x002ddf86, // n0x04ce c0x0000 (---------------) + I tienda + 0x0039f287, // n0x04cf c0x0000 (---------------) + I tiffany + 0x002e6a44, // n0x04d0 c0x0000 (---------------) + I tips + 0x0034f885, // n0x04d1 c0x0000 (---------------) + I tires + 0x002bc705, // n0x04d2 c0x0000 (---------------) + I tirol + 0x50631342, // n0x04d3 c0x0141 (n0x1ca6-n0x1cb5) + I tj + 0x0027db46, // n0x04d4 c0x0000 (---------------) + I tjmaxx + 0x00231343, // n0x04d5 c0x0000 (---------------) + I tjx + 0x0021a4c2, // n0x04d6 c0x0000 (---------------) + I tk + 0x00238946, // n0x04d7 c0x0000 (---------------) + I tkmaxx + 0x50a17cc2, // n0x04d8 c0x0142 (n0x1cb5-n0x1cb6) + I tl + 0x50e00c82, // n0x04d9 c0x0143 (n0x1cb6-n0x1cbe) + I tm + 0x00200c85, // n0x04da c0x0000 (---------------) + I tmall + 0x5124fd82, // n0x04db c0x0144 (n0x1cbe-n0x1cd2) + I tn + 0x51606e42, // n0x04dc c0x0145 (n0x1cd2-n0x1cd8) + I to + 0x00263b05, // n0x04dd c0x0000 (---------------) + I today + 0x00342205, // n0x04de c0x0000 (---------------) + I tokyo + 0x0021f585, // n0x04df c0x0000 (---------------) + I tools + 0x00206e43, // n0x04e0 c0x0000 (---------------) + I top + 0x00368b45, // n0x04e1 c0x0000 (---------------) + I toray + 0x002d28c7, // n0x04e2 c0x0000 (---------------) + I toshiba + 0x0025c405, // n0x04e3 c0x0000 (---------------) + I total + 0x002fc205, // n0x04e4 c0x0000 (---------------) + I tours + 0x002dc0c4, // n0x04e5 c0x0000 (---------------) + I town + 0x00264186, // n0x04e6 c0x0000 (---------------) + I toyota + 0x0026f0c4, // n0x04e7 c0x0000 (---------------) + I toys + 0x51a03902, // n0x04e8 c0x0146 (n0x1cd8-n0x1ced) + I tr + 0x00265705, // n0x04e9 c0x0000 (---------------) + I trade + 0x002a5c47, // n0x04ea c0x0000 (---------------) + I trading + 0x00305c88, // n0x04eb c0x0000 (---------------) + I training + 0x002a3206, // n0x04ec c0x0000 (---------------) + I travel + 0x002a320d, // n0x04ed c0x0000 (---------------) + I travelchannel + 0x002aa689, // n0x04ee c0x0000 (---------------) + I travelers + 0x002aa692, // n0x04ef c0x0000 (---------------) + I travelersinsurance + 0x0032a345, // n0x04f0 c0x0000 (---------------) + I trust + 0x003424c3, // n0x04f1 c0x0000 (---------------) + I trv + 0x5260fac2, // n0x04f2 c0x0149 (n0x1cef-n0x1d00) + I tt + 0x002e5644, // n0x04f3 c0x0000 (---------------) + I tube + 0x002f78c3, // n0x04f4 c0x0000 (---------------) + I tui + 0x002ede45, // n0x04f5 c0x0000 (---------------) + I tunes + 0x002eeb85, // n0x04f6 c0x0000 (---------------) + I tushu + 0x52a203c2, // n0x04f7 c0x014a (n0x1d00-n0x1d04) + I tv + 0x00364c43, // n0x04f8 c0x0000 (---------------) + I tvs + 0x52e534c2, // n0x04f9 c0x014b (n0x1d04-n0x1d12) + I tw + 0x53223bc2, // n0x04fa c0x014c (n0x1d12-n0x1d1e) + I tz + 0x53624242, // n0x04fb c0x014d (n0x1d1e-n0x1d6d) + I ua + 0x0033c185, // n0x04fc c0x0000 (---------------) + I ubank + 0x00255ec3, // n0x04fd c0x0000 (---------------) + I ubs + 0x0022ae08, // n0x04fe c0x0000 (---------------) + I uconnect + 0x53a04682, // n0x04ff c0x014e (n0x1d6d-n0x1d76) + I ug + 0x53e01b02, // n0x0500 c0x014f (n0x1d76-n0x1d81) + I uk + 0x002a7c46, // n0x0501 c0x0000 (---------------) + I unicom + 0x00309e4a, // n0x0502 c0x0000 (---------------) + I university + 0x0020e783, // n0x0503 c0x0000 (---------------) + I uno + 0x00249583, // n0x0504 c0x0000 (---------------) + I uol + 0x002d2003, // n0x0505 c0x0000 (---------------) + I ups + 0x54a02242, // n0x0506 c0x0152 (n0x1d83-n0x1dc2) + I us + 0x62e041c2, // n0x0507 c0x018b (n0x1e65-n0x1e6b) + I uy + 0x6360fec2, // n0x0508 c0x018d (n0x1e6c-n0x1e70) + I uz + 0x00200c02, // n0x0509 c0x0000 (---------------) + I va + 0x00375889, // n0x050a c0x0000 (---------------) + I vacations + 0x002be804, // n0x050b c0x0000 (---------------) + I vana + 0x00343f88, // n0x050c c0x0000 (---------------) + I vanguard + 0x63ae7802, // n0x050d c0x018e (n0x1e70-n0x1e76) + I vc + 0x63e02a42, // n0x050e c0x018f (n0x1e76-n0x1e87) + I ve + 0x0023dfc5, // n0x050f c0x0000 (---------------) + I vegas + 0x0023a188, // n0x0510 c0x0000 (---------------) + I ventures + 0x002ecd08, // n0x0511 c0x0000 (---------------) + I verisign + 0x003939cc, // n0x0512 c0x0000 (---------------) + I versicherung + 0x00240683, // n0x0513 c0x0000 (---------------) + I vet + 0x00234e42, // n0x0514 c0x0000 (---------------) + I vg + 0x642065c2, // n0x0515 c0x0190 (n0x1e87-n0x1e8c) + I vi + 0x002c7086, // n0x0516 c0x0000 (---------------) + I viajes + 0x002f1145, // n0x0517 c0x0000 (---------------) + I video + 0x0030a8c3, // n0x0518 c0x0000 (---------------) + I vig + 0x0032ae86, // n0x0519 c0x0000 (---------------) + I viking + 0x002f1286, // n0x051a c0x0000 (---------------) + I villas + 0x0025e683, // n0x051b c0x0000 (---------------) + I vin + 0x002f69c3, // n0x051c c0x0000 (---------------) + I vip + 0x002f6d86, // n0x051d c0x0000 (---------------) + I virgin + 0x002f7304, // n0x051e c0x0000 (---------------) + I visa + 0x0027bc46, // n0x051f c0x0000 (---------------) + I vision + 0x002caa45, // n0x0520 c0x0000 (---------------) + I vista + 0x002f768a, // n0x0521 c0x0000 (---------------) + I vistaprint + 0x00240044, // n0x0522 c0x0000 (---------------) + I viva + 0x002f88c4, // n0x0523 c0x0000 (---------------) + I vivo + 0x0034514a, // n0x0524 c0x0000 (---------------) + I vlaanderen + 0x64602f42, // n0x0525 c0x0191 (n0x1e8c-n0x1e99) + I vn + 0x00275ec5, // n0x0526 c0x0000 (---------------) + I vodka + 0x002fa4ca, // n0x0527 c0x0000 (---------------) + I volkswagen + 0x002fb385, // n0x0528 c0x0000 (---------------) + I volvo + 0x002fbf04, // n0x0529 c0x0000 (---------------) + I vote + 0x002fc006, // n0x052a c0x0000 (---------------) + I voting + 0x002fc184, // n0x052b c0x0000 (---------------) + I voto + 0x00230ac6, // n0x052c c0x0000 (---------------) + I voyage + 0x64a6a402, // n0x052d c0x0192 (n0x1e99-n0x1e9d) + I vu + 0x00308a06, // n0x052e c0x0000 (---------------) + I vuelos + 0x00309ac5, // n0x052f c0x0000 (---------------) + I wales + 0x00201c47, // n0x0530 c0x0000 (---------------) + I walmart + 0x00295246, // n0x0531 c0x0000 (---------------) + I walter + 0x00234644, // n0x0532 c0x0000 (---------------) + I wang + 0x002aeac7, // n0x0533 c0x0000 (---------------) + I wanggou + 0x0036de86, // n0x0534 c0x0000 (---------------) + I warman + 0x002b0685, // n0x0535 c0x0000 (---------------) + I watch + 0x003a5007, // n0x0536 c0x0000 (---------------) + I watches + 0x00390e47, // n0x0537 c0x0000 (---------------) + I weather + 0x00390e4e, // n0x0538 c0x0000 (---------------) + I weatherchannel + 0x0021e246, // n0x0539 c0x0000 (---------------) + I webcam + 0x0022fb85, // n0x053a c0x0000 (---------------) + I weber + 0x002c2487, // n0x053b c0x0000 (---------------) + I website + 0x002ebe43, // n0x053c c0x0000 (---------------) + I wed + 0x00353f07, // n0x053d c0x0000 (---------------) + I wedding + 0x00211745, // n0x053e c0x0000 (---------------) + I weibo + 0x00212044, // n0x053f c0x0000 (---------------) + I weir + 0x00230242, // n0x0540 c0x0000 (---------------) + I wf + 0x0036e507, // n0x0541 c0x0000 (---------------) + I whoswho + 0x002ea684, // n0x0542 c0x0000 (---------------) + I wien + 0x0023e984, // n0x0543 c0x0000 (---------------) + I wiki + 0x0025a64b, // n0x0544 c0x0000 (---------------) + I williamhill + 0x00220ac3, // n0x0545 c0x0000 (---------------) + I win + 0x002fd1c7, // n0x0546 c0x0000 (---------------) + I windows + 0x00220ac4, // n0x0547 c0x0000 (---------------) + I wine + 0x002b2dc7, // n0x0548 c0x0000 (---------------) + I winners + 0x002318c3, // n0x0549 c0x0000 (---------------) + I wme + 0x0032c58d, // n0x054a c0x0000 (---------------) + I wolterskluwer + 0x0037ee88, // n0x054b c0x0000 (---------------) + I woodside + 0x00256684, // n0x054c c0x0000 (---------------) + I work + 0x00357085, // n0x054d c0x0000 (---------------) + I works + 0x002ffbc5, // n0x054e c0x0000 (---------------) + I world + 0x002fdac3, // n0x054f c0x0000 (---------------) + I wow + 0x64e0a882, // n0x0550 c0x0193 (n0x1e9d-n0x1ea4) + I ws + 0x002fedc3, // n0x0551 c0x0000 (---------------) + I wtc + 0x002ff283, // n0x0552 c0x0000 (---------------) + I wtf + 0x00219604, // n0x0553 c0x0000 (---------------) + I xbox + 0x0027c3c5, // n0x0554 c0x0000 (---------------) + I xerox + 0x0027dcc7, // n0x0555 c0x0000 (---------------) + I xfinity + 0x00224186, // n0x0556 c0x0000 (---------------) + I xihuan + 0x00367383, // n0x0557 c0x0000 (---------------) + I xin + 0x00238a8b, // n0x0558 c0x0000 (---------------) + I xn--11b4c3d + 0x0024780b, // n0x0559 c0x0000 (---------------) + I xn--1ck2e1b + 0x0027314b, // n0x055a c0x0000 (---------------) + I xn--1qqw23a + 0x002a6fca, // n0x055b c0x0000 (---------------) + I xn--30rr7y + 0x002bf80b, // n0x055c c0x0000 (---------------) + I xn--3bst00m + 0x002d538b, // n0x055d c0x0000 (---------------) + I xn--3ds443g + 0x002edb4c, // n0x055e c0x0000 (---------------) + I xn--3e0b707e + 0x00339a11, // n0x055f c0x0000 (---------------) + I xn--3oq18vl8pn36a + 0x00347f0a, // n0x0560 c0x0000 (---------------) + I xn--3pxu8k + 0x0036fa4b, // n0x0561 c0x0000 (---------------) + I xn--42c2d9a + 0x003a208b, // n0x0562 c0x0000 (---------------) + I xn--45brj9c + 0x003a49ca, // n0x0563 c0x0000 (---------------) + I xn--45q11c + 0x002fffca, // n0x0564 c0x0000 (---------------) + I xn--4gbrim + 0x0030038d, // n0x0565 c0x0000 (---------------) + I xn--4gq48lf9j + 0x0030310e, // n0x0566 c0x0000 (---------------) + I xn--54b7fta0cc + 0x0030368b, // n0x0567 c0x0000 (---------------) + I xn--55qw42g + 0x0030394a, // n0x0568 c0x0000 (---------------) + I xn--55qx5d + 0x00304751, // n0x0569 c0x0000 (---------------) + I xn--5su34j936bgsg + 0x00304b8a, // n0x056a c0x0000 (---------------) + I xn--5tzm5g + 0x0030508b, // n0x056b c0x0000 (---------------) + I xn--6frz82g + 0x003055ce, // n0x056c c0x0000 (---------------) + I xn--6qq986b3xl + 0x0030650c, // n0x056d c0x0000 (---------------) + I xn--80adxhks + 0x00306b4b, // n0x056e c0x0000 (---------------) + I xn--80ao21a + 0x00306e0e, // n0x056f c0x0000 (---------------) + I xn--80aqecdr1a + 0x0030718c, // n0x0570 c0x0000 (---------------) + I xn--80asehdb + 0x0030b78a, // n0x0571 c0x0000 (---------------) + I xn--80aswg + 0x0030ca0c, // n0x0572 c0x0000 (---------------) + I xn--8y0a063a + 0x6530cd0a, // n0x0573 c0x0194 (n0x1ea4-n0x1eaa) + I xn--90a3ac + 0x0030da49, // n0x0574 c0x0000 (---------------) + I xn--90ais + 0x0030f00a, // n0x0575 c0x0000 (---------------) + I xn--9dbq2a + 0x0030f28a, // n0x0576 c0x0000 (---------------) + I xn--9et52u + 0x0030f50b, // n0x0577 c0x0000 (---------------) + I xn--9krt00a + 0x0031404e, // n0x0578 c0x0000 (---------------) + I xn--b4w605ferd + 0x003143d1, // n0x0579 c0x0000 (---------------) + I xn--bck1b9a5dre4c + 0x0031b349, // n0x057a c0x0000 (---------------) + I xn--c1avg + 0x0031b58a, // n0x057b c0x0000 (---------------) + I xn--c2br7g + 0x0031c28b, // n0x057c c0x0000 (---------------) + I xn--cck2b3b + 0x0031ca4a, // n0x057d c0x0000 (---------------) + I xn--cg4bki + 0x0031d1d6, // n0x057e c0x0000 (---------------) + I xn--clchc0ea0b2g2a9gcd + 0x0031e9cb, // n0x057f c0x0000 (---------------) + I xn--czr694b + 0x0032220a, // n0x0580 c0x0000 (---------------) + I xn--czrs0t + 0x00322a4a, // n0x0581 c0x0000 (---------------) + I xn--czru2d + 0x0032400b, // n0x0582 c0x0000 (---------------) + I xn--d1acj3b + 0x00329dc9, // n0x0583 c0x0000 (---------------) + I xn--d1alf + 0x0032cf0d, // n0x0584 c0x0000 (---------------) + I xn--eckvdtc9d + 0x0032d58b, // n0x0585 c0x0000 (---------------) + I xn--efvy88h + 0x0032e48b, // n0x0586 c0x0000 (---------------) + I xn--estv75g + 0x0032ee4b, // n0x0587 c0x0000 (---------------) + I xn--fct429k + 0x0032f409, // n0x0588 c0x0000 (---------------) + I xn--fhbei + 0x0032fa4e, // n0x0589 c0x0000 (---------------) + I xn--fiq228c5hs + 0x003300ca, // n0x058a c0x0000 (---------------) + I xn--fiq64b + 0x003326ca, // n0x058b c0x0000 (---------------) + I xn--fiqs8s + 0x00332b4a, // n0x058c c0x0000 (---------------) + I xn--fiqz9s + 0x0033318b, // n0x058d c0x0000 (---------------) + I xn--fjq720a + 0x003339cb, // n0x058e c0x0000 (---------------) + I xn--flw351e + 0x00333c8d, // n0x058f c0x0000 (---------------) + I xn--fpcrj9c3d + 0x0033548d, // n0x0590 c0x0000 (---------------) + I xn--fzc2c9e2c + 0x00335d90, // n0x0591 c0x0000 (---------------) + I xn--fzys8d69uvgm + 0x0033624b, // n0x0592 c0x0000 (---------------) + I xn--g2xx48c + 0x0033670c, // n0x0593 c0x0000 (---------------) + I xn--gckr3f0f + 0x0033738b, // n0x0594 c0x0000 (---------------) + I xn--gecrj9c + 0x0033a18b, // n0x0595 c0x0000 (---------------) + I xn--gk3at1e + 0x0033d00b, // n0x0596 c0x0000 (---------------) + I xn--h2brj9c + 0x0034094b, // n0x0597 c0x0000 (---------------) + I xn--hxt814e + 0x003413cf, // n0x0598 c0x0000 (---------------) + I xn--i1b6b1a6a2e + 0x0034178b, // n0x0599 c0x0000 (---------------) + I xn--imr513n + 0x0034278a, // n0x059a c0x0000 (---------------) + I xn--io0a7i + 0x00343489, // n0x059b c0x0000 (---------------) + I xn--j1aef + 0x00343849, // n0x059c c0x0000 (---------------) + I xn--j1amh + 0x0034418b, // n0x059d c0x0000 (---------------) + I xn--j6w193g + 0x0034444e, // n0x059e c0x0000 (---------------) + I xn--jlq61u9w7b + 0x003457cb, // n0x059f c0x0000 (---------------) + I xn--jvr189m + 0x00346acf, // n0x05a0 c0x0000 (---------------) + I xn--kcrx77d1x4a + 0x00348b4b, // n0x05a1 c0x0000 (---------------) + I xn--kprw13d + 0x00348e0b, // n0x05a2 c0x0000 (---------------) + I xn--kpry57d + 0x003490cb, // n0x05a3 c0x0000 (---------------) + I xn--kpu716f + 0x00349a4a, // n0x05a4 c0x0000 (---------------) + I xn--kput3i + 0x0034fb89, // n0x05a5 c0x0000 (---------------) + I xn--l1acc + 0x00355ecf, // n0x05a6 c0x0000 (---------------) + I xn--lgbbat1ad8j + 0x0035aecc, // n0x05a7 c0x0000 (---------------) + I xn--mgb2ddes + 0x0035b34c, // n0x05a8 c0x0000 (---------------) + I xn--mgb9awbf + 0x0035b80e, // n0x05a9 c0x0000 (---------------) + I xn--mgba3a3ejt + 0x0035cf4f, // n0x05aa c0x0000 (---------------) + I xn--mgba3a4f16a + 0x0035d30e, // n0x05ab c0x0000 (---------------) + I xn--mgba3a4fra + 0x0035de10, // n0x05ac c0x0000 (---------------) + I xn--mgba7c0bbn0a + 0x0035e20f, // n0x05ad c0x0000 (---------------) + I xn--mgbaakc7dvf + 0x0035f64e, // n0x05ae c0x0000 (---------------) + I xn--mgbaam7a8h + 0x0035fb0c, // n0x05af c0x0000 (---------------) + I xn--mgbab2bd + 0x0035fe12, // n0x05b0 c0x0000 (---------------) + I xn--mgbai9a5eva00b + 0x00361151, // n0x05b1 c0x0000 (---------------) + I xn--mgbai9azgqp6j + 0x0036170e, // n0x05b2 c0x0000 (---------------) + I xn--mgbayh7gpa + 0x00361b4e, // n0x05b3 c0x0000 (---------------) + I xn--mgbb9fbpob + 0x0036208e, // n0x05b4 c0x0000 (---------------) + I xn--mgbbh1a71e + 0x0036240f, // n0x05b5 c0x0000 (---------------) + I xn--mgbc0a9azcg + 0x003627ce, // n0x05b6 c0x0000 (---------------) + I xn--mgbca7dzdo + 0x00362cd3, // n0x05b7 c0x0000 (---------------) + I xn--mgberp4a5d4a87g + 0x00363191, // n0x05b8 c0x0000 (---------------) + I xn--mgberp4a5d4ar + 0x003635ce, // n0x05b9 c0x0000 (---------------) + I xn--mgbi4ecexp + 0x00363a4c, // n0x05ba c0x0000 (---------------) + I xn--mgbpl2fh + 0x00363e93, // n0x05bb c0x0000 (---------------) + I xn--mgbqly7c0a67fbc + 0x00364610, // n0x05bc c0x0000 (---------------) + I xn--mgbqly7cvafr + 0x00364f4c, // n0x05bd c0x0000 (---------------) + I xn--mgbt3dhd + 0x0036524c, // n0x05be c0x0000 (---------------) + I xn--mgbtf8fl + 0x0036578b, // n0x05bf c0x0000 (---------------) + I xn--mgbtx2b + 0x00365c4e, // n0x05c0 c0x0000 (---------------) + I xn--mgbx4cd0ab + 0x0036614b, // n0x05c1 c0x0000 (---------------) + I xn--mix082f + 0x0036650b, // n0x05c2 c0x0000 (---------------) + I xn--mix891f + 0x00367a0c, // n0x05c3 c0x0000 (---------------) + I xn--mk1bu44c + 0x0036eb8a, // n0x05c4 c0x0000 (---------------) + I xn--mxtq1m + 0x0036f24c, // n0x05c5 c0x0000 (---------------) + I xn--ngbc5azd + 0x0036f54c, // n0x05c6 c0x0000 (---------------) + I xn--ngbe9e0a + 0x0036f849, // n0x05c7 c0x0000 (---------------) + I xn--ngbrx + 0x00370acb, // n0x05c8 c0x0000 (---------------) + I xn--nnx388a + 0x00370d88, // n0x05c9 c0x0000 (---------------) + I xn--node + 0x00371249, // n0x05ca c0x0000 (---------------) + I xn--nqv7f + 0x0037124f, // n0x05cb c0x0000 (---------------) + I xn--nqv7fs00ema + 0x00372bcb, // n0x05cc c0x0000 (---------------) + I xn--nyqy26a + 0x003747ca, // n0x05cd c0x0000 (---------------) + I xn--o3cw4h + 0x00375f0c, // n0x05ce c0x0000 (---------------) + I xn--ogbpf8fl + 0x00377ac9, // n0x05cf c0x0000 (---------------) + I xn--p1acf + 0x00377d48, // n0x05d0 c0x0000 (---------------) + I xn--p1ai + 0x00377f4b, // n0x05d1 c0x0000 (---------------) + I xn--pbt977c + 0x00379f8b, // n0x05d2 c0x0000 (---------------) + I xn--pgbs0dh + 0x0037ab8a, // n0x05d3 c0x0000 (---------------) + I xn--pssy2u + 0x0037ae0b, // n0x05d4 c0x0000 (---------------) + I xn--q9jyb4c + 0x0037be4c, // n0x05d5 c0x0000 (---------------) + I xn--qcka1pmc + 0x0037c908, // n0x05d6 c0x0000 (---------------) + I xn--qxam + 0x0037f08b, // n0x05d7 c0x0000 (---------------) + I xn--rhqv96g + 0x0038174b, // n0x05d8 c0x0000 (---------------) + I xn--rovu88b + 0x0038548b, // n0x05d9 c0x0000 (---------------) + I xn--s9brj9c + 0x00386b8b, // n0x05da c0x0000 (---------------) + I xn--ses554g + 0x003909cb, // n0x05db c0x0000 (---------------) + I xn--t60b56a + 0x00390c89, // n0x05dc c0x0000 (---------------) + I xn--tckwe + 0x003911cd, // n0x05dd c0x0000 (---------------) + I xn--tiq49xqyj + 0x00395b0a, // n0x05de c0x0000 (---------------) + I xn--unup4y + 0x00396a57, // n0x05df c0x0000 (---------------) + I xn--vermgensberater-ctb + 0x00397898, // n0x05e0 c0x0000 (---------------) + I xn--vermgensberatung-pwb + 0x0039bc89, // n0x05e1 c0x0000 (---------------) + I xn--vhquv + 0x0039ce8b, // n0x05e2 c0x0000 (---------------) + I xn--vuq861b + 0x0039dc54, // n0x05e3 c0x0000 (---------------) + I xn--w4r85el8fhu5dnra + 0x0039e14b, // n0x05e4 c0x0000 (---------------) + I xn--w4rs40l + 0x0039e6ca, // n0x05e5 c0x0000 (---------------) + I xn--wgbh1c + 0x0039ec8a, // n0x05e6 c0x0000 (---------------) + I xn--wgbl6a + 0x0039ef0b, // n0x05e7 c0x0000 (---------------) + I xn--xhq521b + 0x0039fd90, // n0x05e8 c0x0000 (---------------) + I xn--xkc2al3hye2a + 0x003a0191, // n0x05e9 c0x0000 (---------------) + I xn--xkc2dl3a5ee0h + 0x003a0a4a, // n0x05ea c0x0000 (---------------) + I xn--y9a3aq + 0x003a168d, // n0x05eb c0x0000 (---------------) + I xn--yfro4i67o + 0x003a1d8d, // n0x05ec c0x0000 (---------------) + I xn--ygbi2ammx + 0x003a548b, // n0x05ed c0x0000 (---------------) + I xn--zfr164b + 0x003a5c46, // n0x05ee c0x0000 (---------------) + I xperia + 0x0027dc43, // n0x05ef c0x0000 (---------------) + I xxx + 0x00246b83, // n0x05f0 c0x0000 (---------------) + I xyz + 0x00308546, // n0x05f1 c0x0000 (---------------) + I yachts + 0x0028f8c5, // n0x05f2 c0x0000 (---------------) + I yahoo + 0x002c92c7, // n0x05f3 c0x0000 (---------------) + I yamaxun + 0x003398c6, // n0x05f4 c0x0000 (---------------) + I yandex + 0x01607002, // n0x05f5 c0x0005 (---------------)* o I ye + 0x003a23c9, // n0x05f6 c0x0000 (---------------) + I yodobashi + 0x00352c44, // n0x05f7 c0x0000 (---------------) + I yoga + 0x002d1a88, // n0x05f8 c0x0000 (---------------) + I yokohama + 0x0024a803, // n0x05f9 c0x0000 (---------------) + I you + 0x002e5587, // n0x05fa c0x0000 (---------------) + I youtube + 0x00219c02, // n0x05fb c0x0000 (---------------) + I yt + 0x002ad943, // n0x05fc c0x0000 (---------------) + I yun + 0x65600182, // n0x05fd c0x0195 (n0x1eaa-n0x1ebb) o I za + 0x002c5d86, // n0x05fe c0x0000 (---------------) + I zappos + 0x002c6684, // n0x05ff c0x0000 (---------------) + I zara + 0x00326f84, // n0x0600 c0x0000 (---------------) + I zero + 0x0023b883, // n0x0601 c0x0000 (---------------) + I zip + 0x0023b885, // n0x0602 c0x0000 (---------------) + I zippo + 0x016ffd42, // n0x0603 c0x0005 (---------------)* o I zm + 0x002dd744, // n0x0604 c0x0000 (---------------) + I zone + 0x00273607, // n0x0605 c0x0000 (---------------) + I zuerich + 0x016fd182, // n0x0606 c0x0005 (---------------)* o I zw + 0x00233243, // n0x0607 c0x0000 (---------------) + I com + 0x00239103, // n0x0608 c0x0000 (---------------) + I edu + 0x0027d903, // n0x0609 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x060a c0x0000 (---------------) + I mil + 0x00223b43, // n0x060b c0x0000 (---------------) + I net + 0x00228743, // n0x060c c0x0000 (---------------) + I org + 0x00201383, // n0x060d c0x0000 (---------------) + I nom + 0x00200342, // n0x060e c0x0000 (---------------) + I ac + 0x000fe108, // n0x060f c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x0610 c0x0000 (---------------) + I co + 0x0027d903, // n0x0611 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x0612 c0x0000 (---------------) + I mil + 0x00223b43, // n0x0613 c0x0000 (---------------) + I net + 0x00228743, // n0x0614 c0x0000 (---------------) + I org + 0x00217283, // n0x0615 c0x0000 (---------------) + I sch + 0x00318816, // n0x0616 c0x0000 (---------------) + I accident-investigation + 0x0031a353, // n0x0617 c0x0000 (---------------) + I accident-prevention + 0x002f2189, // n0x0618 c0x0000 (---------------) + I aerobatic + 0x00378b48, // n0x0619 c0x0000 (---------------) + I aeroclub + 0x002e2dc9, // n0x061a c0x0000 (---------------) + I aerodrome + 0x002fa646, // n0x061b c0x0000 (---------------) + I agents + 0x0030e650, // n0x061c c0x0000 (---------------) + I air-surveillance + 0x0033f613, // n0x061d c0x0000 (---------------) + I air-traffic-control + 0x00205108, // n0x061e c0x0000 (---------------) + I aircraft + 0x0024e5c7, // n0x061f c0x0000 (---------------) + I airline + 0x002791c7, // n0x0620 c0x0000 (---------------) + I airport + 0x00287c0a, // n0x0621 c0x0000 (---------------) + I airtraffic + 0x002c06c9, // n0x0622 c0x0000 (---------------) + I ambulance + 0x00332009, // n0x0623 c0x0000 (---------------) + I amusement + 0x002d5e8b, // n0x0624 c0x0000 (---------------) + I association + 0x00320ec6, // n0x0625 c0x0000 (---------------) + I author + 0x0022e08a, // n0x0626 c0x0000 (---------------) + I ballooning + 0x00224906, // n0x0627 c0x0000 (---------------) + I broker + 0x00352843, // n0x0628 c0x0000 (---------------) + I caa + 0x002f3245, // n0x0629 c0x0000 (---------------) + I cargo + 0x0037b1c8, // n0x062a c0x0000 (---------------) + I catering + 0x00324e8d, // n0x062b c0x0000 (---------------) + I certification + 0x0033f1cc, // n0x062c c0x0000 (---------------) + I championship + 0x00309787, // n0x062d c0x0000 (---------------) + I charter + 0x00359e8d, // n0x062e c0x0000 (---------------) + I civilaviation + 0x00378c44, // n0x062f c0x0000 (---------------) + I club + 0x0023734a, // n0x0630 c0x0000 (---------------) + I conference + 0x00237e4a, // n0x0631 c0x0000 (---------------) + I consultant + 0x0023830a, // n0x0632 c0x0000 (---------------) + I consulting + 0x002f4607, // n0x0633 c0x0000 (---------------) + I control + 0x00242307, // n0x0634 c0x0000 (---------------) + I council + 0x00244144, // n0x0635 c0x0000 (---------------) + I crew + 0x00228206, // n0x0636 c0x0000 (---------------) + I design + 0x00249384, // n0x0637 c0x0000 (---------------) + I dgca + 0x0035c248, // n0x0638 c0x0000 (---------------) + I educator + 0x00311d49, // n0x0639 c0x0000 (---------------) + I emergency + 0x0030c4c6, // n0x063a c0x0000 (---------------) + I engine + 0x0030c4c8, // n0x063b c0x0000 (---------------) + I engineer + 0x00246fcd, // n0x063c c0x0000 (---------------) + I entertainment + 0x002c4489, // n0x063d c0x0000 (---------------) + I equipment + 0x00379608, // n0x063e c0x0000 (---------------) + I exchange + 0x00246987, // n0x063f c0x0000 (---------------) + I express + 0x00310d8a, // n0x0640 c0x0000 (---------------) + I federation + 0x00251346, // n0x0641 c0x0000 (---------------) + I flight + 0x0025cb47, // n0x0642 c0x0000 (---------------) + I freight + 0x0023ff44, // n0x0643 c0x0000 (---------------) + I fuel + 0x0026f907, // n0x0644 c0x0000 (---------------) + I gliding + 0x0027d90a, // n0x0645 c0x0000 (---------------) + I government + 0x00288dce, // n0x0646 c0x0000 (---------------) + I groundhandling + 0x0020c745, // n0x0647 c0x0000 (---------------) + I group + 0x002fd80b, // n0x0648 c0x0000 (---------------) + I hanggliding + 0x002f3589, // n0x0649 c0x0000 (---------------) + I homebuilt + 0x00263309, // n0x064a c0x0000 (---------------) + I insurance + 0x0027b207, // n0x064b c0x0000 (---------------) + I journal + 0x0038d78a, // n0x064c c0x0000 (---------------) + I journalist + 0x002869c7, // n0x064d c0x0000 (---------------) + I leasing + 0x002e2849, // n0x064e c0x0000 (---------------) + I logistics + 0x00395588, // n0x064f c0x0000 (---------------) + I magazine + 0x0027614b, // n0x0650 c0x0000 (---------------) + I maintenance + 0x00303545, // n0x0651 c0x0000 (---------------) + I media + 0x00288aca, // n0x0652 c0x0000 (---------------) + I microlight + 0x002a4849, // n0x0653 c0x0000 (---------------) + I modelling + 0x0030a84a, // n0x0654 c0x0000 (---------------) + I navigation + 0x002c6c8b, // n0x0655 c0x0000 (---------------) + I parachuting + 0x0026f80b, // n0x0656 c0x0000 (---------------) + I paragliding + 0x002d5c15, // n0x0657 c0x0000 (---------------) + I passenger-association + 0x002d6ac5, // n0x0658 c0x0000 (---------------) + I pilot + 0x00246a05, // n0x0659 c0x0000 (---------------) + I press + 0x002e1bca, // n0x065a c0x0000 (---------------) + I production + 0x0031d94a, // n0x065b c0x0000 (---------------) + I recreation + 0x0022ed87, // n0x065c c0x0000 (---------------) + I repbody + 0x00221903, // n0x065d c0x0000 (---------------) + I res + 0x002a1188, // n0x065e c0x0000 (---------------) + I research + 0x002ce40a, // n0x065f c0x0000 (---------------) + I rotorcraft + 0x0039f4c6, // n0x0660 c0x0000 (---------------) + I safety + 0x00242649, // n0x0661 c0x0000 (---------------) + I scientist + 0x0020b748, // n0x0662 c0x0000 (---------------) + I services + 0x002b2f44, // n0x0663 c0x0000 (---------------) + I show + 0x00288309, // n0x0664 c0x0000 (---------------) + I skydiving + 0x002b9808, // n0x0665 c0x0000 (---------------) + I software + 0x002ac947, // n0x0666 c0x0000 (---------------) + I student + 0x00265706, // n0x0667 c0x0000 (---------------) + I trader + 0x002a5c47, // n0x0668 c0x0000 (---------------) + I trading + 0x00299907, // n0x0669 c0x0000 (---------------) + I trainer + 0x00243b85, // n0x066a c0x0000 (---------------) + I union + 0x002dbb8c, // n0x066b c0x0000 (---------------) + I workinggroup + 0x00357085, // n0x066c c0x0000 (---------------) + I works + 0x00233243, // n0x066d c0x0000 (---------------) + I com + 0x00239103, // n0x066e c0x0000 (---------------) + I edu + 0x0027d903, // n0x066f c0x0000 (---------------) + I gov + 0x00223b43, // n0x0670 c0x0000 (---------------) + I net + 0x00228743, // n0x0671 c0x0000 (---------------) + I org + 0x0020ce42, // n0x0672 c0x0000 (---------------) + I co + 0x00233243, // n0x0673 c0x0000 (---------------) + I com + 0x00223b43, // n0x0674 c0x0000 (---------------) + I net + 0x00201383, // n0x0675 c0x0000 (---------------) + I nom + 0x00228743, // n0x0676 c0x0000 (---------------) + I org + 0x00233243, // n0x0677 c0x0000 (---------------) + I com + 0x00223b43, // n0x0678 c0x0000 (---------------) + I net + 0x0020ce83, // n0x0679 c0x0000 (---------------) + I off + 0x00228743, // n0x067a c0x0000 (---------------) + I org + 0x000fe108, // n0x067b c0x0000 (---------------) + blogspot + 0x00233243, // n0x067c c0x0000 (---------------) + I com + 0x00239103, // n0x067d c0x0000 (---------------) + I edu + 0x0027d903, // n0x067e c0x0000 (---------------) + I gov + 0x00207dc3, // n0x067f c0x0000 (---------------) + I mil + 0x00223b43, // n0x0680 c0x0000 (---------------) + I net + 0x00228743, // n0x0681 c0x0000 (---------------) + I org + 0x000fe108, // n0x0682 c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x0683 c0x0000 (---------------) + I co + 0x002024c2, // n0x0684 c0x0000 (---------------) + I ed + 0x00238542, // n0x0685 c0x0000 (---------------) + I gv + 0x002017c2, // n0x0686 c0x0000 (---------------) + I it + 0x00201902, // n0x0687 c0x0000 (---------------) + I og + 0x0022ee02, // n0x0688 c0x0000 (---------------) + I pb + 0x04633243, // n0x0689 c0x0011 (n0x0692-n0x0693) + I com + 0x00239103, // n0x068a c0x0000 (---------------) + I edu + 0x00212b03, // n0x068b c0x0000 (---------------) + I gob + 0x0027d903, // n0x068c c0x0000 (---------------) + I gov + 0x00201503, // n0x068d c0x0000 (---------------) + I int + 0x00207dc3, // n0x068e c0x0000 (---------------) + I mil + 0x00223b43, // n0x068f c0x0000 (---------------) + I net + 0x00228743, // n0x0690 c0x0000 (---------------) + I org + 0x00208c03, // n0x0691 c0x0000 (---------------) + I tur + 0x000fe108, // n0x0692 c0x0000 (---------------) + blogspot + 0x0025dc44, // n0x0693 c0x0000 (---------------) + I e164 + 0x00329387, // n0x0694 c0x0000 (---------------) + I in-addr + 0x00214243, // n0x0695 c0x0000 (---------------) + I ip6 + 0x0029b804, // n0x0696 c0x0000 (---------------) + I iris + 0x0020f003, // n0x0697 c0x0000 (---------------) + I uri + 0x0027b283, // n0x0698 c0x0000 (---------------) + I urn + 0x0027d903, // n0x0699 c0x0000 (---------------) + I gov + 0x00200342, // n0x069a c0x0000 (---------------) + I ac + 0x00131a83, // n0x069b c0x0000 (---------------) + biz + 0x0560ce42, // n0x069c c0x0015 (n0x06a1-n0x06a2) + I co + 0x00238542, // n0x069d c0x0000 (---------------) + I gv + 0x00001844, // n0x069e c0x0000 (---------------) + info + 0x00200dc2, // n0x069f c0x0000 (---------------) + I or + 0x000e17c4, // n0x06a0 c0x0000 (---------------) + priv + 0x000fe108, // n0x06a1 c0x0000 (---------------) + blogspot + 0x002388c3, // n0x06a2 c0x0000 (---------------) + I act + 0x0022b643, // n0x06a3 c0x0000 (---------------) + I asn + 0x05e33243, // n0x06a4 c0x0017 (n0x06b4-n0x06b5) + I com + 0x00237344, // n0x06a5 c0x0000 (---------------) + I conf + 0x06239103, // n0x06a6 c0x0018 (n0x06b5-n0x06bd) + I edu + 0x0667d903, // n0x06a7 c0x0019 (n0x06bd-n0x06c2) + I gov + 0x0020d9c2, // n0x06a8 c0x0000 (---------------) + I id + 0x00201844, // n0x06a9 c0x0000 (---------------) + I info + 0x00223b43, // n0x06aa c0x0000 (---------------) + I net + 0x002ebf43, // n0x06ab c0x0000 (---------------) + I nsw + 0x00201542, // n0x06ac c0x0000 (---------------) + I nt + 0x00228743, // n0x06ad c0x0000 (---------------) + I org + 0x0021e882, // n0x06ae c0x0000 (---------------) + I oz + 0x002e7143, // n0x06af c0x0000 (---------------) + I qld + 0x00201002, // n0x06b0 c0x0000 (---------------) + I sa + 0x00203f83, // n0x06b1 c0x0000 (---------------) + I tas + 0x0020b803, // n0x06b2 c0x0000 (---------------) + I vic + 0x00201c42, // n0x06b3 c0x0000 (---------------) + I wa + 0x000fe108, // n0x06b4 c0x0000 (---------------) + blogspot + 0x002388c3, // n0x06b5 c0x0000 (---------------) + I act + 0x002ebf43, // n0x06b6 c0x0000 (---------------) + I nsw + 0x00201542, // n0x06b7 c0x0000 (---------------) + I nt + 0x002e7143, // n0x06b8 c0x0000 (---------------) + I qld + 0x00201002, // n0x06b9 c0x0000 (---------------) + I sa + 0x00203f83, // n0x06ba c0x0000 (---------------) + I tas + 0x0020b803, // n0x06bb c0x0000 (---------------) + I vic + 0x00201c42, // n0x06bc c0x0000 (---------------) + I wa + 0x002e7143, // n0x06bd c0x0000 (---------------) + I qld + 0x00201002, // n0x06be c0x0000 (---------------) + I sa + 0x00203f83, // n0x06bf c0x0000 (---------------) + I tas + 0x0020b803, // n0x06c0 c0x0000 (---------------) + I vic + 0x00201c42, // n0x06c1 c0x0000 (---------------) + I wa + 0x00233243, // n0x06c2 c0x0000 (---------------) + I com + 0x00331a83, // n0x06c3 c0x0000 (---------------) + I biz + 0x00233243, // n0x06c4 c0x0000 (---------------) + I com + 0x00239103, // n0x06c5 c0x0000 (---------------) + I edu + 0x0027d903, // n0x06c6 c0x0000 (---------------) + I gov + 0x00201844, // n0x06c7 c0x0000 (---------------) + I info + 0x00201503, // n0x06c8 c0x0000 (---------------) + I int + 0x00207dc3, // n0x06c9 c0x0000 (---------------) + I mil + 0x00200904, // n0x06ca c0x0000 (---------------) + I name + 0x00223b43, // n0x06cb c0x0000 (---------------) + I net + 0x00228743, // n0x06cc c0x0000 (---------------) + I org + 0x002080c2, // n0x06cd c0x0000 (---------------) + I pp + 0x00224b03, // n0x06ce c0x0000 (---------------) + I pro + 0x000fe108, // n0x06cf c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x06d0 c0x0000 (---------------) + I co + 0x00233243, // n0x06d1 c0x0000 (---------------) + I com + 0x00239103, // n0x06d2 c0x0000 (---------------) + I edu + 0x0027d903, // n0x06d3 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x06d4 c0x0000 (---------------) + I mil + 0x00223b43, // n0x06d5 c0x0000 (---------------) + I net + 0x00228743, // n0x06d6 c0x0000 (---------------) + I org + 0x002006c2, // n0x06d7 c0x0000 (---------------) + I rs + 0x0024e904, // n0x06d8 c0x0000 (---------------) + I unbi + 0x00399f44, // n0x06d9 c0x0000 (---------------) + I unsa + 0x00331a83, // n0x06da c0x0000 (---------------) + I biz + 0x0020ce42, // n0x06db c0x0000 (---------------) + I co + 0x00233243, // n0x06dc c0x0000 (---------------) + I com + 0x00239103, // n0x06dd c0x0000 (---------------) + I edu + 0x0027d903, // n0x06de c0x0000 (---------------) + I gov + 0x00201844, // n0x06df c0x0000 (---------------) + I info + 0x00223b43, // n0x06e0 c0x0000 (---------------) + I net + 0x00228743, // n0x06e1 c0x0000 (---------------) + I org + 0x00364cc5, // n0x06e2 c0x0000 (---------------) + I store + 0x002203c2, // n0x06e3 c0x0000 (---------------) + I tv + 0x00200342, // n0x06e4 c0x0000 (---------------) + I ac + 0x000fe108, // n0x06e5 c0x0000 (---------------) + blogspot + 0x0027d903, // n0x06e6 c0x0000 (---------------) + I gov + 0x002314c1, // n0x06e7 c0x0000 (---------------) + I 0 + 0x0022bdc1, // n0x06e8 c0x0000 (---------------) + I 1 + 0x002479c1, // n0x06e9 c0x0000 (---------------) + I 2 + 0x0022ba81, // n0x06ea c0x0000 (---------------) + I 3 + 0x00238c41, // n0x06eb c0x0000 (---------------) + I 4 + 0x0027c701, // n0x06ec c0x0000 (---------------) + I 5 + 0x002142c1, // n0x06ed c0x0000 (---------------) + I 6 + 0x002315c1, // n0x06ee c0x0000 (---------------) + I 7 + 0x00300581, // n0x06ef c0x0000 (---------------) + I 8 + 0x00300641, // n0x06f0 c0x0000 (---------------) + I 9 + 0x002001c1, // n0x06f1 c0x0000 (---------------) + I a + 0x00200001, // n0x06f2 c0x0000 (---------------) + I b + 0x000fe108, // n0x06f3 c0x0000 (---------------) + blogspot + 0x00200141, // n0x06f4 c0x0000 (---------------) + I c + 0x00200201, // n0x06f5 c0x0000 (---------------) + I d + 0x00200081, // n0x06f6 c0x0000 (---------------) + I e + 0x00201701, // n0x06f7 c0x0000 (---------------) + I f + 0x00200281, // n0x06f8 c0x0000 (---------------) + I g + 0x002003c1, // n0x06f9 c0x0000 (---------------) + I h + 0x00200041, // n0x06fa c0x0000 (---------------) + I i + 0x002010c1, // n0x06fb c0x0000 (---------------) + I j + 0x00201b41, // n0x06fc c0x0000 (---------------) + I k + 0x00200d41, // n0x06fd c0x0000 (---------------) + I l + 0x00200441, // n0x06fe c0x0000 (---------------) + I m + 0x00200781, // n0x06ff c0x0000 (---------------) + I n + 0x00200dc1, // n0x0700 c0x0000 (---------------) + I o + 0x00200581, // n0x0701 c0x0000 (---------------) + I p + 0x00200f41, // n0x0702 c0x0000 (---------------) + I q + 0x002006c1, // n0x0703 c0x0000 (---------------) + I r + 0x002000c1, // n0x0704 c0x0000 (---------------) + I s + 0x002004c1, // n0x0705 c0x0000 (---------------) + I t + 0x00200741, // n0x0706 c0x0000 (---------------) + I u + 0x00200c01, // n0x0707 c0x0000 (---------------) + I v + 0x00201c41, // n0x0708 c0x0000 (---------------) + I w + 0x00200a01, // n0x0709 c0x0000 (---------------) + I x + 0x00200241, // n0x070a c0x0000 (---------------) + I y + 0x00200101, // n0x070b c0x0000 (---------------) + I z + 0x00233243, // n0x070c c0x0000 (---------------) + I com + 0x00239103, // n0x070d c0x0000 (---------------) + I edu + 0x0027d903, // n0x070e c0x0000 (---------------) + I gov + 0x00223b43, // n0x070f c0x0000 (---------------) + I net + 0x00228743, // n0x0710 c0x0000 (---------------) + I org + 0x0020ce42, // n0x0711 c0x0000 (---------------) + I co + 0x00233243, // n0x0712 c0x0000 (---------------) + I com + 0x00239103, // n0x0713 c0x0000 (---------------) + I edu + 0x00200dc2, // n0x0714 c0x0000 (---------------) + I or + 0x00228743, // n0x0715 c0x0000 (---------------) + I org + 0x00007ec7, // n0x0716 c0x0000 (---------------) + dscloud + 0x00013206, // n0x0717 c0x0000 (---------------) + dyndns + 0x000568ca, // n0x0718 c0x0000 (---------------) + for-better + 0x0008a448, // n0x0719 c0x0000 (---------------) + for-more + 0x00056ec8, // n0x071a c0x0000 (---------------) + for-some + 0x00057907, // n0x071b c0x0000 (---------------) + for-the + 0x0005abc6, // n0x071c c0x0000 (---------------) + selfip + 0x001267c6, // n0x071d c0x0000 (---------------) + webhop + 0x002d5e84, // n0x071e c0x0000 (---------------) + I asso + 0x0031c507, // n0x071f c0x0000 (---------------) + I barreau + 0x000fe108, // n0x0720 c0x0000 (---------------) + blogspot + 0x002aebc4, // n0x0721 c0x0000 (---------------) + I gouv + 0x00233243, // n0x0722 c0x0000 (---------------) + I com + 0x00239103, // n0x0723 c0x0000 (---------------) + I edu + 0x0027d903, // n0x0724 c0x0000 (---------------) + I gov + 0x00223b43, // n0x0725 c0x0000 (---------------) + I net + 0x00228743, // n0x0726 c0x0000 (---------------) + I org + 0x00233243, // n0x0727 c0x0000 (---------------) + I com + 0x00239103, // n0x0728 c0x0000 (---------------) + I edu + 0x00212b03, // n0x0729 c0x0000 (---------------) + I gob + 0x0027d903, // n0x072a c0x0000 (---------------) + I gov + 0x00201503, // n0x072b c0x0000 (---------------) + I int + 0x00207dc3, // n0x072c c0x0000 (---------------) + I mil + 0x00223b43, // n0x072d c0x0000 (---------------) + I net + 0x00228743, // n0x072e c0x0000 (---------------) + I org + 0x002203c2, // n0x072f c0x0000 (---------------) + I tv + 0x002c52c3, // n0x0730 c0x0000 (---------------) + I adm + 0x002da143, // n0x0731 c0x0000 (---------------) + I adv + 0x00208a43, // n0x0732 c0x0000 (---------------) + I agr + 0x00200942, // n0x0733 c0x0000 (---------------) + I am + 0x0024f683, // n0x0734 c0x0000 (---------------) + I arq + 0x00201d43, // n0x0735 c0x0000 (---------------) + I art + 0x00211e03, // n0x0736 c0x0000 (---------------) + I ato + 0x00200001, // n0x0737 c0x0000 (---------------) + I b + 0x00203e43, // n0x0738 c0x0000 (---------------) + I bio + 0x0022f084, // n0x0739 c0x0000 (---------------) + I blog + 0x00311b03, // n0x073a c0x0000 (---------------) + I bmd + 0x0026b803, // n0x073b c0x0000 (---------------) + I cim + 0x0021dac3, // n0x073c c0x0000 (---------------) + I cng + 0x002312c3, // n0x073d c0x0000 (---------------) + I cnt + 0x0a233243, // n0x073e c0x0028 (n0x0776-n0x0777) + I com + 0x0023c344, // n0x073f c0x0000 (---------------) + I coop + 0x0021da83, // n0x0740 c0x0000 (---------------) + I ecn + 0x0020ce03, // n0x0741 c0x0000 (---------------) + I eco + 0x00239103, // n0x0742 c0x0000 (---------------) + I edu + 0x00238e43, // n0x0743 c0x0000 (---------------) + I emp + 0x00213083, // n0x0744 c0x0000 (---------------) + I eng + 0x0029c403, // n0x0745 c0x0000 (---------------) + I esp + 0x0026b783, // n0x0746 c0x0000 (---------------) + I etc + 0x00226d43, // n0x0747 c0x0000 (---------------) + I eti + 0x002112c3, // n0x0748 c0x0000 (---------------) + I far + 0x00252284, // n0x0749 c0x0000 (---------------) + I flog + 0x00234802, // n0x074a c0x0000 (---------------) + I fm + 0x00256243, // n0x074b c0x0000 (---------------) + I fnd + 0x0025c203, // n0x074c c0x0000 (---------------) + I fot + 0x00277503, // n0x074d c0x0000 (---------------) + I fst + 0x00329c43, // n0x074e c0x0000 (---------------) + I g12 + 0x00327ec3, // n0x074f c0x0000 (---------------) + I ggf + 0x0027d903, // n0x0750 c0x0000 (---------------) + I gov + 0x002c9cc3, // n0x0751 c0x0000 (---------------) + I imb + 0x00221b03, // n0x0752 c0x0000 (---------------) + I ind + 0x00201683, // n0x0753 c0x0000 (---------------) + I inf + 0x0021cc83, // n0x0754 c0x0000 (---------------) + I jor + 0x002eee83, // n0x0755 c0x0000 (---------------) + I jus + 0x0022f7c3, // n0x0756 c0x0000 (---------------) + I leg + 0x002c1303, // n0x0757 c0x0000 (---------------) + I lel + 0x00200443, // n0x0758 c0x0000 (---------------) + I mat + 0x00213443, // n0x0759 c0x0000 (---------------) + I med + 0x00207dc3, // n0x075a c0x0000 (---------------) + I mil + 0x0022c182, // n0x075b c0x0000 (---------------) + I mp + 0x002812c3, // n0x075c c0x0000 (---------------) + I mus + 0x00223b43, // n0x075d c0x0000 (---------------) + I net + 0x01601383, // n0x075e c0x0005 (---------------)* o I nom + 0x00257ec3, // n0x075f c0x0000 (---------------) + I not + 0x0022bc43, // n0x0760 c0x0000 (---------------) + I ntr + 0x00212bc3, // n0x0761 c0x0000 (---------------) + I odo + 0x00228743, // n0x0762 c0x0000 (---------------) + I org + 0x00248a83, // n0x0763 c0x0000 (---------------) + I ppg + 0x00224b03, // n0x0764 c0x0000 (---------------) + I pro + 0x00232143, // n0x0765 c0x0000 (---------------) + I psc + 0x002f6a43, // n0x0766 c0x0000 (---------------) + I psi + 0x002e7303, // n0x0767 c0x0000 (---------------) + I qsl + 0x00264a45, // n0x0768 c0x0000 (---------------) + I radio + 0x0022c2c3, // n0x0769 c0x0000 (---------------) + I rec + 0x002e7343, // n0x076a c0x0000 (---------------) + I slg + 0x0033b7c3, // n0x076b c0x0000 (---------------) + I srv + 0x00224104, // n0x076c c0x0000 (---------------) + I taxi + 0x00337c43, // n0x076d c0x0000 (---------------) + I teo + 0x00245b03, // n0x076e c0x0000 (---------------) + I tmp + 0x0036f183, // n0x076f c0x0000 (---------------) + I trd + 0x00208c03, // n0x0770 c0x0000 (---------------) + I tur + 0x002203c2, // n0x0771 c0x0000 (---------------) + I tv + 0x00240683, // n0x0772 c0x0000 (---------------) + I vet + 0x002f96c4, // n0x0773 c0x0000 (---------------) + I vlog + 0x0023e984, // n0x0774 c0x0000 (---------------) + I wiki + 0x0025ca83, // n0x0775 c0x0000 (---------------) + I zlg + 0x000fe108, // n0x0776 c0x0000 (---------------) + blogspot + 0x00233243, // n0x0777 c0x0000 (---------------) + I com + 0x00239103, // n0x0778 c0x0000 (---------------) + I edu + 0x0027d903, // n0x0779 c0x0000 (---------------) + I gov + 0x00223b43, // n0x077a c0x0000 (---------------) + I net + 0x00228743, // n0x077b c0x0000 (---------------) + I org + 0x00233243, // n0x077c c0x0000 (---------------) + I com + 0x00239103, // n0x077d c0x0000 (---------------) + I edu + 0x0027d903, // n0x077e c0x0000 (---------------) + I gov + 0x00223b43, // n0x077f c0x0000 (---------------) + I net + 0x00228743, // n0x0780 c0x0000 (---------------) + I org + 0x0020ce42, // n0x0781 c0x0000 (---------------) + I co + 0x00228743, // n0x0782 c0x0000 (---------------) + I org + 0x0b633243, // n0x0783 c0x002d (n0x0787-n0x0788) + I com + 0x0027d903, // n0x0784 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x0785 c0x0000 (---------------) + I mil + 0x0020ce82, // n0x0786 c0x0000 (---------------) + I of + 0x000fe108, // n0x0787 c0x0000 (---------------) + blogspot + 0x00233243, // n0x0788 c0x0000 (---------------) + I com + 0x00239103, // n0x0789 c0x0000 (---------------) + I edu + 0x0027d903, // n0x078a c0x0000 (---------------) + I gov + 0x00223b43, // n0x078b c0x0000 (---------------) + I net + 0x00228743, // n0x078c c0x0000 (---------------) + I org + 0x00000182, // n0x078d c0x0000 (---------------) + za + 0x00201a02, // n0x078e c0x0000 (---------------) + I ab + 0x0021e2c2, // n0x078f c0x0000 (---------------) + I bc + 0x000fe108, // n0x0790 c0x0000 (---------------) + blogspot + 0x0000ce42, // n0x0791 c0x0000 (---------------) + co + 0x0023ad42, // n0x0792 c0x0000 (---------------) + I gc + 0x00205a82, // n0x0793 c0x0000 (---------------) + I mb + 0x00215b02, // n0x0794 c0x0000 (---------------) + I nb + 0x002016c2, // n0x0795 c0x0000 (---------------) + I nf + 0x00246d02, // n0x0796 c0x0000 (---------------) + I nl + 0x0020df42, // n0x0797 c0x0000 (---------------) + I ns + 0x00201542, // n0x0798 c0x0000 (---------------) + I nt + 0x00204182, // n0x0799 c0x0000 (---------------) + I nu + 0x00203a42, // n0x079a c0x0000 (---------------) + I on + 0x00200582, // n0x079b c0x0000 (---------------) + I pe + 0x0037bf42, // n0x079c c0x0000 (---------------) + I qc + 0x00208502, // n0x079d c0x0000 (---------------) + I sk + 0x00225782, // n0x079e c0x0000 (---------------) + I yk + 0x00120b09, // n0x079f c0x0000 (---------------) + ftpaccess + 0x0017248b, // n0x07a0 c0x0000 (---------------) + game-server + 0x000d2788, // n0x07a1 c0x0000 (---------------) + myphotos + 0x00045689, // n0x07a2 c0x0000 (---------------) + scrapping + 0x0027d903, // n0x07a3 c0x0000 (---------------) + I gov + 0x000fe108, // n0x07a4 c0x0000 (---------------) + blogspot + 0x000fe108, // n0x07a5 c0x0000 (---------------) + blogspot + 0x00200342, // n0x07a6 c0x0000 (---------------) + I ac + 0x002d5e84, // n0x07a7 c0x0000 (---------------) + I asso + 0x0020ce42, // n0x07a8 c0x0000 (---------------) + I co + 0x00233243, // n0x07a9 c0x0000 (---------------) + I com + 0x002024c2, // n0x07aa c0x0000 (---------------) + I ed + 0x00239103, // n0x07ab c0x0000 (---------------) + I edu + 0x00210a42, // n0x07ac c0x0000 (---------------) + I go + 0x002aebc4, // n0x07ad c0x0000 (---------------) + I gouv + 0x00201503, // n0x07ae c0x0000 (---------------) + I int + 0x0024dd82, // n0x07af c0x0000 (---------------) + I md + 0x00223b43, // n0x07b0 c0x0000 (---------------) + I net + 0x00200dc2, // n0x07b1 c0x0000 (---------------) + I or + 0x00228743, // n0x07b2 c0x0000 (---------------) + I org + 0x00246a06, // n0x07b3 c0x0000 (---------------) + I presse + 0x0030facf, // n0x07b4 c0x0000 (---------------) + I xn--aroport-bya + 0x006ffb43, // n0x07b5 c0x0001 (---------------) ! I www + 0x000fe108, // n0x07b6 c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x07b7 c0x0000 (---------------) + I co + 0x00212b03, // n0x07b8 c0x0000 (---------------) + I gob + 0x0027d903, // n0x07b9 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x07ba c0x0000 (---------------) + I mil + 0x0020ce42, // n0x07bb c0x0000 (---------------) + I co + 0x00233243, // n0x07bc c0x0000 (---------------) + I com + 0x0027d903, // n0x07bd c0x0000 (---------------) + I gov + 0x00223b43, // n0x07be c0x0000 (---------------) + I net + 0x00200342, // n0x07bf c0x0000 (---------------) + I ac + 0x00205702, // n0x07c0 c0x0000 (---------------) + I ah + 0x0e6f1ec9, // n0x07c1 c0x0039 (n0x07ec-n0x07ed) o I amazonaws + 0x0020b442, // n0x07c2 c0x0000 (---------------) + I bj + 0x0ee33243, // n0x07c3 c0x003b (n0x07ee-n0x07ef) + I com + 0x00242e82, // n0x07c4 c0x0000 (---------------) + I cq + 0x00239103, // n0x07c5 c0x0000 (---------------) + I edu + 0x0021cc42, // n0x07c6 c0x0000 (---------------) + I fj + 0x002265c2, // n0x07c7 c0x0000 (---------------) + I gd + 0x0027d903, // n0x07c8 c0x0000 (---------------) + I gov + 0x00245dc2, // n0x07c9 c0x0000 (---------------) + I gs + 0x00253302, // n0x07ca c0x0000 (---------------) + I gx + 0x0025ca42, // n0x07cb c0x0000 (---------------) + I gz + 0x00202302, // n0x07cc c0x0000 (---------------) + I ha + 0x0028ea42, // n0x07cd c0x0000 (---------------) + I hb + 0x002069c2, // n0x07ce c0x0000 (---------------) + I he + 0x002003c2, // n0x07cf c0x0000 (---------------) + I hi + 0x0020c482, // n0x07d0 c0x0000 (---------------) + I hk + 0x002484c2, // n0x07d1 c0x0000 (---------------) + I hl + 0x0021c682, // n0x07d2 c0x0000 (---------------) + I hn + 0x002add82, // n0x07d3 c0x0000 (---------------) + I jl + 0x00233742, // n0x07d4 c0x0000 (---------------) + I js + 0x00231382, // n0x07d5 c0x0000 (---------------) + I jx + 0x00229282, // n0x07d6 c0x0000 (---------------) + I ln + 0x00207dc3, // n0x07d7 c0x0000 (---------------) + I mil + 0x00208442, // n0x07d8 c0x0000 (---------------) + I mo + 0x00223b43, // n0x07d9 c0x0000 (---------------) + I net + 0x0022b882, // n0x07da c0x0000 (---------------) + I nm + 0x00268e82, // n0x07db c0x0000 (---------------) + I nx + 0x00228743, // n0x07dc c0x0000 (---------------) + I org + 0x0024f702, // n0x07dd c0x0000 (---------------) + I qh + 0x00207f02, // n0x07de c0x0000 (---------------) + I sc + 0x0022b2c2, // n0x07df c0x0000 (---------------) + I sd + 0x00201242, // n0x07e0 c0x0000 (---------------) + I sh + 0x00214b82, // n0x07e1 c0x0000 (---------------) + I sn + 0x002edb02, // n0x07e2 c0x0000 (---------------) + I sx + 0x00231342, // n0x07e3 c0x0000 (---------------) + I tj + 0x002534c2, // n0x07e4 c0x0000 (---------------) + I tw + 0x003a5242, // n0x07e5 c0x0000 (---------------) + I xj + 0x0030394a, // n0x07e6 c0x0000 (---------------) + I xn--55qx5d + 0x0034278a, // n0x07e7 c0x0000 (---------------) + I xn--io0a7i + 0x0037530a, // n0x07e8 c0x0000 (---------------) + I xn--od0alg + 0x003a5dc2, // n0x07e9 c0x0000 (---------------) + I xz + 0x00212fc2, // n0x07ea c0x0000 (---------------) + I yn + 0x00246c02, // n0x07eb c0x0000 (---------------) + I zj + 0x0e8358c7, // n0x07ec c0x003a (n0x07ed-n0x07ee) + compute + 0x00179d0a, // n0x07ed c0x0000 (---------------) + cn-north-1 + 0x0f2f1ec9, // n0x07ee c0x003c (n0x07ef-n0x07f0) o I amazonaws + 0x0f779d0a, // n0x07ef c0x003d (n0x07f0-n0x07f1) o I cn-north-1 + 0x0002ba42, // n0x07f0 c0x0000 (---------------) + s3 + 0x0024b944, // n0x07f1 c0x0000 (---------------) + I arts + 0x0fe33243, // n0x07f2 c0x003f (n0x07fe-n0x07ff) + I com + 0x00239103, // n0x07f3 c0x0000 (---------------) + I edu + 0x0024dcc4, // n0x07f4 c0x0000 (---------------) + I firm + 0x0027d903, // n0x07f5 c0x0000 (---------------) + I gov + 0x00201844, // n0x07f6 c0x0000 (---------------) + I info + 0x00201503, // n0x07f7 c0x0000 (---------------) + I int + 0x00207dc3, // n0x07f8 c0x0000 (---------------) + I mil + 0x00223b43, // n0x07f9 c0x0000 (---------------) + I net + 0x00201383, // n0x07fa c0x0000 (---------------) + I nom + 0x00228743, // n0x07fb c0x0000 (---------------) + I org + 0x0022c2c3, // n0x07fc c0x0000 (---------------) + I rec + 0x0021e243, // n0x07fd c0x0000 (---------------) + I web + 0x000fe108, // n0x07fe c0x0000 (---------------) + blogspot + 0x0006c185, // n0x07ff c0x0000 (---------------) + 1kapp + 0x0010c982, // n0x0800 c0x0000 (---------------) + 4u + 0x00174cc6, // n0x0801 c0x0000 (---------------) + africa + 0x106f1ec9, // n0x0802 c0x0041 (n0x08d1-n0x08e3) o I amazonaws + 0x00008087, // n0x0803 c0x0000 (---------------) + appspot + 0x00001d42, // n0x0804 c0x0000 (---------------) + ar + 0x0019d10a, // n0x0805 c0x0000 (---------------) + betainabox + 0x0002f087, // n0x0806 c0x0000 (---------------) + blogdns + 0x000fe108, // n0x0807 c0x0000 (---------------) + blogspot + 0x0001e3c2, // n0x0808 c0x0000 (---------------) + br + 0x00138747, // n0x0809 c0x0000 (---------------) + cechire + 0x0019458f, // n0x080a c0x0000 (---------------) + cloudcontrolapp + 0x000f44cf, // n0x080b c0x0000 (---------------) + cloudcontrolled + 0x0001dac2, // n0x080c c0x0000 (---------------) + cn + 0x0000ce42, // n0x080d c0x0000 (---------------) + co + 0x0009c348, // n0x080e c0x0000 (---------------) + codespot + 0x00005582, // n0x080f c0x0000 (---------------) + de + 0x00142e48, // n0x0810 c0x0000 (---------------) + dnsalias + 0x0007cf07, // n0x0811 c0x0000 (---------------) + dnsdojo + 0x0001580b, // n0x0812 c0x0000 (---------------) + doesntexist + 0x0016a789, // n0x0813 c0x0000 (---------------) + dontexist + 0x00142d47, // n0x0814 c0x0000 (---------------) + doomdns + 0x000efc0c, // n0x0815 c0x0000 (---------------) + dreamhosters + 0x0013c907, // n0x0816 c0x0000 (---------------) + dsmynas + 0x0012394a, // n0x0817 c0x0000 (---------------) + dyn-o-saur + 0x00197108, // n0x0818 c0x0000 (---------------) + dynalias + 0x00073a8e, // n0x0819 c0x0000 (---------------) + dyndns-at-home + 0x000db90e, // n0x081a c0x0000 (---------------) + dyndns-at-work + 0x0002eecb, // n0x081b c0x0000 (---------------) + dyndns-blog + 0x000e7ecb, // n0x081c c0x0000 (---------------) + dyndns-free + 0x0001320b, // n0x081d c0x0000 (---------------) + dyndns-home + 0x00014089, // n0x081e c0x0000 (---------------) + dyndns-ip + 0x00018acb, // n0x081f c0x0000 (---------------) + dyndns-mail + 0x0001dd0d, // n0x0820 c0x0000 (---------------) + dyndns-office + 0x0002144b, // n0x0821 c0x0000 (---------------) + dyndns-pics + 0x000251cd, // n0x0822 c0x0000 (---------------) + dyndns-remote + 0x0002e54d, // n0x0823 c0x0000 (---------------) + dyndns-server + 0x0002f9ca, // n0x0824 c0x0000 (---------------) + dyndns-web + 0x0003e7cb, // n0x0825 c0x0000 (---------------) + dyndns-wiki + 0x00156ecb, // n0x0826 c0x0000 (---------------) + dyndns-work + 0x00022a90, // n0x0827 c0x0000 (---------------) + elasticbeanstalk + 0x000b7d0f, // n0x0828 c0x0000 (---------------) + est-a-la-maison + 0x00008f0f, // n0x0829 c0x0000 (---------------) + est-a-la-masion + 0x001574cd, // n0x082a c0x0000 (---------------) + est-le-patron + 0x0007b810, // n0x082b c0x0000 (---------------) + est-mon-blogueur + 0x00005382, // n0x082c c0x0000 (---------------) + eu + 0x00007d48, // n0x082d c0x0000 (---------------) + familyds + 0x0004c58b, // n0x082e c0x0000 (---------------) + firebaseapp + 0x00054ec8, // n0x082f c0x0000 (---------------) + flynnhub + 0x00062387, // n0x0830 c0x0000 (---------------) + from-ak + 0x000626c7, // n0x0831 c0x0000 (---------------) + from-al + 0x00062887, // n0x0832 c0x0000 (---------------) + from-ar + 0x00063547, // n0x0833 c0x0000 (---------------) + from-ca + 0x00064007, // n0x0834 c0x0000 (---------------) + from-ct + 0x00064607, // n0x0835 c0x0000 (---------------) + from-dc + 0x00065347, // n0x0836 c0x0000 (---------------) + from-de + 0x00065887, // n0x0837 c0x0000 (---------------) + from-fl + 0x000668c7, // n0x0838 c0x0000 (---------------) + from-ga + 0x00066c47, // n0x0839 c0x0000 (---------------) + from-hi + 0x000674c7, // n0x083a c0x0000 (---------------) + from-ia + 0x00067687, // n0x083b c0x0000 (---------------) + from-id + 0x00067847, // n0x083c c0x0000 (---------------) + from-il + 0x00067a07, // n0x083d c0x0000 (---------------) + from-in + 0x00067d07, // n0x083e c0x0000 (---------------) + from-ks + 0x00068107, // n0x083f c0x0000 (---------------) + from-ky + 0x00068cc7, // n0x0840 c0x0000 (---------------) + from-ma + 0x00069187, // n0x0841 c0x0000 (---------------) + from-md + 0x00069707, // n0x0842 c0x0000 (---------------) + from-mi + 0x0006d147, // n0x0843 c0x0000 (---------------) + from-mn + 0x0006d307, // n0x0844 c0x0000 (---------------) + from-mo + 0x0006d607, // n0x0845 c0x0000 (---------------) + from-ms + 0x0006da07, // n0x0846 c0x0000 (---------------) + from-mt + 0x0006dc07, // n0x0847 c0x0000 (---------------) + from-nc + 0x0006e907, // n0x0848 c0x0000 (---------------) + from-nd + 0x0006eac7, // n0x0849 c0x0000 (---------------) + from-ne + 0x0006eec7, // n0x084a c0x0000 (---------------) + from-nh + 0x0006f607, // n0x084b c0x0000 (---------------) + from-nj + 0x0006fac7, // n0x084c c0x0000 (---------------) + from-nm + 0x00070587, // n0x084d c0x0000 (---------------) + from-nv + 0x00070b87, // n0x084e c0x0000 (---------------) + from-oh + 0x00070e47, // n0x084f c0x0000 (---------------) + from-ok + 0x000711c7, // n0x0850 c0x0000 (---------------) + from-or + 0x00071387, // n0x0851 c0x0000 (---------------) + from-pa + 0x00071707, // n0x0852 c0x0000 (---------------) + from-pr + 0x00071d87, // n0x0853 c0x0000 (---------------) + from-ri + 0x00072207, // n0x0854 c0x0000 (---------------) + from-sc + 0x00072607, // n0x0855 c0x0000 (---------------) + from-sd + 0x00072e07, // n0x0856 c0x0000 (---------------) + from-tn + 0x00072fc7, // n0x0857 c0x0000 (---------------) + from-tx + 0x00073407, // n0x0858 c0x0000 (---------------) + from-ut + 0x00074407, // n0x0859 c0x0000 (---------------) + from-va + 0x00074a47, // n0x085a c0x0000 (---------------) + from-vt + 0x00074d47, // n0x085b c0x0000 (---------------) + from-wa + 0x00074f07, // n0x085c c0x0000 (---------------) + from-wi + 0x00075287, // n0x085d c0x0000 (---------------) + from-wv + 0x00076407, // n0x085e c0x0000 (---------------) + from-wy + 0x0000e482, // n0x085f c0x0000 (---------------) + gb + 0x000d5a87, // n0x0860 c0x0000 (---------------) + getmyip + 0x000cbb91, // n0x0861 c0x0000 (---------------) + githubusercontent + 0x000df04a, // n0x0862 c0x0000 (---------------) + googleapis + 0x0009c1ca, // n0x0863 c0x0000 (---------------) + googlecode + 0x00058186, // n0x0864 c0x0000 (---------------) + gotdns + 0x00010a4b, // n0x0865 c0x0000 (---------------) + gotpantheon + 0x00008a82, // n0x0866 c0x0000 (---------------) + gr + 0x0009cf49, // n0x0867 c0x0000 (---------------) + herokuapp + 0x00093209, // n0x0868 c0x0000 (---------------) + herokussl + 0x0000c482, // n0x0869 c0x0000 (---------------) + hk + 0x0014a8ca, // n0x086a c0x0000 (---------------) + hobby-site + 0x000a6dc9, // n0x086b c0x0000 (---------------) + homelinux + 0x000a8148, // n0x086c c0x0000 (---------------) + homeunix + 0x00024202, // n0x086d c0x0000 (---------------) + hu + 0x00119609, // n0x086e c0x0000 (---------------) + iamallama + 0x0016cf4e, // n0x086f c0x0000 (---------------) + is-a-anarchist + 0x000a550c, // n0x0870 c0x0000 (---------------) + is-a-blogger + 0x000d3b8f, // n0x0871 c0x0000 (---------------) + is-a-bookkeeper + 0x0018ac0e, // n0x0872 c0x0000 (---------------) + is-a-bulls-fan + 0x0000f08c, // n0x0873 c0x0000 (---------------) + is-a-caterer + 0x000110c9, // n0x0874 c0x0000 (---------------) + is-a-chef + 0x00014711, // n0x0875 c0x0000 (---------------) + is-a-conservative + 0x00016788, // n0x0876 c0x0000 (---------------) + is-a-cpa + 0x0001fdd2, // n0x0877 c0x0000 (---------------) + is-a-cubicle-slave + 0x000244cd, // n0x0878 c0x0000 (---------------) + is-a-democrat + 0x000280cd, // n0x0879 c0x0000 (---------------) + is-a-designer + 0x0016894b, // n0x087a c0x0000 (---------------) + is-a-doctor + 0x000d9dd5, // n0x087b c0x0000 (---------------) + is-a-financialadvisor + 0x0004ef49, // n0x087c c0x0000 (---------------) + is-a-geek + 0x0005200a, // n0x087d c0x0000 (---------------) + is-a-green + 0x00053949, // n0x087e c0x0000 (---------------) + is-a-guru + 0x0005b990, // n0x087f c0x0000 (---------------) + is-a-hard-worker + 0x0006434b, // n0x0880 c0x0000 (---------------) + is-a-hunter + 0x0006640f, // n0x0881 c0x0000 (---------------) + is-a-landscaper + 0x00071acb, // n0x0882 c0x0000 (---------------) + is-a-lawyer + 0x00071f0c, // n0x0883 c0x0000 (---------------) + is-a-liberal + 0x00074010, // n0x0884 c0x0000 (---------------) + is-a-libertarian + 0x0008080a, // n0x0885 c0x0000 (---------------) + is-a-llama + 0x0008118d, // n0x0886 c0x0000 (---------------) + is-a-musician + 0x0008b00e, // n0x0887 c0x0000 (---------------) + is-a-nascarfan + 0x00143b4a, // n0x0888 c0x0000 (---------------) + is-a-nurse + 0x0008c5cc, // n0x0889 c0x0000 (---------------) + is-a-painter + 0x000995d4, // n0x088a c0x0000 (---------------) + is-a-personaltrainer + 0x0009cbd1, // n0x088b c0x0000 (---------------) + is-a-photographer + 0x0009ff8b, // n0x088c c0x0000 (---------------) + is-a-player + 0x000a0d0f, // n0x088d c0x0000 (---------------) + is-a-republican + 0x000a270d, // n0x088e c0x0000 (---------------) + is-a-rockstar + 0x000a4e8e, // n0x088f c0x0000 (---------------) + is-a-socialist + 0x000ac80c, // n0x0890 c0x0000 (---------------) + is-a-student + 0x000acf4c, // n0x0891 c0x0000 (---------------) + is-a-teacher + 0x000d004b, // n0x0892 c0x0000 (---------------) + is-a-techie + 0x000d034e, // n0x0893 c0x0000 (---------------) + is-a-therapist + 0x000cf950, // n0x0894 c0x0000 (---------------) + is-an-accountant + 0x000bbf0b, // n0x0895 c0x0000 (---------------) + is-an-actor + 0x000cf44d, // n0x0896 c0x0000 (---------------) + is-an-actress + 0x0014b44f, // n0x0897 c0x0000 (---------------) + is-an-anarchist + 0x0013ba8c, // n0x0898 c0x0000 (---------------) + is-an-artist + 0x0010c34e, // n0x0899 c0x0000 (---------------) + is-an-engineer + 0x00169751, // n0x089a c0x0000 (---------------) + is-an-entertainer + 0x000b47cc, // n0x089b c0x0000 (---------------) + is-certified + 0x000ba5c7, // n0x089c c0x0000 (---------------) + is-gone + 0x000bb94d, // n0x089d c0x0000 (---------------) + is-into-anime + 0x000bd18c, // n0x089e c0x0000 (---------------) + is-into-cars + 0x000fc8d0, // n0x089f c0x0000 (---------------) + is-into-cartoons + 0x00145b8d, // n0x08a0 c0x0000 (---------------) + is-into-games + 0x0016f007, // n0x08a1 c0x0000 (---------------) + is-leet + 0x00173bd0, // n0x08a2 c0x0000 (---------------) + is-not-certified + 0x000f2bc8, // n0x08a3 c0x0000 (---------------) + is-slick + 0x000e984b, // n0x08a4 c0x0000 (---------------) + is-uberleet + 0x001429cf, // n0x08a5 c0x0000 (---------------) + is-with-theband + 0x000862c8, // n0x08a6 c0x0000 (---------------) + isa-geek + 0x000df24d, // n0x08a7 c0x0000 (---------------) + isa-hockeynut + 0x0014dcd0, // n0x08a8 c0x0000 (---------------) + issmarterthanyou + 0x000b0a83, // n0x08a9 c0x0000 (---------------) + jpn + 0x0000bdc2, // n0x08aa c0x0000 (---------------) + kr + 0x00058c89, // n0x08ab c0x0000 (---------------) + likes-pie + 0x0007388a, // n0x08ac c0x0000 (---------------) + likescandy + 0x00000983, // n0x08ad c0x0000 (---------------) + mex + 0x0010d047, // n0x08ae c0x0000 (---------------) + mydrobo + 0x00119d48, // n0x08af c0x0000 (---------------) + neat-url + 0x0016c0c7, // n0x08b0 c0x0000 (---------------) + nfshost + 0x00001382, // n0x08b1 c0x0000 (---------------) + no + 0x00064bca, // n0x08b2 c0x0000 (---------------) + operaunite + 0x0019430f, // n0x08b3 c0x0000 (---------------) + outsystemscloud + 0x0012690c, // n0x08b4 c0x0000 (---------------) + pagefrontapp + 0x00126bd2, // n0x08b5 c0x0000 (---------------) + pagespeedmobilizer + 0x116e1185, // n0x08b6 c0x0045 (n0x08ef-n0x08f0) o I prgmr + 0x00116bc3, // n0x08b7 c0x0000 (---------------) + qa2 + 0x0017bf42, // n0x08b8 c0x0000 (---------------) + qc + 0x00127bc8, // n0x08b9 c0x0000 (---------------) + rackmaze + 0x000f4447, // n0x08ba c0x0000 (---------------) + rhcloud + 0x000020c2, // n0x08bb c0x0000 (---------------) + ro + 0x0000fe82, // n0x08bc c0x0000 (---------------) + ru + 0x00001002, // n0x08bd c0x0000 (---------------) + sa + 0x00187d50, // n0x08be c0x0000 (---------------) + saves-the-whales + 0x00004ec2, // n0x08bf c0x0000 (---------------) + se + 0x0005abc6, // n0x08c0 c0x0000 (---------------) + selfip + 0x0004d00e, // n0x08c1 c0x0000 (---------------) + sells-for-less + 0x0008e5cb, // n0x08c2 c0x0000 (---------------) + sells-for-u + 0x000ccd88, // n0x08c3 c0x0000 (---------------) + servebbs + 0x000ca1ca, // n0x08c4 c0x0000 (---------------) + simple-url + 0x000f6a87, // n0x08c5 c0x0000 (---------------) + sinaapp + 0x0000aa8d, // n0x08c6 c0x0000 (---------------) + space-to-rent + 0x00152a4c, // n0x08c7 c0x0000 (---------------) + teaches-yoga + 0x00001b02, // n0x08c8 c0x0000 (---------------) + uk + 0x00002242, // n0x08c9 c0x0000 (---------------) + us + 0x000041c2, // n0x08ca c0x0000 (---------------) + uy + 0x000f69ca, // n0x08cb c0x0000 (---------------) + vipsinaapp + 0x000def4a, // n0x08cc c0x0000 (---------------) + withgoogle + 0x000e548b, // n0x08cd c0x0000 (---------------) + withyoutube + 0x000fde8e, // n0x08ce c0x0000 (---------------) + writesthisblog + 0x000d80c8, // n0x08cf c0x0000 (---------------) + yolasite + 0x00000182, // n0x08d0 c0x0000 (---------------) + za + 0x108358c7, // n0x08d1 c0x0042 (n0x08e3-n0x08ec) + compute + 0x10c358c9, // n0x08d2 c0x0043 (n0x08ec-n0x08ee) + compute-1 + 0x000123c3, // n0x08d3 c0x0000 (---------------) + elb + 0x1122bb0c, // n0x08d4 c0x0044 (n0x08ee-n0x08ef) o I eu-central-1 + 0x0002ba42, // n0x08d5 c0x0000 (---------------) + s3 + 0x0006cd11, // n0x08d6 c0x0000 (---------------) + s3-ap-northeast-1 + 0x0006bd91, // n0x08d7 c0x0000 (---------------) + s3-ap-southeast-1 + 0x000f5791, // n0x08d8 c0x0000 (---------------) + s3-ap-southeast-2 + 0x0002ba4f, // n0x08d9 c0x0000 (---------------) + s3-eu-central-1 + 0x00055f4c, // n0x08da c0x0000 (---------------) + s3-eu-west-1 + 0x000dd0cd, // n0x08db c0x0000 (---------------) + s3-external-1 + 0x0011358d, // n0x08dc c0x0000 (---------------) + s3-external-2 + 0x00121cd5, // n0x08dd c0x0000 (---------------) + s3-fips-us-gov-west-1 + 0x00123d0c, // n0x08de c0x0000 (---------------) + s3-sa-east-1 + 0x0016c590, // n0x08df c0x0000 (---------------) + s3-us-gov-west-1 + 0x000e3acc, // n0x08e0 c0x0000 (---------------) + s3-us-west-1 + 0x000c330c, // n0x08e1 c0x0000 (---------------) + s3-us-west-2 + 0x0003ef09, // n0x08e2 c0x0000 (---------------) + us-east-1 + 0x0006cdce, // n0x08e3 c0x0000 (---------------) + ap-northeast-1 + 0x0006be4e, // n0x08e4 c0x0000 (---------------) + ap-southeast-1 + 0x000f584e, // n0x08e5 c0x0000 (---------------) + ap-southeast-2 + 0x0002bb0c, // n0x08e6 c0x0000 (---------------) + eu-central-1 + 0x00056009, // n0x08e7 c0x0000 (---------------) + eu-west-1 + 0x00123dc9, // n0x08e8 c0x0000 (---------------) + sa-east-1 + 0x00121ecd, // n0x08e9 c0x0000 (---------------) + us-gov-west-1 + 0x000e3b89, // n0x08ea c0x0000 (---------------) + us-west-1 + 0x000c33c9, // n0x08eb c0x0000 (---------------) + us-west-2 + 0x00155a83, // n0x08ec c0x0000 (---------------) + z-1 + 0x0013e483, // n0x08ed c0x0000 (---------------) + z-2 + 0x0002ba42, // n0x08ee c0x0000 (---------------) + s3 + 0x000196c3, // n0x08ef c0x0000 (---------------) + xen + 0x00200342, // n0x08f0 c0x0000 (---------------) + I ac + 0x0020ce42, // n0x08f1 c0x0000 (---------------) + I co + 0x002024c2, // n0x08f2 c0x0000 (---------------) + I ed + 0x00201702, // n0x08f3 c0x0000 (---------------) + I fi + 0x00210a42, // n0x08f4 c0x0000 (---------------) + I go + 0x00200dc2, // n0x08f5 c0x0000 (---------------) + I or + 0x00201002, // n0x08f6 c0x0000 (---------------) + I sa + 0x00233243, // n0x08f7 c0x0000 (---------------) + I com + 0x00239103, // n0x08f8 c0x0000 (---------------) + I edu + 0x0027d903, // n0x08f9 c0x0000 (---------------) + I gov + 0x00201683, // n0x08fa c0x0000 (---------------) + I inf + 0x00223b43, // n0x08fb c0x0000 (---------------) + I net + 0x00228743, // n0x08fc c0x0000 (---------------) + I org + 0x000fe108, // n0x08fd c0x0000 (---------------) + blogspot + 0x00233243, // n0x08fe c0x0000 (---------------) + I com + 0x00239103, // n0x08ff c0x0000 (---------------) + I edu + 0x00223b43, // n0x0900 c0x0000 (---------------) + I net + 0x00228743, // n0x0901 c0x0000 (---------------) + I org + 0x0003cfc3, // n0x0902 c0x0000 (---------------) + ath + 0x0027d903, // n0x0903 c0x0000 (---------------) + I gov + 0x00200342, // n0x0904 c0x0000 (---------------) + I ac + 0x00331a83, // n0x0905 c0x0000 (---------------) + I biz + 0x13233243, // n0x0906 c0x004c (n0x0911-n0x0912) + I com + 0x00279fc7, // n0x0907 c0x0000 (---------------) + I ekloges + 0x0027d903, // n0x0908 c0x0000 (---------------) + I gov + 0x00312883, // n0x0909 c0x0000 (---------------) + I ltd + 0x00200904, // n0x090a c0x0000 (---------------) + I name + 0x00223b43, // n0x090b c0x0000 (---------------) + I net + 0x00228743, // n0x090c c0x0000 (---------------) + I org + 0x0028458a, // n0x090d c0x0000 (---------------) + I parliament + 0x00246a05, // n0x090e c0x0000 (---------------) + I press + 0x00224b03, // n0x090f c0x0000 (---------------) + I pro + 0x00200c82, // n0x0910 c0x0000 (---------------) + I tm + 0x000fe108, // n0x0911 c0x0000 (---------------) + blogspot + 0x000fe108, // n0x0912 c0x0000 (---------------) + blogspot + 0x0000ce42, // n0x0913 c0x0000 (---------------) + co + 0x000fe108, // n0x0914 c0x0000 (---------------) + blogspot + 0x00033243, // n0x0915 c0x0000 (---------------) + com + 0x000fce0f, // n0x0916 c0x0000 (---------------) + fuettertdasnetz + 0x0016a90a, // n0x0917 c0x0000 (---------------) + isteingeek + 0x000a5147, // n0x0918 c0x0000 (---------------) + istmein + 0x000239ca, // n0x0919 c0x0000 (---------------) + lebtimnetz + 0x00097c0a, // n0x091a c0x0000 (---------------) + leitungsen + 0x000052cd, // n0x091b c0x0000 (---------------) + traeumtgerade + 0x000fe108, // n0x091c c0x0000 (---------------) + blogspot + 0x00233243, // n0x091d c0x0000 (---------------) + I com + 0x00239103, // n0x091e c0x0000 (---------------) + I edu + 0x0027d903, // n0x091f c0x0000 (---------------) + I gov + 0x00223b43, // n0x0920 c0x0000 (---------------) + I net + 0x00228743, // n0x0921 c0x0000 (---------------) + I org + 0x00201d43, // n0x0922 c0x0000 (---------------) + I art + 0x00233243, // n0x0923 c0x0000 (---------------) + I com + 0x00239103, // n0x0924 c0x0000 (---------------) + I edu + 0x00212b03, // n0x0925 c0x0000 (---------------) + I gob + 0x0027d903, // n0x0926 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x0927 c0x0000 (---------------) + I mil + 0x00223b43, // n0x0928 c0x0000 (---------------) + I net + 0x00228743, // n0x0929 c0x0000 (---------------) + I org + 0x002933c3, // n0x092a c0x0000 (---------------) + I sld + 0x0021e243, // n0x092b c0x0000 (---------------) + I web + 0x00201d43, // n0x092c c0x0000 (---------------) + I art + 0x002d5e84, // n0x092d c0x0000 (---------------) + I asso + 0x00233243, // n0x092e c0x0000 (---------------) + I com + 0x00239103, // n0x092f c0x0000 (---------------) + I edu + 0x0027d903, // n0x0930 c0x0000 (---------------) + I gov + 0x00223b43, // n0x0931 c0x0000 (---------------) + I net + 0x00228743, // n0x0932 c0x0000 (---------------) + I org + 0x00206ec3, // n0x0933 c0x0000 (---------------) + I pol + 0x00233243, // n0x0934 c0x0000 (---------------) + I com + 0x00239103, // n0x0935 c0x0000 (---------------) + I edu + 0x00201703, // n0x0936 c0x0000 (---------------) + I fin + 0x00212b03, // n0x0937 c0x0000 (---------------) + I gob + 0x0027d903, // n0x0938 c0x0000 (---------------) + I gov + 0x00201844, // n0x0939 c0x0000 (---------------) + I info + 0x00332603, // n0x093a c0x0000 (---------------) + I k12 + 0x00213443, // n0x093b c0x0000 (---------------) + I med + 0x00207dc3, // n0x093c c0x0000 (---------------) + I mil + 0x00223b43, // n0x093d c0x0000 (---------------) + I net + 0x00228743, // n0x093e c0x0000 (---------------) + I org + 0x00224b03, // n0x093f c0x0000 (---------------) + I pro + 0x00200503, // n0x0940 c0x0000 (---------------) + I aip + 0x15633243, // n0x0941 c0x0055 (n0x094a-n0x094b) + I com + 0x00239103, // n0x0942 c0x0000 (---------------) + I edu + 0x002b49c3, // n0x0943 c0x0000 (---------------) + I fie + 0x0027d903, // n0x0944 c0x0000 (---------------) + I gov + 0x00272043, // n0x0945 c0x0000 (---------------) + I lib + 0x00213443, // n0x0946 c0x0000 (---------------) + I med + 0x00228743, // n0x0947 c0x0000 (---------------) + I org + 0x00204e03, // n0x0948 c0x0000 (---------------) + I pri + 0x0030a104, // n0x0949 c0x0000 (---------------) + I riik + 0x000fe108, // n0x094a c0x0000 (---------------) + blogspot + 0x15e33243, // n0x094b c0x0057 (n0x0954-n0x0955) + I com + 0x00239103, // n0x094c c0x0000 (---------------) + I edu + 0x002a8203, // n0x094d c0x0000 (---------------) + I eun + 0x0027d903, // n0x094e c0x0000 (---------------) + I gov + 0x00207dc3, // n0x094f c0x0000 (---------------) + I mil + 0x00200904, // n0x0950 c0x0000 (---------------) + I name + 0x00223b43, // n0x0951 c0x0000 (---------------) + I net + 0x00228743, // n0x0952 c0x0000 (---------------) + I org + 0x00221983, // n0x0953 c0x0000 (---------------) + I sci + 0x000fe108, // n0x0954 c0x0000 (---------------) + blogspot + 0x16633243, // n0x0955 c0x0059 (n0x095a-n0x095b) + I com + 0x00239103, // n0x0956 c0x0000 (---------------) + I edu + 0x00212b03, // n0x0957 c0x0000 (---------------) + I gob + 0x00201383, // n0x0958 c0x0000 (---------------) + I nom + 0x00228743, // n0x0959 c0x0000 (---------------) + I org + 0x000fe108, // n0x095a c0x0000 (---------------) + blogspot + 0x00331a83, // n0x095b c0x0000 (---------------) + I biz + 0x00233243, // n0x095c c0x0000 (---------------) + I com + 0x00239103, // n0x095d c0x0000 (---------------) + I edu + 0x0027d903, // n0x095e c0x0000 (---------------) + I gov + 0x00201844, // n0x095f c0x0000 (---------------) + I info + 0x00200904, // n0x0960 c0x0000 (---------------) + I name + 0x00223b43, // n0x0961 c0x0000 (---------------) + I net + 0x00228743, // n0x0962 c0x0000 (---------------) + I org + 0x00321085, // n0x0963 c0x0000 (---------------) + I aland + 0x000fe108, // n0x0964 c0x0000 (---------------) + blogspot + 0x0003a783, // n0x0965 c0x0000 (---------------) + iki + 0x003274c8, // n0x0966 c0x0000 (---------------) + I aeroport + 0x0034f007, // n0x0967 c0x0000 (---------------) + I assedic + 0x002d5e84, // n0x0968 c0x0000 (---------------) + I asso + 0x00353c06, // n0x0969 c0x0000 (---------------) + I avocat + 0x0036c446, // n0x096a c0x0000 (---------------) + I avoues + 0x000fe108, // n0x096b c0x0000 (---------------) + blogspot + 0x00234f03, // n0x096c c0x0000 (---------------) + I cci + 0x00208909, // n0x096d c0x0000 (---------------) + I chambagri + 0x002b3c95, // n0x096e c0x0000 (---------------) + I chirurgiens-dentistes + 0x00233243, // n0x096f c0x0000 (---------------) + I com + 0x0031f2d2, // n0x0970 c0x0000 (---------------) + I experts-comptables + 0x0031f08f, // n0x0971 c0x0000 (---------------) + I geometre-expert + 0x002aebc4, // n0x0972 c0x0000 (---------------) + I gouv + 0x0021a045, // n0x0973 c0x0000 (---------------) + I greta + 0x002eec50, // n0x0974 c0x0000 (---------------) + I huissier-justice + 0x00378d47, // n0x0975 c0x0000 (---------------) + I medecin + 0x00201383, // n0x0976 c0x0000 (---------------) + I nom + 0x0035f0c8, // n0x0977 c0x0000 (---------------) + I notaires + 0x0034af0a, // n0x0978 c0x0000 (---------------) + I pharmacien + 0x00245144, // n0x0979 c0x0000 (---------------) + I port + 0x002e0bc3, // n0x097a c0x0000 (---------------) + I prd + 0x00246a06, // n0x097b c0x0000 (---------------) + I presse + 0x00200c82, // n0x097c c0x0000 (---------------) + I tm + 0x002d32cb, // n0x097d c0x0000 (---------------) + I veterinaire + 0x00233243, // n0x097e c0x0000 (---------------) + I com + 0x00239103, // n0x097f c0x0000 (---------------) + I edu + 0x0027d903, // n0x0980 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x0981 c0x0000 (---------------) + I mil + 0x00223b43, // n0x0982 c0x0000 (---------------) + I net + 0x00228743, // n0x0983 c0x0000 (---------------) + I org + 0x002e62c3, // n0x0984 c0x0000 (---------------) + I pvt + 0x0020ce42, // n0x0985 c0x0000 (---------------) + I co + 0x00223b43, // n0x0986 c0x0000 (---------------) + I net + 0x00228743, // n0x0987 c0x0000 (---------------) + I org + 0x00233243, // n0x0988 c0x0000 (---------------) + I com + 0x00239103, // n0x0989 c0x0000 (---------------) + I edu + 0x0027d903, // n0x098a c0x0000 (---------------) + I gov + 0x00207dc3, // n0x098b c0x0000 (---------------) + I mil + 0x00228743, // n0x098c c0x0000 (---------------) + I org + 0x00233243, // n0x098d c0x0000 (---------------) + I com + 0x00239103, // n0x098e c0x0000 (---------------) + I edu + 0x0027d903, // n0x098f c0x0000 (---------------) + I gov + 0x00312883, // n0x0990 c0x0000 (---------------) + I ltd + 0x002177c3, // n0x0991 c0x0000 (---------------) + I mod + 0x00228743, // n0x0992 c0x0000 (---------------) + I org + 0x0020ce42, // n0x0993 c0x0000 (---------------) + I co + 0x00233243, // n0x0994 c0x0000 (---------------) + I com + 0x00239103, // n0x0995 c0x0000 (---------------) + I edu + 0x00223b43, // n0x0996 c0x0000 (---------------) + I net + 0x00228743, // n0x0997 c0x0000 (---------------) + I org + 0x00200342, // n0x0998 c0x0000 (---------------) + I ac + 0x00233243, // n0x0999 c0x0000 (---------------) + I com + 0x00239103, // n0x099a c0x0000 (---------------) + I edu + 0x0027d903, // n0x099b c0x0000 (---------------) + I gov + 0x00223b43, // n0x099c c0x0000 (---------------) + I net + 0x00228743, // n0x099d c0x0000 (---------------) + I org + 0x002d5e84, // n0x099e c0x0000 (---------------) + I asso + 0x00233243, // n0x099f c0x0000 (---------------) + I com + 0x00239103, // n0x09a0 c0x0000 (---------------) + I edu + 0x0020bf04, // n0x09a1 c0x0000 (---------------) + I mobi + 0x00223b43, // n0x09a2 c0x0000 (---------------) + I net + 0x00228743, // n0x09a3 c0x0000 (---------------) + I org + 0x000fe108, // n0x09a4 c0x0000 (---------------) + blogspot + 0x00233243, // n0x09a5 c0x0000 (---------------) + I com + 0x00239103, // n0x09a6 c0x0000 (---------------) + I edu + 0x0027d903, // n0x09a7 c0x0000 (---------------) + I gov + 0x00223b43, // n0x09a8 c0x0000 (---------------) + I net + 0x00228743, // n0x09a9 c0x0000 (---------------) + I org + 0x00233243, // n0x09aa c0x0000 (---------------) + I com + 0x00239103, // n0x09ab c0x0000 (---------------) + I edu + 0x00212b03, // n0x09ac c0x0000 (---------------) + I gob + 0x00221b03, // n0x09ad c0x0000 (---------------) + I ind + 0x00207dc3, // n0x09ae c0x0000 (---------------) + I mil + 0x00223b43, // n0x09af c0x0000 (---------------) + I net + 0x00228743, // n0x09b0 c0x0000 (---------------) + I org + 0x0020ce42, // n0x09b1 c0x0000 (---------------) + I co + 0x00233243, // n0x09b2 c0x0000 (---------------) + I com + 0x00239103, // n0x09b3 c0x0000 (---------------) + I edu + 0x0027d903, // n0x09b4 c0x0000 (---------------) + I gov + 0x00223b43, // n0x09b5 c0x0000 (---------------) + I net + 0x00228743, // n0x09b6 c0x0000 (---------------) + I org + 0x000fe108, // n0x09b7 c0x0000 (---------------) + blogspot + 0x00233243, // n0x09b8 c0x0000 (---------------) + I com + 0x00239103, // n0x09b9 c0x0000 (---------------) + I edu + 0x0027d903, // n0x09ba c0x0000 (---------------) + I gov + 0x0020de03, // n0x09bb c0x0000 (---------------) + I idv + 0x0002fd03, // n0x09bc c0x0000 (---------------) + inc + 0x00112883, // n0x09bd c0x0000 (---------------) + ltd + 0x00223b43, // n0x09be c0x0000 (---------------) + I net + 0x00228743, // n0x09bf c0x0000 (---------------) + I org + 0x0030394a, // n0x09c0 c0x0000 (---------------) + I xn--55qx5d + 0x0031cf89, // n0x09c1 c0x0000 (---------------) + I xn--ciqpn + 0x0033a84b, // n0x09c2 c0x0000 (---------------) + I xn--gmq050i + 0x0033b18a, // n0x09c3 c0x0000 (---------------) + I xn--gmqw5a + 0x0034278a, // n0x09c4 c0x0000 (---------------) + I xn--io0a7i + 0x00350d0b, // n0x09c5 c0x0000 (---------------) + I xn--lcvr32d + 0x0036718a, // n0x09c6 c0x0000 (---------------) + I xn--mk0axi + 0x0036eb8a, // n0x09c7 c0x0000 (---------------) + I xn--mxtq1m + 0x0037530a, // n0x09c8 c0x0000 (---------------) + I xn--od0alg + 0x0037558b, // n0x09c9 c0x0000 (---------------) + I xn--od0aq3b + 0x00391bc9, // n0x09ca c0x0000 (---------------) + I xn--tn0ag + 0x0039378a, // n0x09cb c0x0000 (---------------) + I xn--uc0atv + 0x00393ccb, // n0x09cc c0x0000 (---------------) + I xn--uc0ay4a + 0x0039e40b, // n0x09cd c0x0000 (---------------) + I xn--wcvs22d + 0x003a478a, // n0x09ce c0x0000 (---------------) + I xn--zf0avx + 0x00233243, // n0x09cf c0x0000 (---------------) + I com + 0x00239103, // n0x09d0 c0x0000 (---------------) + I edu + 0x00212b03, // n0x09d1 c0x0000 (---------------) + I gob + 0x00207dc3, // n0x09d2 c0x0000 (---------------) + I mil + 0x00223b43, // n0x09d3 c0x0000 (---------------) + I net + 0x00228743, // n0x09d4 c0x0000 (---------------) + I org + 0x000fe108, // n0x09d5 c0x0000 (---------------) + blogspot + 0x00233243, // n0x09d6 c0x0000 (---------------) + I com + 0x00262384, // n0x09d7 c0x0000 (---------------) + I from + 0x00214502, // n0x09d8 c0x0000 (---------------) + I iz + 0x00200904, // n0x09d9 c0x0000 (---------------) + I name + 0x002a3105, // n0x09da c0x0000 (---------------) + I adult + 0x00201d43, // n0x09db c0x0000 (---------------) + I art + 0x002d5e84, // n0x09dc c0x0000 (---------------) + I asso + 0x00233243, // n0x09dd c0x0000 (---------------) + I com + 0x0023c344, // n0x09de c0x0000 (---------------) + I coop + 0x00239103, // n0x09df c0x0000 (---------------) + I edu + 0x0024dcc4, // n0x09e0 c0x0000 (---------------) + I firm + 0x002aebc4, // n0x09e1 c0x0000 (---------------) + I gouv + 0x00201844, // n0x09e2 c0x0000 (---------------) + I info + 0x00213443, // n0x09e3 c0x0000 (---------------) + I med + 0x00223b43, // n0x09e4 c0x0000 (---------------) + I net + 0x00228743, // n0x09e5 c0x0000 (---------------) + I org + 0x00299705, // n0x09e6 c0x0000 (---------------) + I perso + 0x00206ec3, // n0x09e7 c0x0000 (---------------) + I pol + 0x00224b03, // n0x09e8 c0x0000 (---------------) + I pro + 0x00286903, // n0x09e9 c0x0000 (---------------) + I rel + 0x00357184, // n0x09ea c0x0000 (---------------) + I shop + 0x00329cc4, // n0x09eb c0x0000 (---------------) + I 2000 + 0x00251805, // n0x09ec c0x0000 (---------------) + I agrar + 0x000fe108, // n0x09ed c0x0000 (---------------) + blogspot + 0x002f8204, // n0x09ee c0x0000 (---------------) + I bolt + 0x00356846, // n0x09ef c0x0000 (---------------) + I casino + 0x00285804, // n0x09f0 c0x0000 (---------------) + I city + 0x0020ce42, // n0x09f1 c0x0000 (---------------) + I co + 0x00336ac7, // n0x09f2 c0x0000 (---------------) + I erotica + 0x002505c7, // n0x09f3 c0x0000 (---------------) + I erotika + 0x0024b184, // n0x09f4 c0x0000 (---------------) + I film + 0x0025aec5, // n0x09f5 c0x0000 (---------------) + I forum + 0x00345d85, // n0x09f6 c0x0000 (---------------) + I games + 0x00234305, // n0x09f7 c0x0000 (---------------) + I hotel + 0x00201844, // n0x09f8 c0x0000 (---------------) + I info + 0x00227c88, // n0x09f9 c0x0000 (---------------) + I ingatlan + 0x00294b06, // n0x09fa c0x0000 (---------------) + I jogasz + 0x002d20c8, // n0x09fb c0x0000 (---------------) + I konyvelo + 0x0023bb85, // n0x09fc c0x0000 (---------------) + I lakas + 0x00303545, // n0x09fd c0x0000 (---------------) + I media + 0x0021e604, // n0x09fe c0x0000 (---------------) + I news + 0x00228743, // n0x09ff c0x0000 (---------------) + I org + 0x002e17c4, // n0x0a00 c0x0000 (---------------) + I priv + 0x0034fec6, // n0x0a01 c0x0000 (---------------) + I reklam + 0x00246b03, // n0x0a02 c0x0000 (---------------) + I sex + 0x00357184, // n0x0a03 c0x0000 (---------------) + I shop + 0x0029c605, // n0x0a04 c0x0000 (---------------) + I sport + 0x0023a984, // n0x0a05 c0x0000 (---------------) + I suli + 0x0020a8c4, // n0x0a06 c0x0000 (---------------) + I szex + 0x00200c82, // n0x0a07 c0x0000 (---------------) + I tm + 0x00274bc6, // n0x0a08 c0x0000 (---------------) + I tozsde + 0x00387586, // n0x0a09 c0x0000 (---------------) + I utazas + 0x002f1145, // n0x0a0a c0x0000 (---------------) + I video + 0x00200342, // n0x0a0b c0x0000 (---------------) + I ac + 0x00331a83, // n0x0a0c c0x0000 (---------------) + I biz + 0x1b60ce42, // n0x0a0d c0x006d (n0x0a16-n0x0a17) + I co + 0x0023a484, // n0x0a0e c0x0000 (---------------) + I desa + 0x00210a42, // n0x0a0f c0x0000 (---------------) + I go + 0x00207dc3, // n0x0a10 c0x0000 (---------------) + I mil + 0x00225742, // n0x0a11 c0x0000 (---------------) + I my + 0x00223b43, // n0x0a12 c0x0000 (---------------) + I net + 0x00200dc2, // n0x0a13 c0x0000 (---------------) + I or + 0x00217283, // n0x0a14 c0x0000 (---------------) + I sch + 0x0021e243, // n0x0a15 c0x0000 (---------------) + I web + 0x000fe108, // n0x0a16 c0x0000 (---------------) + blogspot + 0x000fe108, // n0x0a17 c0x0000 (---------------) + blogspot + 0x0027d903, // n0x0a18 c0x0000 (---------------) + I gov + 0x00200342, // n0x0a19 c0x0000 (---------------) + I ac + 0x1c20ce42, // n0x0a1a c0x0070 (n0x0a21-n0x0a22) + I co + 0x0027d903, // n0x0a1b c0x0000 (---------------) + I gov + 0x002677c3, // n0x0a1c c0x0000 (---------------) + I idf + 0x00332603, // n0x0a1d c0x0000 (---------------) + I k12 + 0x0022d004, // n0x0a1e c0x0000 (---------------) + I muni + 0x00223b43, // n0x0a1f c0x0000 (---------------) + I net + 0x00228743, // n0x0a20 c0x0000 (---------------) + I org + 0x000fe108, // n0x0a21 c0x0000 (---------------) + blogspot + 0x00200342, // n0x0a22 c0x0000 (---------------) + I ac + 0x1ca0ce42, // n0x0a23 c0x0072 (n0x0a29-n0x0a2b) + I co + 0x00233243, // n0x0a24 c0x0000 (---------------) + I com + 0x00223b43, // n0x0a25 c0x0000 (---------------) + I net + 0x00228743, // n0x0a26 c0x0000 (---------------) + I org + 0x0020fac2, // n0x0a27 c0x0000 (---------------) + I tt + 0x002203c2, // n0x0a28 c0x0000 (---------------) + I tv + 0x00312883, // n0x0a29 c0x0000 (---------------) + I ltd + 0x002d96c3, // n0x0a2a c0x0000 (---------------) + I plc + 0x00200342, // n0x0a2b c0x0000 (---------------) + I ac + 0x000fe108, // n0x0a2c c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x0a2d c0x0000 (---------------) + I co + 0x00239103, // n0x0a2e c0x0000 (---------------) + I edu + 0x0024dcc4, // n0x0a2f c0x0000 (---------------) + I firm + 0x002060c3, // n0x0a30 c0x0000 (---------------) + I gen + 0x0027d903, // n0x0a31 c0x0000 (---------------) + I gov + 0x00221b03, // n0x0a32 c0x0000 (---------------) + I ind + 0x00207dc3, // n0x0a33 c0x0000 (---------------) + I mil + 0x00223b43, // n0x0a34 c0x0000 (---------------) + I net + 0x0021b843, // n0x0a35 c0x0000 (---------------) + I nic + 0x00228743, // n0x0a36 c0x0000 (---------------) + I org + 0x00221903, // n0x0a37 c0x0000 (---------------) + I res + 0x0011ec53, // n0x0a38 c0x0000 (---------------) + barrel-of-knowledge + 0x00122f54, // n0x0a39 c0x0000 (---------------) + barrell-of-knowledge + 0x00013206, // n0x0a3a c0x0000 (---------------) + dyndns + 0x00056d07, // n0x0a3b c0x0000 (---------------) + for-our + 0x00152f89, // n0x0a3c c0x0000 (---------------) + groks-the + 0x000f4c0a, // n0x0a3d c0x0000 (---------------) + groks-this + 0x0008a30d, // n0x0a3e c0x0000 (---------------) + here-for-more + 0x0003dd0a, // n0x0a3f c0x0000 (---------------) + knowsitall + 0x0005abc6, // n0x0a40 c0x0000 (---------------) + selfip + 0x001267c6, // n0x0a41 c0x0000 (---------------) + webhop + 0x00205382, // n0x0a42 c0x0000 (---------------) + I eu + 0x00233243, // n0x0a43 c0x0000 (---------------) + I com + 0x000cbb86, // n0x0a44 c0x0000 (---------------) + github + 0x00152f45, // n0x0a45 c0x0000 (---------------) + ngrok + 0x0000ddc3, // n0x0a46 c0x0000 (---------------) + nid + 0x00010b08, // n0x0a47 c0x0000 (---------------) + pantheon + 0x000b1c48, // n0x0a48 c0x0000 (---------------) + sandcats + 0x00233243, // n0x0a49 c0x0000 (---------------) + I com + 0x00239103, // n0x0a4a c0x0000 (---------------) + I edu + 0x0027d903, // n0x0a4b c0x0000 (---------------) + I gov + 0x00207dc3, // n0x0a4c c0x0000 (---------------) + I mil + 0x00223b43, // n0x0a4d c0x0000 (---------------) + I net + 0x00228743, // n0x0a4e c0x0000 (---------------) + I org + 0x00200342, // n0x0a4f c0x0000 (---------------) + I ac + 0x0020ce42, // n0x0a50 c0x0000 (---------------) + I co + 0x0027d903, // n0x0a51 c0x0000 (---------------) + I gov + 0x0020d9c2, // n0x0a52 c0x0000 (---------------) + I id + 0x00223b43, // n0x0a53 c0x0000 (---------------) + I net + 0x00228743, // n0x0a54 c0x0000 (---------------) + I org + 0x00217283, // n0x0a55 c0x0000 (---------------) + I sch + 0x0035cf4f, // n0x0a56 c0x0000 (---------------) + I xn--mgba3a4f16a + 0x0035d30e, // n0x0a57 c0x0000 (---------------) + I xn--mgba3a4fra + 0x000fe108, // n0x0a58 c0x0000 (---------------) + blogspot + 0x00233243, // n0x0a59 c0x0000 (---------------) + I com + 0x00047607, // n0x0a5a c0x0000 (---------------) + cupcake + 0x00239103, // n0x0a5b c0x0000 (---------------) + I edu + 0x0027d903, // n0x0a5c c0x0000 (---------------) + I gov + 0x00201503, // n0x0a5d c0x0000 (---------------) + I int + 0x00223b43, // n0x0a5e c0x0000 (---------------) + I net + 0x00228743, // n0x0a5f c0x0000 (---------------) + I org + 0x00221883, // n0x0a60 c0x0000 (---------------) + I abr + 0x00328e47, // n0x0a61 c0x0000 (---------------) + I abruzzo + 0x00201b82, // n0x0a62 c0x0000 (---------------) + I ag + 0x003018c9, // n0x0a63 c0x0000 (---------------) + I agrigento + 0x00200d02, // n0x0a64 c0x0000 (---------------) + I al + 0x0038804b, // n0x0a65 c0x0000 (---------------) + I alessandria + 0x002e414a, // n0x0a66 c0x0000 (---------------) + I alto-adige + 0x002d2549, // n0x0a67 c0x0000 (---------------) + I altoadige + 0x002008c2, // n0x0a68 c0x0000 (---------------) + I an + 0x0034ea86, // n0x0a69 c0x0000 (---------------) + I ancona + 0x00291e55, // n0x0a6a c0x0000 (---------------) + I andria-barletta-trani + 0x00388195, // n0x0a6b c0x0000 (---------------) + I andria-trani-barletta + 0x00293953, // n0x0a6c c0x0000 (---------------) + I andriabarlettatrani + 0x00388713, // n0x0a6d c0x0000 (---------------) + I andriatranibarletta + 0x00202882, // n0x0a6e c0x0000 (---------------) + I ao + 0x00216b45, // n0x0a6f c0x0000 (---------------) + I aosta + 0x0025570c, // n0x0a70 c0x0000 (---------------) + I aosta-valley + 0x00216b4b, // n0x0a71 c0x0000 (---------------) + I aostavalley + 0x0024af85, // n0x0a72 c0x0000 (---------------) + I aoste + 0x00208082, // n0x0a73 c0x0000 (---------------) + I ap + 0x00200f02, // n0x0a74 c0x0000 (---------------) + I aq + 0x0036b5c6, // n0x0a75 c0x0000 (---------------) + I aquila + 0x00201d42, // n0x0a76 c0x0000 (---------------) + I ar + 0x0027a206, // n0x0a77 c0x0000 (---------------) + I arezzo + 0x0039728d, // n0x0a78 c0x0000 (---------------) + I ascoli-piceno + 0x00342fcc, // n0x0a79 c0x0000 (---------------) + I ascolipiceno + 0x00222b04, // n0x0a7a c0x0000 (---------------) + I asti + 0x00200482, // n0x0a7b c0x0000 (---------------) + I at + 0x00202f02, // n0x0a7c c0x0000 (---------------) + I av + 0x00220188, // n0x0a7d c0x0000 (---------------) + I avellino + 0x00200882, // n0x0a7e c0x0000 (---------------) + I ba + 0x00247a86, // n0x0a7f c0x0000 (---------------) + I balsan + 0x00248704, // n0x0a80 c0x0000 (---------------) + I bari + 0x00292015, // n0x0a81 c0x0000 (---------------) + I barletta-trani-andria + 0x00293ad3, // n0x0a82 c0x0000 (---------------) + I barlettatraniandria + 0x00206d83, // n0x0a83 c0x0000 (---------------) + I bas + 0x0033030a, // n0x0a84 c0x0000 (---------------) + I basilicata + 0x00286007, // n0x0a85 c0x0000 (---------------) + I belluno + 0x002e56c9, // n0x0a86 c0x0000 (---------------) + I benevento + 0x0022a747, // n0x0a87 c0x0000 (---------------) + I bergamo + 0x00304a82, // n0x0a88 c0x0000 (---------------) + I bg + 0x00200002, // n0x0a89 c0x0000 (---------------) + I bi + 0x003a5706, // n0x0a8a c0x0000 (---------------) + I biella + 0x0020db02, // n0x0a8b c0x0000 (---------------) + I bl + 0x000fe108, // n0x0a8c c0x0000 (---------------) + blogspot + 0x00212142, // n0x0a8d c0x0000 (---------------) + I bn + 0x0020f682, // n0x0a8e c0x0000 (---------------) + I bo + 0x0038d0c7, // n0x0a8f c0x0000 (---------------) + I bologna + 0x00211807, // n0x0a90 c0x0000 (---------------) + I bolzano + 0x0021e845, // n0x0a91 c0x0000 (---------------) + I bozen + 0x0021e3c2, // n0x0a92 c0x0000 (---------------) + I br + 0x002218c7, // n0x0a93 c0x0000 (---------------) + I brescia + 0x00221a88, // n0x0a94 c0x0000 (---------------) + I brindisi + 0x00230fc2, // n0x0a95 c0x0000 (---------------) + I bs + 0x00223a42, // n0x0a96 c0x0000 (---------------) + I bt + 0x00230682, // n0x0a97 c0x0000 (---------------) + I bz + 0x00200e42, // n0x0a98 c0x0000 (---------------) + I ca + 0x0023f288, // n0x0a99 c0x0000 (---------------) + I cagliari + 0x00212ec3, // n0x0a9a c0x0000 (---------------) + I cal + 0x00254cc8, // n0x0a9b c0x0000 (---------------) + I calabria + 0x0023970d, // n0x0a9c c0x0000 (---------------) + I caltanissetta + 0x0021e303, // n0x0a9d c0x0000 (---------------) + I cam + 0x00319488, // n0x0a9e c0x0000 (---------------) + I campania + 0x00241bcf, // n0x0a9f c0x0000 (---------------) + I campidano-medio + 0x00241f8e, // n0x0aa0 c0x0000 (---------------) + I campidanomedio + 0x00336c0a, // n0x0aa1 c0x0000 (---------------) + I campobasso + 0x002f5d11, // n0x0aa2 c0x0000 (---------------) + I carbonia-iglesias + 0x002f6190, // n0x0aa3 c0x0000 (---------------) + I carboniaiglesias + 0x002b584d, // n0x0aa4 c0x0000 (---------------) + I carrara-massa + 0x002b5b8c, // n0x0aa5 c0x0000 (---------------) + I carraramassa + 0x0023d147, // n0x0aa6 c0x0000 (---------------) + I caserta + 0x00330487, // n0x0aa7 c0x0000 (---------------) + I catania + 0x00353cc9, // n0x0aa8 c0x0000 (---------------) + I catanzaro + 0x00222c02, // n0x0aa9 c0x0000 (---------------) + I cb + 0x00204c82, // n0x0aaa c0x0000 (---------------) + I ce + 0x0025874c, // n0x0aab c0x0000 (---------------) + I cesena-forli + 0x00258a4b, // n0x0aac c0x0000 (---------------) + I cesenaforli + 0x00200382, // n0x0aad c0x0000 (---------------) + I ch + 0x002d0206, // n0x0aae c0x0000 (---------------) + I chieti + 0x00209602, // n0x0aaf c0x0000 (---------------) + I ci + 0x00207f42, // n0x0ab0 c0x0000 (---------------) + I cl + 0x0021dac2, // n0x0ab1 c0x0000 (---------------) + I cn + 0x0020ce42, // n0x0ab2 c0x0000 (---------------) + I co + 0x00233d44, // n0x0ab3 c0x0000 (---------------) + I como + 0x00240dc7, // n0x0ab4 c0x0000 (---------------) + I cosenza + 0x002051c2, // n0x0ab5 c0x0000 (---------------) + I cr + 0x00243cc7, // n0x0ab6 c0x0000 (---------------) + I cremona + 0x00244f47, // n0x0ab7 c0x0000 (---------------) + I crotone + 0x00210802, // n0x0ab8 c0x0000 (---------------) + I cs + 0x0022af82, // n0x0ab9 c0x0000 (---------------) + I ct + 0x002474c5, // n0x0aba c0x0000 (---------------) + I cuneo + 0x00200142, // n0x0abb c0x0000 (---------------) + I cz + 0x0025a10e, // n0x0abc c0x0000 (---------------) + I dell-ogliastra + 0x0026548d, // n0x0abd c0x0000 (---------------) + I dellogliastra + 0x00239103, // n0x0abe c0x0000 (---------------) + I edu + 0x003285ce, // n0x0abf c0x0000 (---------------) + I emilia-romagna + 0x0028510d, // n0x0ac0 c0x0000 (---------------) + I emiliaromagna + 0x00361083, // n0x0ac1 c0x0000 (---------------) + I emr + 0x00202a82, // n0x0ac2 c0x0000 (---------------) + I en + 0x00206304, // n0x0ac3 c0x0000 (---------------) + I enna + 0x0024a982, // n0x0ac4 c0x0000 (---------------) + I fc + 0x0020cf02, // n0x0ac5 c0x0000 (---------------) + I fe + 0x002d7ac5, // n0x0ac6 c0x0000 (---------------) + I fermo + 0x002e20c7, // n0x0ac7 c0x0000 (---------------) + I ferrara + 0x00349342, // n0x0ac8 c0x0000 (---------------) + I fg + 0x00201702, // n0x0ac9 c0x0000 (---------------) + I fi + 0x0024d607, // n0x0aca c0x0000 (---------------) + I firenze + 0x00252708, // n0x0acb c0x0000 (---------------) + I florence + 0x00234802, // n0x0acc c0x0000 (---------------) + I fm + 0x002018c6, // n0x0acd c0x0000 (---------------) + I foggia + 0x002585cc, // n0x0ace c0x0000 (---------------) + I forli-cesena + 0x0025890b, // n0x0acf c0x0000 (---------------) + I forlicesena + 0x00240202, // n0x0ad0 c0x0000 (---------------) + I fr + 0x0025e98f, // n0x0ad1 c0x0000 (---------------) + I friuli-v-giulia + 0x0025ed50, // n0x0ad2 c0x0000 (---------------) + I friuli-ve-giulia + 0x0025f14f, // n0x0ad3 c0x0000 (---------------) + I friuli-vegiulia + 0x0025f515, // n0x0ad4 c0x0000 (---------------) + I friuli-venezia-giulia + 0x0025fa54, // n0x0ad5 c0x0000 (---------------) + I friuli-veneziagiulia + 0x0025ff4e, // n0x0ad6 c0x0000 (---------------) + I friuli-vgiulia + 0x002602ce, // n0x0ad7 c0x0000 (---------------) + I friuliv-giulia + 0x0026064f, // n0x0ad8 c0x0000 (---------------) + I friulive-giulia + 0x00260a0e, // n0x0ad9 c0x0000 (---------------) + I friulivegiulia + 0x00260d94, // n0x0ada c0x0000 (---------------) + I friulivenezia-giulia + 0x00261293, // n0x0adb c0x0000 (---------------) + I friuliveneziagiulia + 0x0026174d, // n0x0adc c0x0000 (---------------) + I friulivgiulia + 0x002765c9, // n0x0add c0x0000 (---------------) + I frosinone + 0x0028aec3, // n0x0ade c0x0000 (---------------) + I fvg + 0x00200282, // n0x0adf c0x0000 (---------------) + I ge + 0x003077c5, // n0x0ae0 c0x0000 (---------------) + I genoa + 0x002060c6, // n0x0ae1 c0x0000 (---------------) + I genova + 0x00210a42, // n0x0ae2 c0x0000 (---------------) + I go + 0x002703c7, // n0x0ae3 c0x0000 (---------------) + I gorizia + 0x0027d903, // n0x0ae4 c0x0000 (---------------) + I gov + 0x00208a82, // n0x0ae5 c0x0000 (---------------) + I gr + 0x00288508, // n0x0ae6 c0x0000 (---------------) + I grosseto + 0x002f5f51, // n0x0ae7 c0x0000 (---------------) + I iglesias-carbonia + 0x002f6390, // n0x0ae8 c0x0000 (---------------) + I iglesiascarbonia + 0x00200402, // n0x0ae9 c0x0000 (---------------) + I im + 0x003578c7, // n0x0aea c0x0000 (---------------) + I imperia + 0x00204e82, // n0x0aeb c0x0000 (---------------) + I is + 0x0025d847, // n0x0aec c0x0000 (---------------) + I isernia + 0x0020bdc2, // n0x0aed c0x0000 (---------------) + I kr + 0x0026ad89, // n0x0aee c0x0000 (---------------) + I la-spezia + 0x0036b587, // n0x0aef c0x0000 (---------------) + I laquila + 0x002583c8, // n0x0af0 c0x0000 (---------------) + I laspezia + 0x00226e86, // n0x0af1 c0x0000 (---------------) + I latina + 0x002d95c3, // n0x0af2 c0x0000 (---------------) + I laz + 0x002f49c5, // n0x0af3 c0x0000 (---------------) + I lazio + 0x00239382, // n0x0af4 c0x0000 (---------------) + I lc + 0x0020c8c2, // n0x0af5 c0x0000 (---------------) + I le + 0x003a5b05, // n0x0af6 c0x0000 (---------------) + I lecce + 0x0022f645, // n0x0af7 c0x0000 (---------------) + I lecco + 0x00205bc2, // n0x0af8 c0x0000 (---------------) + I li + 0x0023aa03, // n0x0af9 c0x0000 (---------------) + I lig + 0x0023aa07, // n0x0afa c0x0000 (---------------) + I liguria + 0x002137c7, // n0x0afb c0x0000 (---------------) + I livorno + 0x00200d82, // n0x0afc c0x0000 (---------------) + I lo + 0x00259b44, // n0x0afd c0x0000 (---------------) + I lodi + 0x00214d03, // n0x0afe c0x0000 (---------------) + I lom + 0x002c5f09, // n0x0aff c0x0000 (---------------) + I lombardia + 0x002db788, // n0x0b00 c0x0000 (---------------) + I lombardy + 0x00208bc2, // n0x0b01 c0x0000 (---------------) + I lt + 0x00203842, // n0x0b02 c0x0000 (---------------) + I lu + 0x0026e747, // n0x0b03 c0x0000 (---------------) + I lucania + 0x002da485, // n0x0b04 c0x0000 (---------------) + I lucca + 0x00318f88, // n0x0b05 c0x0000 (---------------) + I macerata + 0x00253e87, // n0x0b06 c0x0000 (---------------) + I mantova + 0x00201d03, // n0x0b07 c0x0000 (---------------) + I mar + 0x002843c6, // n0x0b08 c0x0000 (---------------) + I marche + 0x002b56cd, // n0x0b09 c0x0000 (---------------) + I massa-carrara + 0x002b5a4c, // n0x0b0a c0x0000 (---------------) + I massacarrara + 0x0024be06, // n0x0b0b c0x0000 (---------------) + I matera + 0x00205a82, // n0x0b0c c0x0000 (---------------) + I mb + 0x0021a3c2, // n0x0b0d c0x0000 (---------------) + I mc + 0x00200982, // n0x0b0e c0x0000 (---------------) + I me + 0x00241a4f, // n0x0b0f c0x0000 (---------------) + I medio-campidano + 0x00241e4e, // n0x0b10 c0x0000 (---------------) + I mediocampidano + 0x00345e07, // n0x0b11 c0x0000 (---------------) + I messina + 0x00207dc2, // n0x0b12 c0x0000 (---------------) + I mi + 0x002fb205, // n0x0b13 c0x0000 (---------------) + I milan + 0x002fb206, // n0x0b14 c0x0000 (---------------) + I milano + 0x00223b02, // n0x0b15 c0x0000 (---------------) + I mn + 0x00208442, // n0x0b16 c0x0000 (---------------) + I mo + 0x002177c6, // n0x0b17 c0x0000 (---------------) + I modena + 0x00212d43, // n0x0b18 c0x0000 (---------------) + I mol + 0x0025d786, // n0x0b19 c0x0000 (---------------) + I molise + 0x002c4b05, // n0x0b1a c0x0000 (---------------) + I monza + 0x002c4b0d, // n0x0b1b c0x0000 (---------------) + I monza-brianza + 0x002c5355, // n0x0b1c c0x0000 (---------------) + I monza-e-della-brianza + 0x002c5b0c, // n0x0b1d c0x0000 (---------------) + I monzabrianza + 0x002c63cd, // n0x0b1e c0x0000 (---------------) + I monzaebrianza + 0x002c6792, // n0x0b1f c0x0000 (---------------) + I monzaedellabrianza + 0x00210f42, // n0x0b20 c0x0000 (---------------) + I ms + 0x00205402, // n0x0b21 c0x0000 (---------------) + I mt + 0x00200902, // n0x0b22 c0x0000 (---------------) + I na + 0x0039ba46, // n0x0b23 c0x0000 (---------------) + I naples + 0x002a53c6, // n0x0b24 c0x0000 (---------------) + I napoli + 0x00201382, // n0x0b25 c0x0000 (---------------) + I no + 0x00206146, // n0x0b26 c0x0000 (---------------) + I novara + 0x00204182, // n0x0b27 c0x0000 (---------------) + I nu + 0x0039d545, // n0x0b28 c0x0000 (---------------) + I nuoro + 0x00201902, // n0x0b29 c0x0000 (---------------) + I og + 0x0025a249, // n0x0b2a c0x0000 (---------------) + I ogliastra + 0x0027548c, // n0x0b2b c0x0000 (---------------) + I olbia-tempio + 0x002757cb, // n0x0b2c c0x0000 (---------------) + I olbiatempio + 0x00200dc2, // n0x0b2d c0x0000 (---------------) + I or + 0x00252b48, // n0x0b2e c0x0000 (---------------) + I oristano + 0x00201102, // n0x0b2f c0x0000 (---------------) + I ot + 0x0020aac2, // n0x0b30 c0x0000 (---------------) + I pa + 0x00216906, // n0x0b31 c0x0000 (---------------) + I padova + 0x00361a05, // n0x0b32 c0x0000 (---------------) + I padua + 0x00305ec7, // n0x0b33 c0x0000 (---------------) + I palermo + 0x00394905, // n0x0b34 c0x0000 (---------------) + I parma + 0x002dbe45, // n0x0b35 c0x0000 (---------------) + I pavia + 0x00247682, // n0x0b36 c0x0000 (---------------) + I pc + 0x00357282, // n0x0b37 c0x0000 (---------------) + I pd + 0x00200582, // n0x0b38 c0x0000 (---------------) + I pe + 0x00266707, // n0x0b39 c0x0000 (---------------) + I perugia + 0x0022c3cd, // n0x0b3a c0x0000 (---------------) + I pesaro-urbino + 0x0022c74c, // n0x0b3b c0x0000 (---------------) + I pesarourbino + 0x00237007, // n0x0b3c c0x0000 (---------------) + I pescara + 0x00248ac2, // n0x0b3d c0x0000 (---------------) + I pg + 0x00219f82, // n0x0b3e c0x0000 (---------------) + I pi + 0x00338208, // n0x0b3f c0x0000 (---------------) + I piacenza + 0x00258e08, // n0x0b40 c0x0000 (---------------) + I piedmont + 0x002d68c8, // n0x0b41 c0x0000 (---------------) + I piemonte + 0x002df204, // n0x0b42 c0x0000 (---------------) + I pisa + 0x002d05c7, // n0x0b43 c0x0000 (---------------) + I pistoia + 0x002dd5c3, // n0x0b44 c0x0000 (---------------) + I pmn + 0x002488c2, // n0x0b45 c0x0000 (---------------) + I pn + 0x00206ec2, // n0x0b46 c0x0000 (---------------) + I po + 0x002df8c9, // n0x0b47 c0x0000 (---------------) + I pordenone + 0x00208187, // n0x0b48 c0x0000 (---------------) + I potenza + 0x00204e02, // n0x0b49 c0x0000 (---------------) + I pr + 0x00271845, // n0x0b4a c0x0000 (---------------) + I prato + 0x002d3242, // n0x0b4b c0x0000 (---------------) + I pt + 0x00235982, // n0x0b4c c0x0000 (---------------) + I pu + 0x00278643, // n0x0b4d c0x0000 (---------------) + I pug + 0x00278646, // n0x0b4e c0x0000 (---------------) + I puglia + 0x002e62c2, // n0x0b4f c0x0000 (---------------) + I pv + 0x002e70c2, // n0x0b50 c0x0000 (---------------) + I pz + 0x00202382, // n0x0b51 c0x0000 (---------------) + I ra + 0x0030e106, // n0x0b52 c0x0000 (---------------) + I ragusa + 0x00206247, // n0x0b53 c0x0000 (---------------) + I ravenna + 0x00200e02, // n0x0b54 c0x0000 (---------------) + I rc + 0x00208c82, // n0x0b55 c0x0000 (---------------) + I re + 0x0033d54f, // n0x0b56 c0x0000 (---------------) + I reggio-calabria + 0x0032840d, // n0x0b57 c0x0000 (---------------) + I reggio-emilia + 0x00254b4e, // n0x0b58 c0x0000 (---------------) + I reggiocalabria + 0x00284f8c, // n0x0b59 c0x0000 (---------------) + I reggioemilia + 0x00205b42, // n0x0b5a c0x0000 (---------------) + I rg + 0x00204e42, // n0x0b5b c0x0000 (---------------) + I ri + 0x00226cc5, // n0x0b5c c0x0000 (---------------) + I rieti + 0x00300186, // n0x0b5d c0x0000 (---------------) + I rimini + 0x00225a02, // n0x0b5e c0x0000 (---------------) + I rm + 0x0020dd82, // n0x0b5f c0x0000 (---------------) + I rn + 0x002020c2, // n0x0b60 c0x0000 (---------------) + I ro + 0x0022cb44, // n0x0b61 c0x0000 (---------------) + I roma + 0x002e2f04, // n0x0b62 c0x0000 (---------------) + I rome + 0x00334ec6, // n0x0b63 c0x0000 (---------------) + I rovigo + 0x00201002, // n0x0b64 c0x0000 (---------------) + I sa + 0x00279547, // n0x0b65 c0x0000 (---------------) + I salerno + 0x0021adc3, // n0x0b66 c0x0000 (---------------) + I sar + 0x0021f988, // n0x0b67 c0x0000 (---------------) + I sardegna + 0x002216c8, // n0x0b68 c0x0000 (---------------) + I sardinia + 0x002d9c47, // n0x0b69 c0x0000 (---------------) + I sassari + 0x0039b946, // n0x0b6a c0x0000 (---------------) + I savona + 0x002091c2, // n0x0b6b c0x0000 (---------------) + I si + 0x0023f203, // n0x0b6c c0x0000 (---------------) + I sic + 0x00375147, // n0x0b6d c0x0000 (---------------) + I sicilia + 0x00337206, // n0x0b6e c0x0000 (---------------) + I sicily + 0x0031bf85, // n0x0b6f c0x0000 (---------------) + I siena + 0x00341fc8, // n0x0b70 c0x0000 (---------------) + I siracusa + 0x00205f02, // n0x0b71 c0x0000 (---------------) + I so + 0x0030b1c7, // n0x0b72 c0x0000 (---------------) + I sondrio + 0x00208142, // n0x0b73 c0x0000 (---------------) + I sp + 0x00332d82, // n0x0b74 c0x0000 (---------------) + I sr + 0x0020b702, // n0x0b75 c0x0000 (---------------) + I ss + 0x002d0e49, // n0x0b76 c0x0000 (---------------) + I suedtirol + 0x002365c2, // n0x0b77 c0x0000 (---------------) + I sv + 0x002004c2, // n0x0b78 c0x0000 (---------------) + I ta + 0x00237283, // n0x0b79 c0x0000 (---------------) + I taa + 0x00332207, // n0x0b7a c0x0000 (---------------) + I taranto + 0x00200a82, // n0x0b7b c0x0000 (---------------) + I te + 0x0027560c, // n0x0b7c c0x0000 (---------------) + I tempio-olbia + 0x0027590b, // n0x0b7d c0x0000 (---------------) + I tempioolbia + 0x0024be86, // n0x0b7e c0x0000 (---------------) + I teramo + 0x0020dd05, // n0x0b7f c0x0000 (---------------) + I terni + 0x0024fd82, // n0x0b80 c0x0000 (---------------) + I tn + 0x00206e42, // n0x0b81 c0x0000 (---------------) + I to + 0x002b34c6, // n0x0b82 c0x0000 (---------------) + I torino + 0x002230c3, // n0x0b83 c0x0000 (---------------) + I tos + 0x00324507, // n0x0b84 c0x0000 (---------------) + I toscana + 0x00210ac2, // n0x0b85 c0x0000 (---------------) + I tp + 0x00203902, // n0x0b86 c0x0000 (---------------) + I tr + 0x00291cd5, // n0x0b87 c0x0000 (---------------) + I trani-andria-barletta + 0x00388355, // n0x0b88 c0x0000 (---------------) + I trani-barletta-andria + 0x00293813, // n0x0b89 c0x0000 (---------------) + I traniandriabarletta + 0x00388893, // n0x0b8a c0x0000 (---------------) + I tranibarlettaandria + 0x0029c707, // n0x0b8b c0x0000 (---------------) + I trapani + 0x002bc488, // n0x0b8c c0x0000 (---------------) + I trentino + 0x002e9ad0, // n0x0b8d c0x0000 (---------------) + I trentino-a-adige + 0x0033adcf, // n0x0b8e c0x0000 (---------------) + I trentino-aadige + 0x0034ccd3, // n0x0b8f c0x0000 (---------------) + I trentino-alto-adige + 0x002d2312, // n0x0b90 c0x0000 (---------------) + I trentino-altoadige + 0x00301490, // n0x0b91 c0x0000 (---------------) + I trentino-s-tirol + 0x002bc48f, // n0x0b92 c0x0000 (---------------) + I trentino-stirol + 0x002c4692, // n0x0b93 c0x0000 (---------------) + I trentino-sud-tirol + 0x002cbf91, // n0x0b94 c0x0000 (---------------) + I trentino-sudtirol + 0x002ce653, // n0x0b95 c0x0000 (---------------) + I trentino-sued-tirol + 0x002d0c12, // n0x0b96 c0x0000 (---------------) + I trentino-suedtirol + 0x002d628f, // n0x0b97 c0x0000 (---------------) + I trentinoa-adige + 0x002df54e, // n0x0b98 c0x0000 (---------------) + I trentinoaadige + 0x002e3f52, // n0x0b99 c0x0000 (---------------) + I trentinoalto-adige + 0x002e4791, // n0x0b9a c0x0000 (---------------) + I trentinoaltoadige + 0x002e634f, // n0x0b9b c0x0000 (---------------) + I trentinos-tirol + 0x002e744e, // n0x0b9c c0x0000 (---------------) + I trentinostirol + 0x002ee591, // n0x0b9d c0x0000 (---------------) + I trentinosud-tirol + 0x00334510, // n0x0b9e c0x0000 (---------------) + I trentinosudtirol + 0x002e8f12, // n0x0b9f c0x0000 (---------------) + I trentinosued-tirol + 0x002fa091, // n0x0ba0 c0x0000 (---------------) + I trentinosuedtirol + 0x002f7986, // n0x0ba1 c0x0000 (---------------) + I trento + 0x002f82c7, // n0x0ba2 c0x0000 (---------------) + I treviso + 0x00367507, // n0x0ba3 c0x0000 (---------------) + I trieste + 0x00207a42, // n0x0ba4 c0x0000 (---------------) + I ts + 0x0027ff05, // n0x0ba5 c0x0000 (---------------) + I turin + 0x002ee9c7, // n0x0ba6 c0x0000 (---------------) + I tuscany + 0x002203c2, // n0x0ba7 c0x0000 (---------------) + I tv + 0x00208002, // n0x0ba8 c0x0000 (---------------) + I ud + 0x0022bf85, // n0x0ba9 c0x0000 (---------------) + I udine + 0x00222403, // n0x0baa c0x0000 (---------------) + I umb + 0x00251a86, // n0x0bab c0x0000 (---------------) + I umbria + 0x0022c58d, // n0x0bac c0x0000 (---------------) + I urbino-pesaro + 0x0022c8cc, // n0x0bad c0x0000 (---------------) + I urbinopesaro + 0x00200c02, // n0x0bae c0x0000 (---------------) + I va + 0x0025558b, // n0x0baf c0x0000 (---------------) + I val-d-aosta + 0x00216a0a, // n0x0bb0 c0x0000 (---------------) + I val-daosta + 0x0032264a, // n0x0bb1 c0x0000 (---------------) + I vald-aosta + 0x002b2889, // n0x0bb2 c0x0000 (---------------) + I valdaosta + 0x002de48b, // n0x0bb3 c0x0000 (---------------) + I valle-aosta + 0x002ef0cd, // n0x0bb4 c0x0000 (---------------) + I valle-d-aosta + 0x00253fcc, // n0x0bb5 c0x0000 (---------------) + I valle-daosta + 0x0021af4a, // n0x0bb6 c0x0000 (---------------) + I valleaosta + 0x0022040c, // n0x0bb7 c0x0000 (---------------) + I valled-aosta + 0x0023fbcb, // n0x0bb8 c0x0000 (---------------) + I valledaosta + 0x0024adcc, // n0x0bb9 c0x0000 (---------------) + I vallee-aoste + 0x0024f1cb, // n0x0bba c0x0000 (---------------) + I valleeaoste + 0x00275403, // n0x0bbb c0x0000 (---------------) + I vao + 0x0028bb86, // n0x0bbc c0x0000 (---------------) + I varese + 0x002dc442, // n0x0bbd c0x0000 (---------------) + I vb + 0x002e7802, // n0x0bbe c0x0000 (---------------) + I vc + 0x00211b83, // n0x0bbf c0x0000 (---------------) + I vda + 0x00202a42, // n0x0bc0 c0x0000 (---------------) + I ve + 0x00202a43, // n0x0bc1 c0x0000 (---------------) + I ven + 0x00368646, // n0x0bc2 c0x0000 (---------------) + I veneto + 0x0025f6c7, // n0x0bc3 c0x0000 (---------------) + I venezia + 0x00270846, // n0x0bc4 c0x0000 (---------------) + I venice + 0x0022e7c8, // n0x0bc5 c0x0000 (---------------) + I verbania + 0x002e3748, // n0x0bc6 c0x0000 (---------------) + I vercelli + 0x00360dc6, // n0x0bc7 c0x0000 (---------------) + I verona + 0x002065c2, // n0x0bc8 c0x0000 (---------------) + I vi + 0x002f0b0d, // n0x0bc9 c0x0000 (---------------) + I vibo-valentia + 0x002f0e4c, // n0x0bca c0x0000 (---------------) + I vibovalentia + 0x002aec87, // n0x0bcb c0x0000 (---------------) + I vicenza + 0x002f80c7, // n0x0bcc c0x0000 (---------------) + I viterbo + 0x0020de82, // n0x0bcd c0x0000 (---------------) + I vr + 0x00229a42, // n0x0bce c0x0000 (---------------) + I vs + 0x0026a302, // n0x0bcf c0x0000 (---------------) + I vt + 0x00215382, // n0x0bd0 c0x0000 (---------------) + I vv + 0x0020ce42, // n0x0bd1 c0x0000 (---------------) + I co + 0x00223b43, // n0x0bd2 c0x0000 (---------------) + I net + 0x00228743, // n0x0bd3 c0x0000 (---------------) + I org + 0x00233243, // n0x0bd4 c0x0000 (---------------) + I com + 0x00239103, // n0x0bd5 c0x0000 (---------------) + I edu + 0x0027d903, // n0x0bd6 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x0bd7 c0x0000 (---------------) + I mil + 0x00200904, // n0x0bd8 c0x0000 (---------------) + I name + 0x00223b43, // n0x0bd9 c0x0000 (---------------) + I net + 0x00228743, // n0x0bda c0x0000 (---------------) + I org + 0x00217283, // n0x0bdb c0x0000 (---------------) + I sch + 0x00200342, // n0x0bdc c0x0000 (---------------) + I ac + 0x002001c2, // n0x0bdd c0x0000 (---------------) + I ad + 0x1fa90e05, // n0x0bde c0x007e (n0x0c4b-n0x0c7f) + I aichi + 0x1fe04785, // n0x0bdf c0x007f (n0x0c7f-n0x0c9b) + I akita + 0x2030ddc6, // n0x0be0 c0x0080 (n0x0c9b-n0x0cb1) + I aomori + 0x000fe108, // n0x0be1 c0x0000 (---------------) + blogspot + 0x206afa45, // n0x0be2 c0x0081 (n0x0cb1-n0x0ceb) + I chiba + 0x0020ce42, // n0x0be3 c0x0000 (---------------) + I co + 0x002024c2, // n0x0be4 c0x0000 (---------------) + I ed + 0x20b54dc5, // n0x0be5 c0x0082 (n0x0ceb-n0x0d01) + I ehime + 0x20e7de85, // n0x0be6 c0x0083 (n0x0d01-n0x0d10) + I fukui + 0x2127f5c7, // n0x0be7 c0x0084 (n0x0d10-n0x0d4f) + I fukuoka + 0x217547c9, // n0x0be8 c0x0085 (n0x0d4f-n0x0d82) + I fukushima + 0x21aae0c4, // n0x0be9 c0x0086 (n0x0d82-n0x0da8) + I gifu + 0x00210a42, // n0x0bea c0x0000 (---------------) + I go + 0x00208a82, // n0x0beb c0x0000 (---------------) + I gr + 0x21e45885, // n0x0bec c0x0087 (n0x0da8-n0x0dcc) + I gunma + 0x22209e49, // n0x0bed c0x0088 (n0x0dcc-n0x0de5) + I hiroshima + 0x2276a608, // n0x0bee c0x0089 (n0x0de5-n0x0e73) + I hokkaido + 0x22aacdc5, // n0x0bef c0x008a (n0x0e73-n0x0ea1) + I hyogo + 0x22ec3847, // n0x0bf0 c0x008b (n0x0ea1-n0x0ed4) + I ibaraki + 0x2321b2c8, // n0x0bf1 c0x008c (n0x0ed4-n0x0ee7) + I ishikawa + 0x236d7d45, // n0x0bf2 c0x008d (n0x0ee7-n0x0f09) + I iwate + 0x23a01b46, // n0x0bf3 c0x008e (n0x0f09-n0x0f18) + I kagawa + 0x23e75f89, // n0x0bf4 c0x008f (n0x0f18-n0x0f2c) + I kagoshima + 0x2430ad88, // n0x0bf5 c0x0090 (n0x0f2c-n0x0f4a) + I kanagawa + 0x246ba408, // n0x0bf6 c0x0091 (n0x0f4a-n0x0f4b)* o I kawasaki + 0x24a9e08a, // n0x0bf7 c0x0092 (n0x0f4b-n0x0f4c)* o I kitakyushu + 0x24e4fa44, // n0x0bf8 c0x0093 (n0x0f4c-n0x0f4d)* o I kobe + 0x252cc705, // n0x0bf9 c0x0094 (n0x0f4d-n0x0f6c) + I kochi + 0x256b5448, // n0x0bfa c0x0095 (n0x0f6c-n0x0f86) + I kumamoto + 0x25ac0005, // n0x0bfb c0x0096 (n0x0f86-n0x0fa5) + I kyoto + 0x0021b942, // n0x0bfc c0x0000 (---------------) + I lg + 0x25e65083, // n0x0bfd c0x0097 (n0x0fa5-n0x0fc3) + I mie + 0x262a4006, // n0x0bfe c0x0098 (n0x0fc3-n0x0fe4) + I miyagi + 0x26666248, // n0x0bff c0x0099 (n0x0fe4-n0x0fff) + I miyazaki + 0x26b52206, // n0x0c00 c0x009a (n0x0fff-n0x104a) + I nagano + 0x26ee33c8, // n0x0c01 c0x009b (n0x104a-n0x1060) + I nagasaki + 0x27255a46, // n0x0c02 c0x009c (n0x1060-n0x1061)* o I nagoya + 0x2771c044, // n0x0c03 c0x009d (n0x1061-n0x1087) + I nara + 0x00202ac2, // n0x0c04 c0x0000 (---------------) + I ne + 0x27a350c7, // n0x0c05 c0x009e (n0x1087-n0x10a9) + I niigata + 0x27ea9804, // n0x0c06 c0x009f (n0x10a9-n0x10bc) + I oita + 0x28278bc7, // n0x0c07 c0x00a0 (n0x10bc-n0x10d6) + I okayama + 0x28795107, // n0x0c08 c0x00a1 (n0x10d6-n0x1100) + I okinawa + 0x00200dc2, // n0x0c09 c0x0000 (---------------) + I or + 0x28a9b185, // n0x0c0a c0x00a2 (n0x1100-n0x1132) + I osaka + 0x28f78a84, // n0x0c0b c0x00a3 (n0x1132-n0x114c) + I saga + 0x29373887, // n0x0c0c c0x00a4 (n0x114c-n0x1191) + I saitama + 0x29617047, // n0x0c0d c0x00a5 (n0x1191-n0x1192)* o I sapporo + 0x29a83506, // n0x0c0e c0x00a6 (n0x1192-n0x1193)* o I sendai + 0x29e235c5, // n0x0c0f c0x00a7 (n0x1193-n0x11aa) + I shiga + 0x2a295687, // n0x0c10 c0x00a8 (n0x11aa-n0x11c1) + I shimane + 0x2a6b13c8, // n0x0c11 c0x00a9 (n0x11c1-n0x11e5) + I shizuoka + 0x2ab44807, // n0x0c12 c0x00aa (n0x11e5-n0x1204) + I tochigi + 0x2ae90009, // n0x0c13 c0x00ab (n0x1204-n0x1215) + I tokushima + 0x2b342205, // n0x0c14 c0x00ac (n0x1215-n0x124e) + I tokyo + 0x2b6f7a87, // n0x0c15 c0x00ad (n0x124e-n0x125b) + I tottori + 0x2ba902c6, // n0x0c16 c0x00ae (n0x125b-n0x1273) + I toyama + 0x2be27348, // n0x0c17 c0x00af (n0x1273-n0x1290) + I wakayama + 0x002313cd, // n0x0c18 c0x0000 (---------------) + I xn--0trq7p7nn + 0x00253349, // n0x0c19 c0x0000 (---------------) + I xn--1ctwo + 0x0025c5cb, // n0x0c1a c0x0000 (---------------) + I xn--1lqs03n + 0x00268ecb, // n0x0c1b c0x0000 (---------------) + I xn--1lqs71d + 0x0027c4cb, // n0x0c1c c0x0000 (---------------) + I xn--2m4a15e + 0x002a830b, // n0x0c1d c0x0000 (---------------) + I xn--32vp30h + 0x00300a8b, // n0x0c1e c0x0000 (---------------) + I xn--4it168d + 0x00300d4b, // n0x0c1f c0x0000 (---------------) + I xn--4it797k + 0x00302ac9, // n0x0c20 c0x0000 (---------------) + I xn--4pvxs + 0x00303bcb, // n0x0c21 c0x0000 (---------------) + I xn--5js045d + 0x00303e8b, // n0x0c22 c0x0000 (---------------) + I xn--5rtp49c + 0x0030430b, // n0x0c23 c0x0000 (---------------) + I xn--5rtq34k + 0x00304e0a, // n0x0c24 c0x0000 (---------------) + I xn--6btw5a + 0x0030534a, // n0x0c25 c0x0000 (---------------) + I xn--6orx2r + 0x0030594c, // n0x0c26 c0x0000 (---------------) + I xn--7t0a264c + 0x0030bdcb, // n0x0c27 c0x0000 (---------------) + I xn--8ltr62k + 0x0030c78a, // n0x0c28 c0x0000 (---------------) + I xn--8pvr4u + 0x0031b80a, // n0x0c29 c0x0000 (---------------) + I xn--c3s14m + 0x0032a50e, // n0x0c2a c0x0000 (---------------) + I xn--d5qv7z876c + 0x0032b7ce, // n0x0c2b c0x0000 (---------------) + I xn--djrs72d6uy + 0x0032bb4a, // n0x0c2c c0x0000 (---------------) + I xn--djty4k + 0x0032d24a, // n0x0c2d c0x0000 (---------------) + I xn--efvn9s + 0x0032db8b, // n0x0c2e c0x0000 (---------------) + I xn--ehqz56n + 0x0032de4b, // n0x0c2f c0x0000 (---------------) + I xn--elqq16h + 0x0032eb8b, // n0x0c30 c0x0000 (---------------) + I xn--f6qx53a + 0x0034624b, // n0x0c31 c0x0000 (---------------) + I xn--k7yn95e + 0x0034684a, // n0x0c32 c0x0000 (---------------) + I xn--kbrq7o + 0x0034750b, // n0x0c33 c0x0000 (---------------) + I xn--klt787d + 0x003477ca, // n0x0c34 c0x0000 (---------------) + I xn--kltp7d + 0x00347a4a, // n0x0c35 c0x0000 (---------------) + I xn--kltx9a + 0x00347cca, // n0x0c36 c0x0000 (---------------) + I xn--klty5x + 0x00367fcb, // n0x0c37 c0x0000 (---------------) + I xn--mkru45i + 0x0036fd0b, // n0x0c38 c0x0000 (---------------) + I xn--nit225k + 0x0037194e, // n0x0c39 c0x0000 (---------------) + I xn--ntso0iqx3a + 0x00371ccb, // n0x0c3a c0x0000 (---------------) + I xn--ntsq17g + 0x0037a8cb, // n0x0c3b c0x0000 (---------------) + I xn--pssu33l + 0x0037c50b, // n0x0c3c c0x0000 (---------------) + I xn--qqqt11m + 0x0037f34a, // n0x0c3d c0x0000 (---------------) + I xn--rht27z + 0x0037f5c9, // n0x0c3e c0x0000 (---------------) + I xn--rht3d + 0x0037f80a, // n0x0c3f c0x0000 (---------------) + I xn--rht61e + 0x00380e8a, // n0x0c40 c0x0000 (---------------) + I xn--rny31h + 0x0039244b, // n0x0c41 c0x0000 (---------------) + I xn--tor131o + 0x00393f8b, // n0x0c42 c0x0000 (---------------) + I xn--uist22h + 0x00394a4a, // n0x0c43 c0x0000 (---------------) + I xn--uisz3g + 0x00395d8b, // n0x0c44 c0x0000 (---------------) + I xn--uuwu58a + 0x0039b38b, // n0x0c45 c0x0000 (---------------) + I xn--vgu402c + 0x003a41cb, // n0x0c46 c0x0000 (---------------) + I xn--zbx025d + 0x2c2815c8, // n0x0c47 c0x00b0 (n0x1290-n0x12b2) + I yamagata + 0x2c689a89, // n0x0c48 c0x00b1 (n0x12b2-n0x12c2) + I yamaguchi + 0x2caa2d49, // n0x0c49 c0x00b2 (n0x12c2-n0x12de) + I yamanashi + 0x2ced1a88, // n0x0c4a c0x00b3 (n0x12de-n0x12df)* o I yokohama + 0x00334c45, // n0x0c4b c0x0000 (---------------) + I aisai + 0x00201f03, // n0x0c4c c0x0000 (---------------) + I ama + 0x00201044, // n0x0c4d c0x0000 (---------------) + I anjo + 0x00360f85, // n0x0c4e c0x0000 (---------------) + I asuke + 0x002ade06, // n0x0c4f c0x0000 (---------------) + I chiryu + 0x002b0305, // n0x0c50 c0x0000 (---------------) + I chita + 0x00289284, // n0x0c51 c0x0000 (---------------) + I fuso + 0x002702c8, // n0x0c52 c0x0000 (---------------) + I gamagori + 0x00256bc5, // n0x0c53 c0x0000 (---------------) + I handa + 0x00291884, // n0x0c54 c0x0000 (---------------) + I hazu + 0x002c5007, // n0x0c55 c0x0000 (---------------) + I hekinan + 0x0029e9ca, // n0x0c56 c0x0000 (---------------) + I higashiura + 0x002d37ca, // n0x0c57 c0x0000 (---------------) + I ichinomiya + 0x00302f47, // n0x0c58 c0x0000 (---------------) + I inazawa + 0x00204147, // n0x0c59 c0x0000 (---------------) + I inuyama + 0x002ed587, // n0x0c5a c0x0000 (---------------) + I isshiki + 0x0022cc87, // n0x0c5b c0x0000 (---------------) + I iwakura + 0x0029a545, // n0x0c5c c0x0000 (---------------) + I kanie + 0x00324906, // n0x0c5d c0x0000 (---------------) + I kariya + 0x00311947, // n0x0c5e c0x0000 (---------------) + I kasugai + 0x0024c144, // n0x0c5f c0x0000 (---------------) + I kira + 0x00358786, // n0x0c60 c0x0000 (---------------) + I kiyosu + 0x0028ee46, // n0x0c61 c0x0000 (---------------) + I komaki + 0x00203b05, // n0x0c62 c0x0000 (---------------) + I konan + 0x00355204, // n0x0c63 c0x0000 (---------------) + I kota + 0x002a9086, // n0x0c64 c0x0000 (---------------) + I mihama + 0x0029dbc7, // n0x0c65 c0x0000 (---------------) + I miyoshi + 0x002210c6, // n0x0c66 c0x0000 (---------------) + I nishio + 0x0022fe47, // n0x0c67 c0x0000 (---------------) + I nisshin + 0x0027d083, // n0x0c68 c0x0000 (---------------) + I obu + 0x00252306, // n0x0c69 c0x0000 (---------------) + I oguchi + 0x00236705, // n0x0c6a c0x0000 (---------------) + I oharu + 0x0027f6c7, // n0x0c6b c0x0000 (---------------) + I okazaki + 0x002c09ca, // n0x0c6c c0x0000 (---------------) + I owariasahi + 0x00288604, // n0x0c6d c0x0000 (---------------) + I seto + 0x002197c8, // n0x0c6e c0x0000 (---------------) + I shikatsu + 0x00381509, // n0x0c6f c0x0000 (---------------) + I shinshiro + 0x002fd347, // n0x0c70 c0x0000 (---------------) + I shitara + 0x002e8886, // n0x0c71 c0x0000 (---------------) + I tahara + 0x0035e8c8, // n0x0c72 c0x0000 (---------------) + I takahama + 0x00307b49, // n0x0c73 c0x0000 (---------------) + I tobishima + 0x00368744, // n0x0c74 c0x0000 (---------------) + I toei + 0x002ff504, // n0x0c75 c0x0000 (---------------) + I togo + 0x002f91c5, // n0x0c76 c0x0000 (---------------) + I tokai + 0x002c1548, // n0x0c77 c0x0000 (---------------) + I tokoname + 0x002c1f87, // n0x0c78 c0x0000 (---------------) + I toyoake + 0x00285c49, // n0x0c79 c0x0000 (---------------) + I toyohashi + 0x002472c8, // n0x0c7a c0x0000 (---------------) + I toyokawa + 0x00366b06, // n0x0c7b c0x0000 (---------------) + I toyone + 0x00264186, // n0x0c7c c0x0000 (---------------) + I toyota + 0x002980c8, // n0x0c7d c0x0000 (---------------) + I tsushima + 0x0036af06, // n0x0c7e c0x0000 (---------------) + I yatomi + 0x00204785, // n0x0c7f c0x0000 (---------------) + I akita + 0x002835c6, // n0x0c80 c0x0000 (---------------) + I daisen + 0x00278ec8, // n0x0c81 c0x0000 (---------------) + I fujisato + 0x00239506, // n0x0c82 c0x0000 (---------------) + I gojome + 0x00250e8b, // n0x0c83 c0x0000 (---------------) + I hachirogata + 0x0028d246, // n0x0c84 c0x0000 (---------------) + I happou + 0x00299acd, // n0x0c85 c0x0000 (---------------) + I higashinaruse + 0x0038d6c5, // n0x0c86 c0x0000 (---------------) + I honjo + 0x002a96c6, // n0x0c87 c0x0000 (---------------) + I honjyo + 0x0021b385, // n0x0c88 c0x0000 (---------------) + I ikawa + 0x002971c9, // n0x0c89 c0x0000 (---------------) + I kamikoani + 0x0030a307, // n0x0c8a c0x0000 (---------------) + I kamioka + 0x00376ec8, // n0x0c8b c0x0000 (---------------) + I katagami + 0x002db5c6, // n0x0c8c c0x0000 (---------------) + I kazuno + 0x00298a49, // n0x0c8d c0x0000 (---------------) + I kitaakita + 0x002e2c86, // n0x0c8e c0x0000 (---------------) + I kosaka + 0x002c0945, // n0x0c8f c0x0000 (---------------) + I kyowa + 0x0022da46, // n0x0c90 c0x0000 (---------------) + I misato + 0x002b3246, // n0x0c91 c0x0000 (---------------) + I mitane + 0x002c81c9, // n0x0c92 c0x0000 (---------------) + I moriyoshi + 0x0034f4c6, // n0x0c93 c0x0000 (---------------) + I nikaho + 0x003744c7, // n0x0c94 c0x0000 (---------------) + I noshiro + 0x002c7905, // n0x0c95 c0x0000 (---------------) + I odate + 0x002028c3, // n0x0c96 c0x0000 (---------------) + I oga + 0x002270c5, // n0x0c97 c0x0000 (---------------) + I ogata + 0x002a7407, // n0x0c98 c0x0000 (---------------) + I semboku + 0x00331906, // n0x0c99 c0x0000 (---------------) + I yokote + 0x0038d5c9, // n0x0c9a c0x0000 (---------------) + I yurihonjo + 0x0030ddc6, // n0x0c9b c0x0000 (---------------) + I aomori + 0x0024ed86, // n0x0c9c c0x0000 (---------------) + I gonohe + 0x0020ed89, // n0x0c9d c0x0000 (---------------) + I hachinohe + 0x00282fc9, // n0x0c9e c0x0000 (---------------) + I hashikami + 0x002a0b87, // n0x0c9f c0x0000 (---------------) + I hiranai + 0x00327108, // n0x0ca0 c0x0000 (---------------) + I hirosaki + 0x0025e449, // n0x0ca1 c0x0000 (---------------) + I itayanagi + 0x0027fb88, // n0x0ca2 c0x0000 (---------------) + I kuroishi + 0x0037c786, // n0x0ca3 c0x0000 (---------------) + I misawa + 0x002d1485, // n0x0ca4 c0x0000 (---------------) + I mutsu + 0x002227ca, // n0x0ca5 c0x0000 (---------------) + I nakadomari + 0x0024ee06, // n0x0ca6 c0x0000 (---------------) + I noheji + 0x00206c06, // n0x0ca7 c0x0000 (---------------) + I oirase + 0x002a41c5, // n0x0ca8 c0x0000 (---------------) + I owani + 0x002ae408, // n0x0ca9 c0x0000 (---------------) + I rokunohe + 0x00209a87, // n0x0caa c0x0000 (---------------) + I sannohe + 0x00236a0a, // n0x0cab c0x0000 (---------------) + I shichinohe + 0x0024ec86, // n0x0cac c0x0000 (---------------) + I shingo + 0x0023fe05, // n0x0cad c0x0000 (---------------) + I takko + 0x00255cc6, // n0x0cae c0x0000 (---------------) + I towada + 0x0028f587, // n0x0caf c0x0000 (---------------) + I tsugaru + 0x002e8747, // n0x0cb0 c0x0000 (---------------) + I tsuruta + 0x00374145, // n0x0cb1 c0x0000 (---------------) + I abiko + 0x002c0b05, // n0x0cb2 c0x0000 (---------------) + I asahi + 0x002e6786, // n0x0cb3 c0x0000 (---------------) + I chonan + 0x002e7846, // n0x0cb4 c0x0000 (---------------) + I chosei + 0x002fee46, // n0x0cb5 c0x0000 (---------------) + I choshi + 0x0032c104, // n0x0cb6 c0x0000 (---------------) + I chuo + 0x00282089, // n0x0cb7 c0x0000 (---------------) + I funabashi + 0x0028a946, // n0x0cb8 c0x0000 (---------------) + I futtsu + 0x00283b8a, // n0x0cb9 c0x0000 (---------------) + I hanamigawa + 0x00290e48, // n0x0cba c0x0000 (---------------) + I ichihara + 0x00263808, // n0x0cbb c0x0000 (---------------) + I ichikawa + 0x002d37ca, // n0x0cbc c0x0000 (---------------) + I ichinomiya + 0x00209705, // n0x0cbd c0x0000 (---------------) + I inzai + 0x0029db05, // n0x0cbe c0x0000 (---------------) + I isumi + 0x003083c8, // n0x0cbf c0x0000 (---------------) + I kamagaya + 0x002cc488, // n0x0cc0 c0x0000 (---------------) + I kamogawa + 0x002032c7, // n0x0cc1 c0x0000 (---------------) + I kashiwa + 0x0029ca86, // n0x0cc2 c0x0000 (---------------) + I katori + 0x00316708, // n0x0cc3 c0x0000 (---------------) + I katsuura + 0x0023e107, // n0x0cc4 c0x0000 (---------------) + I kimitsu + 0x00281a88, // n0x0cc5 c0x0000 (---------------) + I kisarazu + 0x00369606, // n0x0cc6 c0x0000 (---------------) + I kozaki + 0x00284148, // n0x0cc7 c0x0000 (---------------) + I kujukuri + 0x002b5f46, // n0x0cc8 c0x0000 (---------------) + I kyonan + 0x0023bd07, // n0x0cc9 c0x0000 (---------------) + I matsudo + 0x00299486, // n0x0cca c0x0000 (---------------) + I midori + 0x002a9086, // n0x0ccb c0x0000 (---------------) + I mihama + 0x0023484a, // n0x0ccc c0x0000 (---------------) + I minamiboso + 0x00233dc6, // n0x0ccd c0x0000 (---------------) + I mobara + 0x002d1489, // n0x0cce c0x0000 (---------------) + I mutsuzawa + 0x002afd46, // n0x0ccf c0x0000 (---------------) + I nagara + 0x002d2c8a, // n0x0cd0 c0x0000 (---------------) + I nagareyama + 0x0031c049, // n0x0cd1 c0x0000 (---------------) + I narashino + 0x0035bd46, // n0x0cd2 c0x0000 (---------------) + I narita + 0x0037d844, // n0x0cd3 c0x0000 (---------------) + I noda + 0x0030788d, // n0x0cd4 c0x0000 (---------------) + I oamishirasato + 0x00289d07, // n0x0cd5 c0x0000 (---------------) + I omigawa + 0x00318d06, // n0x0cd6 c0x0000 (---------------) + I onjuku + 0x002ba2c5, // n0x0cd7 c0x0000 (---------------) + I otaki + 0x002e2d05, // n0x0cd8 c0x0000 (---------------) + I sakae + 0x002dc646, // n0x0cd9 c0x0000 (---------------) + I sakura + 0x0028fc49, // n0x0cda c0x0000 (---------------) + I shimofusa + 0x002a6b07, // n0x0cdb c0x0000 (---------------) + I shirako + 0x0027a7c6, // n0x0cdc c0x0000 (---------------) + I shiroi + 0x002fcc86, // n0x0cdd c0x0000 (---------------) + I shisui + 0x00289309, // n0x0cde c0x0000 (---------------) + I sodegaura + 0x0021d284, // n0x0cdf c0x0000 (---------------) + I sosa + 0x00229144, // n0x0ce0 c0x0000 (---------------) + I tako + 0x00201dc8, // n0x0ce1 c0x0000 (---------------) + I tateyama + 0x002b0fc6, // n0x0ce2 c0x0000 (---------------) + I togane + 0x002a0508, // n0x0ce3 c0x0000 (---------------) + I tohnosho + 0x0022d9c8, // n0x0ce4 c0x0000 (---------------) + I tomisato + 0x0027eac7, // n0x0ce5 c0x0000 (---------------) + I urayasu + 0x00200309, // n0x0ce6 c0x0000 (---------------) + I yachimata + 0x002ff047, // n0x0ce7 c0x0000 (---------------) + I yachiyo + 0x002af90a, // n0x0ce8 c0x0000 (---------------) + I yokaichiba + 0x0022d38f, // n0x0ce9 c0x0000 (---------------) + I yokoshibahikari + 0x0026840a, // n0x0cea c0x0000 (---------------) + I yotsukaido + 0x00226ac5, // n0x0ceb c0x0000 (---------------) + I ainan + 0x00279105, // n0x0cec c0x0000 (---------------) + I honai + 0x00216505, // n0x0ced c0x0000 (---------------) + I ikata + 0x00248647, // n0x0cee c0x0000 (---------------) + I imabari + 0x00203543, // n0x0cef c0x0000 (---------------) + I iyo + 0x00327308, // n0x0cf0 c0x0000 (---------------) + I kamijima + 0x002f1746, // n0x0cf1 c0x0000 (---------------) + I kihoku + 0x002f1849, // n0x0cf2 c0x0000 (---------------) + I kumakogen + 0x003a4d86, // n0x0cf3 c0x0000 (---------------) + I masaki + 0x002c1947, // n0x0cf4 c0x0000 (---------------) + I matsuno + 0x00298809, // n0x0cf5 c0x0000 (---------------) + I matsuyama + 0x00376dc8, // n0x0cf6 c0x0000 (---------------) + I namikata + 0x002a4287, // n0x0cf7 c0x0000 (---------------) + I niihama + 0x002ffa83, // n0x0cf8 c0x0000 (---------------) + I ozu + 0x00334cc5, // n0x0cf9 c0x0000 (---------------) + I saijo + 0x00379845, // n0x0cfa c0x0000 (---------------) + I seiyo + 0x0032bf4b, // n0x0cfb c0x0000 (---------------) + I shikokuchuo + 0x002c00c4, // n0x0cfc c0x0000 (---------------) + I tobe + 0x0020cc04, // n0x0cfd c0x0000 (---------------) + I toon + 0x00277e86, // n0x0cfe c0x0000 (---------------) + I uchiko + 0x002ffe07, // n0x0cff c0x0000 (---------------) + I uwajima + 0x0038e68a, // n0x0d00 c0x0000 (---------------) + I yawatahama + 0x00349887, // n0x0d01 c0x0000 (---------------) + I echizen + 0x003687c7, // n0x0d02 c0x0000 (---------------) + I eiheiji + 0x0027de85, // n0x0d03 c0x0000 (---------------) + I fukui + 0x00202445, // n0x0d04 c0x0000 (---------------) + I ikeda + 0x0021c9c9, // n0x0d05 c0x0000 (---------------) + I katsuyama + 0x002a9086, // n0x0d06 c0x0000 (---------------) + I mihama + 0x0034970d, // n0x0d07 c0x0000 (---------------) + I minamiechizen + 0x003954c5, // n0x0d08 c0x0000 (---------------) + I obama + 0x002a0703, // n0x0d09 c0x0000 (---------------) + I ohi + 0x0020c303, // n0x0d0a c0x0000 (---------------) + I ono + 0x002f20c5, // n0x0d0b c0x0000 (---------------) + I sabae + 0x0034a305, // n0x0d0c c0x0000 (---------------) + I sakai + 0x0035e8c8, // n0x0d0d c0x0000 (---------------) + I takahama + 0x0027bec7, // n0x0d0e c0x0000 (---------------) + I tsuruga + 0x00228ec6, // n0x0d0f c0x0000 (---------------) + I wakasa + 0x0029f086, // n0x0d10 c0x0000 (---------------) + I ashiya + 0x0022e9c5, // n0x0d11 c0x0000 (---------------) + I buzen + 0x002393c7, // n0x0d12 c0x0000 (---------------) + I chikugo + 0x002043c7, // n0x0d13 c0x0000 (---------------) + I chikuho + 0x002949c7, // n0x0d14 c0x0000 (---------------) + I chikujo + 0x002cc78a, // n0x0d15 c0x0000 (---------------) + I chikushino + 0x002523c8, // n0x0d16 c0x0000 (---------------) + I chikuzen + 0x0032c104, // n0x0d17 c0x0000 (---------------) + I chuo + 0x00215507, // n0x0d18 c0x0000 (---------------) + I dazaifu + 0x0027d1c7, // n0x0d19 c0x0000 (---------------) + I fukuchi + 0x0032d806, // n0x0d1a c0x0000 (---------------) + I hakata + 0x00266d87, // n0x0d1b c0x0000 (---------------) + I higashi + 0x002d4208, // n0x0d1c c0x0000 (---------------) + I hirokawa + 0x002a2c48, // n0x0d1d c0x0000 (---------------) + I hisayama + 0x0026fd86, // n0x0d1e c0x0000 (---------------) + I iizuka + 0x0021a8c8, // n0x0d1f c0x0000 (---------------) + I inatsuki + 0x002c7d84, // n0x0d20 c0x0000 (---------------) + I kaho + 0x00311946, // n0x0d21 c0x0000 (---------------) + I kasuga + 0x0020ba06, // n0x0d22 c0x0000 (---------------) + I kasuya + 0x00203606, // n0x0d23 c0x0000 (---------------) + I kawara + 0x002f5006, // n0x0d24 c0x0000 (---------------) + I keisen + 0x0021fc44, // n0x0d25 c0x0000 (---------------) + I koga + 0x0022cd46, // n0x0d26 c0x0000 (---------------) + I kurate + 0x002b9346, // n0x0d27 c0x0000 (---------------) + I kurogi + 0x00297846, // n0x0d28 c0x0000 (---------------) + I kurume + 0x00223406, // n0x0d29 c0x0000 (---------------) + I minami + 0x0020c1c6, // n0x0d2a c0x0000 (---------------) + I miyako + 0x002d4046, // n0x0d2b c0x0000 (---------------) + I miyama + 0x00228dc8, // n0x0d2c c0x0000 (---------------) + I miyawaka + 0x00358608, // n0x0d2d c0x0000 (---------------) + I mizumaki + 0x002cd388, // n0x0d2e c0x0000 (---------------) + I munakata + 0x002b0508, // n0x0d2f c0x0000 (---------------) + I nakagawa + 0x00308346, // n0x0d30 c0x0000 (---------------) + I nakama + 0x00210385, // n0x0d31 c0x0000 (---------------) + I nishi + 0x00227086, // n0x0d32 c0x0000 (---------------) + I nogata + 0x002ace45, // n0x0d33 c0x0000 (---------------) + I ogori + 0x0037e787, // n0x0d34 c0x0000 (---------------) + I okagaki + 0x002035c5, // n0x0d35 c0x0000 (---------------) + I okawa + 0x00215e83, // n0x0d36 c0x0000 (---------------) + I oki + 0x00203ec5, // n0x0d37 c0x0000 (---------------) + I omuta + 0x0026e544, // n0x0d38 c0x0000 (---------------) + I onga + 0x0020c305, // n0x0d39 c0x0000 (---------------) + I onojo + 0x002135c3, // n0x0d3a c0x0000 (---------------) + I oto + 0x002ddcc7, // n0x0d3b c0x0000 (---------------) + I saigawa + 0x0036ee48, // n0x0d3c c0x0000 (---------------) + I sasaguri + 0x0022ff06, // n0x0d3d c0x0000 (---------------) + I shingu + 0x0029a1cd, // n0x0d3e c0x0000 (---------------) + I shinyoshitomi + 0x002790c6, // n0x0d3f c0x0000 (---------------) + I shonai + 0x002968c5, // n0x0d40 c0x0000 (---------------) + I soeda + 0x002c8583, // n0x0d41 c0x0000 (---------------) + I sue + 0x002b4e09, // n0x0d42 c0x0000 (---------------) + I tachiarai + 0x002c3a06, // n0x0d43 c0x0000 (---------------) + I tagawa + 0x00296ec6, // n0x0d44 c0x0000 (---------------) + I takata + 0x0034a844, // n0x0d45 c0x0000 (---------------) + I toho + 0x00268387, // n0x0d46 c0x0000 (---------------) + I toyotsu + 0x0023a6c6, // n0x0d47 c0x0000 (---------------) + I tsuiki + 0x002ae245, // n0x0d48 c0x0000 (---------------) + I ukiha + 0x0020a4c3, // n0x0d49 c0x0000 (---------------) + I umi + 0x0020b604, // n0x0d4a c0x0000 (---------------) + I usui + 0x0027d386, // n0x0d4b c0x0000 (---------------) + I yamada + 0x0029d304, // n0x0d4c c0x0000 (---------------) + I yame + 0x0030fe08, // n0x0d4d c0x0000 (---------------) + I yanagawa + 0x00381b49, // n0x0d4e c0x0000 (---------------) + I yukuhashi + 0x002bb289, // n0x0d4f c0x0000 (---------------) + I aizubange + 0x002a030a, // n0x0d50 c0x0000 (---------------) + I aizumisato + 0x0024438d, // n0x0d51 c0x0000 (---------------) + I aizuwakamatsu + 0x00247f07, // n0x0d52 c0x0000 (---------------) + I asakawa + 0x00206a86, // n0x0d53 c0x0000 (---------------) + I bandai + 0x0020da04, // n0x0d54 c0x0000 (---------------) + I date + 0x003547c9, // n0x0d55 c0x0000 (---------------) + I fukushima + 0x00287748, // n0x0d56 c0x0000 (---------------) + I furudono + 0x00289906, // n0x0d57 c0x0000 (---------------) + I futaba + 0x0025a4c6, // n0x0d58 c0x0000 (---------------) + I hanawa + 0x00266d87, // n0x0d59 c0x0000 (---------------) + I higashi + 0x002cfd86, // n0x0d5a c0x0000 (---------------) + I hirata + 0x0021c306, // n0x0d5b c0x0000 (---------------) + I hirono + 0x00381e46, // n0x0d5c c0x0000 (---------------) + I iitate + 0x0039518a, // n0x0d5d c0x0000 (---------------) + I inawashiro + 0x0021b2c8, // n0x0d5e c0x0000 (---------------) + I ishikawa + 0x002243c5, // n0x0d5f c0x0000 (---------------) + I iwaki + 0x0027e809, // n0x0d60 c0x0000 (---------------) + I izumizaki + 0x002c270a, // n0x0d61 c0x0000 (---------------) + I kagamiishi + 0x002c91c8, // n0x0d62 c0x0000 (---------------) + I kaneyama + 0x0029bec8, // n0x0d63 c0x0000 (---------------) + I kawamata + 0x00296e48, // n0x0d64 c0x0000 (---------------) + I kitakata + 0x002047cc, // n0x0d65 c0x0000 (---------------) + I kitashiobara + 0x0034b345, // n0x0d66 c0x0000 (---------------) + I koori + 0x0029f308, // n0x0d67 c0x0000 (---------------) + I koriyama + 0x002fb106, // n0x0d68 c0x0000 (---------------) + I kunimi + 0x002ac346, // n0x0d69 c0x0000 (---------------) + I miharu + 0x002c0d47, // n0x0d6a c0x0000 (---------------) + I mishima + 0x00349785, // n0x0d6b c0x0000 (---------------) + I namie + 0x00283745, // n0x0d6c c0x0000 (---------------) + I nango + 0x002bb149, // n0x0d6d c0x0000 (---------------) + I nishiaizu + 0x00210907, // n0x0d6e c0x0000 (---------------) + I nishigo + 0x002f1805, // n0x0d6f c0x0000 (---------------) + I okuma + 0x0021cf87, // n0x0d70 c0x0000 (---------------) + I omotego + 0x0020c303, // n0x0d71 c0x0000 (---------------) + I ono + 0x002c2bc5, // n0x0d72 c0x0000 (---------------) + I otama + 0x00320d08, // n0x0d73 c0x0000 (---------------) + I samegawa + 0x002af287, // n0x0d74 c0x0000 (---------------) + I shimogo + 0x0029bd89, // n0x0d75 c0x0000 (---------------) + I shirakawa + 0x002b2f45, // n0x0d76 c0x0000 (---------------) + I showa + 0x002f87c4, // n0x0d77 c0x0000 (---------------) + I soma + 0x002a1a88, // n0x0d78 c0x0000 (---------------) + I sukagawa + 0x0023d287, // n0x0d79 c0x0000 (---------------) + I taishin + 0x002a4448, // n0x0d7a c0x0000 (---------------) + I tamakawa + 0x00331e48, // n0x0d7b c0x0000 (---------------) + I tanagura + 0x002cf345, // n0x0d7c c0x0000 (---------------) + I tenei + 0x0034ed86, // n0x0d7d c0x0000 (---------------) + I yabuki + 0x00290986, // n0x0d7e c0x0000 (---------------) + I yamato + 0x0025b789, // n0x0d7f c0x0000 (---------------) + I yamatsuri + 0x00316f87, // n0x0d80 c0x0000 (---------------) + I yanaizu + 0x002ad706, // n0x0d81 c0x0000 (---------------) + I yugawa + 0x0033c5c7, // n0x0d82 c0x0000 (---------------) + I anpachi + 0x00217883, // n0x0d83 c0x0000 (---------------) + I ena + 0x002ae0c4, // n0x0d84 c0x0000 (---------------) + I gifu + 0x002a23c5, // n0x0d85 c0x0000 (---------------) + I ginan + 0x00215784, // n0x0d86 c0x0000 (---------------) + I godo + 0x002328c4, // n0x0d87 c0x0000 (---------------) + I gujo + 0x00281847, // n0x0d88 c0x0000 (---------------) + I hashima + 0x00217f87, // n0x0d89 c0x0000 (---------------) + I hichiso + 0x0027a984, // n0x0d8a c0x0000 (---------------) + I hida + 0x0029bbd0, // n0x0d8b c0x0000 (---------------) + I higashishirakawa + 0x002dc7c7, // n0x0d8c c0x0000 (---------------) + I ibigawa + 0x00202445, // n0x0d8d c0x0000 (---------------) + I ikeda + 0x002eb24c, // n0x0d8e c0x0000 (---------------) + I kakamigahara + 0x00279ac4, // n0x0d8f c0x0000 (---------------) + I kani + 0x00292e08, // n0x0d90 c0x0000 (---------------) + I kasahara + 0x0023bc09, // n0x0d91 c0x0000 (---------------) + I kasamatsu + 0x00300906, // n0x0d92 c0x0000 (---------------) + I kawaue + 0x0021d388, // n0x0d93 c0x0000 (---------------) + I kitagata + 0x0024e344, // n0x0d94 c0x0000 (---------------) + I mino + 0x0024e348, // n0x0d95 c0x0000 (---------------) + I minokamo + 0x00267246, // n0x0d96 c0x0000 (---------------) + I mitake + 0x00223288, // n0x0d97 c0x0000 (---------------) + I mizunami + 0x002a20c6, // n0x0d98 c0x0000 (---------------) + I motosu + 0x0030624b, // n0x0d99 c0x0000 (---------------) + I nakatsugawa + 0x002028c5, // n0x0d9a c0x0000 (---------------) + I ogaki + 0x002c7d08, // n0x0d9b c0x0000 (---------------) + I sakahogi + 0x00219284, // n0x0d9c c0x0000 (---------------) + I seki + 0x00282c4a, // n0x0d9d c0x0000 (---------------) + I sekigahara + 0x0029bd89, // n0x0d9e c0x0000 (---------------) + I shirakawa + 0x002889c6, // n0x0d9f c0x0000 (---------------) + I tajimi + 0x002c17c8, // n0x0da0 c0x0000 (---------------) + I takayama + 0x00273f05, // n0x0da1 c0x0000 (---------------) + I tarui + 0x00226184, // n0x0da2 c0x0000 (---------------) + I toki + 0x00292d06, // n0x0da3 c0x0000 (---------------) + I tomika + 0x00294888, // n0x0da4 c0x0000 (---------------) + I wanouchi + 0x002815c8, // n0x0da5 c0x0000 (---------------) + I yamagata + 0x00341d46, // n0x0da6 c0x0000 (---------------) + I yaotsu + 0x00311044, // n0x0da7 c0x0000 (---------------) + I yoro + 0x00222746, // n0x0da8 c0x0000 (---------------) + I annaka + 0x002ff0c7, // n0x0da9 c0x0000 (---------------) + I chiyoda + 0x00278ac7, // n0x0daa c0x0000 (---------------) + I fujioka + 0x00266d8f, // n0x0dab c0x0000 (---------------) + I higashiagatsuma + 0x00204e87, // n0x0dac c0x0000 (---------------) + I isesaki + 0x0035be07, // n0x0dad c0x0000 (---------------) + I itakura + 0x002ac205, // n0x0dae c0x0000 (---------------) + I kanna + 0x002d6c85, // n0x0daf c0x0000 (---------------) + I kanra + 0x002a0849, // n0x0db0 c0x0000 (---------------) + I katashina + 0x00250c86, // n0x0db1 c0x0000 (---------------) + I kawaba + 0x00280285, // n0x0db2 c0x0000 (---------------) + I kiryu + 0x002832c7, // n0x0db3 c0x0000 (---------------) + I kusatsu + 0x002c76c8, // n0x0db4 c0x0000 (---------------) + I maebashi + 0x002bbc05, // n0x0db5 c0x0000 (---------------) + I meiwa + 0x00299486, // n0x0db6 c0x0000 (---------------) + I midori + 0x00215fc8, // n0x0db7 c0x0000 (---------------) + I minakami + 0x0035220a, // n0x0db8 c0x0000 (---------------) + I naganohara + 0x003536c8, // n0x0db9 c0x0000 (---------------) + I nakanojo + 0x003a0647, // n0x0dba c0x0000 (---------------) + I nanmoku + 0x0022d7c6, // n0x0dbb c0x0000 (---------------) + I numata + 0x0027e7c6, // n0x0dbc c0x0000 (---------------) + I oizumi + 0x0021edc3, // n0x0dbd c0x0000 (---------------) + I ora + 0x00201103, // n0x0dbe c0x0000 (---------------) + I ota + 0x002c28c9, // n0x0dbf c0x0000 (---------------) + I shibukawa + 0x0025e2c9, // n0x0dc0 c0x0000 (---------------) + I shimonita + 0x0028ff06, // n0x0dc1 c0x0000 (---------------) + I shinto + 0x002b2f45, // n0x0dc2 c0x0000 (---------------) + I showa + 0x002a1e48, // n0x0dc3 c0x0000 (---------------) + I takasaki + 0x002c17c8, // n0x0dc4 c0x0000 (---------------) + I takayama + 0x0039b188, // n0x0dc5 c0x0000 (---------------) + I tamamura + 0x00381ecb, // n0x0dc6 c0x0000 (---------------) + I tatebayashi + 0x0029a407, // n0x0dc7 c0x0000 (---------------) + I tomioka + 0x002fdc49, // n0x0dc8 c0x0000 (---------------) + I tsukiyono + 0x00267008, // n0x0dc9 c0x0000 (---------------) + I tsumagoi + 0x00385884, // n0x0dca c0x0000 (---------------) + I ueno + 0x002c82c8, // n0x0dcb c0x0000 (---------------) + I yoshioka + 0x0028e249, // n0x0dcc c0x0000 (---------------) + I asaminami + 0x002ada05, // n0x0dcd c0x0000 (---------------) + I daiwa + 0x00248547, // n0x0dce c0x0000 (---------------) + I etajima + 0x002be405, // n0x0dcf c0x0000 (---------------) + I fuchu + 0x002814c8, // n0x0dd0 c0x0000 (---------------) + I fukuyama + 0x00290c8b, // n0x0dd1 c0x0000 (---------------) + I hatsukaichi + 0x002953d0, // n0x0dd2 c0x0000 (---------------) + I higashihiroshima + 0x002a94c5, // n0x0dd3 c0x0000 (---------------) + I hongo + 0x002191cc, // n0x0dd4 c0x0000 (---------------) + I jinsekikogen + 0x00229085, // n0x0dd5 c0x0000 (---------------) + I kaita + 0x0027df03, // n0x0dd6 c0x0000 (---------------) + I kui + 0x0027f446, // n0x0dd7 c0x0000 (---------------) + I kumano + 0x002b78c4, // n0x0dd8 c0x0000 (---------------) + I kure + 0x0039a0c6, // n0x0dd9 c0x0000 (---------------) + I mihara + 0x0029dbc7, // n0x0dda c0x0000 (---------------) + I miyoshi + 0x00216044, // n0x0ddb c0x0000 (---------------) + I naka + 0x002d36c8, // n0x0ddc c0x0000 (---------------) + I onomichi + 0x003271cd, // n0x0ddd c0x0000 (---------------) + I osakikamijima + 0x002fc585, // n0x0dde c0x0000 (---------------) + I otake + 0x00244884, // n0x0ddf c0x0000 (---------------) + I saka + 0x00226804, // n0x0de0 c0x0000 (---------------) + I sera + 0x0027e289, // n0x0de1 c0x0000 (---------------) + I seranishi + 0x00272b48, // n0x0de2 c0x0000 (---------------) + I shinichi + 0x0030dc47, // n0x0de3 c0x0000 (---------------) + I shobara + 0x002672c8, // n0x0de4 c0x0000 (---------------) + I takehara + 0x00282148, // n0x0de5 c0x0000 (---------------) + I abashiri + 0x0027aac5, // n0x0de6 c0x0000 (---------------) + I abira + 0x00207947, // n0x0de7 c0x0000 (---------------) + I aibetsu + 0x0027aa47, // n0x0de8 c0x0000 (---------------) + I akabira + 0x002086c7, // n0x0de9 c0x0000 (---------------) + I akkeshi + 0x002c0b09, // n0x0dea c0x0000 (---------------) + I asahikawa + 0x0023a549, // n0x0deb c0x0000 (---------------) + I ashibetsu + 0x00243e46, // n0x0dec c0x0000 (---------------) + I ashoro + 0x002b5d86, // n0x0ded c0x0000 (---------------) + I assabu + 0x00266fc6, // n0x0dee c0x0000 (---------------) + I atsuma + 0x00268ac5, // n0x0def c0x0000 (---------------) + I bibai + 0x0024e984, // n0x0df0 c0x0000 (---------------) + I biei + 0x00201a46, // n0x0df1 c0x0000 (---------------) + I bifuka + 0x00201fc6, // n0x0df2 c0x0000 (---------------) + I bihoro + 0x0027ab08, // n0x0df3 c0x0000 (---------------) + I biratori + 0x0028f24b, // n0x0df4 c0x0000 (---------------) + I chippubetsu + 0x002b0b47, // n0x0df5 c0x0000 (---------------) + I chitose + 0x0020da04, // n0x0df6 c0x0000 (---------------) + I date + 0x002276c6, // n0x0df7 c0x0000 (---------------) + I ebetsu + 0x00280f47, // n0x0df8 c0x0000 (---------------) + I embetsu + 0x002f1a05, // n0x0df9 c0x0000 (---------------) + I eniwa + 0x003792c5, // n0x0dfa c0x0000 (---------------) + I erimo + 0x00200fc4, // n0x0dfb c0x0000 (---------------) + I esan + 0x0023a4c6, // n0x0dfc c0x0000 (---------------) + I esashi + 0x00201ac8, // n0x0dfd c0x0000 (---------------) + I fukagawa + 0x003547c9, // n0x0dfe c0x0000 (---------------) + I fukushima + 0x0024b3c6, // n0x0dff c0x0000 (---------------) + I furano + 0x00286648, // n0x0e00 c0x0000 (---------------) + I furubira + 0x002ae306, // n0x0e01 c0x0000 (---------------) + I haboro + 0x0032e0c8, // n0x0e02 c0x0000 (---------------) + I hakodate + 0x002a39cc, // n0x0e03 c0x0000 (---------------) + I hamatonbetsu + 0x0027a986, // n0x0e04 c0x0000 (---------------) + I hidaka + 0x0029658d, // n0x0e05 c0x0000 (---------------) + I higashikagura + 0x00296a0b, // n0x0e06 c0x0000 (---------------) + I higashikawa + 0x00374585, // n0x0e07 c0x0000 (---------------) + I hiroo + 0x00204507, // n0x0e08 c0x0000 (---------------) + I hokuryu + 0x0034f5c6, // n0x0e09 c0x0000 (---------------) + I hokuto + 0x002e8608, // n0x0e0a c0x0000 (---------------) + I honbetsu + 0x00243ec9, // n0x0e0b c0x0000 (---------------) + I horokanai + 0x002bac88, // n0x0e0c c0x0000 (---------------) + I horonobe + 0x00202445, // n0x0e0d c0x0000 (---------------) + I ikeda + 0x0035c607, // n0x0e0e c0x0000 (---------------) + I imakane + 0x0027fc88, // n0x0e0f c0x0000 (---------------) + I ishikari + 0x0026a609, // n0x0e10 c0x0000 (---------------) + I iwamizawa + 0x00239a46, // n0x0e11 c0x0000 (---------------) + I iwanai + 0x0035eeca, // n0x0e12 c0x0000 (---------------) + I kamifurano + 0x002e8388, // n0x0e13 c0x0000 (---------------) + I kamikawa + 0x002baacb, // n0x0e14 c0x0000 (---------------) + I kamishihoro + 0x0028744c, // n0x0e15 c0x0000 (---------------) + I kamisunagawa + 0x0024e448, // n0x0e16 c0x0000 (---------------) + I kamoenai + 0x0027cac6, // n0x0e17 c0x0000 (---------------) + I kayabe + 0x00207348, // n0x0e18 c0x0000 (---------------) + I kembuchi + 0x00204fc7, // n0x0e19 c0x0000 (---------------) + I kikonai + 0x0023a7c9, // n0x0e1a c0x0000 (---------------) + I kimobetsu + 0x00209d4d, // n0x0e1b c0x0000 (---------------) + I kitahiroshima + 0x0029ed06, // n0x0e1c c0x0000 (---------------) + I kitami + 0x0028ef48, // n0x0e1d c0x0000 (---------------) + I kiyosato + 0x003584c9, // n0x0e1e c0x0000 (---------------) + I koshimizu + 0x002b6748, // n0x0e1f c0x0000 (---------------) + I kunneppu + 0x00284248, // n0x0e20 c0x0000 (---------------) + I kuriyama + 0x002b9c0c, // n0x0e21 c0x0000 (---------------) + I kuromatsunai + 0x002bb4c7, // n0x0e22 c0x0000 (---------------) + I kushiro + 0x002bc847, // n0x0e23 c0x0000 (---------------) + I kutchan + 0x002c0945, // n0x0e24 c0x0000 (---------------) + I kyowa + 0x00240c07, // n0x0e25 c0x0000 (---------------) + I mashike + 0x002c7588, // n0x0e26 c0x0000 (---------------) + I matsumae + 0x00292d86, // n0x0e27 c0x0000 (---------------) + I mikasa + 0x0024b24c, // n0x0e28 c0x0000 (---------------) + I minamifurano + 0x002e4488, // n0x0e29 c0x0000 (---------------) + I mombetsu + 0x002c95c8, // n0x0e2a c0x0000 (---------------) + I moseushi + 0x002daf06, // n0x0e2b c0x0000 (---------------) + I mukawa + 0x00395787, // n0x0e2c c0x0000 (---------------) + I muroran + 0x00244044, // n0x0e2d c0x0000 (---------------) + I naie + 0x002b0508, // n0x0e2e c0x0000 (---------------) + I nakagawa + 0x002853cc, // n0x0e2f c0x0000 (---------------) + I nakasatsunai + 0x002178cc, // n0x0e30 c0x0000 (---------------) + I nakatombetsu + 0x00226b45, // n0x0e31 c0x0000 (---------------) + I nanae + 0x00389f87, // n0x0e32 c0x0000 (---------------) + I nanporo + 0x00310fc6, // n0x0e33 c0x0000 (---------------) + I nayoro + 0x00395706, // n0x0e34 c0x0000 (---------------) + I nemuro + 0x00297388, // n0x0e35 c0x0000 (---------------) + I niikappu + 0x003a38c4, // n0x0e36 c0x0000 (---------------) + I niki + 0x002210cb, // n0x0e37 c0x0000 (---------------) + I nishiokoppe + 0x0026c9cb, // n0x0e38 c0x0000 (---------------) + I noboribetsu + 0x0022d7c6, // n0x0e39 c0x0000 (---------------) + I numata + 0x00327047, // n0x0e3a c0x0000 (---------------) + I obihiro + 0x002f4ac5, // n0x0e3b c0x0000 (---------------) + I obira + 0x00270f85, // n0x0e3c c0x0000 (---------------) + I oketo + 0x00221206, // n0x0e3d c0x0000 (---------------) + I okoppe + 0x00273ec5, // n0x0e3e c0x0000 (---------------) + I otaru + 0x002c0085, // n0x0e3f c0x0000 (---------------) + I otobe + 0x002c1007, // n0x0e40 c0x0000 (---------------) + I otofuke + 0x00278489, // n0x0e41 c0x0000 (---------------) + I otoineppu + 0x002e7a04, // n0x0e42 c0x0000 (---------------) + I oumu + 0x00276f45, // n0x0e43 c0x0000 (---------------) + I ozora + 0x002d75c5, // n0x0e44 c0x0000 (---------------) + I pippu + 0x0028c188, // n0x0e45 c0x0000 (---------------) + I rankoshi + 0x002d3505, // n0x0e46 c0x0000 (---------------) + I rebun + 0x002bfcc9, // n0x0e47 c0x0000 (---------------) + I rikubetsu + 0x0029b847, // n0x0e48 c0x0000 (---------------) + I rishiri + 0x0029b84b, // n0x0e49 c0x0000 (---------------) + I rishirifuji + 0x0022cac6, // n0x0e4a c0x0000 (---------------) + I saroma + 0x00228b09, // n0x0e4b c0x0000 (---------------) + I sarufutsu + 0x00355148, // n0x0e4c c0x0000 (---------------) + I shakotan + 0x00251f05, // n0x0e4d c0x0000 (---------------) + I shari + 0x002087c8, // n0x0e4e c0x0000 (---------------) + I shibecha + 0x0023a588, // n0x0e4f c0x0000 (---------------) + I shibetsu + 0x00218687, // n0x0e50 c0x0000 (---------------) + I shikabe + 0x0027e687, // n0x0e51 c0x0000 (---------------) + I shikaoi + 0x002818c9, // n0x0e52 c0x0000 (---------------) + I shimamaki + 0x002231c7, // n0x0e53 c0x0000 (---------------) + I shimizu + 0x002592c9, // n0x0e54 c0x0000 (---------------) + I shimokawa + 0x00286c0c, // n0x0e55 c0x0000 (---------------) + I shinshinotsu + 0x0028ff08, // n0x0e56 c0x0000 (---------------) + I shintoku + 0x002a8b09, // n0x0e57 c0x0000 (---------------) + I shiranuka + 0x002aac87, // n0x0e58 c0x0000 (---------------) + I shiraoi + 0x00282209, // n0x0e59 c0x0000 (---------------) + I shiriuchi + 0x002180c7, // n0x0e5a c0x0000 (---------------) + I sobetsu + 0x00287548, // n0x0e5b c0x0000 (---------------) + I sunagawa + 0x0028c4c5, // n0x0e5c c0x0000 (---------------) + I taiki + 0x003118c6, // n0x0e5d c0x0000 (---------------) + I takasu + 0x002ba308, // n0x0e5e c0x0000 (---------------) + I takikawa + 0x002f7488, // n0x0e5f c0x0000 (---------------) + I takinoue + 0x002c25c9, // n0x0e60 c0x0000 (---------------) + I teshikaga + 0x002c00c7, // n0x0e61 c0x0000 (---------------) + I tobetsu + 0x00271905, // n0x0e62 c0x0000 (---------------) + I tohma + 0x0020ae89, // n0x0e63 c0x0000 (---------------) + I tomakomai + 0x00219c46, // n0x0e64 c0x0000 (---------------) + I tomari + 0x002902c4, // n0x0e65 c0x0000 (---------------) + I toya + 0x0034a546, // n0x0e66 c0x0000 (---------------) + I toyako + 0x002660c8, // n0x0e67 c0x0000 (---------------) + I toyotomi + 0x00269547, // n0x0e68 c0x0000 (---------------) + I toyoura + 0x0028f448, // n0x0e69 c0x0000 (---------------) + I tsubetsu + 0x0021a989, // n0x0e6a c0x0000 (---------------) + I tsukigata + 0x002dac87, // n0x0e6b c0x0000 (---------------) + I urakawa + 0x0029eb86, // n0x0e6c c0x0000 (---------------) + I urausu + 0x002045c4, // n0x0e6d c0x0000 (---------------) + I uryu + 0x00203f49, // n0x0e6e c0x0000 (---------------) + I utashinai + 0x002077c8, // n0x0e6f c0x0000 (---------------) + I wakkanai + 0x002dadc7, // n0x0e70 c0x0000 (---------------) + I wassamu + 0x00324a06, // n0x0e71 c0x0000 (---------------) + I yakumo + 0x00379906, // n0x0e72 c0x0000 (---------------) + I yoichi + 0x00206b84, // n0x0e73 c0x0000 (---------------) + I aioi + 0x002a98c6, // n0x0e74 c0x0000 (---------------) + I akashi + 0x0020af43, // n0x0e75 c0x0000 (---------------) + I ako + 0x003277c9, // n0x0e76 c0x0000 (---------------) + I amagasaki + 0x00202886, // n0x0e77 c0x0000 (---------------) + I aogaki + 0x0029c105, // n0x0e78 c0x0000 (---------------) + I asago + 0x0029f086, // n0x0e79 c0x0000 (---------------) + I ashiya + 0x002a4585, // n0x0e7a c0x0000 (---------------) + I awaji + 0x00280108, // n0x0e7b c0x0000 (---------------) + I fukusaki + 0x0024e187, // n0x0e7c c0x0000 (---------------) + I goshiki + 0x00206406, // n0x0e7d c0x0000 (---------------) + I harima + 0x00354e06, // n0x0e7e c0x0000 (---------------) + I himeji + 0x00263808, // n0x0e7f c0x0000 (---------------) + I ichikawa + 0x002a09c7, // n0x0e80 c0x0000 (---------------) + I inagawa + 0x0029ed45, // n0x0e81 c0x0000 (---------------) + I itami + 0x0029f588, // n0x0e82 c0x0000 (---------------) + I kakogawa + 0x00381248, // n0x0e83 c0x0000 (---------------) + I kamigori + 0x002e8388, // n0x0e84 c0x0000 (---------------) + I kamikawa + 0x00228f45, // n0x0e85 c0x0000 (---------------) + I kasai + 0x00311946, // n0x0e86 c0x0000 (---------------) + I kasuga + 0x002bb049, // n0x0e87 c0x0000 (---------------) + I kawanishi + 0x00290804, // n0x0e88 c0x0000 (---------------) + I miki + 0x0036b00b, // n0x0e89 c0x0000 (---------------) + I minamiawaji + 0x0021c00b, // n0x0e8a c0x0000 (---------------) + I nishinomiya + 0x002242c9, // n0x0e8b c0x0000 (---------------) + I nishiwaki + 0x0020c303, // n0x0e8c c0x0000 (---------------) + I ono + 0x00259945, // n0x0e8d c0x0000 (---------------) + I sanda + 0x00202b46, // n0x0e8e c0x0000 (---------------) + I sannan + 0x0022f208, // n0x0e8f c0x0000 (---------------) + I sasayama + 0x0022d304, // n0x0e90 c0x0000 (---------------) + I sayo + 0x0022ff06, // n0x0e91 c0x0000 (---------------) + I shingu + 0x002cc8c9, // n0x0e92 c0x0000 (---------------) + I shinonsen + 0x002bd445, // n0x0e93 c0x0000 (---------------) + I shiso + 0x002c0f46, // n0x0e94 c0x0000 (---------------) + I sumoto + 0x0023d286, // n0x0e95 c0x0000 (---------------) + I taishi + 0x002165c4, // n0x0e96 c0x0000 (---------------) + I taka + 0x00296fca, // n0x0e97 c0x0000 (---------------) + I takarazuka + 0x0029c048, // n0x0e98 c0x0000 (---------------) + I takasago + 0x002f7486, // n0x0e99 c0x0000 (---------------) + I takino + 0x00302505, // n0x0e9a c0x0000 (---------------) + I tamba + 0x0020e687, // n0x0e9b c0x0000 (---------------) + I tatsuno + 0x0025b2c7, // n0x0e9c c0x0000 (---------------) + I toyooka + 0x0034ed84, // n0x0e9d c0x0000 (---------------) + I yabu + 0x0021c247, // n0x0e9e c0x0000 (---------------) + I yashiro + 0x00203584, // n0x0e9f c0x0000 (---------------) + I yoka + 0x00203586, // n0x0ea0 c0x0000 (---------------) + I yokawa + 0x00207d83, // n0x0ea1 c0x0000 (---------------) + I ami + 0x002c0b05, // n0x0ea2 c0x0000 (---------------) + I asahi + 0x00342c85, // n0x0ea3 c0x0000 (---------------) + I bando + 0x0023d608, // n0x0ea4 c0x0000 (---------------) + I chikusei + 0x002156c5, // n0x0ea5 c0x0000 (---------------) + I daigo + 0x0027a6c9, // n0x0ea6 c0x0000 (---------------) + I fujishiro + 0x002a3e07, // n0x0ea7 c0x0000 (---------------) + I hitachi + 0x002b034b, // n0x0ea8 c0x0000 (---------------) + I hitachinaka + 0x002a3e0c, // n0x0ea9 c0x0000 (---------------) + I hitachiomiya + 0x002a4a8a, // n0x0eaa c0x0000 (---------------) + I hitachiota + 0x002c3847, // n0x0eab c0x0000 (---------------) + I ibaraki + 0x002012c3, // n0x0eac c0x0000 (---------------) + I ina + 0x00345f08, // n0x0ead c0x0000 (---------------) + I inashiki + 0x00229105, // n0x0eae c0x0000 (---------------) + I itako + 0x002bbc85, // n0x0eaf c0x0000 (---------------) + I iwama + 0x00334d84, // n0x0eb0 c0x0000 (---------------) + I joso + 0x00287446, // n0x0eb1 c0x0000 (---------------) + I kamisu + 0x0023bc06, // n0x0eb2 c0x0000 (---------------) + I kasama + 0x002a9907, // n0x0eb3 c0x0000 (---------------) + I kashima + 0x0020a40b, // n0x0eb4 c0x0000 (---------------) + I kasumigaura + 0x0021fc44, // n0x0eb5 c0x0000 (---------------) + I koga + 0x00377044, // n0x0eb6 c0x0000 (---------------) + I miho + 0x0026ff04, // n0x0eb7 c0x0000 (---------------) + I mito + 0x002c7a46, // n0x0eb8 c0x0000 (---------------) + I moriya + 0x00216044, // n0x0eb9 c0x0000 (---------------) + I naka + 0x002c1648, // n0x0eba c0x0000 (---------------) + I namegata + 0x00334b85, // n0x0ebb c0x0000 (---------------) + I oarai + 0x00230545, // n0x0ebc c0x0000 (---------------) + I ogawa + 0x0039b0c7, // n0x0ebd c0x0000 (---------------) + I omitama + 0x00204609, // n0x0ebe c0x0000 (---------------) + I ryugasaki + 0x0034a305, // n0x0ebf c0x0000 (---------------) + I sakai + 0x00370fca, // n0x0ec0 c0x0000 (---------------) + I sakuragawa + 0x002c7809, // n0x0ec1 c0x0000 (---------------) + I shimodate + 0x0026d78a, // n0x0ec2 c0x0000 (---------------) + I shimotsuma + 0x003952c9, // n0x0ec3 c0x0000 (---------------) + I shirosato + 0x0032d484, // n0x0ec4 c0x0000 (---------------) + I sowa + 0x002fcd45, // n0x0ec5 c0x0000 (---------------) + I suifu + 0x002cfe88, // n0x0ec6 c0x0000 (---------------) + I takahagi + 0x0037394b, // n0x0ec7 c0x0000 (---------------) + I tamatsukuri + 0x002f91c5, // n0x0ec8 c0x0000 (---------------) + I tokai + 0x00285f06, // n0x0ec9 c0x0000 (---------------) + I tomobe + 0x0021e584, // n0x0eca c0x0000 (---------------) + I tone + 0x0027ac06, // n0x0ecb c0x0000 (---------------) + I toride + 0x002dab09, // n0x0ecc c0x0000 (---------------) + I tsuchiura + 0x00227787, // n0x0ecd c0x0000 (---------------) + I tsukuba + 0x0030df88, // n0x0ece c0x0000 (---------------) + I uchihara + 0x00244706, // n0x0ecf c0x0000 (---------------) + I ushiku + 0x002ff047, // n0x0ed0 c0x0000 (---------------) + I yachiyo + 0x002815c8, // n0x0ed1 c0x0000 (---------------) + I yamagata + 0x00384c06, // n0x0ed2 c0x0000 (---------------) + I yawara + 0x00253884, // n0x0ed3 c0x0000 (---------------) + I yuki + 0x0035d647, // n0x0ed4 c0x0000 (---------------) + I anamizu + 0x00343a45, // n0x0ed5 c0x0000 (---------------) + I hakui + 0x00348747, // n0x0ed6 c0x0000 (---------------) + I hakusan + 0x00201b44, // n0x0ed7 c0x0000 (---------------) + I kaga + 0x0034f546, // n0x0ed8 c0x0000 (---------------) + I kahoku + 0x0021b548, // n0x0ed9 c0x0000 (---------------) + I kanazawa + 0x00296bc8, // n0x0eda c0x0000 (---------------) + I kawakita + 0x002ab807, // n0x0edb c0x0000 (---------------) + I komatsu + 0x003288c8, // n0x0edc c0x0000 (---------------) + I nakanoto + 0x002b6005, // n0x0edd c0x0000 (---------------) + I nanao + 0x0020c144, // n0x0ede c0x0000 (---------------) + I nomi + 0x00263708, // n0x0edf c0x0000 (---------------) + I nonoichi + 0x00257ec4, // n0x0ee0 c0x0000 (---------------) + I noto + 0x00216485, // n0x0ee1 c0x0000 (---------------) + I shika + 0x002ea3c4, // n0x0ee2 c0x0000 (---------------) + I suzu + 0x0023e207, // n0x0ee3 c0x0000 (---------------) + I tsubata + 0x0028aa07, // n0x0ee4 c0x0000 (---------------) + I tsurugi + 0x00282348, // n0x0ee5 c0x0000 (---------------) + I uchinada + 0x002a45c6, // n0x0ee6 c0x0000 (---------------) + I wajima + 0x00215645, // n0x0ee7 c0x0000 (---------------) + I fudai + 0x0027a4c8, // n0x0ee8 c0x0000 (---------------) + I fujisawa + 0x003538c8, // n0x0ee9 c0x0000 (---------------) + I hanamaki + 0x002a0249, // n0x0eea c0x0000 (---------------) + I hiraizumi + 0x0021c306, // n0x0eeb c0x0000 (---------------) + I hirono + 0x00236a88, // n0x0eec c0x0000 (---------------) + I ichinohe + 0x00282aca, // n0x0eed c0x0000 (---------------) + I ichinoseki + 0x002f1a88, // n0x0eee c0x0000 (---------------) + I iwaizumi + 0x002d7d45, // n0x0eef c0x0000 (---------------) + I iwate + 0x00227f86, // n0x0ef0 c0x0000 (---------------) + I joboji + 0x0028fb08, // n0x0ef1 c0x0000 (---------------) + I kamaishi + 0x0035c6ca, // n0x0ef2 c0x0000 (---------------) + I kanegasaki + 0x00269ec7, // n0x0ef3 c0x0000 (---------------) + I karumai + 0x00287b45, // n0x0ef4 c0x0000 (---------------) + I kawai + 0x00295bc8, // n0x0ef5 c0x0000 (---------------) + I kitakami + 0x003a2804, // n0x0ef6 c0x0000 (---------------) + I kuji + 0x002ae486, // n0x0ef7 c0x0000 (---------------) + I kunohe + 0x002bcfc8, // n0x0ef8 c0x0000 (---------------) + I kuzumaki + 0x0020c1c6, // n0x0ef9 c0x0000 (---------------) + I miyako + 0x002f3888, // n0x0efa c0x0000 (---------------) + I mizusawa + 0x0021a207, // n0x0efb c0x0000 (---------------) + I morioka + 0x00209286, // n0x0efc c0x0000 (---------------) + I ninohe + 0x0037d844, // n0x0efd c0x0000 (---------------) + I noda + 0x002d97c7, // n0x0efe c0x0000 (---------------) + I ofunato + 0x002fac04, // n0x0eff c0x0000 (---------------) + I oshu + 0x002daac7, // n0x0f00 c0x0000 (---------------) + I otsuchi + 0x0037860d, // n0x0f01 c0x0000 (---------------) + I rikuzentakata + 0x00203345, // n0x0f02 c0x0000 (---------------) + I shiwa + 0x002af08b, // n0x0f03 c0x0000 (---------------) + I shizukuishi + 0x002a21c6, // n0x0f04 c0x0000 (---------------) + I sumita + 0x00252c48, // n0x0f05 c0x0000 (---------------) + I tanohata + 0x00387b44, // n0x0f06 c0x0000 (---------------) + I tono + 0x00276d06, // n0x0f07 c0x0000 (---------------) + I yahaba + 0x0027d386, // n0x0f08 c0x0000 (---------------) + I yamada + 0x00207687, // n0x0f09 c0x0000 (---------------) + I ayagawa + 0x0029624d, // n0x0f0a c0x0000 (---------------) + I higashikagawa + 0x00312347, // n0x0f0b c0x0000 (---------------) + I kanonji + 0x00300fc8, // n0x0f0c c0x0000 (---------------) + I kotohira + 0x0035ea45, // n0x0f0d c0x0000 (---------------) + I manno + 0x00298248, // n0x0f0e c0x0000 (---------------) + I marugame + 0x002c1f06, // n0x0f0f c0x0000 (---------------) + I mitoyo + 0x002b6088, // n0x0f10 c0x0000 (---------------) + I naoshima + 0x00210f86, // n0x0f11 c0x0000 (---------------) + I sanuki + 0x003541c7, // n0x0f12 c0x0000 (---------------) + I tadotsu + 0x0021d509, // n0x0f13 c0x0000 (---------------) + I takamatsu + 0x00387b47, // n0x0f14 c0x0000 (---------------) + I tonosho + 0x00289bc8, // n0x0f15 c0x0000 (---------------) + I uchinomi + 0x00273545, // n0x0f16 c0x0000 (---------------) + I utazu + 0x0021e8c8, // n0x0f17 c0x0000 (---------------) + I zentsuji + 0x00326185, // n0x0f18 c0x0000 (---------------) + I akune + 0x00240f45, // n0x0f19 c0x0000 (---------------) + I amami + 0x002e5945, // n0x0f1a c0x0000 (---------------) + I hioki + 0x00226dc3, // n0x0f1b c0x0000 (---------------) + I isa + 0x00283644, // n0x0f1c c0x0000 (---------------) + I isen + 0x0027e805, // n0x0f1d c0x0000 (---------------) + I izumi + 0x00275f89, // n0x0f1e c0x0000 (---------------) + I kagoshima + 0x002b1546, // n0x0f1f c0x0000 (---------------) + I kanoya + 0x002d4308, // n0x0f20 c0x0000 (---------------) + I kawanabe + 0x0035c8c5, // n0x0f21 c0x0000 (---------------) + I kinko + 0x0032bd87, // n0x0f22 c0x0000 (---------------) + I kouyama + 0x003544ca, // n0x0f23 c0x0000 (---------------) + I makurazaki + 0x002c0e89, // n0x0f24 c0x0000 (---------------) + I matsumoto + 0x002b314a, // n0x0f25 c0x0000 (---------------) + I minamitane + 0x002cd408, // n0x0f26 c0x0000 (---------------) + I nakatane + 0x0021cdcc, // n0x0f27 c0x0000 (---------------) + I nishinoomote + 0x0028334d, // n0x0f28 c0x0000 (---------------) + I satsumasendai + 0x002edf43, // n0x0f29 c0x0000 (---------------) + I soo + 0x002f3788, // n0x0f2a c0x0000 (---------------) + I tarumizu + 0x0020b5c5, // n0x0f2b c0x0000 (---------------) + I yusui + 0x00351fc6, // n0x0f2c c0x0000 (---------------) + I aikawa + 0x00376c46, // n0x0f2d c0x0000 (---------------) + I atsugi + 0x0024cf45, // n0x0f2e c0x0000 (---------------) + I ayase + 0x0033c6c9, // n0x0f2f c0x0000 (---------------) + I chigasaki + 0x00324c05, // n0x0f30 c0x0000 (---------------) + I ebina + 0x0027a4c8, // n0x0f31 c0x0000 (---------------) + I fujisawa + 0x00257dc6, // n0x0f32 c0x0000 (---------------) + I hadano + 0x00338fc6, // n0x0f33 c0x0000 (---------------) + I hakone + 0x002a1949, // n0x0f34 c0x0000 (---------------) + I hiratsuka + 0x00384407, // n0x0f35 c0x0000 (---------------) + I isehara + 0x002f2a86, // n0x0f36 c0x0000 (---------------) + I kaisei + 0x00354448, // n0x0f37 c0x0000 (---------------) + I kamakura + 0x00203508, // n0x0f38 c0x0000 (---------------) + I kiyokawa + 0x002d1c87, // n0x0f39 c0x0000 (---------------) + I matsuda + 0x0022340e, // n0x0f3a c0x0000 (---------------) + I minamiashigara + 0x002c2145, // n0x0f3b c0x0000 (---------------) + I miura + 0x0026a505, // n0x0f3c c0x0000 (---------------) + I nakai + 0x0020c0c8, // n0x0f3d c0x0000 (---------------) + I ninomiya + 0x0036c2c7, // n0x0f3e c0x0000 (---------------) + I odawara + 0x00206c02, // n0x0f3f c0x0000 (---------------) + I oi + 0x002b9784, // n0x0f40 c0x0000 (---------------) + I oiso + 0x00399fca, // n0x0f41 c0x0000 (---------------) + I sagamihara + 0x002dae88, // n0x0f42 c0x0000 (---------------) + I samukawa + 0x00281046, // n0x0f43 c0x0000 (---------------) + I tsukui + 0x00298948, // n0x0f44 c0x0000 (---------------) + I yamakita + 0x00290986, // n0x0f45 c0x0000 (---------------) + I yamato + 0x00325b48, // n0x0f46 c0x0000 (---------------) + I yokosuka + 0x002ad708, // n0x0f47 c0x0000 (---------------) + I yugawara + 0x00240f04, // n0x0f48 c0x0000 (---------------) + I zama + 0x0032f185, // n0x0f49 c0x0000 (---------------) + I zushi + 0x00685804, // n0x0f4a c0x0001 (---------------) ! I city + 0x00685804, // n0x0f4b c0x0001 (---------------) ! I city + 0x00685804, // n0x0f4c c0x0001 (---------------) ! I city + 0x00202943, // n0x0f4d c0x0000 (---------------) + I aki + 0x00379786, // n0x0f4e c0x0000 (---------------) + I geisei + 0x0027a986, // n0x0f4f c0x0000 (---------------) + I hidaka + 0x0029e3cc, // n0x0f50 c0x0000 (---------------) + I higashitsuno + 0x002092c3, // n0x0f51 c0x0000 (---------------) + I ino + 0x002bdd86, // n0x0f52 c0x0000 (---------------) + I kagami + 0x002160c4, // n0x0f53 c0x0000 (---------------) + I kami + 0x002c3988, // n0x0f54 c0x0000 (---------------) + I kitagawa + 0x002cc705, // n0x0f55 c0x0000 (---------------) + I kochi + 0x0039a0c6, // n0x0f56 c0x0000 (---------------) + I mihara + 0x002b5548, // n0x0f57 c0x0000 (---------------) + I motoyama + 0x002ce386, // n0x0f58 c0x0000 (---------------) + I muroto + 0x00206386, // n0x0f59 c0x0000 (---------------) + I nahari + 0x0035e6c8, // n0x0f5a c0x0000 (---------------) + I nakamura + 0x002a2447, // n0x0f5b c0x0000 (---------------) + I nankoku + 0x00222f89, // n0x0f5c c0x0000 (---------------) + I nishitosa + 0x0023040a, // n0x0f5d c0x0000 (---------------) + I niyodogawa + 0x00247c84, // n0x0f5e c0x0000 (---------------) + I ochi + 0x002035c5, // n0x0f5f c0x0000 (---------------) + I okawa + 0x0025c245, // n0x0f60 c0x0000 (---------------) + I otoyo + 0x0021d106, // n0x0f61 c0x0000 (---------------) + I otsuki + 0x00247f46, // n0x0f62 c0x0000 (---------------) + I sakawa + 0x002a7846, // n0x0f63 c0x0000 (---------------) + I sukumo + 0x002e9706, // n0x0f64 c0x0000 (---------------) + I susaki + 0x002230c4, // n0x0f65 c0x0000 (---------------) + I tosa + 0x002230cb, // n0x0f66 c0x0000 (---------------) + I tosashimizu + 0x002472c4, // n0x0f67 c0x0000 (---------------) + I toyo + 0x0020e705, // n0x0f68 c0x0000 (---------------) + I tsuno + 0x002ac705, // n0x0f69 c0x0000 (---------------) + I umaji + 0x0027eb86, // n0x0f6a c0x0000 (---------------) + I yasuda + 0x00202208, // n0x0f6b c0x0000 (---------------) + I yusuhara + 0x00283207, // n0x0f6c c0x0000 (---------------) + I amakusa + 0x0030dd44, // n0x0f6d c0x0000 (---------------) + I arao + 0x00262cc3, // n0x0f6e c0x0000 (---------------) + I aso + 0x003a2305, // n0x0f6f c0x0000 (---------------) + I choyo + 0x0024a4c7, // n0x0f70 c0x0000 (---------------) + I gyokuto + 0x002a5809, // n0x0f71 c0x0000 (---------------) + I hitoyoshi + 0x0028310b, // n0x0f72 c0x0000 (---------------) + I kamiamakusa + 0x002a9907, // n0x0f73 c0x0000 (---------------) + I kashima + 0x0023d507, // n0x0f74 c0x0000 (---------------) + I kikuchi + 0x002ddc44, // n0x0f75 c0x0000 (---------------) + I kosa + 0x002b5448, // n0x0f76 c0x0000 (---------------) + I kumamoto + 0x002aba87, // n0x0f77 c0x0000 (---------------) + I mashiki + 0x002a5a46, // n0x0f78 c0x0000 (---------------) + I mifune + 0x00253608, // n0x0f79 c0x0000 (---------------) + I minamata + 0x002a7a4b, // n0x0f7a c0x0000 (---------------) + I minamioguni + 0x00360ec6, // n0x0f7b c0x0000 (---------------) + I nagasu + 0x00210cc9, // n0x0f7c c0x0000 (---------------) + I nishihara + 0x002a7bc5, // n0x0f7d c0x0000 (---------------) + I oguni + 0x002ffa83, // n0x0f7e c0x0000 (---------------) + I ozu + 0x002c0f46, // n0x0f7f c0x0000 (---------------) + I sumoto + 0x0021a108, // n0x0f80 c0x0000 (---------------) + I takamori + 0x00211043, // n0x0f81 c0x0000 (---------------) + I uki + 0x00229f83, // n0x0f82 c0x0000 (---------------) + I uto + 0x00227446, // n0x0f83 c0x0000 (---------------) + I yamaga + 0x00290986, // n0x0f84 c0x0000 (---------------) + I yamato + 0x00380c0a, // n0x0f85 c0x0000 (---------------) + I yatsushiro + 0x0027cb05, // n0x0f86 c0x0000 (---------------) + I ayabe + 0x0027d1cb, // n0x0f87 c0x0000 (---------------) + I fukuchiyama + 0x0029efcb, // n0x0f88 c0x0000 (---------------) + I higashiyama + 0x0022ab43, // n0x0f89 c0x0000 (---------------) + I ide + 0x00220b03, // n0x0f8a c0x0000 (---------------) + I ine + 0x002af884, // n0x0f8b c0x0000 (---------------) + I joyo + 0x0021a507, // n0x0f8c c0x0000 (---------------) + I kameoka + 0x0021a184, // n0x0f8d c0x0000 (---------------) + I kamo + 0x002047c4, // n0x0f8e c0x0000 (---------------) + I kita + 0x002faf84, // n0x0f8f c0x0000 (---------------) + I kizu + 0x002f1d88, // n0x0f90 c0x0000 (---------------) + I kumiyama + 0x00302448, // n0x0f91 c0x0000 (---------------) + I kyotamba + 0x00308709, // n0x0f92 c0x0000 (---------------) + I kyotanabe + 0x00342288, // n0x0f93 c0x0000 (---------------) + I kyotango + 0x002d2e87, // n0x0f94 c0x0000 (---------------) + I maizuru + 0x00223406, // n0x0f95 c0x0000 (---------------) + I minami + 0x002d3f4f, // n0x0f96 c0x0000 (---------------) + I minamiyamashiro + 0x002c2286, // n0x0f97 c0x0000 (---------------) + I miyazu + 0x002cc684, // n0x0f98 c0x0000 (---------------) + I muko + 0x0030228a, // n0x0f99 c0x0000 (---------------) + I nagaokakyo + 0x0024a3c7, // n0x0f9a c0x0000 (---------------) + I nakagyo + 0x00203b86, // n0x0f9b c0x0000 (---------------) + I nantan + 0x00290309, // n0x0f9c c0x0000 (---------------) + I oyamazaki + 0x00308685, // n0x0f9d c0x0000 (---------------) + I sakyo + 0x0023d745, // n0x0f9e c0x0000 (---------------) + I seika + 0x003087c6, // n0x0f9f c0x0000 (---------------) + I tanabe + 0x0021ea03, // n0x0fa0 c0x0000 (---------------) + I uji + 0x003a2849, // n0x0fa1 c0x0000 (---------------) + I ujitawara + 0x0021b446, // n0x0fa2 c0x0000 (---------------) + I wazuka + 0x0021a749, // n0x0fa3 c0x0000 (---------------) + I yamashina + 0x0038e686, // n0x0fa4 c0x0000 (---------------) + I yawata + 0x002c0b05, // n0x0fa5 c0x0000 (---------------) + I asahi + 0x00226f45, // n0x0fa6 c0x0000 (---------------) + I inabe + 0x00204e83, // n0x0fa7 c0x0000 (---------------) + I ise + 0x0021a648, // n0x0fa8 c0x0000 (---------------) + I kameyama + 0x00398b87, // n0x0fa9 c0x0000 (---------------) + I kawagoe + 0x002f1744, // n0x0faa c0x0000 (---------------) + I kiho + 0x0021d208, // n0x0fab c0x0000 (---------------) + I kisosaki + 0x002a8e04, // n0x0fac c0x0000 (---------------) + I kiwa + 0x002b4486, // n0x0fad c0x0000 (---------------) + I komono + 0x0027f446, // n0x0fae c0x0000 (---------------) + I kumano + 0x00243186, // n0x0faf c0x0000 (---------------) + I kuwana + 0x002c7bc9, // n0x0fb0 c0x0000 (---------------) + I matsusaka + 0x002bbc05, // n0x0fb1 c0x0000 (---------------) + I meiwa + 0x002a9086, // n0x0fb2 c0x0000 (---------------) + I mihama + 0x0025afc9, // n0x0fb3 c0x0000 (---------------) + I minamiise + 0x002c13c6, // n0x0fb4 c0x0000 (---------------) + I misugi + 0x002d4046, // n0x0fb5 c0x0000 (---------------) + I miyama + 0x0037dbc6, // n0x0fb6 c0x0000 (---------------) + I nabari + 0x00209f45, // n0x0fb7 c0x0000 (---------------) + I shima + 0x002ea3c6, // n0x0fb8 c0x0000 (---------------) + I suzuka + 0x003541c4, // n0x0fb9 c0x0000 (---------------) + I tado + 0x0028c4c5, // n0x0fba c0x0000 (---------------) + I taiki + 0x002ba304, // n0x0fbb c0x0000 (---------------) + I taki + 0x0030c206, // n0x0fbc c0x0000 (---------------) + I tamaki + 0x00395484, // n0x0fbd c0x0000 (---------------) + I toba + 0x00207a43, // n0x0fbe c0x0000 (---------------) + I tsu + 0x00287805, // n0x0fbf c0x0000 (---------------) + I udono + 0x0023a288, // n0x0fc0 c0x0000 (---------------) + I ureshino + 0x0022e387, // n0x0fc1 c0x0000 (---------------) + I watarai + 0x002b3b09, // n0x0fc2 c0x0000 (---------------) + I yokkaichi + 0x00287a48, // n0x0fc3 c0x0000 (---------------) + I furukawa + 0x00297e91, // n0x0fc4 c0x0000 (---------------) + I higashimatsushima + 0x0023d30a, // n0x0fc5 c0x0000 (---------------) + I ishinomaki + 0x0022d707, // n0x0fc6 c0x0000 (---------------) + I iwanuma + 0x003990c6, // n0x0fc7 c0x0000 (---------------) + I kakuda + 0x002160c4, // n0x0fc8 c0x0000 (---------------) + I kami + 0x002ba408, // n0x0fc9 c0x0000 (---------------) + I kawasaki + 0x00294e89, // n0x0fca c0x0000 (---------------) + I kesennuma + 0x002a9a48, // n0x0fcb c0x0000 (---------------) + I marumori + 0x0029804a, // n0x0fcc c0x0000 (---------------) + I matsushima + 0x002bfa8d, // n0x0fcd c0x0000 (---------------) + I minamisanriku + 0x0022da46, // n0x0fce c0x0000 (---------------) + I misato + 0x0035e7c6, // n0x0fcf c0x0000 (---------------) + I murata + 0x002d9886, // n0x0fd0 c0x0000 (---------------) + I natori + 0x00373fc7, // n0x0fd1 c0x0000 (---------------) + I ogawara + 0x002a0705, // n0x0fd2 c0x0000 (---------------) + I ohira + 0x0034eb47, // n0x0fd3 c0x0000 (---------------) + I onagawa + 0x0021d2c5, // n0x0fd4 c0x0000 (---------------) + I osaki + 0x0029b984, // n0x0fd5 c0x0000 (---------------) + I rifu + 0x002aa106, // n0x0fd6 c0x0000 (---------------) + I semine + 0x00311787, // n0x0fd7 c0x0000 (---------------) + I shibata + 0x003a254d, // n0x0fd8 c0x0000 (---------------) + I shichikashuku + 0x0028fa47, // n0x0fd9 c0x0000 (---------------) + I shikama + 0x002701c8, // n0x0fda c0x0000 (---------------) + I shiogama + 0x0027a7c9, // n0x0fdb c0x0000 (---------------) + I shiroishi + 0x00227e86, // n0x0fdc c0x0000 (---------------) + I tagajo + 0x002399c5, // n0x0fdd c0x0000 (---------------) + I taiwa + 0x00213604, // n0x0fde c0x0000 (---------------) + I tome + 0x002661c6, // n0x0fdf c0x0000 (---------------) + I tomiya + 0x0034ec86, // n0x0fe0 c0x0000 (---------------) + I wakuya + 0x002db006, // n0x0fe1 c0x0000 (---------------) + I watari + 0x0029b348, // n0x0fe2 c0x0000 (---------------) + I yamamoto + 0x002126c3, // n0x0fe3 c0x0000 (---------------) + I zao + 0x00207683, // n0x0fe4 c0x0000 (---------------) + I aya + 0x00325f05, // n0x0fe5 c0x0000 (---------------) + I ebino + 0x0023c086, // n0x0fe6 c0x0000 (---------------) + I gokase + 0x002ad6c5, // n0x0fe7 c0x0000 (---------------) + I hyuga + 0x00244908, // n0x0fe8 c0x0000 (---------------) + I kadogawa + 0x0029dd8a, // n0x0fe9 c0x0000 (---------------) + I kawaminami + 0x002e3544, // n0x0fea c0x0000 (---------------) + I kijo + 0x002c3988, // n0x0feb c0x0000 (---------------) + I kitagawa + 0x00296e48, // n0x0fec c0x0000 (---------------) + I kitakata + 0x0027e9c7, // n0x0fed c0x0000 (---------------) + I kitaura + 0x0035c989, // n0x0fee c0x0000 (---------------) + I kobayashi + 0x002b5148, // n0x0fef c0x0000 (---------------) + I kunitomi + 0x00290087, // n0x0ff0 c0x0000 (---------------) + I kushima + 0x0029c906, // n0x0ff1 c0x0000 (---------------) + I mimata + 0x0020c1ca, // n0x0ff2 c0x0000 (---------------) + I miyakonojo + 0x00266248, // n0x0ff3 c0x0000 (---------------) + I miyazaki + 0x002ba909, // n0x0ff4 c0x0000 (---------------) + I morotsuka + 0x00272c08, // n0x0ff5 c0x0000 (---------------) + I nichinan + 0x0021bac9, // n0x0ff6 c0x0000 (---------------) + I nishimera + 0x002bad87, // n0x0ff7 c0x0000 (---------------) + I nobeoka + 0x00342145, // n0x0ff8 c0x0000 (---------------) + I saito + 0x002a2ec6, // n0x0ff9 c0x0000 (---------------) + I shiiba + 0x00292c08, // n0x0ffa c0x0000 (---------------) + I shintomi + 0x00252dc8, // n0x0ffb c0x0000 (---------------) + I takaharu + 0x0021ab48, // n0x0ffc c0x0000 (---------------) + I takanabe + 0x002165c8, // n0x0ffd c0x0000 (---------------) + I takazaki + 0x0020e705, // n0x0ffe c0x0000 (---------------) + I tsuno + 0x00200344, // n0x0fff c0x0000 (---------------) + I achi + 0x00398888, // n0x1000 c0x0000 (---------------) + I agematsu + 0x00203c84, // n0x1001 c0x0000 (---------------) + I anan + 0x003950c4, // n0x1002 c0x0000 (---------------) + I aoki + 0x002c0b05, // n0x1003 c0x0000 (---------------) + I asahi + 0x002918c7, // n0x1004 c0x0000 (---------------) + I azumino + 0x002043c9, // n0x1005 c0x0000 (---------------) + I chikuhoku + 0x00207487, // n0x1006 c0x0000 (---------------) + I chikuma + 0x0020ee05, // n0x1007 c0x0000 (---------------) + I chino + 0x00278086, // n0x1008 c0x0000 (---------------) + I fujimi + 0x0033c0c6, // n0x1009 c0x0000 (---------------) + I hakuba + 0x00202304, // n0x100a c0x0000 (---------------) + I hara + 0x002a1c86, // n0x100b c0x0000 (---------------) + I hiraya + 0x00215484, // n0x100c c0x0000 (---------------) + I iida + 0x00257606, // n0x100d c0x0000 (---------------) + I iijima + 0x003a3986, // n0x100e c0x0000 (---------------) + I iiyama + 0x002144c6, // n0x100f c0x0000 (---------------) + I iizuna + 0x00202445, // n0x1010 c0x0000 (---------------) + I ikeda + 0x002447c7, // n0x1011 c0x0000 (---------------) + I ikusaka + 0x002012c3, // n0x1012 c0x0000 (---------------) + I ina + 0x00248c49, // n0x1013 c0x0000 (---------------) + I karuizawa + 0x002f2788, // n0x1014 c0x0000 (---------------) + I kawakami + 0x0021d204, // n0x1015 c0x0000 (---------------) + I kiso + 0x003546cd, // n0x1016 c0x0000 (---------------) + I kisofukushima + 0x00296cc8, // n0x1017 c0x0000 (---------------) + I kitaaiki + 0x0028d488, // n0x1018 c0x0000 (---------------) + I komagane + 0x002ba886, // n0x1019 c0x0000 (---------------) + I komoro + 0x0021d609, // n0x101a c0x0000 (---------------) + I matsukawa + 0x002c0e89, // n0x101b c0x0000 (---------------) + I matsumoto + 0x002da805, // n0x101c c0x0000 (---------------) + I miasa + 0x0029de8a, // n0x101d c0x0000 (---------------) + I minamiaiki + 0x002805ca, // n0x101e c0x0000 (---------------) + I minamimaki + 0x0028abcc, // n0x101f c0x0000 (---------------) + I minamiminowa + 0x0028ad46, // n0x1020 c0x0000 (---------------) + I minowa + 0x00278946, // n0x1021 c0x0000 (---------------) + I miyada + 0x002c2b06, // n0x1022 c0x0000 (---------------) + I miyota + 0x0024bf89, // n0x1023 c0x0000 (---------------) + I mochizuki + 0x00352206, // n0x1024 c0x0000 (---------------) + I nagano + 0x002875c6, // n0x1025 c0x0000 (---------------) + I nagawa + 0x00324cc6, // n0x1026 c0x0000 (---------------) + I nagiso + 0x002b0508, // n0x1027 c0x0000 (---------------) + I nakagawa + 0x003288c6, // n0x1028 c0x0000 (---------------) + I nakano + 0x002c7f0b, // n0x1029 c0x0000 (---------------) + I nozawaonsen + 0x00291a45, // n0x102a c0x0000 (---------------) + I obuse + 0x00230545, // n0x102b c0x0000 (---------------) + I ogawa + 0x00278bc5, // n0x102c c0x0000 (---------------) + I okaya + 0x002013c6, // n0x102d c0x0000 (---------------) + I omachi + 0x0020c183, // n0x102e c0x0000 (---------------) + I omi + 0x00243106, // n0x102f c0x0000 (---------------) + I ookuwa + 0x0028f9c7, // n0x1030 c0x0000 (---------------) + I ooshika + 0x002ba2c5, // n0x1031 c0x0000 (---------------) + I otaki + 0x00264245, // n0x1032 c0x0000 (---------------) + I otari + 0x002e2d05, // n0x1033 c0x0000 (---------------) + I sakae + 0x0031ac86, // n0x1034 c0x0000 (---------------) + I sakaki + 0x002da8c4, // n0x1035 c0x0000 (---------------) + I saku + 0x0036a506, // n0x1036 c0x0000 (---------------) + I sakuho + 0x00265b89, // n0x1037 c0x0000 (---------------) + I shimosuwa + 0x0020124c, // n0x1038 c0x0000 (---------------) + I shinanomachi + 0x0029b6c8, // n0x1039 c0x0000 (---------------) + I shiojiri + 0x00265cc4, // n0x103a c0x0000 (---------------) + I suwa + 0x002ea046, // n0x103b c0x0000 (---------------) + I suzaka + 0x002a22c6, // n0x103c c0x0000 (---------------) + I takagi + 0x0021a108, // n0x103d c0x0000 (---------------) + I takamori + 0x002c17c8, // n0x103e c0x0000 (---------------) + I takayama + 0x00201149, // n0x103f c0x0000 (---------------) + I tateshina + 0x0020e687, // n0x1040 c0x0000 (---------------) + I tatsuno + 0x002b0d09, // n0x1041 c0x0000 (---------------) + I togakushi + 0x00271046, // n0x1042 c0x0000 (---------------) + I togura + 0x0022d9c4, // n0x1043 c0x0000 (---------------) + I tomi + 0x0020f404, // n0x1044 c0x0000 (---------------) + I ueda + 0x00255d44, // n0x1045 c0x0000 (---------------) + I wada + 0x002815c8, // n0x1046 c0x0000 (---------------) + I yamagata + 0x0020420a, // n0x1047 c0x0000 (---------------) + I yamanouchi + 0x0034a286, // n0x1048 c0x0000 (---------------) + I yasaka + 0x00350687, // n0x1049 c0x0000 (---------------) + I yasuoka + 0x00288747, // n0x104a c0x0000 (---------------) + I chijiwa + 0x00228c05, // n0x104b c0x0000 (---------------) + I futsu + 0x00285bc4, // n0x104c c0x0000 (---------------) + I goto + 0x0028e206, // n0x104d c0x0000 (---------------) + I hasami + 0x003010c6, // n0x104e c0x0000 (---------------) + I hirado + 0x0023a783, // n0x104f c0x0000 (---------------) + I iki + 0x002f25c7, // n0x1050 c0x0000 (---------------) + I isahaya + 0x00331d48, // n0x1051 c0x0000 (---------------) + I kawatana + 0x002da94a, // n0x1052 c0x0000 (---------------) + I kuchinotsu + 0x002cb708, // n0x1053 c0x0000 (---------------) + I matsuura + 0x002e33c8, // n0x1054 c0x0000 (---------------) + I nagasaki + 0x003954c5, // n0x1055 c0x0000 (---------------) + I obama + 0x00374685, // n0x1056 c0x0000 (---------------) + I omura + 0x002b0c45, // n0x1057 c0x0000 (---------------) + I oseto + 0x00228fc6, // n0x1058 c0x0000 (---------------) + I saikai + 0x0023db86, // n0x1059 c0x0000 (---------------) + I sasebo + 0x00217ec5, // n0x105a c0x0000 (---------------) + I seihi + 0x00327a09, // n0x105b c0x0000 (---------------) + I shimabara + 0x002859cc, // n0x105c c0x0000 (---------------) + I shinkamigoto + 0x002352c7, // n0x105d c0x0000 (---------------) + I togitsu + 0x002980c8, // n0x105e c0x0000 (---------------) + I tsushima + 0x0028e845, // n0x105f c0x0000 (---------------) + I unzen + 0x00685804, // n0x1060 c0x0001 (---------------) ! I city + 0x002293c4, // n0x1061 c0x0000 (---------------) + I ando + 0x002af3c4, // n0x1062 c0x0000 (---------------) + I gose + 0x0020ef46, // n0x1063 c0x0000 (---------------) + I heguri + 0x0029fb4e, // n0x1064 c0x0000 (---------------) + I higashiyoshino + 0x0023d7c7, // n0x1065 c0x0000 (---------------) + I ikaruga + 0x0028d445, // n0x1066 c0x0000 (---------------) + I ikoma + 0x0029078c, // n0x1067 c0x0000 (---------------) + I kamikitayama + 0x002a8cc7, // n0x1068 c0x0000 (---------------) + I kanmaki + 0x00311707, // n0x1069 c0x0000 (---------------) + I kashiba + 0x003825c9, // n0x106a c0x0000 (---------------) + I kashihara + 0x00219889, // n0x106b c0x0000 (---------------) + I katsuragi + 0x00287b45, // n0x106c c0x0000 (---------------) + I kawai + 0x002f2788, // n0x106d c0x0000 (---------------) + I kawakami + 0x002bb049, // n0x106e c0x0000 (---------------) + I kawanishi + 0x002d8005, // n0x106f c0x0000 (---------------) + I koryo + 0x002ba208, // n0x1070 c0x0000 (---------------) + I kurotaki + 0x002c84c6, // n0x1071 c0x0000 (---------------) + I mitsue + 0x002d3946, // n0x1072 c0x0000 (---------------) + I miyake + 0x0031c044, // n0x1073 c0x0000 (---------------) + I nara + 0x00325fc8, // n0x1074 c0x0000 (---------------) + I nosegawa + 0x00228043, // n0x1075 c0x0000 (---------------) + I oji + 0x00207fc4, // n0x1076 c0x0000 (---------------) + I ouda + 0x003a2385, // n0x1077 c0x0000 (---------------) + I oyodo + 0x002dc647, // n0x1078 c0x0000 (---------------) + I sakurai + 0x003a3fc5, // n0x1079 c0x0000 (---------------) + I sango + 0x00282989, // n0x107a c0x0000 (---------------) + I shimoichi + 0x0025becd, // n0x107b c0x0000 (---------------) + I shimokitayama + 0x0027b106, // n0x107c c0x0000 (---------------) + I shinjo + 0x00262d04, // n0x107d c0x0000 (---------------) + I soni + 0x0029ca08, // n0x107e c0x0000 (---------------) + I takatori + 0x002782ca, // n0x107f c0x0000 (---------------) + I tawaramoto + 0x00218dc7, // n0x1080 c0x0000 (---------------) + I tenkawa + 0x00320785, // n0x1081 c0x0000 (---------------) + I tenri + 0x00208003, // n0x1082 c0x0000 (---------------) + I uda + 0x0029f18e, // n0x1083 c0x0000 (---------------) + I yamatokoriyama + 0x0029098c, // n0x1084 c0x0000 (---------------) + I yamatotakada + 0x002f9507, // n0x1085 c0x0000 (---------------) + I yamazoe + 0x0029fd07, // n0x1086 c0x0000 (---------------) + I yoshino + 0x00201b83, // n0x1087 c0x0000 (---------------) + I aga + 0x00352245, // n0x1088 c0x0000 (---------------) + I agano + 0x002af3c5, // n0x1089 c0x0000 (---------------) + I gosen + 0x00298d08, // n0x108a c0x0000 (---------------) + I itoigawa + 0x00295a09, // n0x108b c0x0000 (---------------) + I izumozaki + 0x00294706, // n0x108c c0x0000 (---------------) + I joetsu + 0x0021a184, // n0x108d c0x0000 (---------------) + I kamo + 0x0022d646, // n0x108e c0x0000 (---------------) + I kariwa + 0x002032cb, // n0x108f c0x0000 (---------------) + I kashiwazaki + 0x002c730c, // n0x1090 c0x0000 (---------------) + I minamiuonuma + 0x002f4ec7, // n0x1091 c0x0000 (---------------) + I mitsuke + 0x002cc3c5, // n0x1092 c0x0000 (---------------) + I muika + 0x00381148, // n0x1093 c0x0000 (---------------) + I murakami + 0x002d1a45, // n0x1094 c0x0000 (---------------) + I myoko + 0x00302287, // n0x1095 c0x0000 (---------------) + I nagaoka + 0x002350c7, // n0x1096 c0x0000 (---------------) + I niigata + 0x0024f885, // n0x1097 c0x0000 (---------------) + I ojiya + 0x0020c183, // n0x1098 c0x0000 (---------------) + I omi + 0x00360b84, // n0x1099 c0x0000 (---------------) + I sado + 0x00201005, // n0x109a c0x0000 (---------------) + I sanjo + 0x002e7905, // n0x109b c0x0000 (---------------) + I seiro + 0x002e7906, // n0x109c c0x0000 (---------------) + I seirou + 0x00261e88, // n0x109d c0x0000 (---------------) + I sekikawa + 0x00311787, // n0x109e c0x0000 (---------------) + I shibata + 0x00376f46, // n0x109f c0x0000 (---------------) + I tagami + 0x00351ec6, // n0x10a0 c0x0000 (---------------) + I tainai + 0x002e5886, // n0x10a1 c0x0000 (---------------) + I tochio + 0x0028f0c9, // n0x10a2 c0x0000 (---------------) + I tokamachi + 0x00207a47, // n0x10a3 c0x0000 (---------------) + I tsubame + 0x00294586, // n0x10a4 c0x0000 (---------------) + I tsunan + 0x002c7486, // n0x10a5 c0x0000 (---------------) + I uonuma + 0x0024f946, // n0x10a6 c0x0000 (---------------) + I yahiko + 0x002a97c5, // n0x10a7 c0x0000 (---------------) + I yoita + 0x00216dc6, // n0x10a8 c0x0000 (---------------) + I yuzawa + 0x0038cf85, // n0x10a9 c0x0000 (---------------) + I beppu + 0x002d3588, // n0x10aa c0x0000 (---------------) + I bungoono + 0x002942cb, // n0x10ab c0x0000 (---------------) + I bungotakada + 0x0028e006, // n0x10ac c0x0000 (---------------) + I hasama + 0x00288784, // n0x10ad c0x0000 (---------------) + I hiji + 0x0035c489, // n0x10ae c0x0000 (---------------) + I himeshima + 0x002a3e04, // n0x10af c0x0000 (---------------) + I hita + 0x002c8448, // n0x10b0 c0x0000 (---------------) + I kamitsue + 0x00286487, // n0x10b1 c0x0000 (---------------) + I kokonoe + 0x00284144, // n0x10b2 c0x0000 (---------------) + I kuju + 0x002b4608, // n0x10b3 c0x0000 (---------------) + I kunisaki + 0x002bc1c4, // n0x10b4 c0x0000 (---------------) + I kusu + 0x002a9804, // n0x10b5 c0x0000 (---------------) + I oita + 0x00289605, // n0x10b6 c0x0000 (---------------) + I saiki + 0x002fc5c6, // n0x10b7 c0x0000 (---------------) + I taketa + 0x002f1cc7, // n0x10b8 c0x0000 (---------------) + I tsukumi + 0x00244843, // n0x10b9 c0x0000 (---------------) + I usa + 0x0029ec45, // n0x10ba c0x0000 (---------------) + I usuki + 0x002be384, // n0x10bb c0x0000 (---------------) + I yufu + 0x0026a546, // n0x10bc c0x0000 (---------------) + I akaiwa + 0x002da888, // n0x10bd c0x0000 (---------------) + I asakuchi + 0x00331a85, // n0x10be c0x0000 (---------------) + I bizen + 0x00291349, // n0x10bf c0x0000 (---------------) + I hayashima + 0x0020b085, // n0x10c0 c0x0000 (---------------) + I ibara + 0x002bdd88, // n0x10c1 c0x0000 (---------------) + I kagamino + 0x0030a1c7, // n0x10c2 c0x0000 (---------------) + I kasaoka + 0x0037e8c8, // n0x10c3 c0x0000 (---------------) + I kibichuo + 0x002b3947, // n0x10c4 c0x0000 (---------------) + I kumenan + 0x0035bec9, // n0x10c5 c0x0000 (---------------) + I kurashiki + 0x0022cbc6, // n0x10c6 c0x0000 (---------------) + I maniwa + 0x00345a46, // n0x10c7 c0x0000 (---------------) + I misaki + 0x0025e584, // n0x10c8 c0x0000 (---------------) + I nagi + 0x0029c845, // n0x10c9 c0x0000 (---------------) + I niimi + 0x002f038c, // n0x10ca c0x0000 (---------------) + I nishiawakura + 0x00278bc7, // n0x10cb c0x0000 (---------------) + I okayama + 0x00278fc7, // n0x10cc c0x0000 (---------------) + I satosho + 0x00288608, // n0x10cd c0x0000 (---------------) + I setouchi + 0x0027b106, // n0x10ce c0x0000 (---------------) + I shinjo + 0x002a0644, // n0x10cf c0x0000 (---------------) + I shoo + 0x00322544, // n0x10d0 c0x0000 (---------------) + I soja + 0x00281749, // n0x10d1 c0x0000 (---------------) + I takahashi + 0x002c2c06, // n0x10d2 c0x0000 (---------------) + I tamano + 0x0021ca47, // n0x10d3 c0x0000 (---------------) + I tsuyama + 0x002072c4, // n0x10d4 c0x0000 (---------------) + I wake + 0x002b1646, // n0x10d5 c0x0000 (---------------) + I yakage + 0x00309dc5, // n0x10d6 c0x0000 (---------------) + I aguni + 0x002a4107, // n0x10d7 c0x0000 (---------------) + I ginowan + 0x002c7e86, // n0x10d8 c0x0000 (---------------) + I ginoza + 0x0035ed89, // n0x10d9 c0x0000 (---------------) + I gushikami + 0x00280407, // n0x10da c0x0000 (---------------) + I haebaru + 0x00266d87, // n0x10db c0x0000 (---------------) + I higashi + 0x002a17c6, // n0x10dc c0x0000 (---------------) + I hirara + 0x00244285, // n0x10dd c0x0000 (---------------) + I iheya + 0x0027ef88, // n0x10de c0x0000 (---------------) + I ishigaki + 0x0021b2c8, // n0x10df c0x0000 (---------------) + I ishikawa + 0x0023b246, // n0x10e0 c0x0000 (---------------) + I itoman + 0x00331ac5, // n0x10e1 c0x0000 (---------------) + I izena + 0x0026c506, // n0x10e2 c0x0000 (---------------) + I kadena + 0x00215ec3, // n0x10e3 c0x0000 (---------------) + I kin + 0x00298b89, // n0x10e4 c0x0000 (---------------) + I kitadaito + 0x002a75ce, // n0x10e5 c0x0000 (---------------) + I kitanakagusuku + 0x002b3648, // n0x10e6 c0x0000 (---------------) + I kumejima + 0x002a8f08, // n0x10e7 c0x0000 (---------------) + I kunigami + 0x0023b04b, // n0x10e8 c0x0000 (---------------) + I minamidaito + 0x00291586, // n0x10e9 c0x0000 (---------------) + I motobu + 0x00247bc4, // n0x10ea c0x0000 (---------------) + I nago + 0x00206384, // n0x10eb c0x0000 (---------------) + I naha + 0x002a76ca, // n0x10ec c0x0000 (---------------) + I nakagusuku + 0x002190c7, // n0x10ed c0x0000 (---------------) + I nakijin + 0x00294645, // n0x10ee c0x0000 (---------------) + I nanjo + 0x00210cc9, // n0x10ef c0x0000 (---------------) + I nishihara + 0x002b9405, // n0x10f0 c0x0000 (---------------) + I ogimi + 0x00395107, // n0x10f1 c0x0000 (---------------) + I okinawa + 0x00300704, // n0x10f2 c0x0000 (---------------) + I onna + 0x00381cc7, // n0x10f3 c0x0000 (---------------) + I shimoji + 0x0022d8c8, // n0x10f4 c0x0000 (---------------) + I taketomi + 0x002fd406, // n0x10f5 c0x0000 (---------------) + I tarama + 0x002fadc9, // n0x10f6 c0x0000 (---------------) + I tokashiki + 0x002b524a, // n0x10f7 c0x0000 (---------------) + I tomigusuku + 0x00219046, // n0x10f8 c0x0000 (---------------) + I tonaki + 0x00296806, // n0x10f9 c0x0000 (---------------) + I urasoe + 0x002ac685, // n0x10fa c0x0000 (---------------) + I uruma + 0x00372285, // n0x10fb c0x0000 (---------------) + I yaese + 0x00355487, // n0x10fc c0x0000 (---------------) + I yomitan + 0x0022ac48, // n0x10fd c0x0000 (---------------) + I yonabaru + 0x00309d08, // n0x10fe c0x0000 (---------------) + I yonaguni + 0x00240f06, // n0x10ff c0x0000 (---------------) + I zamami + 0x00226fc5, // n0x1100 c0x0000 (---------------) + I abeno + 0x00247cce, // n0x1101 c0x0000 (---------------) + I chihayaakasaka + 0x0032c104, // n0x1102 c0x0000 (---------------) + I chuo + 0x0023b1c5, // n0x1103 c0x0000 (---------------) + I daito + 0x00277a09, // n0x1104 c0x0000 (---------------) + I fujiidera + 0x00250a88, // n0x1105 c0x0000 (---------------) + I habikino + 0x003a0586, // n0x1106 c0x0000 (---------------) + I hannan + 0x0029afcc, // n0x1107 c0x0000 (---------------) + I higashiosaka + 0x0029d990, // n0x1108 c0x0000 (---------------) + I higashisumiyoshi + 0x0029f78f, // n0x1109 c0x0000 (---------------) + I higashiyodogawa + 0x002a0748, // n0x110a c0x0000 (---------------) + I hirakata + 0x002c3847, // n0x110b c0x0000 (---------------) + I ibaraki + 0x00202445, // n0x110c c0x0000 (---------------) + I ikeda + 0x0027e805, // n0x110d c0x0000 (---------------) + I izumi + 0x002f1b49, // n0x110e c0x0000 (---------------) + I izumiotsu + 0x00295dc9, // n0x110f c0x0000 (---------------) + I izumisano + 0x00222846, // n0x1110 c0x0000 (---------------) + I kadoma + 0x002f9247, // n0x1111 c0x0000 (---------------) + I kaizuka + 0x00389f05, // n0x1112 c0x0000 (---------------) + I kanan + 0x0038e149, // n0x1113 c0x0000 (---------------) + I kashiwara + 0x0032d886, // n0x1114 c0x0000 (---------------) + I katano + 0x0035204d, // n0x1115 c0x0000 (---------------) + I kawachinagano + 0x002896c9, // n0x1116 c0x0000 (---------------) + I kishiwada + 0x002047c4, // n0x1117 c0x0000 (---------------) + I kita + 0x002b33c8, // n0x1118 c0x0000 (---------------) + I kumatori + 0x00398949, // n0x1119 c0x0000 (---------------) + I matsubara + 0x0034a446, // n0x111a c0x0000 (---------------) + I minato + 0x00278185, // n0x111b c0x0000 (---------------) + I minoh + 0x00345a46, // n0x111c c0x0000 (---------------) + I misaki + 0x0030de49, // n0x111d c0x0000 (---------------) + I moriguchi + 0x00309448, // n0x111e c0x0000 (---------------) + I neyagawa + 0x00210385, // n0x111f c0x0000 (---------------) + I nishi + 0x00261e04, // n0x1120 c0x0000 (---------------) + I nose + 0x0029b18b, // n0x1121 c0x0000 (---------------) + I osakasayama + 0x0034a305, // n0x1122 c0x0000 (---------------) + I sakai + 0x0022f286, // n0x1123 c0x0000 (---------------) + I sayama + 0x00283686, // n0x1124 c0x0000 (---------------) + I sennan + 0x002460c6, // n0x1125 c0x0000 (---------------) + I settsu + 0x003820cb, // n0x1126 c0x0000 (---------------) + I shijonawate + 0x00291449, // n0x1127 c0x0000 (---------------) + I shimamoto + 0x00218205, // n0x1128 c0x0000 (---------------) + I suita + 0x0037e687, // n0x1129 c0x0000 (---------------) + I tadaoka + 0x0023d286, // n0x112a c0x0000 (---------------) + I taishi + 0x003788c6, // n0x112b c0x0000 (---------------) + I tajiri + 0x00282848, // n0x112c c0x0000 (---------------) + I takaishi + 0x002fc6c9, // n0x112d c0x0000 (---------------) + I takatsuki + 0x0026ff8c, // n0x112e c0x0000 (---------------) + I tondabayashi + 0x0024a2c8, // n0x112f c0x0000 (---------------) + I toyonaka + 0x002500c6, // n0x1130 c0x0000 (---------------) + I toyono + 0x00341d43, // n0x1131 c0x0000 (---------------) + I yao + 0x00248746, // n0x1132 c0x0000 (---------------) + I ariake + 0x0027e4c5, // n0x1133 c0x0000 (---------------) + I arita + 0x0027d508, // n0x1134 c0x0000 (---------------) + I fukudomi + 0x002269c6, // n0x1135 c0x0000 (---------------) + I genkai + 0x002a4348, // n0x1136 c0x0000 (---------------) + I hamatama + 0x00349905, // n0x1137 c0x0000 (---------------) + I hizen + 0x0027c105, // n0x1138 c0x0000 (---------------) + I imari + 0x0030a448, // n0x1139 c0x0000 (---------------) + I kamimine + 0x002ea4c7, // n0x113a c0x0000 (---------------) + I kanzaki + 0x00376b87, // n0x113b c0x0000 (---------------) + I karatsu + 0x002a9907, // n0x113c c0x0000 (---------------) + I kashima + 0x0021d388, // n0x113d c0x0000 (---------------) + I kitagata + 0x002904c8, // n0x113e c0x0000 (---------------) + I kitahata + 0x00240b06, // n0x113f c0x0000 (---------------) + I kiyama + 0x0030c047, // n0x1140 c0x0000 (---------------) + I kouhoku + 0x002adf87, // n0x1141 c0x0000 (---------------) + I kyuragi + 0x0027e38a, // n0x1142 c0x0000 (---------------) + I nishiarita + 0x00212e03, // n0x1143 c0x0000 (---------------) + I ogi + 0x002013c6, // n0x1144 c0x0000 (---------------) + I omachi + 0x00204345, // n0x1145 c0x0000 (---------------) + I ouchi + 0x00378a84, // n0x1146 c0x0000 (---------------) + I saga + 0x0027a7c9, // n0x1147 c0x0000 (---------------) + I shiroishi + 0x0035be44, // n0x1148 c0x0000 (---------------) + I taku + 0x0022e404, // n0x1149 c0x0000 (---------------) + I tara + 0x002a2144, // n0x114a c0x0000 (---------------) + I tosu + 0x0029fd0b, // n0x114b c0x0000 (---------------) + I yoshinogari + 0x00398ac7, // n0x114c c0x0000 (---------------) + I arakawa + 0x00247f05, // n0x114d c0x0000 (---------------) + I asaka + 0x00294148, // n0x114e c0x0000 (---------------) + I chichibu + 0x00278086, // n0x114f c0x0000 (---------------) + I fujimi + 0x00278088, // n0x1150 c0x0000 (---------------) + I fujimino + 0x0027ca46, // n0x1151 c0x0000 (---------------) + I fukaya + 0x0028ba45, // n0x1152 c0x0000 (---------------) + I hanno + 0x0028cec5, // n0x1153 c0x0000 (---------------) + I hanyu + 0x0028eb86, // n0x1154 c0x0000 (---------------) + I hasuda + 0x0028f748, // n0x1155 c0x0000 (---------------) + I hatogaya + 0x00290248, // n0x1156 c0x0000 (---------------) + I hatoyama + 0x0027a986, // n0x1157 c0x0000 (---------------) + I hidaka + 0x00293f8f, // n0x1158 c0x0000 (---------------) + I higashichichibu + 0x00298650, // n0x1159 c0x0000 (---------------) + I higashimatsuyama + 0x0038d6c5, // n0x115a c0x0000 (---------------) + I honjo + 0x002012c3, // n0x115b c0x0000 (---------------) + I ina + 0x00251c85, // n0x115c c0x0000 (---------------) + I iruma + 0x002fdb88, // n0x115d c0x0000 (---------------) + I iwatsuki + 0x00295cc9, // n0x115e c0x0000 (---------------) + I kamiizumi + 0x002e8388, // n0x115f c0x0000 (---------------) + I kamikawa + 0x0034a6c8, // n0x1160 c0x0000 (---------------) + I kamisato + 0x00206648, // n0x1161 c0x0000 (---------------) + I kasukabe + 0x00398b87, // n0x1162 c0x0000 (---------------) + I kawagoe + 0x00277d49, // n0x1163 c0x0000 (---------------) + I kawaguchi + 0x002a4548, // n0x1164 c0x0000 (---------------) + I kawajima + 0x002b0984, // n0x1165 c0x0000 (---------------) + I kazo + 0x002a1fc8, // n0x1166 c0x0000 (---------------) + I kitamoto + 0x0028c249, // n0x1167 c0x0000 (---------------) + I koshigaya + 0x0030d747, // n0x1168 c0x0000 (---------------) + I kounosu + 0x002a7544, // n0x1169 c0x0000 (---------------) + I kuki + 0x00207548, // n0x116a c0x0000 (---------------) + I kumagaya + 0x0024458a, // n0x116b c0x0000 (---------------) + I matsubushi + 0x002d8546, // n0x116c c0x0000 (---------------) + I minano + 0x0022da46, // n0x116d c0x0000 (---------------) + I misato + 0x0021c1c9, // n0x116e c0x0000 (---------------) + I miyashiro + 0x0029dbc7, // n0x116f c0x0000 (---------------) + I miyoshi + 0x002c8848, // n0x1170 c0x0000 (---------------) + I moroyama + 0x0038d208, // n0x1171 c0x0000 (---------------) + I nagatoro + 0x00207148, // n0x1172 c0x0000 (---------------) + I namegawa + 0x003501c5, // n0x1173 c0x0000 (---------------) + I niiza + 0x00373245, // n0x1174 c0x0000 (---------------) + I ogano + 0x00230545, // n0x1175 c0x0000 (---------------) + I ogawa + 0x002af385, // n0x1176 c0x0000 (---------------) + I ogose + 0x002eba47, // n0x1177 c0x0000 (---------------) + I okegawa + 0x0020c185, // n0x1178 c0x0000 (---------------) + I omiya + 0x002ba2c5, // n0x1179 c0x0000 (---------------) + I otaki + 0x00342606, // n0x117a c0x0000 (---------------) + I ranzan + 0x002e82c7, // n0x117b c0x0000 (---------------) + I ryokami + 0x00373887, // n0x117c c0x0000 (---------------) + I saitama + 0x00244886, // n0x117d c0x0000 (---------------) + I sakado + 0x002cd945, // n0x117e c0x0000 (---------------) + I satte + 0x0022f286, // n0x117f c0x0000 (---------------) + I sayama + 0x0024e205, // n0x1180 c0x0000 (---------------) + I shiki + 0x002ac088, // n0x1181 c0x0000 (---------------) + I shiraoka + 0x002d6c04, // n0x1182 c0x0000 (---------------) + I soka + 0x002c1446, // n0x1183 c0x0000 (---------------) + I sugito + 0x00263b04, // n0x1184 c0x0000 (---------------) + I toda + 0x00226188, // n0x1185 c0x0000 (---------------) + I tokigawa + 0x00383dca, // n0x1186 c0x0000 (---------------) + I tokorozawa + 0x0027becc, // n0x1187 c0x0000 (---------------) + I tsurugashima + 0x0020a605, // n0x1188 c0x0000 (---------------) + I urawa + 0x00203686, // n0x1189 c0x0000 (---------------) + I warabi + 0x00270146, // n0x118a c0x0000 (---------------) + I yashio + 0x00354c86, // n0x118b c0x0000 (---------------) + I yokoze + 0x00250144, // n0x118c c0x0000 (---------------) + I yono + 0x0030a085, // n0x118d c0x0000 (---------------) + I yorii + 0x0027c887, // n0x118e c0x0000 (---------------) + I yoshida + 0x0029dc49, // n0x118f c0x0000 (---------------) + I yoshikawa + 0x002a5907, // n0x1190 c0x0000 (---------------) + I yoshimi + 0x00685804, // n0x1191 c0x0001 (---------------) ! I city + 0x00685804, // n0x1192 c0x0001 (---------------) ! I city + 0x0030dbc5, // n0x1193 c0x0000 (---------------) + I aisho + 0x0022a804, // n0x1194 c0x0000 (---------------) + I gamo + 0x0029a98a, // n0x1195 c0x0000 (---------------) + I higashiomi + 0x00277f06, // n0x1196 c0x0000 (---------------) + I hikone + 0x0034a644, // n0x1197 c0x0000 (---------------) + I koka + 0x00203b05, // n0x1198 c0x0000 (---------------) + I konan + 0x0033b985, // n0x1199 c0x0000 (---------------) + I kosei + 0x00300fc4, // n0x119a c0x0000 (---------------) + I koto + 0x002832c7, // n0x119b c0x0000 (---------------) + I kusatsu + 0x0020b007, // n0x119c c0x0000 (---------------) + I maibara + 0x002c7a48, // n0x119d c0x0000 (---------------) + I moriyama + 0x0026b048, // n0x119e c0x0000 (---------------) + I nagahama + 0x00210389, // n0x119f c0x0000 (---------------) + I nishiazai + 0x00257ec8, // n0x11a0 c0x0000 (---------------) + I notogawa + 0x0029ab4b, // n0x11a1 c0x0000 (---------------) + I omihachiman + 0x0021d104, // n0x11a2 c0x0000 (---------------) + I otsu + 0x002ff445, // n0x11a3 c0x0000 (---------------) + I ritto + 0x00280305, // n0x11a4 c0x0000 (---------------) + I ryuoh + 0x002a9889, // n0x11a5 c0x0000 (---------------) + I takashima + 0x002fc6c9, // n0x11a6 c0x0000 (---------------) + I takatsuki + 0x0035c388, // n0x11a7 c0x0000 (---------------) + I torahime + 0x0025c288, // n0x11a8 c0x0000 (---------------) + I toyosato + 0x0027eb84, // n0x11a9 c0x0000 (---------------) + I yasu + 0x002a2305, // n0x11aa c0x0000 (---------------) + I akagi + 0x00201f03, // n0x11ab c0x0000 (---------------) + I ama + 0x0021d0c5, // n0x11ac c0x0000 (---------------) + I gotsu + 0x002a9106, // n0x11ad c0x0000 (---------------) + I hamada + 0x0029584c, // n0x11ae c0x0000 (---------------) + I higashiizumo + 0x0021b346, // n0x11af c0x0000 (---------------) + I hikawa + 0x0024e246, // n0x11b0 c0x0000 (---------------) + I hikimi + 0x00295a05, // n0x11b1 c0x0000 (---------------) + I izumo + 0x0031ad08, // n0x11b2 c0x0000 (---------------) + I kakinoki + 0x002b37c6, // n0x11b3 c0x0000 (---------------) + I masuda + 0x00399246, // n0x11b4 c0x0000 (---------------) + I matsue + 0x0022da46, // n0x11b5 c0x0000 (---------------) + I misato + 0x0021ef4c, // n0x11b6 c0x0000 (---------------) + I nishinoshima + 0x002db1c4, // n0x11b7 c0x0000 (---------------) + I ohda + 0x002e59ca, // n0x11b8 c0x0000 (---------------) + I okinoshima + 0x003a0748, // n0x11b9 c0x0000 (---------------) + I okuizumo + 0x00295687, // n0x11ba c0x0000 (---------------) + I shimane + 0x00253786, // n0x11bb c0x0000 (---------------) + I tamayu + 0x002947c7, // n0x11bc c0x0000 (---------------) + I tsuwano + 0x002e0245, // n0x11bd c0x0000 (---------------) + I unnan + 0x00324a06, // n0x11be c0x0000 (---------------) + I yakumo + 0x0034db86, // n0x11bf c0x0000 (---------------) + I yasugi + 0x00376a47, // n0x11c0 c0x0000 (---------------) + I yatsuka + 0x0022e444, // n0x11c1 c0x0000 (---------------) + I arai + 0x0023e305, // n0x11c2 c0x0000 (---------------) + I atami + 0x00277a04, // n0x11c3 c0x0000 (---------------) + I fuji + 0x0029ba07, // n0x11c4 c0x0000 (---------------) + I fujieda + 0x00277c48, // n0x11c5 c0x0000 (---------------) + I fujikawa + 0x002787ca, // n0x11c6 c0x0000 (---------------) + I fujinomiya + 0x0027fb07, // n0x11c7 c0x0000 (---------------) + I fukuroi + 0x0023b3c7, // n0x11c8 c0x0000 (---------------) + I gotemba + 0x002c37c7, // n0x11c9 c0x0000 (---------------) + I haibara + 0x002d1b89, // n0x11ca c0x0000 (---------------) + I hamamatsu + 0x0029584a, // n0x11cb c0x0000 (---------------) + I higashiizu + 0x00223083, // n0x11cc c0x0000 (---------------) + I ito + 0x0022e345, // n0x11cd c0x0000 (---------------) + I iwata + 0x00214503, // n0x11ce c0x0000 (---------------) + I izu + 0x002fafc9, // n0x11cf c0x0000 (---------------) + I izunokuni + 0x002b4b08, // n0x11d0 c0x0000 (---------------) + I kakegawa + 0x002ac207, // n0x11d1 c0x0000 (---------------) + I kannami + 0x002e8489, // n0x11d2 c0x0000 (---------------) + I kawanehon + 0x0021b3c6, // n0x11d3 c0x0000 (---------------) + I kawazu + 0x003a4e88, // n0x11d4 c0x0000 (---------------) + I kikugawa + 0x002ddc45, // n0x11d5 c0x0000 (---------------) + I kosai + 0x003539ca, // n0x11d6 c0x0000 (---------------) + I makinohara + 0x002cee49, // n0x11d7 c0x0000 (---------------) + I matsuzaki + 0x0026fc49, // n0x11d8 c0x0000 (---------------) + I minamiizu + 0x002c0d47, // n0x11d9 c0x0000 (---------------) + I mishima + 0x002a9b49, // n0x11da c0x0000 (---------------) + I morimachi + 0x002143c8, // n0x11db c0x0000 (---------------) + I nishiizu + 0x002ea1c6, // n0x11dc c0x0000 (---------------) + I numazu + 0x00374248, // n0x11dd c0x0000 (---------------) + I omaezaki + 0x00212807, // n0x11de c0x0000 (---------------) + I shimada + 0x002231c7, // n0x11df c0x0000 (---------------) + I shimizu + 0x002c7807, // n0x11e0 c0x0000 (---------------) + I shimoda + 0x002b13c8, // n0x11e1 c0x0000 (---------------) + I shizuoka + 0x002e9ec6, // n0x11e2 c0x0000 (---------------) + I susono + 0x00244345, // n0x11e3 c0x0000 (---------------) + I yaizu + 0x0027c887, // n0x11e4 c0x0000 (---------------) + I yoshida + 0x00296308, // n0x11e5 c0x0000 (---------------) + I ashikaga + 0x00344784, // n0x11e6 c0x0000 (---------------) + I bato + 0x00283a44, // n0x11e7 c0x0000 (---------------) + I haga + 0x002f2987, // n0x11e8 c0x0000 (---------------) + I ichikai + 0x002ada87, // n0x11e9 c0x0000 (---------------) + I iwafune + 0x002baeca, // n0x11ea c0x0000 (---------------) + I kaminokawa + 0x002ea146, // n0x11eb c0x0000 (---------------) + I kanuma + 0x002f938a, // n0x11ec c0x0000 (---------------) + I karasuyama + 0x002b96c7, // n0x11ed c0x0000 (---------------) + I kuroiso + 0x0032bec7, // n0x11ee c0x0000 (---------------) + I mashiko + 0x00241004, // n0x11ef c0x0000 (---------------) + I mibu + 0x00259384, // n0x11f0 c0x0000 (---------------) + I moka + 0x00225406, // n0x11f1 c0x0000 (---------------) + I motegi + 0x00328b84, // n0x11f2 c0x0000 (---------------) + I nasu + 0x00328b8c, // n0x11f3 c0x0000 (---------------) + I nasushiobara + 0x00202c85, // n0x11f4 c0x0000 (---------------) + I nikko + 0x00216409, // n0x11f5 c0x0000 (---------------) + I nishikata + 0x00279684, // n0x11f6 c0x0000 (---------------) + I nogi + 0x002a0705, // n0x11f7 c0x0000 (---------------) + I ohira + 0x00278248, // n0x11f8 c0x0000 (---------------) + I ohtawara + 0x0025b745, // n0x11f9 c0x0000 (---------------) + I oyama + 0x002dc646, // n0x11fa c0x0000 (---------------) + I sakura + 0x0020b904, // n0x11fb c0x0000 (---------------) + I sano + 0x00267e8a, // n0x11fc c0x0000 (---------------) + I shimotsuke + 0x0029d206, // n0x11fd c0x0000 (---------------) + I shioya + 0x002510ca, // n0x11fe c0x0000 (---------------) + I takanezawa + 0x00344807, // n0x11ff c0x0000 (---------------) + I tochigi + 0x0028f585, // n0x1200 c0x0000 (---------------) + I tsuga + 0x0021ea05, // n0x1201 c0x0000 (---------------) + I ujiie + 0x00228c4a, // n0x1202 c0x0000 (---------------) + I utsunomiya + 0x002a1d85, // n0x1203 c0x0000 (---------------) + I yaita + 0x002a0306, // n0x1204 c0x0000 (---------------) + I aizumi + 0x00203c84, // n0x1205 c0x0000 (---------------) + I anan + 0x002afa06, // n0x1206 c0x0000 (---------------) + I ichiba + 0x00355545, // n0x1207 c0x0000 (---------------) + I itano + 0x00226a86, // n0x1208 c0x0000 (---------------) + I kainan + 0x002ab80c, // n0x1209 c0x0000 (---------------) + I komatsushima + 0x002c89ca, // n0x120a c0x0000 (---------------) + I matsushige + 0x002806c4, // n0x120b c0x0000 (---------------) + I mima + 0x00223406, // n0x120c c0x0000 (---------------) + I minami + 0x0029dbc7, // n0x120d c0x0000 (---------------) + I miyoshi + 0x002cbb04, // n0x120e c0x0000 (---------------) + I mugi + 0x002b0508, // n0x120f c0x0000 (---------------) + I nakagawa + 0x00383cc6, // n0x1210 c0x0000 (---------------) + I naruto + 0x00247b49, // n0x1211 c0x0000 (---------------) + I sanagochi + 0x002cf749, // n0x1212 c0x0000 (---------------) + I shishikui + 0x00290009, // n0x1213 c0x0000 (---------------) + I tokushima + 0x0036b1c6, // n0x1214 c0x0000 (---------------) + I wajiki + 0x00212906, // n0x1215 c0x0000 (---------------) + I adachi + 0x00374387, // n0x1216 c0x0000 (---------------) + I akiruno + 0x00327948, // n0x1217 c0x0000 (---------------) + I akishima + 0x00212709, // n0x1218 c0x0000 (---------------) + I aogashima + 0x00398ac7, // n0x1219 c0x0000 (---------------) + I arakawa + 0x002b5e86, // n0x121a c0x0000 (---------------) + I bunkyo + 0x002ff0c7, // n0x121b c0x0000 (---------------) + I chiyoda + 0x002d9745, // n0x121c c0x0000 (---------------) + I chofu + 0x0032c104, // n0x121d c0x0000 (---------------) + I chuo + 0x00373f47, // n0x121e c0x0000 (---------------) + I edogawa + 0x002be405, // n0x121f c0x0000 (---------------) + I fuchu + 0x00289545, // n0x1220 c0x0000 (---------------) + I fussa + 0x002fea47, // n0x1221 c0x0000 (---------------) + I hachijo + 0x0024f748, // n0x1222 c0x0000 (---------------) + I hachioji + 0x003810c6, // n0x1223 c0x0000 (---------------) + I hamura + 0x0029768d, // n0x1224 c0x0000 (---------------) + I higashikurume + 0x00298f0f, // n0x1225 c0x0000 (---------------) + I higashimurayama + 0x0029efcd, // n0x1226 c0x0000 (---------------) + I higashiyamato + 0x0020ee44, // n0x1227 c0x0000 (---------------) + I hino + 0x0023a386, // n0x1228 c0x0000 (---------------) + I hinode + 0x002d08c8, // n0x1229 c0x0000 (---------------) + I hinohara + 0x00324c85, // n0x122a c0x0000 (---------------) + I inagi + 0x0027e548, // n0x122b c0x0000 (---------------) + I itabashi + 0x0021854a, // n0x122c c0x0000 (---------------) + I katsushika + 0x002047c4, // n0x122d c0x0000 (---------------) + I kita + 0x002abbc6, // n0x122e c0x0000 (---------------) + I kiyose + 0x0039da87, // n0x122f c0x0000 (---------------) + I kodaira + 0x0021fc47, // n0x1230 c0x0000 (---------------) + I koganei + 0x002a2509, // n0x1231 c0x0000 (---------------) + I kokubunji + 0x00374205, // n0x1232 c0x0000 (---------------) + I komae + 0x00300fc4, // n0x1233 c0x0000 (---------------) + I koto + 0x0032f0ca, // n0x1234 c0x0000 (---------------) + I kouzushima + 0x002b4d09, // n0x1235 c0x0000 (---------------) + I kunitachi + 0x002a9c47, // n0x1236 c0x0000 (---------------) + I machida + 0x00297946, // n0x1237 c0x0000 (---------------) + I meguro + 0x0034a446, // n0x1238 c0x0000 (---------------) + I minato + 0x002a2246, // n0x1239 c0x0000 (---------------) + I mitaka + 0x0035d706, // n0x123a c0x0000 (---------------) + I mizuho + 0x002ceb0f, // n0x123b c0x0000 (---------------) + I musashimurayama + 0x002d0789, // n0x123c c0x0000 (---------------) + I musashino + 0x003288c6, // n0x123d c0x0000 (---------------) + I nakano + 0x0024bc86, // n0x123e c0x0000 (---------------) + I nerima + 0x00352c89, // n0x123f c0x0000 (---------------) + I ogasawara + 0x0030c147, // n0x1240 c0x0000 (---------------) + I okutama + 0x00213403, // n0x1241 c0x0000 (---------------) + I ome + 0x00209f06, // n0x1242 c0x0000 (---------------) + I oshima + 0x00201103, // n0x1243 c0x0000 (---------------) + I ota + 0x0024ce08, // n0x1244 c0x0000 (---------------) + I setagaya + 0x002fef07, // n0x1245 c0x0000 (---------------) + I shibuya + 0x002a0949, // n0x1246 c0x0000 (---------------) + I shinagawa + 0x0027f2c8, // n0x1247 c0x0000 (---------------) + I shinjuku + 0x00376cc8, // n0x1248 c0x0000 (---------------) + I suginami + 0x00217b46, // n0x1249 c0x0000 (---------------) + I sumida + 0x00227189, // n0x124a c0x0000 (---------------) + I tachikawa + 0x00235205, // n0x124b c0x0000 (---------------) + I taito + 0x00253784, // n0x124c c0x0000 (---------------) + I tama + 0x0024a607, // n0x124d c0x0000 (---------------) + I toshima + 0x0024c005, // n0x124e c0x0000 (---------------) + I chizu + 0x0020ee44, // n0x124f c0x0000 (---------------) + I hino + 0x00247fc8, // n0x1250 c0x0000 (---------------) + I kawahara + 0x00219384, // n0x1251 c0x0000 (---------------) + I koge + 0x00304587, // n0x1252 c0x0000 (---------------) + I kotoura + 0x0036edc6, // n0x1253 c0x0000 (---------------) + I misasa + 0x002e6845, // n0x1254 c0x0000 (---------------) + I nanbu + 0x00272c08, // n0x1255 c0x0000 (---------------) + I nichinan + 0x0034a30b, // n0x1256 c0x0000 (---------------) + I sakaiminato + 0x002f7a87, // n0x1257 c0x0000 (---------------) + I tottori + 0x00228ec6, // n0x1258 c0x0000 (---------------) + I wakasa + 0x002c2304, // n0x1259 c0x0000 (---------------) + I yazu + 0x002559c6, // n0x125a c0x0000 (---------------) + I yonago + 0x002c0b05, // n0x125b c0x0000 (---------------) + I asahi + 0x002be405, // n0x125c c0x0000 (---------------) + I fuchu + 0x0027ed09, // n0x125d c0x0000 (---------------) + I fukumitsu + 0x00282ec9, // n0x125e c0x0000 (---------------) + I funahashi + 0x00223204, // n0x125f c0x0000 (---------------) + I himi + 0x00223245, // n0x1260 c0x0000 (---------------) + I imizu + 0x00223445, // n0x1261 c0x0000 (---------------) + I inami + 0x00353846, // n0x1262 c0x0000 (---------------) + I johana + 0x002f2888, // n0x1263 c0x0000 (---------------) + I kamiichi + 0x002b8d46, // n0x1264 c0x0000 (---------------) + I kurobe + 0x00331b8b, // n0x1265 c0x0000 (---------------) + I nakaniikawa + 0x0030078a, // n0x1266 c0x0000 (---------------) + I namerikawa + 0x002fad05, // n0x1267 c0x0000 (---------------) + I nanto + 0x0028cf46, // n0x1268 c0x0000 (---------------) + I nyuzen + 0x002f1445, // n0x1269 c0x0000 (---------------) + I oyabe + 0x002182c5, // n0x126a c0x0000 (---------------) + I taira + 0x00290647, // n0x126b c0x0000 (---------------) + I takaoka + 0x00201dc8, // n0x126c c0x0000 (---------------) + I tateyama + 0x00257f44, // n0x126d c0x0000 (---------------) + I toga + 0x002da706, // n0x126e c0x0000 (---------------) + I tonami + 0x002902c6, // n0x126f c0x0000 (---------------) + I toyama + 0x00214587, // n0x1270 c0x0000 (---------------) + I unazuki + 0x002ffa44, // n0x1271 c0x0000 (---------------) + I uozu + 0x0027d386, // n0x1272 c0x0000 (---------------) + I yamada + 0x0023f3c5, // n0x1273 c0x0000 (---------------) + I arida + 0x0023f3c9, // n0x1274 c0x0000 (---------------) + I aridagawa + 0x00212b04, // n0x1275 c0x0000 (---------------) + I gobo + 0x00285d49, // n0x1276 c0x0000 (---------------) + I hashimoto + 0x0027a986, // n0x1277 c0x0000 (---------------) + I hidaka + 0x002bb588, // n0x1278 c0x0000 (---------------) + I hirogawa + 0x00223445, // n0x1279 c0x0000 (---------------) + I inami + 0x00288845, // n0x127a c0x0000 (---------------) + I iwade + 0x00226a86, // n0x127b c0x0000 (---------------) + I kainan + 0x0026fe89, // n0x127c c0x0000 (---------------) + I kamitonda + 0x00219889, // n0x127d c0x0000 (---------------) + I katsuragi + 0x0024e2c6, // n0x127e c0x0000 (---------------) + I kimino + 0x00250b88, // n0x127f c0x0000 (---------------) + I kinokawa + 0x0025c008, // n0x1280 c0x0000 (---------------) + I kitayama + 0x002f1404, // n0x1281 c0x0000 (---------------) + I koya + 0x0035dc04, // n0x1282 c0x0000 (---------------) + I koza + 0x0035dc08, // n0x1283 c0x0000 (---------------) + I kozagawa + 0x00318e08, // n0x1284 c0x0000 (---------------) + I kudoyama + 0x002b0e09, // n0x1285 c0x0000 (---------------) + I kushimoto + 0x002a9086, // n0x1286 c0x0000 (---------------) + I mihama + 0x0022da46, // n0x1287 c0x0000 (---------------) + I misato + 0x003165cd, // n0x1288 c0x0000 (---------------) + I nachikatsuura + 0x0022ff06, // n0x1289 c0x0000 (---------------) + I shingu + 0x002a3889, // n0x128a c0x0000 (---------------) + I shirahama + 0x00201585, // n0x128b c0x0000 (---------------) + I taiji + 0x003087c6, // n0x128c c0x0000 (---------------) + I tanabe + 0x00227348, // n0x128d c0x0000 (---------------) + I wakayama + 0x00313b45, // n0x128e c0x0000 (---------------) + I yuasa + 0x002adfc4, // n0x128f c0x0000 (---------------) + I yura + 0x002c0b05, // n0x1290 c0x0000 (---------------) + I asahi + 0x00282548, // n0x1291 c0x0000 (---------------) + I funagata + 0x0029a749, // n0x1292 c0x0000 (---------------) + I higashine + 0x00277ac4, // n0x1293 c0x0000 (---------------) + I iide + 0x0034f546, // n0x1294 c0x0000 (---------------) + I kahoku + 0x0025b60a, // n0x1295 c0x0000 (---------------) + I kaminoyama + 0x002c91c8, // n0x1296 c0x0000 (---------------) + I kaneyama + 0x002bb049, // n0x1297 c0x0000 (---------------) + I kawanishi + 0x0029504a, // n0x1298 c0x0000 (---------------) + I mamurogawa + 0x002e8406, // n0x1299 c0x0000 (---------------) + I mikawa + 0x002990c8, // n0x129a c0x0000 (---------------) + I murayama + 0x00302045, // n0x129b c0x0000 (---------------) + I nagai + 0x002cb588, // n0x129c c0x0000 (---------------) + I nakayama + 0x002b3a45, // n0x129d c0x0000 (---------------) + I nanyo + 0x0021b289, // n0x129e c0x0000 (---------------) + I nishikawa + 0x00361e49, // n0x129f c0x0000 (---------------) + I obanazawa + 0x00202d82, // n0x12a0 c0x0000 (---------------) + I oe + 0x002a7bc5, // n0x12a1 c0x0000 (---------------) + I oguni + 0x00270cc6, // n0x12a2 c0x0000 (---------------) + I ohkura + 0x0027a8c7, // n0x12a3 c0x0000 (---------------) + I oishida + 0x00378a85, // n0x12a4 c0x0000 (---------------) + I sagae + 0x002f7386, // n0x12a5 c0x0000 (---------------) + I sakata + 0x00313c08, // n0x12a6 c0x0000 (---------------) + I sakegawa + 0x0027b106, // n0x12a7 c0x0000 (---------------) + I shinjo + 0x002cfd49, // n0x12a8 c0x0000 (---------------) + I shirataka + 0x002790c6, // n0x12a9 c0x0000 (---------------) + I shonai + 0x002826c8, // n0x12aa c0x0000 (---------------) + I takahata + 0x002aa345, // n0x12ab c0x0000 (---------------) + I tendo + 0x0026f486, // n0x12ac c0x0000 (---------------) + I tozawa + 0x003542c8, // n0x12ad c0x0000 (---------------) + I tsuruoka + 0x002815c8, // n0x12ae c0x0000 (---------------) + I yamagata + 0x003a3a08, // n0x12af c0x0000 (---------------) + I yamanobe + 0x00366b88, // n0x12b0 c0x0000 (---------------) + I yonezawa + 0x00216dc4, // n0x12b1 c0x0000 (---------------) + I yuza + 0x0022e983, // n0x12b2 c0x0000 (---------------) + I abu + 0x002cff84, // n0x12b3 c0x0000 (---------------) + I hagi + 0x0022d5c6, // n0x12b4 c0x0000 (---------------) + I hikari + 0x002d9784, // n0x12b5 c0x0000 (---------------) + I hofu + 0x002a8e47, // n0x12b6 c0x0000 (---------------) + I iwakuni + 0x00399149, // n0x12b7 c0x0000 (---------------) + I kudamatsu + 0x002c1b05, // n0x12b8 c0x0000 (---------------) + I mitou + 0x0038d206, // n0x12b9 c0x0000 (---------------) + I nagato + 0x00209f06, // n0x12ba c0x0000 (---------------) + I oshima + 0x00261ccb, // n0x12bb c0x0000 (---------------) + I shimonoseki + 0x002fac46, // n0x12bc c0x0000 (---------------) + I shunan + 0x00319106, // n0x12bd c0x0000 (---------------) + I tabuse + 0x0022db48, // n0x12be c0x0000 (---------------) + I tokuyama + 0x00264186, // n0x12bf c0x0000 (---------------) + I toyota + 0x0028f383, // n0x12c0 c0x0000 (---------------) + I ube + 0x0020d243, // n0x12c1 c0x0000 (---------------) + I yuu + 0x0032c104, // n0x12c2 c0x0000 (---------------) + I chuo + 0x00236985, // n0x12c3 c0x0000 (---------------) + I doshi + 0x002ae147, // n0x12c4 c0x0000 (---------------) + I fuefuki + 0x00277c48, // n0x12c5 c0x0000 (---------------) + I fujikawa + 0x00277c4f, // n0x12c6 c0x0000 (---------------) + I fujikawaguchiko + 0x0027c78b, // n0x12c7 c0x0000 (---------------) + I fujiyoshida + 0x002f2688, // n0x12c8 c0x0000 (---------------) + I hayakawa + 0x0034f5c6, // n0x12c9 c0x0000 (---------------) + I hokuto + 0x0026380e, // n0x12ca c0x0000 (---------------) + I ichikawamisato + 0x00226a83, // n0x12cb c0x0000 (---------------) + I kai + 0x0023fec4, // n0x12cc c0x0000 (---------------) + I kofu + 0x002fabc5, // n0x12cd c0x0000 (---------------) + I koshu + 0x00348146, // n0x12ce c0x0000 (---------------) + I kosuge + 0x0028e30b, // n0x12cf c0x0000 (---------------) + I minami-alps + 0x00291986, // n0x12d0 c0x0000 (---------------) + I minobu + 0x00216049, // n0x12d1 c0x0000 (---------------) + I nakamichi + 0x002e6845, // n0x12d2 c0x0000 (---------------) + I nanbu + 0x0037fd08, // n0x12d3 c0x0000 (---------------) + I narusawa + 0x0020d5c8, // n0x12d4 c0x0000 (---------------) + I nirasaki + 0x0021974c, // n0x12d5 c0x0000 (---------------) + I nishikatsura + 0x0029fd46, // n0x12d6 c0x0000 (---------------) + I oshino + 0x0021d106, // n0x12d7 c0x0000 (---------------) + I otsuki + 0x002b2f45, // n0x12d8 c0x0000 (---------------) + I showa + 0x00289988, // n0x12d9 c0x0000 (---------------) + I tabayama + 0x0027bec5, // n0x12da c0x0000 (---------------) + I tsuru + 0x00385888, // n0x12db c0x0000 (---------------) + I uenohara + 0x0029f40a, // n0x12dc c0x0000 (---------------) + I yamanakako + 0x002a2d49, // n0x12dd c0x0000 (---------------) + I yamanashi + 0x00685804, // n0x12de c0x0001 (---------------) ! I city + 0x2d60ce42, // n0x12df c0x00b5 (n0x12e0-n0x12e1) o I co + 0x000fe108, // n0x12e0 c0x0000 (---------------) + blogspot + 0x00233243, // n0x12e1 c0x0000 (---------------) + I com + 0x00239103, // n0x12e2 c0x0000 (---------------) + I edu + 0x0027d903, // n0x12e3 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x12e4 c0x0000 (---------------) + I mil + 0x00223b43, // n0x12e5 c0x0000 (---------------) + I net + 0x00228743, // n0x12e6 c0x0000 (---------------) + I org + 0x00331a83, // n0x12e7 c0x0000 (---------------) + I biz + 0x00233243, // n0x12e8 c0x0000 (---------------) + I com + 0x00239103, // n0x12e9 c0x0000 (---------------) + I edu + 0x0027d903, // n0x12ea c0x0000 (---------------) + I gov + 0x00201844, // n0x12eb c0x0000 (---------------) + I info + 0x00223b43, // n0x12ec c0x0000 (---------------) + I net + 0x00228743, // n0x12ed c0x0000 (---------------) + I org + 0x00233c03, // n0x12ee c0x0000 (---------------) + I ass + 0x002d5e84, // n0x12ef c0x0000 (---------------) + I asso + 0x00233243, // n0x12f0 c0x0000 (---------------) + I com + 0x0023c344, // n0x12f1 c0x0000 (---------------) + I coop + 0x00239103, // n0x12f2 c0x0000 (---------------) + I edu + 0x002aebc4, // n0x12f3 c0x0000 (---------------) + I gouv + 0x0027d903, // n0x12f4 c0x0000 (---------------) + I gov + 0x00378d47, // n0x12f5 c0x0000 (---------------) + I medecin + 0x00207dc3, // n0x12f6 c0x0000 (---------------) + I mil + 0x00201383, // n0x12f7 c0x0000 (---------------) + I nom + 0x0035f0c8, // n0x12f8 c0x0000 (---------------) + I notaires + 0x00228743, // n0x12f9 c0x0000 (---------------) + I org + 0x0034af0b, // n0x12fa c0x0000 (---------------) + I pharmaciens + 0x002e0bc3, // n0x12fb c0x0000 (---------------) + I prd + 0x00246a06, // n0x12fc c0x0000 (---------------) + I presse + 0x00200c82, // n0x12fd c0x0000 (---------------) + I tm + 0x002d32cb, // n0x12fe c0x0000 (---------------) + I veterinaire + 0x00239103, // n0x12ff c0x0000 (---------------) + I edu + 0x0027d903, // n0x1300 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1301 c0x0000 (---------------) + I net + 0x00228743, // n0x1302 c0x0000 (---------------) + I org + 0x00233243, // n0x1303 c0x0000 (---------------) + I com + 0x00239103, // n0x1304 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1305 c0x0000 (---------------) + I gov + 0x00228743, // n0x1306 c0x0000 (---------------) + I org + 0x0022ed83, // n0x1307 c0x0000 (---------------) + I rep + 0x00203903, // n0x1308 c0x0000 (---------------) + I tra + 0x00200342, // n0x1309 c0x0000 (---------------) + I ac + 0x000fe108, // n0x130a c0x0000 (---------------) + blogspot + 0x002b7ac5, // n0x130b c0x0000 (---------------) + I busan + 0x003147c8, // n0x130c c0x0000 (---------------) + I chungbuk + 0x0032a848, // n0x130d c0x0000 (---------------) + I chungnam + 0x0020ce42, // n0x130e c0x0000 (---------------) + I co + 0x00255dc5, // n0x130f c0x0000 (---------------) + I daegu + 0x003246c7, // n0x1310 c0x0000 (---------------) + I daejeon + 0x00200082, // n0x1311 c0x0000 (---------------) + I es + 0x00216287, // n0x1312 c0x0000 (---------------) + I gangwon + 0x00210a42, // n0x1313 c0x0000 (---------------) + I go + 0x00234607, // n0x1314 c0x0000 (---------------) + I gwangju + 0x0030d549, // n0x1315 c0x0000 (---------------) + I gyeongbuk + 0x00301c08, // n0x1316 c0x0000 (---------------) + I gyeonggi + 0x00206fc9, // n0x1317 c0x0000 (---------------) + I gyeongnam + 0x00233842, // n0x1318 c0x0000 (---------------) + I hs + 0x00267b47, // n0x1319 c0x0000 (---------------) + I incheon + 0x0024e044, // n0x131a c0x0000 (---------------) + I jeju + 0x00324787, // n0x131b c0x0000 (---------------) + I jeonbuk + 0x00300687, // n0x131c c0x0000 (---------------) + I jeonnam + 0x002b7202, // n0x131d c0x0000 (---------------) + I kg + 0x00207dc3, // n0x131e c0x0000 (---------------) + I mil + 0x00210f42, // n0x131f c0x0000 (---------------) + I ms + 0x00202ac2, // n0x1320 c0x0000 (---------------) + I ne + 0x00200dc2, // n0x1321 c0x0000 (---------------) + I or + 0x00200582, // n0x1322 c0x0000 (---------------) + I pe + 0x00208c82, // n0x1323 c0x0000 (---------------) + I re + 0x00207f02, // n0x1324 c0x0000 (---------------) + I sc + 0x00343d45, // n0x1325 c0x0000 (---------------) + I seoul + 0x00253b45, // n0x1326 c0x0000 (---------------) + I ulsan + 0x00233243, // n0x1327 c0x0000 (---------------) + I com + 0x00239103, // n0x1328 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1329 c0x0000 (---------------) + I gov + 0x00223b43, // n0x132a c0x0000 (---------------) + I net + 0x00228743, // n0x132b c0x0000 (---------------) + I org + 0x00233243, // n0x132c c0x0000 (---------------) + I com + 0x00239103, // n0x132d c0x0000 (---------------) + I edu + 0x0027d903, // n0x132e c0x0000 (---------------) + I gov + 0x00207dc3, // n0x132f c0x0000 (---------------) + I mil + 0x00223b43, // n0x1330 c0x0000 (---------------) + I net + 0x00228743, // n0x1331 c0x0000 (---------------) + I org + 0x00000141, // n0x1332 c0x0000 (---------------) + c + 0x00233243, // n0x1333 c0x0000 (---------------) + I com + 0x00239103, // n0x1334 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1335 c0x0000 (---------------) + I gov + 0x00201844, // n0x1336 c0x0000 (---------------) + I info + 0x00201503, // n0x1337 c0x0000 (---------------) + I int + 0x00223b43, // n0x1338 c0x0000 (---------------) + I net + 0x00228743, // n0x1339 c0x0000 (---------------) + I org + 0x0021e783, // n0x133a c0x0000 (---------------) + I per + 0x00233243, // n0x133b c0x0000 (---------------) + I com + 0x00239103, // n0x133c c0x0000 (---------------) + I edu + 0x0027d903, // n0x133d c0x0000 (---------------) + I gov + 0x00223b43, // n0x133e c0x0000 (---------------) + I net + 0x00228743, // n0x133f c0x0000 (---------------) + I org + 0x0020ce42, // n0x1340 c0x0000 (---------------) + I co + 0x00233243, // n0x1341 c0x0000 (---------------) + I com + 0x00239103, // n0x1342 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1343 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1344 c0x0000 (---------------) + I net + 0x00228743, // n0x1345 c0x0000 (---------------) + I org + 0x000fe108, // n0x1346 c0x0000 (---------------) + blogspot + 0x00200342, // n0x1347 c0x0000 (---------------) + I ac + 0x002bccc4, // n0x1348 c0x0000 (---------------) + I assn + 0x00233243, // n0x1349 c0x0000 (---------------) + I com + 0x00239103, // n0x134a c0x0000 (---------------) + I edu + 0x0027d903, // n0x134b c0x0000 (---------------) + I gov + 0x00305e43, // n0x134c c0x0000 (---------------) + I grp + 0x00234305, // n0x134d c0x0000 (---------------) + I hotel + 0x00201503, // n0x134e c0x0000 (---------------) + I int + 0x00312883, // n0x134f c0x0000 (---------------) + I ltd + 0x00223b43, // n0x1350 c0x0000 (---------------) + I net + 0x0023b383, // n0x1351 c0x0000 (---------------) + I ngo + 0x00228743, // n0x1352 c0x0000 (---------------) + I org + 0x00217283, // n0x1353 c0x0000 (---------------) + I sch + 0x00274603, // n0x1354 c0x0000 (---------------) + I soc + 0x0021e243, // n0x1355 c0x0000 (---------------) + I web + 0x00233243, // n0x1356 c0x0000 (---------------) + I com + 0x00239103, // n0x1357 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1358 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1359 c0x0000 (---------------) + I net + 0x00228743, // n0x135a c0x0000 (---------------) + I org + 0x0020ce42, // n0x135b c0x0000 (---------------) + I co + 0x00228743, // n0x135c c0x0000 (---------------) + I org + 0x000fe108, // n0x135d c0x0000 (---------------) + blogspot + 0x0027d903, // n0x135e c0x0000 (---------------) + I gov + 0x000fe108, // n0x135f c0x0000 (---------------) + blogspot + 0x0022b643, // n0x1360 c0x0000 (---------------) + I asn + 0x00233243, // n0x1361 c0x0000 (---------------) + I com + 0x00237344, // n0x1362 c0x0000 (---------------) + I conf + 0x00239103, // n0x1363 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1364 c0x0000 (---------------) + I gov + 0x0020d9c2, // n0x1365 c0x0000 (---------------) + I id + 0x00207dc3, // n0x1366 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1367 c0x0000 (---------------) + I net + 0x00228743, // n0x1368 c0x0000 (---------------) + I org + 0x00233243, // n0x1369 c0x0000 (---------------) + I com + 0x00239103, // n0x136a c0x0000 (---------------) + I edu + 0x0027d903, // n0x136b c0x0000 (---------------) + I gov + 0x0020d9c2, // n0x136c c0x0000 (---------------) + I id + 0x00213443, // n0x136d c0x0000 (---------------) + I med + 0x00223b43, // n0x136e c0x0000 (---------------) + I net + 0x00228743, // n0x136f c0x0000 (---------------) + I org + 0x002d96c3, // n0x1370 c0x0000 (---------------) + I plc + 0x00217283, // n0x1371 c0x0000 (---------------) + I sch + 0x00200342, // n0x1372 c0x0000 (---------------) + I ac + 0x0020ce42, // n0x1373 c0x0000 (---------------) + I co + 0x0027d903, // n0x1374 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1375 c0x0000 (---------------) + I net + 0x00228743, // n0x1376 c0x0000 (---------------) + I org + 0x00246a05, // n0x1377 c0x0000 (---------------) + I press + 0x002d5e84, // n0x1378 c0x0000 (---------------) + I asso + 0x00200c82, // n0x1379 c0x0000 (---------------) + I tm + 0x000fe108, // n0x137a c0x0000 (---------------) + blogspot + 0x00200342, // n0x137b c0x0000 (---------------) + I ac + 0x0020ce42, // n0x137c c0x0000 (---------------) + I co + 0x0005528b, // n0x137d c0x0000 (---------------) + diskstation + 0x00007ec7, // n0x137e c0x0000 (---------------) + dscloud + 0x00239103, // n0x137f c0x0000 (---------------) + I edu + 0x0027d903, // n0x1380 c0x0000 (---------------) + I gov + 0x00049fc4, // n0x1381 c0x0000 (---------------) + i234 + 0x00235383, // n0x1382 c0x0000 (---------------) + I its + 0x00049004, // n0x1383 c0x0000 (---------------) + myds + 0x00223b43, // n0x1384 c0x0000 (---------------) + I net + 0x00228743, // n0x1385 c0x0000 (---------------) + I org + 0x002e17c4, // n0x1386 c0x0000 (---------------) + I priv + 0x0010d3c8, // n0x1387 c0x0000 (---------------) + synology + 0x0020ce42, // n0x1388 c0x0000 (---------------) + I co + 0x00233243, // n0x1389 c0x0000 (---------------) + I com + 0x00239103, // n0x138a c0x0000 (---------------) + I edu + 0x0027d903, // n0x138b c0x0000 (---------------) + I gov + 0x00207dc3, // n0x138c c0x0000 (---------------) + I mil + 0x00201383, // n0x138d c0x0000 (---------------) + I nom + 0x00228743, // n0x138e c0x0000 (---------------) + I org + 0x002e0bc3, // n0x138f c0x0000 (---------------) + I prd + 0x00200c82, // n0x1390 c0x0000 (---------------) + I tm + 0x000fe108, // n0x1391 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1392 c0x0000 (---------------) + I com + 0x00239103, // n0x1393 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1394 c0x0000 (---------------) + I gov + 0x00201683, // n0x1395 c0x0000 (---------------) + I inf + 0x00200904, // n0x1396 c0x0000 (---------------) + I name + 0x00223b43, // n0x1397 c0x0000 (---------------) + I net + 0x00228743, // n0x1398 c0x0000 (---------------) + I org + 0x00233243, // n0x1399 c0x0000 (---------------) + I com + 0x00239103, // n0x139a c0x0000 (---------------) + I edu + 0x002aebc4, // n0x139b c0x0000 (---------------) + I gouv + 0x0027d903, // n0x139c c0x0000 (---------------) + I gov + 0x00223b43, // n0x139d c0x0000 (---------------) + I net + 0x00228743, // n0x139e c0x0000 (---------------) + I org + 0x00246a06, // n0x139f c0x0000 (---------------) + I presse + 0x00239103, // n0x13a0 c0x0000 (---------------) + I edu + 0x0027d903, // n0x13a1 c0x0000 (---------------) + I gov + 0x0016dcc3, // n0x13a2 c0x0000 (---------------) + nyc + 0x00228743, // n0x13a3 c0x0000 (---------------) + I org + 0x00233243, // n0x13a4 c0x0000 (---------------) + I com + 0x00239103, // n0x13a5 c0x0000 (---------------) + I edu + 0x0027d903, // n0x13a6 c0x0000 (---------------) + I gov + 0x00223b43, // n0x13a7 c0x0000 (---------------) + I net + 0x00228743, // n0x13a8 c0x0000 (---------------) + I org + 0x00007ec7, // n0x13a9 c0x0000 (---------------) + dscloud + 0x000fe108, // n0x13aa c0x0000 (---------------) + blogspot + 0x0027d903, // n0x13ab c0x0000 (---------------) + I gov + 0x00233243, // n0x13ac c0x0000 (---------------) + I com + 0x00239103, // n0x13ad c0x0000 (---------------) + I edu + 0x0027d903, // n0x13ae c0x0000 (---------------) + I gov + 0x00223b43, // n0x13af c0x0000 (---------------) + I net + 0x00228743, // n0x13b0 c0x0000 (---------------) + I org + 0x35a33243, // n0x13b1 c0x00d6 (n0x13b5-n0x13b6) + I com + 0x00239103, // n0x13b2 c0x0000 (---------------) + I edu + 0x00223b43, // n0x13b3 c0x0000 (---------------) + I net + 0x00228743, // n0x13b4 c0x0000 (---------------) + I org + 0x000fe108, // n0x13b5 c0x0000 (---------------) + blogspot + 0x00200342, // n0x13b6 c0x0000 (---------------) + I ac + 0x0020ce42, // n0x13b7 c0x0000 (---------------) + I co + 0x00233243, // n0x13b8 c0x0000 (---------------) + I com + 0x0027d903, // n0x13b9 c0x0000 (---------------) + I gov + 0x00223b43, // n0x13ba c0x0000 (---------------) + I net + 0x00200dc2, // n0x13bb c0x0000 (---------------) + I or + 0x00228743, // n0x13bc c0x0000 (---------------) + I org + 0x0030cf07, // n0x13bd c0x0000 (---------------) + I academy + 0x00208a4b, // n0x13be c0x0000 (---------------) + I agriculture + 0x00205103, // n0x13bf c0x0000 (---------------) + I air + 0x00239b48, // n0x13c0 c0x0000 (---------------) + I airguard + 0x003276c7, // n0x13c1 c0x0000 (---------------) + I alabama + 0x002799c6, // n0x13c2 c0x0000 (---------------) + I alaska + 0x00367785, // n0x13c3 c0x0000 (---------------) + I amber + 0x002c06c9, // n0x13c4 c0x0000 (---------------) + I ambulance + 0x00207b48, // n0x13c5 c0x0000 (---------------) + I american + 0x002f53c9, // n0x13c6 c0x0000 (---------------) + I americana + 0x002f53d0, // n0x13c7 c0x0000 (---------------) + I americanantiques + 0x003580cb, // n0x13c8 c0x0000 (---------------) + I americanart + 0x002c0509, // n0x13c9 c0x0000 (---------------) + I amsterdam + 0x00206ac3, // n0x13ca c0x0000 (---------------) + I and + 0x00249989, // n0x13cb c0x0000 (---------------) + I annefrank + 0x00238006, // n0x13cc c0x0000 (---------------) + I anthro + 0x0023800c, // n0x13cd c0x0000 (---------------) + I anthropology + 0x002b7b88, // n0x13ce c0x0000 (---------------) + I antiques + 0x003a0c48, // n0x13cf c0x0000 (---------------) + I aquarium + 0x002518c9, // n0x13d0 c0x0000 (---------------) + I arboretum + 0x002a128e, // n0x13d1 c0x0000 (---------------) + I archaeological + 0x0037080b, // n0x13d2 c0x0000 (---------------) + I archaeology + 0x00308e4c, // n0x13d3 c0x0000 (---------------) + I architecture + 0x00201d43, // n0x13d4 c0x0000 (---------------) + I art + 0x0038298c, // n0x13d5 c0x0000 (---------------) + I artanddesign + 0x00204bc9, // n0x13d6 c0x0000 (---------------) + I artcenter + 0x0020cd07, // n0x13d7 c0x0000 (---------------) + I artdeco + 0x0023904c, // n0x13d8 c0x0000 (---------------) + I arteducation + 0x0039164a, // n0x13d9 c0x0000 (---------------) + I artgallery + 0x0024b944, // n0x13da c0x0000 (---------------) + I arts + 0x003a3ccd, // n0x13db c0x0000 (---------------) + I artsandcrafts + 0x00382848, // n0x13dc c0x0000 (---------------) + I asmatart + 0x0039838d, // n0x13dd c0x0000 (---------------) + I assassination + 0x00337106, // n0x13de c0x0000 (---------------) + I assisi + 0x002d5e8b, // n0x13df c0x0000 (---------------) + I association + 0x00248e49, // n0x13e0 c0x0000 (---------------) + I astronomy + 0x00227d47, // n0x13e1 c0x0000 (---------------) + I atlanta + 0x002dc946, // n0x13e2 c0x0000 (---------------) + I austin + 0x0030af49, // n0x13e3 c0x0000 (---------------) + I australia + 0x0032364a, // n0x13e4 c0x0000 (---------------) + I automotive + 0x00359fc8, // n0x13e5 c0x0000 (---------------) + I aviation + 0x002e0584, // n0x13e6 c0x0000 (---------------) + I axis + 0x00276e07, // n0x13e7 c0x0000 (---------------) + I badajoz + 0x002a2fc7, // n0x13e8 c0x0000 (---------------) + I baghdad + 0x002f5184, // n0x13e9 c0x0000 (---------------) + I bahn + 0x0022a484, // n0x13ea c0x0000 (---------------) + I bale + 0x0025ce49, // n0x13eb c0x0000 (---------------) + I baltimore + 0x002e3209, // n0x13ec c0x0000 (---------------) + I barcelona + 0x0022df88, // n0x13ed c0x0000 (---------------) + I baseball + 0x00212305, // n0x13ee c0x0000 (---------------) + I basel + 0x003878c5, // n0x13ef c0x0000 (---------------) + I baths + 0x0020e4c6, // n0x13f0 c0x0000 (---------------) + I bauern + 0x003a3b89, // n0x13f1 c0x0000 (---------------) + I beauxarts + 0x002187cd, // n0x13f2 c0x0000 (---------------) + I beeldengeluid + 0x003088c8, // n0x13f3 c0x0000 (---------------) + I bellevue + 0x0020e3c7, // n0x13f4 c0x0000 (---------------) + I bergbau + 0x00367808, // n0x13f5 c0x0000 (---------------) + I berkeley + 0x0022fc06, // n0x13f6 c0x0000 (---------------) + I berlin + 0x0038fc84, // n0x13f7 c0x0000 (---------------) + I bern + 0x00356b45, // n0x13f8 c0x0000 (---------------) + I bible + 0x00202786, // n0x13f9 c0x0000 (---------------) + I bilbao + 0x00203784, // n0x13fa c0x0000 (---------------) + I bill + 0x00204ac7, // n0x13fb c0x0000 (---------------) + I birdart + 0x0020b1ca, // n0x13fc c0x0000 (---------------) + I birthplace + 0x00214304, // n0x13fd c0x0000 (---------------) + I bonn + 0x00218f86, // n0x13fe c0x0000 (---------------) + I boston + 0x0021b749, // n0x13ff c0x0000 (---------------) + I botanical + 0x0021b74f, // n0x1400 c0x0000 (---------------) + I botanicalgarden + 0x0021bd0d, // n0x1401 c0x0000 (---------------) + I botanicgarden + 0x0021c486, // n0x1402 c0x0000 (---------------) + I botany + 0x00220950, // n0x1403 c0x0000 (---------------) + I brandywinevalley + 0x00220d46, // n0x1404 c0x0000 (---------------) + I brasil + 0x00221e07, // n0x1405 c0x0000 (---------------) + I bristol + 0x00222187, // n0x1406 c0x0000 (---------------) + I british + 0x0022218f, // n0x1407 c0x0000 (---------------) + I britishcolumbia + 0x00223789, // n0x1408 c0x0000 (---------------) + I broadcast + 0x00226386, // n0x1409 c0x0000 (---------------) + I brunel + 0x00228407, // n0x140a c0x0000 (---------------) + I brussel + 0x00228408, // n0x140b c0x0000 (---------------) + I brussels + 0x00228909, // n0x140c c0x0000 (---------------) + I bruxelles + 0x00291688, // n0x140d c0x0000 (---------------) + I building + 0x002d7947, // n0x140e c0x0000 (---------------) + I burghof + 0x0020dc43, // n0x140f c0x0000 (---------------) + I bus + 0x002330c6, // n0x1410 c0x0000 (---------------) + I bushey + 0x00200e48, // n0x1411 c0x0000 (---------------) + I cadaques + 0x002a154a, // n0x1412 c0x0000 (---------------) + I california + 0x0021e309, // n0x1413 c0x0000 (---------------) + I cambridge + 0x00207c83, // n0x1414 c0x0000 (---------------) + I can + 0x003245c6, // n0x1415 c0x0000 (---------------) + I canada + 0x002da54a, // n0x1416 c0x0000 (---------------) + I capebreton + 0x00365a87, // n0x1417 c0x0000 (---------------) + I carrier + 0x0020cb4a, // n0x1418 c0x0000 (---------------) + I cartoonart + 0x0021500e, // n0x1419 c0x0000 (---------------) + I casadelamoneda + 0x002238c6, // n0x141a c0x0000 (---------------) + I castle + 0x002a7dc7, // n0x141b c0x0000 (---------------) + I castres + 0x002106c6, // n0x141c c0x0000 (---------------) + I celtic + 0x00204c86, // n0x141d c0x0000 (---------------) + I center + 0x0037304b, // n0x141e c0x0000 (---------------) + I chattanooga + 0x0026478a, // n0x141f c0x0000 (---------------) + I cheltenham + 0x0037b6cd, // n0x1420 c0x0000 (---------------) + I chesapeakebay + 0x002129c7, // n0x1421 c0x0000 (---------------) + I chicago + 0x00274688, // n0x1422 c0x0000 (---------------) + I children + 0x00274689, // n0x1423 c0x0000 (---------------) + I childrens + 0x0027468f, // n0x1424 c0x0000 (---------------) + I childrensgarden + 0x003799cc, // n0x1425 c0x0000 (---------------) + I chiropractic + 0x002b8789, // n0x1426 c0x0000 (---------------) + I chocolate + 0x003149ce, // n0x1427 c0x0000 (---------------) + I christiansburg + 0x00378e4a, // n0x1428 c0x0000 (---------------) + I cincinnati + 0x003028c6, // n0x1429 c0x0000 (---------------) + I cinema + 0x0033d286, // n0x142a c0x0000 (---------------) + I circus + 0x0036430c, // n0x142b c0x0000 (---------------) + I civilisation + 0x00367ccc, // n0x142c c0x0000 (---------------) + I civilization + 0x0036dd48, // n0x142d c0x0000 (---------------) + I civilwar + 0x00387a47, // n0x142e c0x0000 (---------------) + I clinton + 0x002b0885, // n0x142f c0x0000 (---------------) + I clock + 0x003524c4, // n0x1430 c0x0000 (---------------) + I coal + 0x0038510e, // n0x1431 c0x0000 (---------------) + I coastaldefence + 0x003238c4, // n0x1432 c0x0000 (---------------) + I cody + 0x00231a07, // n0x1433 c0x0000 (---------------) + I coldwar + 0x00263d8a, // n0x1434 c0x0000 (---------------) + I collection + 0x00232414, // n0x1435 c0x0000 (---------------) + I colonialwilliamsburg + 0x00232b0f, // n0x1436 c0x0000 (---------------) + I coloradoplateau + 0x00222348, // n0x1437 c0x0000 (---------------) + I columbia + 0x00232f88, // n0x1438 c0x0000 (---------------) + I columbus + 0x0036078d, // n0x1439 c0x0000 (---------------) + I communication + 0x0036078e, // n0x143a c0x0000 (---------------) + I communications + 0x00233249, // n0x143b c0x0000 (---------------) + I community + 0x00235b08, // n0x143c c0x0000 (---------------) + I computer + 0x00235b0f, // n0x143d c0x0000 (---------------) + I computerhistory + 0x00238d4c, // n0x143e c0x0000 (---------------) + I contemporary + 0x00238d4f, // n0x143f c0x0000 (---------------) + I contemporaryart + 0x0023a0c7, // n0x1440 c0x0000 (---------------) + I convent + 0x0023caca, // n0x1441 c0x0000 (---------------) + I copenhagen + 0x0021eccb, // n0x1442 c0x0000 (---------------) + I corporation + 0x002405c8, // n0x1443 c0x0000 (---------------) + I corvette + 0x00241907, // n0x1444 c0x0000 (---------------) + I costume + 0x0033798d, // n0x1445 c0x0000 (---------------) + I countryestate + 0x00321346, // n0x1446 c0x0000 (---------------) + I county + 0x003a3e86, // n0x1447 c0x0000 (---------------) + I crafts + 0x00242f89, // n0x1448 c0x0000 (---------------) + I cranbrook + 0x0031d9c8, // n0x1449 c0x0000 (---------------) + I creation + 0x00246d88, // n0x144a c0x0000 (---------------) + I cultural + 0x00246d8e, // n0x144b c0x0000 (---------------) + I culturalcenter + 0x00208b47, // n0x144c c0x0000 (---------------) + I culture + 0x00311f05, // n0x144d c0x0000 (---------------) + I cyber + 0x0024a0c5, // n0x144e c0x0000 (---------------) + I cymru + 0x00211bc4, // n0x144f c0x0000 (---------------) + I dali + 0x00279c86, // n0x1450 c0x0000 (---------------) + I dallas + 0x0022de88, // n0x1451 c0x0000 (---------------) + I database + 0x00329483, // n0x1452 c0x0000 (---------------) + I ddr + 0x0025df8e, // n0x1453 c0x0000 (---------------) + I decorativearts + 0x00337d48, // n0x1454 c0x0000 (---------------) + I delaware + 0x0027ad0b, // n0x1455 c0x0000 (---------------) + I delmenhorst + 0x0022b807, // n0x1456 c0x0000 (---------------) + I denmark + 0x00273e05, // n0x1457 c0x0000 (---------------) + I depot + 0x00228206, // n0x1458 c0x0000 (---------------) + I design + 0x002ab607, // n0x1459 c0x0000 (---------------) + I detroit + 0x002f9d88, // n0x145a c0x0000 (---------------) + I dinosaur + 0x00331309, // n0x145b c0x0000 (---------------) + I discovery + 0x00237a85, // n0x145c c0x0000 (---------------) + I dolls + 0x00287848, // n0x145d c0x0000 (---------------) + I donostia + 0x00205946, // n0x145e c0x0000 (---------------) + I durham + 0x00374bca, // n0x145f c0x0000 (---------------) + I eastafrica + 0x00385009, // n0x1460 c0x0000 (---------------) + I eastcoast + 0x00239109, // n0x1461 c0x0000 (---------------) + I education + 0x0023910b, // n0x1462 c0x0000 (---------------) + I educational + 0x0033c448, // n0x1463 c0x0000 (---------------) + I egyptian + 0x002f5049, // n0x1464 c0x0000 (---------------) + I eisenbahn + 0x002123c6, // n0x1465 c0x0000 (---------------) + I elburg + 0x002e5cca, // n0x1466 c0x0000 (---------------) + I elvendrell + 0x0022aa0a, // n0x1467 c0x0000 (---------------) + I embroidery + 0x0023cccc, // n0x1468 c0x0000 (---------------) + I encyclopedic + 0x00213087, // n0x1469 c0x0000 (---------------) + I england + 0x00301a0a, // n0x146a c0x0000 (---------------) + I entomology + 0x003307cb, // n0x146b c0x0000 (---------------) + I environment + 0x003307d9, // n0x146c c0x0000 (---------------) + I environmentalconservation + 0x00335a88, // n0x146d c0x0000 (---------------) + I epilepsy + 0x00246a85, // n0x146e c0x0000 (---------------) + I essex + 0x002c4206, // n0x146f c0x0000 (---------------) + I estate + 0x0030edc9, // n0x1470 c0x0000 (---------------) + I ethnology + 0x002009c6, // n0x1471 c0x0000 (---------------) + I exeter + 0x0021014a, // n0x1472 c0x0000 (---------------) + I exhibition + 0x00207d46, // n0x1473 c0x0000 (---------------) + I family + 0x0026a084, // n0x1474 c0x0000 (---------------) + I farm + 0x002c438d, // n0x1475 c0x0000 (---------------) + I farmequipment + 0x00327f47, // n0x1476 c0x0000 (---------------) + I farmers + 0x0026a089, // n0x1477 c0x0000 (---------------) + I farmstead + 0x003663c5, // n0x1478 c0x0000 (---------------) + I field + 0x00366788, // n0x1479 c0x0000 (---------------) + I figueres + 0x0037a689, // n0x147a c0x0000 (---------------) + I filatelia + 0x0024b184, // n0x147b c0x0000 (---------------) + I film + 0x0024b847, // n0x147c c0x0000 (---------------) + I fineart + 0x0024b848, // n0x147d c0x0000 (---------------) + I finearts + 0x0024c247, // n0x147e c0x0000 (---------------) + I finland + 0x002659c8, // n0x147f c0x0000 (---------------) + I flanders + 0x00252907, // n0x1480 c0x0000 (---------------) + I florida + 0x00338685, // n0x1481 c0x0000 (---------------) + I force + 0x00259d4c, // n0x1482 c0x0000 (---------------) + I fortmissoula + 0x0025a909, // n0x1483 c0x0000 (---------------) + I fortworth + 0x002b9f8a, // n0x1484 c0x0000 (---------------) + I foundation + 0x00384289, // n0x1485 c0x0000 (---------------) + I francaise + 0x00249a89, // n0x1486 c0x0000 (---------------) + I frankfurt + 0x0024ba4c, // n0x1487 c0x0000 (---------------) + I franziskaner + 0x002e808b, // n0x1488 c0x0000 (---------------) + I freemasonry + 0x0025c888, // n0x1489 c0x0000 (---------------) + I freiburg + 0x0025e788, // n0x148a c0x0000 (---------------) + I fribourg + 0x00261b44, // n0x148b c0x0000 (---------------) + I frog + 0x00283e08, // n0x148c c0x0000 (---------------) + I fundacio + 0x00284dc9, // n0x148d c0x0000 (---------------) + I furniture + 0x00391707, // n0x148e c0x0000 (---------------) + I gallery + 0x0021b986, // n0x148f c0x0000 (---------------) + I garden + 0x00245307, // n0x1490 c0x0000 (---------------) + I gateway + 0x00331589, // n0x1491 c0x0000 (---------------) + I geelvinck + 0x00212ccb, // n0x1492 c0x0000 (---------------) + I gemological + 0x00395947, // n0x1493 c0x0000 (---------------) + I geology + 0x003234c7, // n0x1494 c0x0000 (---------------) + I georgia + 0x00279707, // n0x1495 c0x0000 (---------------) + I giessen + 0x00398304, // n0x1496 c0x0000 (---------------) + I glas + 0x00398305, // n0x1497 c0x0000 (---------------) + I glass + 0x002a9585, // n0x1498 c0x0000 (---------------) + I gorge + 0x0033420b, // n0x1499 c0x0000 (---------------) + I grandrapids + 0x0038ef04, // n0x149a c0x0000 (---------------) + I graz + 0x00230008, // n0x149b c0x0000 (---------------) + I guernsey + 0x0028708a, // n0x149c c0x0000 (---------------) + I halloffame + 0x00205a07, // n0x149d c0x0000 (---------------) + I hamburg + 0x002f7f07, // n0x149e c0x0000 (---------------) + I handson + 0x0028db92, // n0x149f c0x0000 (---------------) + I harvestcelebration + 0x00257506, // n0x14a0 c0x0000 (---------------) + I hawaii + 0x002ae586, // n0x14a1 c0x0000 (---------------) + I health + 0x00312c8e, // n0x14a2 c0x0000 (---------------) + I heimatunduhren + 0x00258306, // n0x14a3 c0x0000 (---------------) + I hellas + 0x00209bc8, // n0x14a4 c0x0000 (---------------) + I helsinki + 0x0029270f, // n0x14a5 c0x0000 (---------------) + I hembygdsforbund + 0x00398748, // n0x14a6 c0x0000 (---------------) + I heritage + 0x0036d1c8, // n0x14a7 c0x0000 (---------------) + I histoire + 0x0034b70a, // n0x14a8 c0x0000 (---------------) + I historical + 0x0034b711, // n0x14a9 c0x0000 (---------------) + I historicalsociety + 0x002a354e, // n0x14aa c0x0000 (---------------) + I historichouses + 0x0025720a, // n0x14ab c0x0000 (---------------) + I historisch + 0x0025720c, // n0x14ac c0x0000 (---------------) + I historisches + 0x00235d07, // n0x14ad c0x0000 (---------------) + I history + 0x00235d10, // n0x14ae c0x0000 (---------------) + I historyofscience + 0x00202048, // n0x14af c0x0000 (---------------) + I horology + 0x002a3745, // n0x14b0 c0x0000 (---------------) + I house + 0x002abe4a, // n0x14b1 c0x0000 (---------------) + I humanities + 0x002037cc, // n0x14b2 c0x0000 (---------------) + I illustration + 0x002b61cd, // n0x14b3 c0x0000 (---------------) + I imageandsound + 0x002a5286, // n0x14b4 c0x0000 (---------------) + I indian + 0x002a5287, // n0x14b5 c0x0000 (---------------) + I indiana + 0x002a528c, // n0x14b6 c0x0000 (---------------) + I indianapolis + 0x002ec78c, // n0x14b7 c0x0000 (---------------) + I indianmarket + 0x002ff70c, // n0x14b8 c0x0000 (---------------) + I intelligence + 0x0028c78b, // n0x14b9 c0x0000 (---------------) + I interactive + 0x00286784, // n0x14ba c0x0000 (---------------) + I iraq + 0x0021c344, // n0x14bb c0x0000 (---------------) + I iron + 0x00349c89, // n0x14bc c0x0000 (---------------) + I isleofman + 0x002ca6c7, // n0x14bd c0x0000 (---------------) + I jamison + 0x0026e0c9, // n0x14be c0x0000 (---------------) + I jefferson + 0x00280d89, // n0x14bf c0x0000 (---------------) + I jerusalem + 0x00361547, // n0x14c0 c0x0000 (---------------) + I jewelry + 0x003914c6, // n0x14c1 c0x0000 (---------------) + I jewish + 0x003914c9, // n0x14c2 c0x0000 (---------------) + I jewishart + 0x0039b003, // n0x14c3 c0x0000 (---------------) + I jfk + 0x0027b20a, // n0x14c4 c0x0000 (---------------) + I journalism + 0x00352707, // n0x14c5 c0x0000 (---------------) + I judaica + 0x0027724b, // n0x14c6 c0x0000 (---------------) + I judygarland + 0x0037b54a, // n0x14c7 c0x0000 (---------------) + I juedisches + 0x00234744, // n0x14c8 c0x0000 (---------------) + I juif + 0x003507c6, // n0x14c9 c0x0000 (---------------) + I karate + 0x0027fd89, // n0x14ca c0x0000 (---------------) + I karikatur + 0x0033c884, // n0x14cb c0x0000 (---------------) + I kids + 0x00202d4a, // n0x14cc c0x0000 (---------------) + I koebenhavn + 0x002291c5, // n0x14cd c0x0000 (---------------) + I koeln + 0x002b6a85, // n0x14ce c0x0000 (---------------) + I kunst + 0x002b6a8d, // n0x14cf c0x0000 (---------------) + I kunstsammlung + 0x002b6dce, // n0x14d0 c0x0000 (---------------) + I kunstunddesign + 0x00317c05, // n0x14d1 c0x0000 (---------------) + I labor + 0x0038a446, // n0x14d2 c0x0000 (---------------) + I labour + 0x00246607, // n0x14d3 c0x0000 (---------------) + I lajolla + 0x002cb10a, // n0x14d4 c0x0000 (---------------) + I lancashire + 0x00323bc6, // n0x14d5 c0x0000 (---------------) + I landes + 0x0035bbc4, // n0x14d6 c0x0000 (---------------) + I lans + 0x002e0a07, // n0x14d7 c0x0000 (---------------) + I larsson + 0x00213d0b, // n0x14d8 c0x0000 (---------------) + I lewismiller + 0x0022fcc7, // n0x14d9 c0x0000 (---------------) + I lincoln + 0x002096c4, // n0x14da c0x0000 (---------------) + I linz + 0x002de986, // n0x14db c0x0000 (---------------) + I living + 0x002de98d, // n0x14dc c0x0000 (---------------) + I livinghistory + 0x0024960c, // n0x14dd c0x0000 (---------------) + I localhistory + 0x003114c6, // n0x14de c0x0000 (---------------) + I london + 0x00308aca, // n0x14df c0x0000 (---------------) + I losangeles + 0x0022ec86, // n0x14e0 c0x0000 (---------------) + I louvre + 0x0029d408, // n0x14e1 c0x0000 (---------------) + I loyalist + 0x002e6f07, // n0x14e2 c0x0000 (---------------) + I lucerne + 0x0023554a, // n0x14e3 c0x0000 (---------------) + I luxembourg + 0x0023c946, // n0x14e4 c0x0000 (---------------) + I luzern + 0x002128c3, // n0x14e5 c0x0000 (---------------) + I mad + 0x003197c6, // n0x14e6 c0x0000 (---------------) + I madrid + 0x00200cc8, // n0x14e7 c0x0000 (---------------) + I mallorca + 0x0029ad4a, // n0x14e8 c0x0000 (---------------) + I manchester + 0x00251d47, // n0x14e9 c0x0000 (---------------) + I mansion + 0x00251d48, // n0x14ea c0x0000 (---------------) + I mansions + 0x00268e04, // n0x14eb c0x0000 (---------------) + I manx + 0x00278d07, // n0x14ec c0x0000 (---------------) + I marburg + 0x00219cc8, // n0x14ed c0x0000 (---------------) + I maritime + 0x002a46c8, // n0x14ee c0x0000 (---------------) + I maritimo + 0x00257708, // n0x14ef c0x0000 (---------------) + I maryland + 0x00280a0a, // n0x14f0 c0x0000 (---------------) + I marylhurst + 0x00303545, // n0x14f1 c0x0000 (---------------) + I media + 0x00239607, // n0x14f2 c0x0000 (---------------) + I medical + 0x00257053, // n0x14f3 c0x0000 (---------------) + I medizinhistorisches + 0x00259186, // n0x14f4 c0x0000 (---------------) + I meeres + 0x0036e248, // n0x14f5 c0x0000 (---------------) + I memorial + 0x00225a49, // n0x14f6 c0x0000 (---------------) + I mesaverde + 0x00216148, // n0x14f7 c0x0000 (---------------) + I michigan + 0x00217bcb, // n0x14f8 c0x0000 (---------------) + I midatlantic + 0x002b94c8, // n0x14f9 c0x0000 (---------------) + I military + 0x00213e44, // n0x14fa c0x0000 (---------------) + I mill + 0x0030a546, // n0x14fb c0x0000 (---------------) + I miners + 0x00300206, // n0x14fc c0x0000 (---------------) + I mining + 0x002fc409, // n0x14fd c0x0000 (---------------) + I minnesota + 0x002c11c7, // n0x14fe c0x0000 (---------------) + I missile + 0x00259e48, // n0x14ff c0x0000 (---------------) + I missoula + 0x003a08c6, // n0x1500 c0x0000 (---------------) + I modern + 0x00306004, // n0x1501 c0x0000 (---------------) + I moma + 0x002c8705, // n0x1502 c0x0000 (---------------) + I money + 0x002c3608, // n0x1503 c0x0000 (---------------) + I monmouth + 0x002c3d4a, // n0x1504 c0x0000 (---------------) + I monticello + 0x002c4008, // n0x1505 c0x0000 (---------------) + I montreal + 0x002c8e46, // n0x1506 c0x0000 (---------------) + I moscow + 0x0029b44a, // n0x1507 c0x0000 (---------------) + I motorcycle + 0x002e7a88, // n0x1508 c0x0000 (---------------) + I muenchen + 0x002cb908, // n0x1509 c0x0000 (---------------) + I muenster + 0x002ccc08, // n0x150a c0x0000 (---------------) + I mulhouse + 0x002cd606, // n0x150b c0x0000 (---------------) + I muncie + 0x002d0ac6, // n0x150c c0x0000 (---------------) + I museet + 0x002f418c, // n0x150d c0x0000 (---------------) + I museumcenter + 0x002d1090, // n0x150e c0x0000 (---------------) + I museumvereniging + 0x002812c5, // n0x150f c0x0000 (---------------) + I music + 0x0031bbc8, // n0x1510 c0x0000 (---------------) + I national + 0x0031bbd0, // n0x1511 c0x0000 (---------------) + I nationalfirearms + 0x00398550, // n0x1512 c0x0000 (---------------) + I nationalheritage + 0x002f524e, // n0x1513 c0x0000 (---------------) + I nativeamerican + 0x002f3e0e, // n0x1514 c0x0000 (---------------) + I naturalhistory + 0x002f3e14, // n0x1515 c0x0000 (---------------) + I naturalhistorymuseum + 0x002dcacf, // n0x1516 c0x0000 (---------------) + I naturalsciences + 0x002dce86, // n0x1517 c0x0000 (---------------) + I nature + 0x003218d1, // n0x1518 c0x0000 (---------------) + I naturhistorisches + 0x00325193, // n0x1519 c0x0000 (---------------) + I natuurwetenschappen + 0x00325608, // n0x151a c0x0000 (---------------) + I naumburg + 0x00255505, // n0x151b c0x0000 (---------------) + I naval + 0x0024e708, // n0x151c c0x0000 (---------------) + I nebraska + 0x002e39c5, // n0x151d c0x0000 (---------------) + I neues + 0x0022c04c, // n0x151e c0x0000 (---------------) + I newhampshire + 0x002b10c9, // n0x151f c0x0000 (---------------) + I newjersey + 0x00231849, // n0x1520 c0x0000 (---------------) + I newmexico + 0x00245087, // n0x1521 c0x0000 (---------------) + I newport + 0x0021e609, // n0x1522 c0x0000 (---------------) + I newspaper + 0x00328187, // n0x1523 c0x0000 (---------------) + I newyork + 0x0029a5c6, // n0x1524 c0x0000 (---------------) + I niepce + 0x00356947, // n0x1525 c0x0000 (---------------) + I norfolk + 0x0023c505, // n0x1526 c0x0000 (---------------) + I north + 0x0026e2c3, // n0x1527 c0x0000 (---------------) + I nrw + 0x00329649, // n0x1528 c0x0000 (---------------) + I nuernberg + 0x0037ba89, // n0x1529 c0x0000 (---------------) + I nuremberg + 0x0036dcc3, // n0x152a c0x0000 (---------------) + I nyc + 0x0039f3c4, // n0x152b c0x0000 (---------------) + I nyny + 0x0031110d, // n0x152c c0x0000 (---------------) + I oceanographic + 0x0039f9cf, // n0x152d c0x0000 (---------------) + I oceanographique + 0x002fe985, // n0x152e c0x0000 (---------------) + I omaha + 0x00319c46, // n0x152f c0x0000 (---------------) + I online + 0x0039f847, // n0x1530 c0x0000 (---------------) + I ontario + 0x0033f507, // n0x1531 c0x0000 (---------------) + I openair + 0x0028a586, // n0x1532 c0x0000 (---------------) + I oregon + 0x0028a58b, // n0x1533 c0x0000 (---------------) + I oregontrail + 0x002a4c45, // n0x1534 c0x0000 (---------------) + I otago + 0x0039d306, // n0x1535 c0x0000 (---------------) + I oxford + 0x0038ff07, // n0x1536 c0x0000 (---------------) + I pacific + 0x002714c9, // n0x1537 c0x0000 (---------------) + I paderborn + 0x00311c06, // n0x1538 c0x0000 (---------------) + I palace + 0x0020c845, // n0x1539 c0x0000 (---------------) + I paleo + 0x00245b8b, // n0x153a c0x0000 (---------------) + I palmsprings + 0x002546c6, // n0x153b c0x0000 (---------------) + I panama + 0x00277705, // n0x153c c0x0000 (---------------) + I paris + 0x002b7348, // n0x153d c0x0000 (---------------) + I pasadena + 0x00373588, // n0x153e c0x0000 (---------------) + I pharmacy + 0x002d470c, // n0x153f c0x0000 (---------------) + I philadelphia + 0x002d4710, // n0x1540 c0x0000 (---------------) + I philadelphiaarea + 0x002d4dc9, // n0x1541 c0x0000 (---------------) + I philately + 0x002d5207, // n0x1542 c0x0000 (---------------) + I phoenix + 0x002d564b, // n0x1543 c0x0000 (---------------) + I photography + 0x002d6ac6, // n0x1544 c0x0000 (---------------) + I pilots + 0x002d780a, // n0x1545 c0x0000 (---------------) + I pittsburgh + 0x002d82cb, // n0x1546 c0x0000 (---------------) + I planetarium + 0x002d86ca, // n0x1547 c0x0000 (---------------) + I plantation + 0x002d8946, // n0x1548 c0x0000 (---------------) + I plants + 0x002d9585, // n0x1549 c0x0000 (---------------) + I plaza + 0x003275c6, // n0x154a c0x0000 (---------------) + I portal + 0x00279288, // n0x154b c0x0000 (---------------) + I portland + 0x0024514a, // n0x154c c0x0000 (---------------) + I portlligat + 0x0036041c, // n0x154d c0x0000 (---------------) + I posts-and-telecommunications + 0x002e0c8c, // n0x154e c0x0000 (---------------) + I preservation + 0x002e0f88, // n0x154f c0x0000 (---------------) + I presidio + 0x00246a05, // n0x1550 c0x0000 (---------------) + I press + 0x002e3dc7, // n0x1551 c0x0000 (---------------) + I project + 0x002a0ec6, // n0x1552 c0x0000 (---------------) + I public + 0x0038d045, // n0x1553 c0x0000 (---------------) + I pubol + 0x0021d986, // n0x1554 c0x0000 (---------------) + I quebec + 0x0028a748, // n0x1555 c0x0000 (---------------) + I railroad + 0x002b4f87, // n0x1556 c0x0000 (---------------) + I railway + 0x002a1188, // n0x1557 c0x0000 (---------------) + I research + 0x002a7eca, // n0x1558 c0x0000 (---------------) + I resistance + 0x0030b2cc, // n0x1559 c0x0000 (---------------) + I riodejaneiro + 0x0030b549, // n0x155a c0x0000 (---------------) + I rochester + 0x0038d387, // n0x155b c0x0000 (---------------) + I rockart + 0x0022cb44, // n0x155c c0x0000 (---------------) + I roma + 0x00252f46, // n0x155d c0x0000 (---------------) + I russia + 0x0036cd4a, // n0x155e c0x0000 (---------------) + I saintlouis + 0x00280e85, // n0x155f c0x0000 (---------------) + I salem + 0x0031f70c, // n0x1560 c0x0000 (---------------) + I salvadordali + 0x00320388, // n0x1561 c0x0000 (---------------) + I salzburg + 0x0023bf08, // n0x1562 c0x0000 (---------------) + I sandiego + 0x00399b0c, // n0x1563 c0x0000 (---------------) + I sanfrancisco + 0x0020df8c, // n0x1564 c0x0000 (---------------) + I santabarbara + 0x0020fd09, // n0x1565 c0x0000 (---------------) + I santacruz + 0x0020ff47, // n0x1566 c0x0000 (---------------) + I santafe + 0x002ae88c, // n0x1567 c0x0000 (---------------) + I saskatchewan + 0x003a5184, // n0x1568 c0x0000 (---------------) + I satx + 0x0037750a, // n0x1569 c0x0000 (---------------) + I savannahga + 0x0033cb8c, // n0x156a c0x0000 (---------------) + I schlesisches + 0x0027234b, // n0x156b c0x0000 (---------------) + I schoenbrunn + 0x0023100b, // n0x156c c0x0000 (---------------) + I schokoladen + 0x00232186, // n0x156d c0x0000 (---------------) + I school + 0x00237b87, // n0x156e c0x0000 (---------------) + I schweiz + 0x00235f47, // n0x156f c0x0000 (---------------) + I science + 0x00235f4f, // n0x1570 c0x0000 (---------------) + I science-fiction + 0x002ed0d1, // n0x1571 c0x0000 (---------------) + I scienceandhistory + 0x003a3452, // n0x1572 c0x0000 (---------------) + I scienceandindustry + 0x0024124d, // n0x1573 c0x0000 (---------------) + I sciencecenter + 0x0024124e, // n0x1574 c0x0000 (---------------) + I sciencecenters + 0x0024158e, // n0x1575 c0x0000 (---------------) + I sciencehistory + 0x002dcc88, // n0x1576 c0x0000 (---------------) + I sciences + 0x002dcc92, // n0x1577 c0x0000 (---------------) + I sciencesnaturelles + 0x00399d48, // n0x1578 c0x0000 (---------------) + I scotland + 0x002f9ac7, // n0x1579 c0x0000 (---------------) + I seaport + 0x0024fe8a, // n0x157a c0x0000 (---------------) + I settlement + 0x0021f7c8, // n0x157b c0x0000 (---------------) + I settlers + 0x002582c5, // n0x157c c0x0000 (---------------) + I shell + 0x002eb88a, // n0x157d c0x0000 (---------------) + I sherbrooke + 0x00221c07, // n0x157e c0x0000 (---------------) + I sibenik + 0x00358404, // n0x157f c0x0000 (---------------) + I silk + 0x00208503, // n0x1580 c0x0000 (---------------) + I ski + 0x00297b45, // n0x1581 c0x0000 (---------------) + I skole + 0x0034b987, // n0x1582 c0x0000 (---------------) + I society + 0x002e1e47, // n0x1583 c0x0000 (---------------) + I sologne + 0x002b63ce, // n0x1584 c0x0000 (---------------) + I soundandvision + 0x00302ccd, // n0x1585 c0x0000 (---------------) + I southcarolina + 0x003067c9, // n0x1586 c0x0000 (---------------) + I southwest + 0x0020aa85, // n0x1587 c0x0000 (---------------) + I space + 0x00332903, // n0x1588 c0x0000 (---------------) + I spy + 0x0027a146, // n0x1589 c0x0000 (---------------) + I square + 0x00364b45, // n0x158a c0x0000 (---------------) + I stadt + 0x0027af48, // n0x158b c0x0000 (---------------) + I stalbans + 0x00322809, // n0x158c c0x0000 (---------------) + I starnberg + 0x0020a205, // n0x158d c0x0000 (---------------) + I state + 0x00337b8f, // n0x158e c0x0000 (---------------) + I stateofdelaware + 0x00255387, // n0x158f c0x0000 (---------------) + I station + 0x00367605, // n0x1590 c0x0000 (---------------) + I steam + 0x00229cca, // n0x1591 c0x0000 (---------------) + I steiermark + 0x0033bd06, // n0x1592 c0x0000 (---------------) + I stjohn + 0x0029d589, // n0x1593 c0x0000 (---------------) + I stockholm + 0x003906cc, // n0x1594 c0x0000 (---------------) + I stpetersburg + 0x002e8d09, // n0x1595 c0x0000 (---------------) + I stuttgart + 0x0020b646, // n0x1596 c0x0000 (---------------) + I suisse + 0x00286e8c, // n0x1597 c0x0000 (---------------) + I surgeonshall + 0x002e9586, // n0x1598 c0x0000 (---------------) + I surrey + 0x002ebc08, // n0x1599 c0x0000 (---------------) + I svizzera + 0x002ebe06, // n0x159a c0x0000 (---------------) + I sweden + 0x00335c06, // n0x159b c0x0000 (---------------) + I sydney + 0x00355284, // n0x159c c0x0000 (---------------) + I tank + 0x0025ccc3, // n0x159d c0x0000 (---------------) + I tcm + 0x002ad44a, // n0x159e c0x0000 (---------------) + I technology + 0x0022ce51, // n0x159f c0x0000 (---------------) + I telekommunikation + 0x002b894a, // n0x15a0 c0x0000 (---------------) + I television + 0x0034aac5, // n0x15a1 c0x0000 (---------------) + I texas + 0x00382307, // n0x15a2 c0x0000 (---------------) + I textile + 0x00257a07, // n0x15a3 c0x0000 (---------------) + I theater + 0x00219dc4, // n0x15a4 c0x0000 (---------------) + I time + 0x00219dcb, // n0x15a5 c0x0000 (---------------) + I timekeeping + 0x00206e48, // n0x15a6 c0x0000 (---------------) + I topology + 0x002b34c6, // n0x15a7 c0x0000 (---------------) + I torino + 0x00288685, // n0x15a8 c0x0000 (---------------) + I touch + 0x002dc0c4, // n0x15a9 c0x0000 (---------------) + I town + 0x0029c509, // n0x15aa c0x0000 (---------------) + I transport + 0x00353204, // n0x15ab c0x0000 (---------------) + I tree + 0x0033f9c7, // n0x15ac c0x0000 (---------------) + I trolley + 0x0032a345, // n0x15ad c0x0000 (---------------) + I trust + 0x0032a347, // n0x15ae c0x0000 (---------------) + I trustee + 0x00312ec5, // n0x15af c0x0000 (---------------) + I uhren + 0x00349683, // n0x15b0 c0x0000 (---------------) + I ulm + 0x002f9988, // n0x15b1 c0x0000 (---------------) + I undersea + 0x00309e4a, // n0x15b2 c0x0000 (---------------) + I university + 0x00244843, // n0x15b3 c0x0000 (---------------) + I usa + 0x002b7b0a, // n0x15b4 c0x0000 (---------------) + I usantiques + 0x0028fdc6, // n0x15b5 c0x0000 (---------------) + I usarts + 0x0033790f, // n0x15b6 c0x0000 (---------------) + I uscountryestate + 0x0033d389, // n0x15b7 c0x0000 (---------------) + I usculture + 0x0025df10, // n0x15b8 c0x0000 (---------------) + I usdecorativearts + 0x0026ecc8, // n0x15b9 c0x0000 (---------------) + I usgarden + 0x002c96c9, // n0x15ba c0x0000 (---------------) + I ushistory + 0x0029e207, // n0x15bb c0x0000 (---------------) + I ushuaia + 0x002de90f, // n0x15bc c0x0000 (---------------) + I uslivinghistory + 0x002e8844, // n0x15bd c0x0000 (---------------) + I utah + 0x002aec44, // n0x15be c0x0000 (---------------) + I uvic + 0x00216c86, // n0x15bf c0x0000 (---------------) + I valley + 0x002371c6, // n0x15c0 c0x0000 (---------------) + I vantaa + 0x0031758a, // n0x15c1 c0x0000 (---------------) + I versailles + 0x0032ae86, // n0x15c2 c0x0000 (---------------) + I viking + 0x002ed947, // n0x15c3 c0x0000 (---------------) + I village + 0x002f6d88, // n0x15c4 c0x0000 (---------------) + I virginia + 0x002f6f87, // n0x15c5 c0x0000 (---------------) + I virtual + 0x002f7147, // n0x15c6 c0x0000 (---------------) + I virtuel + 0x0034514a, // n0x15c7 c0x0000 (---------------) + I vlaanderen + 0x002f97cb, // n0x15c8 c0x0000 (---------------) + I volkenkunde + 0x00309ac5, // n0x15c9 c0x0000 (---------------) + I wales + 0x003a3088, // n0x15ca c0x0000 (---------------) + I wallonie + 0x00203683, // n0x15cb c0x0000 (---------------) + I war + 0x0023f70c, // n0x15cc c0x0000 (---------------) + I washingtondc + 0x00375acf, // n0x15cd c0x0000 (---------------) + I watch-and-clock + 0x002b068d, // n0x15ce c0x0000 (---------------) + I watchandclock + 0x0023c647, // n0x15cf c0x0000 (---------------) + I western + 0x00306909, // n0x15d0 c0x0000 (---------------) + I westfalen + 0x0026e347, // n0x15d1 c0x0000 (---------------) + I whaling + 0x0035f308, // n0x15d2 c0x0000 (---------------) + I wildlife + 0x0023260c, // n0x15d3 c0x0000 (---------------) + I williamsburg + 0x00284bc8, // n0x15d4 c0x0000 (---------------) + I windmill + 0x00357088, // n0x15d5 c0x0000 (---------------) + I workshop + 0x0030ea4e, // n0x15d6 c0x0000 (---------------) + I xn--9dbhblg6di + 0x0031dbd4, // n0x15d7 c0x0000 (---------------) + I xn--comunicaes-v6a2o + 0x0031e0e4, // n0x15d8 c0x0000 (---------------) + I xn--correios-e-telecomunicaes-ghc29a + 0x0033be8a, // n0x15d9 c0x0000 (---------------) + I xn--h1aegh + 0x00358c0b, // n0x15da c0x0000 (---------------) + I xn--lns-qla + 0x00328244, // n0x15db c0x0000 (---------------) + I york + 0x00328249, // n0x15dc c0x0000 (---------------) + I yorkshire + 0x002abc48, // n0x15dd c0x0000 (---------------) + I yosemite + 0x0024a805, // n0x15de c0x0000 (---------------) + I youth + 0x00328f8a, // n0x15df c0x0000 (---------------) + I zoological + 0x0027a307, // n0x15e0 c0x0000 (---------------) + I zoology + 0x002e2dc4, // n0x15e1 c0x0000 (---------------) + I aero + 0x00331a83, // n0x15e2 c0x0000 (---------------) + I biz + 0x00233243, // n0x15e3 c0x0000 (---------------) + I com + 0x0023c344, // n0x15e4 c0x0000 (---------------) + I coop + 0x00239103, // n0x15e5 c0x0000 (---------------) + I edu + 0x0027d903, // n0x15e6 c0x0000 (---------------) + I gov + 0x00201844, // n0x15e7 c0x0000 (---------------) + I info + 0x00201503, // n0x15e8 c0x0000 (---------------) + I int + 0x00207dc3, // n0x15e9 c0x0000 (---------------) + I mil + 0x002d1086, // n0x15ea c0x0000 (---------------) + I museum + 0x00200904, // n0x15eb c0x0000 (---------------) + I name + 0x00223b43, // n0x15ec c0x0000 (---------------) + I net + 0x00228743, // n0x15ed c0x0000 (---------------) + I org + 0x00224b03, // n0x15ee c0x0000 (---------------) + I pro + 0x00200342, // n0x15ef c0x0000 (---------------) + I ac + 0x00331a83, // n0x15f0 c0x0000 (---------------) + I biz + 0x0020ce42, // n0x15f1 c0x0000 (---------------) + I co + 0x00233243, // n0x15f2 c0x0000 (---------------) + I com + 0x0023c344, // n0x15f3 c0x0000 (---------------) + I coop + 0x00239103, // n0x15f4 c0x0000 (---------------) + I edu + 0x0027d903, // n0x15f5 c0x0000 (---------------) + I gov + 0x00201503, // n0x15f6 c0x0000 (---------------) + I int + 0x002d1086, // n0x15f7 c0x0000 (---------------) + I museum + 0x00223b43, // n0x15f8 c0x0000 (---------------) + I net + 0x00228743, // n0x15f9 c0x0000 (---------------) + I org + 0x000fe108, // n0x15fa c0x0000 (---------------) + blogspot + 0x00233243, // n0x15fb c0x0000 (---------------) + I com + 0x00239103, // n0x15fc c0x0000 (---------------) + I edu + 0x00212b03, // n0x15fd c0x0000 (---------------) + I gob + 0x00223b43, // n0x15fe c0x0000 (---------------) + I net + 0x00228743, // n0x15ff c0x0000 (---------------) + I org + 0x000fe108, // n0x1600 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1601 c0x0000 (---------------) + I com + 0x00239103, // n0x1602 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1603 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1604 c0x0000 (---------------) + I mil + 0x00200904, // n0x1605 c0x0000 (---------------) + I name + 0x00223b43, // n0x1606 c0x0000 (---------------) + I net + 0x00228743, // n0x1607 c0x0000 (---------------) + I org + 0x0062dd88, // n0x1608 c0x0001 (---------------) ! I teledata + 0x00200e42, // n0x1609 c0x0000 (---------------) + I ca + 0x0022f6c2, // n0x160a c0x0000 (---------------) + I cc + 0x0020ce42, // n0x160b c0x0000 (---------------) + I co + 0x00233243, // n0x160c c0x0000 (---------------) + I com + 0x0026ab42, // n0x160d c0x0000 (---------------) + I dr + 0x002012c2, // n0x160e c0x0000 (---------------) + I in + 0x00201844, // n0x160f c0x0000 (---------------) + I info + 0x0020bf04, // n0x1610 c0x0000 (---------------) + I mobi + 0x002195c2, // n0x1611 c0x0000 (---------------) + I mx + 0x00200904, // n0x1612 c0x0000 (---------------) + I name + 0x00200dc2, // n0x1613 c0x0000 (---------------) + I or + 0x00228743, // n0x1614 c0x0000 (---------------) + I org + 0x00224b03, // n0x1615 c0x0000 (---------------) + I pro + 0x00232186, // n0x1616 c0x0000 (---------------) + I school + 0x002203c2, // n0x1617 c0x0000 (---------------) + I tv + 0x00202242, // n0x1618 c0x0000 (---------------) + I us + 0x0020a882, // n0x1619 c0x0000 (---------------) + I ws + 0x38225983, // n0x161a c0x00e0 (n0x161c-n0x161d) o I her + 0x38618043, // n0x161b c0x00e1 (n0x161d-n0x161e) o I his + 0x000580c6, // n0x161c c0x0000 (---------------) + forgot + 0x000580c6, // n0x161d c0x0000 (---------------) + forgot + 0x002d5e84, // n0x161e c0x0000 (---------------) + I asso + 0x0011928c, // n0x161f c0x0000 (---------------) + at-band-camp + 0x00081bcc, // n0x1620 c0x0000 (---------------) + azure-mobile + 0x000c234d, // n0x1621 c0x0000 (---------------) + azurewebsites + 0x0002f087, // n0x1622 c0x0000 (---------------) + blogdns + 0x00023f48, // n0x1623 c0x0000 (---------------) + broke-it + 0x00197f4a, // n0x1624 c0x0000 (---------------) + buyshouses + 0x39262e05, // n0x1625 c0x00e4 (n0x1654-n0x1655) o I cdn77 + 0x00062e09, // n0x1626 c0x0000 (---------------) + cdn77-ssl + 0x00007f48, // n0x1627 c0x0000 (---------------) + cloudapp + 0x0019e90a, // n0x1628 c0x0000 (---------------) + cloudfront + 0x00030c4e, // n0x1629 c0x0000 (---------------) + cloudfunctions + 0x00142e48, // n0x162a c0x0000 (---------------) + dnsalias + 0x0007cf07, // n0x162b c0x0000 (---------------) + dnsdojo + 0x00160c07, // n0x162c c0x0000 (---------------) + does-it + 0x0016a789, // n0x162d c0x0000 (---------------) + dontexist + 0x0013c907, // n0x162e c0x0000 (---------------) + dsmynas + 0x00197108, // n0x162f c0x0000 (---------------) + dynalias + 0x000f3449, // n0x1630 c0x0000 (---------------) + dynathome + 0x000aa38d, // n0x1631 c0x0000 (---------------) + endofinternet + 0x00007d48, // n0x1632 c0x0000 (---------------) + familyds + 0x39646286, // n0x1633 c0x00e5 (n0x1655-n0x1657) o I fastly + 0x00062a47, // n0x1634 c0x0000 (---------------) + from-az + 0x00063c47, // n0x1635 c0x0000 (---------------) + from-co + 0x000688c7, // n0x1636 c0x0000 (---------------) + from-la + 0x000709c7, // n0x1637 c0x0000 (---------------) + from-ny + 0x0000e482, // n0x1638 c0x0000 (---------------) + gb + 0x00049d47, // n0x1639 c0x0000 (---------------) + gets-it + 0x0006494c, // n0x163a c0x0000 (---------------) + ham-radio-op + 0x00120a07, // n0x163b c0x0000 (---------------) + homeftp + 0x000a6806, // n0x163c c0x0000 (---------------) + homeip + 0x000a6dc9, // n0x163d c0x0000 (---------------) + homelinux + 0x000a8148, // n0x163e c0x0000 (---------------) + homeunix + 0x00024202, // n0x163f c0x0000 (---------------) + hu + 0x000012c2, // n0x1640 c0x0000 (---------------) + in + 0x000068cb, // n0x1641 c0x0000 (---------------) + in-the-band + 0x000110c9, // n0x1642 c0x0000 (---------------) + is-a-chef + 0x0004ef49, // n0x1643 c0x0000 (---------------) + is-a-geek + 0x000862c8, // n0x1644 c0x0000 (---------------) + isa-geek + 0x000b00c2, // n0x1645 c0x0000 (---------------) + jp + 0x0014ee89, // n0x1646 c0x0000 (---------------) + kicks-ass + 0x0001decd, // n0x1647 c0x0000 (---------------) + office-on-the + 0x000dd687, // n0x1648 c0x0000 (---------------) + podzone + 0x00127bc8, // n0x1649 c0x0000 (---------------) + rackmaze + 0x0004344d, // n0x164a c0x0000 (---------------) + scrapper-site + 0x00004ec2, // n0x164b c0x0000 (---------------) + se + 0x0005abc6, // n0x164c c0x0000 (---------------) + selfip + 0x00091b08, // n0x164d c0x0000 (---------------) + sells-it + 0x000ccd88, // n0x164e c0x0000 (---------------) + servebbs + 0x0008bc88, // n0x164f c0x0000 (---------------) + serveftp + 0x000549c8, // n0x1650 c0x0000 (---------------) + thruhere + 0x00001b02, // n0x1651 c0x0000 (---------------) + uk + 0x001267c6, // n0x1652 c0x0000 (---------------) + webhop + 0x00000182, // n0x1653 c0x0000 (---------------) + za + 0x000006c1, // n0x1654 c0x0000 (---------------) + r + 0x39ae1bc4, // n0x1655 c0x00e6 (n0x1657-n0x1659) o I prod + 0x39e62f83, // n0x1656 c0x00e7 (n0x1659-n0x165c) o I ssl + 0x000001c1, // n0x1657 c0x0000 (---------------) + a + 0x0000eac6, // n0x1658 c0x0000 (---------------) + global + 0x000001c1, // n0x1659 c0x0000 (---------------) + a + 0x00000001, // n0x165a c0x0000 (---------------) + b + 0x0000eac6, // n0x165b c0x0000 (---------------) + global + 0x0024b944, // n0x165c c0x0000 (---------------) + I arts + 0x00233243, // n0x165d c0x0000 (---------------) + I com + 0x0024dcc4, // n0x165e c0x0000 (---------------) + I firm + 0x00201844, // n0x165f c0x0000 (---------------) + I info + 0x00223b43, // n0x1660 c0x0000 (---------------) + I net + 0x00225905, // n0x1661 c0x0000 (---------------) + I other + 0x0021e783, // n0x1662 c0x0000 (---------------) + I per + 0x0022c2c3, // n0x1663 c0x0000 (---------------) + I rec + 0x00364cc5, // n0x1664 c0x0000 (---------------) + I store + 0x0021e243, // n0x1665 c0x0000 (---------------) + I web + 0x3aa33243, // n0x1666 c0x00ea (n0x1670-n0x1671) + I com + 0x00239103, // n0x1667 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1668 c0x0000 (---------------) + I gov + 0x00200041, // n0x1669 c0x0000 (---------------) + I i + 0x00207dc3, // n0x166a c0x0000 (---------------) + I mil + 0x0020bf04, // n0x166b c0x0000 (---------------) + I mobi + 0x00200904, // n0x166c c0x0000 (---------------) + I name + 0x00223b43, // n0x166d c0x0000 (---------------) + I net + 0x00228743, // n0x166e c0x0000 (---------------) + I org + 0x00217283, // n0x166f c0x0000 (---------------) + I sch + 0x000fe108, // n0x1670 c0x0000 (---------------) + blogspot + 0x00200342, // n0x1671 c0x0000 (---------------) + I ac + 0x00331a83, // n0x1672 c0x0000 (---------------) + I biz + 0x0020ce42, // n0x1673 c0x0000 (---------------) + I co + 0x00233243, // n0x1674 c0x0000 (---------------) + I com + 0x00239103, // n0x1675 c0x0000 (---------------) + I edu + 0x00212b03, // n0x1676 c0x0000 (---------------) + I gob + 0x002012c2, // n0x1677 c0x0000 (---------------) + I in + 0x00201844, // n0x1678 c0x0000 (---------------) + I info + 0x00201503, // n0x1679 c0x0000 (---------------) + I int + 0x00207dc3, // n0x167a c0x0000 (---------------) + I mil + 0x00223b43, // n0x167b c0x0000 (---------------) + I net + 0x00201383, // n0x167c c0x0000 (---------------) + I nom + 0x00228743, // n0x167d c0x0000 (---------------) + I org + 0x0021e243, // n0x167e c0x0000 (---------------) + I web + 0x000fe108, // n0x167f c0x0000 (---------------) + blogspot + 0x00365fc2, // n0x1680 c0x0000 (---------------) + I bv + 0x0000ce42, // n0x1681 c0x0000 (---------------) + co + 0x3ba26782, // n0x1682 c0x00ee (n0x1958-n0x1959) + I aa + 0x003528c8, // n0x1683 c0x0000 (---------------) + I aarborte + 0x00226c06, // n0x1684 c0x0000 (---------------) + I aejrie + 0x002bd6c6, // n0x1685 c0x0000 (---------------) + I afjord + 0x00226587, // n0x1686 c0x0000 (---------------) + I agdenes + 0x3be05702, // n0x1687 c0x00ef (n0x1959-n0x195a) + I ah + 0x3c23ed88, // n0x1688 c0x00f0 (n0x195a-n0x195b) o I akershus + 0x00351cca, // n0x1689 c0x0000 (---------------) + I aknoluokta + 0x002624c8, // n0x168a c0x0000 (---------------) + I akrehamn + 0x00200d02, // n0x168b c0x0000 (---------------) + I al + 0x00352549, // n0x168c c0x0000 (---------------) + I alaheadju + 0x00309b07, // n0x168d c0x0000 (---------------) + I alesund + 0x0021b906, // n0x168e c0x0000 (---------------) + I algard + 0x00205609, // n0x168f c0x0000 (---------------) + I alstahaug + 0x00239744, // n0x1690 c0x0000 (---------------) + I alta + 0x002be146, // n0x1691 c0x0000 (---------------) + I alvdal + 0x002bdac4, // n0x1692 c0x0000 (---------------) + I amli + 0x00278404, // n0x1693 c0x0000 (---------------) + I amot + 0x00259989, // n0x1694 c0x0000 (---------------) + I andasuolo + 0x002b8206, // n0x1695 c0x0000 (---------------) + I andebu + 0x002293c5, // n0x1696 c0x0000 (---------------) + I andoy + 0x00266b05, // n0x1697 c0x0000 (---------------) + I ardal + 0x00234047, // n0x1698 c0x0000 (---------------) + I aremark + 0x002b9947, // n0x1699 c0x0000 (---------------) + I arendal + 0x003549c4, // n0x169a c0x0000 (---------------) + I arna + 0x002267c6, // n0x169b c0x0000 (---------------) + I aseral + 0x002e2685, // n0x169c c0x0000 (---------------) + I asker + 0x0023e085, // n0x169d c0x0000 (---------------) + I askim + 0x002f1385, // n0x169e c0x0000 (---------------) + I askoy + 0x00387687, // n0x169f c0x0000 (---------------) + I askvoll + 0x0022b645, // n0x16a0 c0x0000 (---------------) + I asnes + 0x0030bb89, // n0x16a1 c0x0000 (---------------) + I audnedaln + 0x0025d9c5, // n0x16a2 c0x0000 (---------------) + I aukra + 0x002f9ec4, // n0x16a3 c0x0000 (---------------) + I aure + 0x00323b07, // n0x16a4 c0x0000 (---------------) + I aurland + 0x0026a80e, // n0x16a5 c0x0000 (---------------) + I aurskog-holand + 0x002f3a49, // n0x16a6 c0x0000 (---------------) + I austevoll + 0x00312b49, // n0x16a7 c0x0000 (---------------) + I austrheim + 0x00330606, // n0x16a8 c0x0000 (---------------) + I averoy + 0x002eaac8, // n0x16a9 c0x0000 (---------------) + I badaddja + 0x002afb0b, // n0x16aa c0x0000 (---------------) + I bahcavuotna + 0x002d2a0c, // n0x16ab c0x0000 (---------------) + I bahccavuotna + 0x00268b46, // n0x16ac c0x0000 (---------------) + I baidar + 0x003706c7, // n0x16ad c0x0000 (---------------) + I bajddar + 0x0026b905, // n0x16ae c0x0000 (---------------) + I balat + 0x0022a48a, // n0x16af c0x0000 (---------------) + I balestrand + 0x00307649, // n0x16b0 c0x0000 (---------------) + I ballangen + 0x00255089, // n0x16b1 c0x0000 (---------------) + I balsfjord + 0x00269c86, // n0x16b2 c0x0000 (---------------) + I bamble + 0x002eb045, // n0x16b3 c0x0000 (---------------) + I bardu + 0x002804c5, // n0x16b4 c0x0000 (---------------) + I barum + 0x003517c9, // n0x16b5 c0x0000 (---------------) + I batsfjord + 0x002f150b, // n0x16b6 c0x0000 (---------------) + I bearalvahki + 0x0027cbc6, // n0x16b7 c0x0000 (---------------) + I beardu + 0x0032f586, // n0x16b8 c0x0000 (---------------) + I beiarn + 0x0020e3c4, // n0x16b9 c0x0000 (---------------) + I berg + 0x0028d846, // n0x16ba c0x0000 (---------------) + I bergen + 0x00311f88, // n0x16bb c0x0000 (---------------) + I berlevag + 0x00200b46, // n0x16bc c0x0000 (---------------) + I bievat + 0x0038df46, // n0x16bd c0x0000 (---------------) + I bindal + 0x00205d48, // n0x16be c0x0000 (---------------) + I birkenes + 0x0020b447, // n0x16bf c0x0000 (---------------) + I bjarkoy + 0x0020bcc9, // n0x16c0 c0x0000 (---------------) + I bjerkreim + 0x0020d4c5, // n0x16c1 c0x0000 (---------------) + I bjugn + 0x000fe108, // n0x16c2 c0x0000 (---------------) + blogspot + 0x00212b84, // n0x16c3 c0x0000 (---------------) + I bodo + 0x0023dc84, // n0x16c4 c0x0000 (---------------) + I bokn + 0x00213985, // n0x16c5 c0x0000 (---------------) + I bomlo + 0x0038b709, // n0x16c6 c0x0000 (---------------) + I bremanger + 0x00224f47, // n0x16c7 c0x0000 (---------------) + I bronnoy + 0x00224f4b, // n0x16c8 c0x0000 (---------------) + I bronnoysund + 0x00225e8a, // n0x16c9 c0x0000 (---------------) + I brumunddal + 0x0022a185, // n0x16ca c0x0000 (---------------) + I bryne + 0x3c605ac2, // n0x16cb c0x00f1 (n0x195b-n0x195c) + I bu + 0x0037b407, // n0x16cc c0x0000 (---------------) + I budejju + 0x3ca2be08, // n0x16cd c0x00f2 (n0x195c-n0x195d) o I buskerud + 0x002b9187, // n0x16ce c0x0000 (---------------) + I bygland + 0x002b8545, // n0x16cf c0x0000 (---------------) + I bykle + 0x0024940a, // n0x16d0 c0x0000 (---------------) + I cahcesuolo + 0x0000ce42, // n0x16d1 c0x0000 (---------------) + co + 0x002db24b, // n0x16d2 c0x0000 (---------------) + I davvenjarga + 0x0021530a, // n0x16d3 c0x0000 (---------------) + I davvesiida + 0x0039d446, // n0x16d4 c0x0000 (---------------) + I deatnu + 0x00273e03, // n0x16d5 c0x0000 (---------------) + I dep + 0x0037834d, // n0x16d6 c0x0000 (---------------) + I dielddanuorri + 0x0026a28c, // n0x16d7 c0x0000 (---------------) + I divtasvuodna + 0x0030808d, // n0x16d8 c0x0000 (---------------) + I divttasvuotna + 0x0035e605, // n0x16d9 c0x0000 (---------------) + I donna + 0x00268605, // n0x16da c0x0000 (---------------) + I dovre + 0x003294c7, // n0x16db c0x0000 (---------------) + I drammen + 0x0031ff89, // n0x16dc c0x0000 (---------------) + I drangedal + 0x00351bc6, // n0x16dd c0x0000 (---------------) + I drobak + 0x0032ad05, // n0x16de c0x0000 (---------------) + I dyroy + 0x0022f808, // n0x16df c0x0000 (---------------) + I egersund + 0x0024ea03, // n0x16e0 c0x0000 (---------------) + I eid + 0x0032ab48, // n0x16e1 c0x0000 (---------------) + I eidfjord + 0x0028d748, // n0x16e2 c0x0000 (---------------) + I eidsberg + 0x002bf047, // n0x16e3 c0x0000 (---------------) + I eidskog + 0x0024ea08, // n0x16e4 c0x0000 (---------------) + I eidsvoll + 0x002005c9, // n0x16e5 c0x0000 (---------------) + I eigersund + 0x0023aec7, // n0x16e6 c0x0000 (---------------) + I elverum + 0x002085c7, // n0x16e7 c0x0000 (---------------) + I enebakk + 0x00279848, // n0x16e8 c0x0000 (---------------) + I engerdal + 0x0035cd84, // n0x16e9 c0x0000 (---------------) + I etne + 0x0035cd87, // n0x16ea c0x0000 (---------------) + I etnedal + 0x00337008, // n0x16eb c0x0000 (---------------) + I evenassi + 0x00202a06, // n0x16ec c0x0000 (---------------) + I evenes + 0x0039978f, // n0x16ed c0x0000 (---------------) + I evje-og-hornnes + 0x002112c7, // n0x16ee c0x0000 (---------------) + I farsund + 0x0024cac6, // n0x16ef c0x0000 (---------------) + I fauske + 0x0024df85, // n0x16f0 c0x0000 (---------------) + I fedje + 0x00343683, // n0x16f1 c0x0000 (---------------) + I fet + 0x00343687, // n0x16f2 c0x0000 (---------------) + I fetsund + 0x00233803, // n0x16f3 c0x0000 (---------------) + I fhs + 0x0024c406, // n0x16f4 c0x0000 (---------------) + I finnoy + 0x0024f586, // n0x16f5 c0x0000 (---------------) + I fitjar + 0x00250246, // n0x16f6 c0x0000 (---------------) + I fjaler + 0x00291145, // n0x16f7 c0x0000 (---------------) + I fjell + 0x002659c3, // n0x16f8 c0x0000 (---------------) + I fla + 0x0037e548, // n0x16f9 c0x0000 (---------------) + I flakstad + 0x0031c809, // n0x16fa c0x0000 (---------------) + I flatanger + 0x003654cb, // n0x16fb c0x0000 (---------------) + I flekkefjord + 0x00376188, // n0x16fc c0x0000 (---------------) + I flesberg + 0x002525c5, // n0x16fd c0x0000 (---------------) + I flora + 0x002530c5, // n0x16fe c0x0000 (---------------) + I floro + 0x3ce34802, // n0x16ff c0x00f3 (n0x195d-n0x195e) + I fm + 0x00356a09, // n0x1700 c0x0000 (---------------) + I folkebibl + 0x00256307, // n0x1701 c0x0000 (---------------) + I folldal + 0x0039d385, // n0x1702 c0x0000 (---------------) + I forde + 0x00259887, // n0x1703 c0x0000 (---------------) + I forsand + 0x0025bd86, // n0x1704 c0x0000 (---------------) + I fosnes + 0x0035d5c5, // n0x1705 c0x0000 (---------------) + I frana + 0x0036498b, // n0x1706 c0x0000 (---------------) + I fredrikstad + 0x0025c884, // n0x1707 c0x0000 (---------------) + I frei + 0x00262085, // n0x1708 c0x0000 (---------------) + I frogn + 0x002621c7, // n0x1709 c0x0000 (---------------) + I froland + 0x00276806, // n0x170a c0x0000 (---------------) + I frosta + 0x00276c45, // n0x170b c0x0000 (---------------) + I froya + 0x00284007, // n0x170c c0x0000 (---------------) + I fuoisku + 0x00284947, // n0x170d c0x0000 (---------------) + I fuossko + 0x0028fd84, // n0x170e c0x0000 (---------------) + I fusa + 0x0028b38a, // n0x170f c0x0000 (---------------) + I fylkesbibl + 0x0028b848, // n0x1710 c0x0000 (---------------) + I fyresdal + 0x003020c9, // n0x1711 c0x0000 (---------------) + I gaivuotna + 0x00221fc5, // n0x1712 c0x0000 (---------------) + I galsa + 0x002db486, // n0x1713 c0x0000 (---------------) + I gamvik + 0x0031214a, // n0x1714 c0x0000 (---------------) + I gangaviika + 0x00266a06, // n0x1715 c0x0000 (---------------) + I gaular + 0x0026e5c7, // n0x1716 c0x0000 (---------------) + I gausdal + 0x00301d8d, // n0x1717 c0x0000 (---------------) + I giehtavuoatna + 0x00225509, // n0x1718 c0x0000 (---------------) + I gildeskal + 0x00382fc5, // n0x1719 c0x0000 (---------------) + I giske + 0x00313407, // n0x171a c0x0000 (---------------) + I gjemnes + 0x003257c8, // n0x171b c0x0000 (---------------) + I gjerdrum + 0x00354088, // n0x171c c0x0000 (---------------) + I gjerstad + 0x0022b207, // n0x171d c0x0000 (---------------) + I gjesdal + 0x00248b06, // n0x171e c0x0000 (---------------) + I gjovik + 0x00212507, // n0x171f c0x0000 (---------------) + I gloppen + 0x0024dec3, // n0x1720 c0x0000 (---------------) + I gol + 0x00334204, // n0x1721 c0x0000 (---------------) + I gran + 0x0035a405, // n0x1722 c0x0000 (---------------) + I grane + 0x003833c7, // n0x1723 c0x0000 (---------------) + I granvin + 0x00387089, // n0x1724 c0x0000 (---------------) + I gratangen + 0x0021db48, // n0x1725 c0x0000 (---------------) + I grimstad + 0x0026e4c5, // n0x1726 c0x0000 (---------------) + I grong + 0x00314d04, // n0x1727 c0x0000 (---------------) + I grue + 0x00235785, // n0x1728 c0x0000 (---------------) + I gulen + 0x0034938d, // n0x1729 c0x0000 (---------------) + I guovdageaidnu + 0x00202302, // n0x172a c0x0000 (---------------) + I ha + 0x0036d3c6, // n0x172b c0x0000 (---------------) + I habmer + 0x0025ab06, // n0x172c c0x0000 (---------------) + I hadsel + 0x002a858a, // n0x172d c0x0000 (---------------) + I hagebostad + 0x0035f986, // n0x172e c0x0000 (---------------) + I halden + 0x0036cc85, // n0x172f c0x0000 (---------------) + I halsa + 0x0026b145, // n0x1730 c0x0000 (---------------) + I hamar + 0x0026b147, // n0x1731 c0x0000 (---------------) + I hamaroy + 0x00374a0c, // n0x1732 c0x0000 (---------------) + I hammarfeasta + 0x0027b64a, // n0x1733 c0x0000 (---------------) + I hammerfest + 0x0028d0c6, // n0x1734 c0x0000 (---------------) + I hapmir + 0x002d09c5, // n0x1735 c0x0000 (---------------) + I haram + 0x0028d686, // n0x1736 c0x0000 (---------------) + I hareid + 0x0028d9c7, // n0x1737 c0x0000 (---------------) + I harstad + 0x0028ed06, // n0x1738 c0x0000 (---------------) + I hasvik + 0x0029104c, // n0x1739 c0x0000 (---------------) + I hattfjelldal + 0x00205749, // n0x173a c0x0000 (---------------) + I haugesund + 0x3d236c07, // n0x173b c0x00f4 (n0x195e-n0x1961) o I hedmark + 0x00292ac5, // n0x173c c0x0000 (---------------) + I hemne + 0x00292ac6, // n0x173d c0x0000 (---------------) + I hemnes + 0x00293008, // n0x173e c0x0000 (---------------) + I hemsedal + 0x002b24c5, // n0x173f c0x0000 (---------------) + I herad + 0x002a5bc5, // n0x1740 c0x0000 (---------------) + I hitra + 0x002a5e08, // n0x1741 c0x0000 (---------------) + I hjartdal + 0x002a600a, // n0x1742 c0x0000 (---------------) + I hjelmeland + 0x3d6484c2, // n0x1743 c0x00f5 (n0x1961-n0x1962) + I hl + 0x3da0fbc2, // n0x1744 c0x00f6 (n0x1962-n0x1963) + I hm + 0x003770c5, // n0x1745 c0x0000 (---------------) + I hobol + 0x002d7a43, // n0x1746 c0x0000 (---------------) + I hof + 0x0036e648, // n0x1747 c0x0000 (---------------) + I hokksund + 0x00231f43, // n0x1748 c0x0000 (---------------) + I hol + 0x002a6284, // n0x1749 c0x0000 (---------------) + I hole + 0x0029d6cb, // n0x174a c0x0000 (---------------) + I holmestrand + 0x002afec8, // n0x174b c0x0000 (---------------) + I holtalen + 0x002a8948, // n0x174c c0x0000 (---------------) + I honefoss + 0x3df20f89, // n0x174d c0x00f7 (n0x1963-n0x1964) o I hordaland + 0x002a9e09, // n0x174e c0x0000 (---------------) + I hornindal + 0x002aa286, // n0x174f c0x0000 (---------------) + I horten + 0x002ab288, // n0x1750 c0x0000 (---------------) + I hoyanger + 0x002ab489, // n0x1751 c0x0000 (---------------) + I hoylandet + 0x002ac4c6, // n0x1752 c0x0000 (---------------) + I hurdal + 0x002ac645, // n0x1753 c0x0000 (---------------) + I hurum + 0x00363d06, // n0x1754 c0x0000 (---------------) + I hvaler + 0x002acb89, // n0x1755 c0x0000 (---------------) + I hyllestad + 0x00354f47, // n0x1756 c0x0000 (---------------) + I ibestad + 0x0026f346, // n0x1757 c0x0000 (---------------) + I idrett + 0x0037cc07, // n0x1758 c0x0000 (---------------) + I inderoy + 0x00351a47, // n0x1759 c0x0000 (---------------) + I iveland + 0x00234e04, // n0x175a c0x0000 (---------------) + I ivgu + 0x3e220ec9, // n0x175b c0x00f8 (n0x1964-n0x1965) + I jan-mayen + 0x002c7148, // n0x175c c0x0000 (---------------) + I jessheim + 0x00356248, // n0x175d c0x0000 (---------------) + I jevnaker + 0x00232947, // n0x175e c0x0000 (---------------) + I jolster + 0x002c2dc6, // n0x175f c0x0000 (---------------) + I jondal + 0x002feb89, // n0x1760 c0x0000 (---------------) + I jorpeland + 0x002be607, // n0x1761 c0x0000 (---------------) + I kafjord + 0x0025b40a, // n0x1762 c0x0000 (---------------) + I karasjohka + 0x002ee1c8, // n0x1763 c0x0000 (---------------) + I karasjok + 0x00331787, // n0x1764 c0x0000 (---------------) + I karlsoy + 0x00355346, // n0x1765 c0x0000 (---------------) + I karmoy + 0x00229f0a, // n0x1766 c0x0000 (---------------) + I kautokeino + 0x0027f108, // n0x1767 c0x0000 (---------------) + I kirkenes + 0x00250905, // n0x1768 c0x0000 (---------------) + I klabu + 0x00373485, // n0x1769 c0x0000 (---------------) + I klepp + 0x00386347, // n0x176a c0x0000 (---------------) + I kommune + 0x002d9089, // n0x176b c0x0000 (---------------) + I kongsberg + 0x002c9e4b, // n0x176c c0x0000 (---------------) + I kongsvinger + 0x002d6e88, // n0x176d c0x0000 (---------------) + I kopervik + 0x0025da49, // n0x176e c0x0000 (---------------) + I kraanghke + 0x002504c7, // n0x176f c0x0000 (---------------) + I kragero + 0x002b1a4c, // n0x1770 c0x0000 (---------------) + I kristiansand + 0x002b208c, // n0x1771 c0x0000 (---------------) + I kristiansund + 0x002b238a, // n0x1772 c0x0000 (---------------) + I krodsherad + 0x002b260c, // n0x1773 c0x0000 (---------------) + I krokstadelva + 0x002bd648, // n0x1774 c0x0000 (---------------) + I kvafjord + 0x002bd848, // n0x1775 c0x0000 (---------------) + I kvalsund + 0x002bda44, // n0x1776 c0x0000 (---------------) + I kvam + 0x002be7c9, // n0x1777 c0x0000 (---------------) + I kvanangen + 0x002bea09, // n0x1778 c0x0000 (---------------) + I kvinesdal + 0x002bec4a, // n0x1779 c0x0000 (---------------) + I kvinnherad + 0x002beec9, // n0x177a c0x0000 (---------------) + I kviteseid + 0x002bf207, // n0x177b c0x0000 (---------------) + I kvitsoy + 0x003a580c, // n0x177c c0x0000 (---------------) + I laakesvuemie + 0x00338106, // n0x177d c0x0000 (---------------) + I lahppi + 0x00251688, // n0x177e c0x0000 (---------------) + I langevag + 0x00266ac6, // n0x177f c0x0000 (---------------) + I lardal + 0x0037d606, // n0x1780 c0x0000 (---------------) + I larvik + 0x00382ec7, // n0x1781 c0x0000 (---------------) + I lavagis + 0x002f3c48, // n0x1782 c0x0000 (---------------) + I lavangen + 0x0026c2cb, // n0x1783 c0x0000 (---------------) + I leangaviika + 0x002b9047, // n0x1784 c0x0000 (---------------) + I lebesby + 0x00259649, // n0x1785 c0x0000 (---------------) + I leikanger + 0x00281e49, // n0x1786 c0x0000 (---------------) + I leirfjord + 0x0035da87, // n0x1787 c0x0000 (---------------) + I leirvik + 0x002bdd04, // n0x1788 c0x0000 (---------------) + I leka + 0x00382447, // n0x1789 c0x0000 (---------------) + I leksvik + 0x00353546, // n0x178a c0x0000 (---------------) + I lenvik + 0x00217446, // n0x178b c0x0000 (---------------) + I lerdal + 0x00308c85, // n0x178c c0x0000 (---------------) + I lesja + 0x002d1848, // n0x178d c0x0000 (---------------) + I levanger + 0x002e38c4, // n0x178e c0x0000 (---------------) + I lier + 0x002e38c6, // n0x178f c0x0000 (---------------) + I lierne + 0x0027b50b, // n0x1790 c0x0000 (---------------) + I lillehammer + 0x00330f89, // n0x1791 c0x0000 (---------------) + I lillesand + 0x00312986, // n0x1792 c0x0000 (---------------) + I lindas + 0x00320189, // n0x1793 c0x0000 (---------------) + I lindesnes + 0x00387806, // n0x1794 c0x0000 (---------------) + I loabat + 0x00259b48, // n0x1795 c0x0000 (---------------) + I lodingen + 0x00214d03, // n0x1796 c0x0000 (---------------) + I lom + 0x0038fe45, // n0x1797 c0x0000 (---------------) + I loppa + 0x00217589, // n0x1798 c0x0000 (---------------) + I lorenskog + 0x00218d45, // n0x1799 c0x0000 (---------------) + I loten + 0x002e2ac4, // n0x179a c0x0000 (---------------) + I lund + 0x00275106, // n0x179b c0x0000 (---------------) + I lunner + 0x002322c5, // n0x179c c0x0000 (---------------) + I luroy + 0x002dd446, // n0x179d c0x0000 (---------------) + I luster + 0x002fb707, // n0x179e c0x0000 (---------------) + I lyngdal + 0x00212f86, // n0x179f c0x0000 (---------------) + I lyngen + 0x0029924b, // n0x17a0 c0x0000 (---------------) + I malatvuopmi + 0x002e5bc7, // n0x17a1 c0x0000 (---------------) + I malselv + 0x00206506, // n0x17a2 c0x0000 (---------------) + I malvik + 0x00349e06, // n0x17a3 c0x0000 (---------------) + I mandal + 0x00234106, // n0x17a4 c0x0000 (---------------) + I marker + 0x00354989, // n0x17a5 c0x0000 (---------------) + I marnardal + 0x0021cb8a, // n0x17a6 c0x0000 (---------------) + I masfjorden + 0x0032f2c5, // n0x17a7 c0x0000 (---------------) + I masoy + 0x0021f1cd, // n0x17a8 c0x0000 (---------------) + I matta-varjjat + 0x002a6106, // n0x17a9 c0x0000 (---------------) + I meland + 0x00213686, // n0x17aa c0x0000 (---------------) + I meldal + 0x00287286, // n0x17ab c0x0000 (---------------) + I melhus + 0x0029d385, // n0x17ac c0x0000 (---------------) + I meloy + 0x0023ecc7, // n0x17ad c0x0000 (---------------) + I meraker + 0x0029ee07, // n0x17ae c0x0000 (---------------) + I midsund + 0x002e6bce, // n0x17af c0x0000 (---------------) + I midtre-gauldal + 0x00207dc3, // n0x17b0 c0x0000 (---------------) + I mil + 0x002c2d89, // n0x17b1 c0x0000 (---------------) + I mjondalen + 0x00379389, // n0x17b2 c0x0000 (---------------) + I mo-i-rana + 0x0022a887, // n0x17b3 c0x0000 (---------------) + I moareke + 0x0026d447, // n0x17b4 c0x0000 (---------------) + I modalen + 0x002a7945, // n0x17b5 c0x0000 (---------------) + I modum + 0x00324b05, // n0x17b6 c0x0000 (---------------) + I molde + 0x3e65cf8f, // n0x17b7 c0x00f9 (n0x1965-n0x1967) o I more-og-romsdal + 0x002c9907, // n0x17b8 c0x0000 (---------------) + I mosjoen + 0x002c9ac8, // n0x17b9 c0x0000 (---------------) + I moskenes + 0x002ca104, // n0x17ba c0x0000 (---------------) + I moss + 0x002ca446, // n0x17bb c0x0000 (---------------) + I mosvik + 0x3ea4a142, // n0x17bc c0x00fa (n0x1967-n0x1968) + I mr + 0x002cd886, // n0x17bd c0x0000 (---------------) + I muosat + 0x002d1086, // n0x17be c0x0000 (---------------) + I museum + 0x0026c60e, // n0x17bf c0x0000 (---------------) + I naamesjevuemie + 0x0032a98a, // n0x17c0 c0x0000 (---------------) + I namdalseid + 0x002b74c6, // n0x17c1 c0x0000 (---------------) + I namsos + 0x0021fb0a, // n0x17c2 c0x0000 (---------------) + I namsskogan + 0x002c5109, // n0x17c3 c0x0000 (---------------) + I nannestad + 0x003183c5, // n0x17c4 c0x0000 (---------------) + I naroy + 0x00389d88, // n0x17c5 c0x0000 (---------------) + I narviika + 0x003a1306, // n0x17c6 c0x0000 (---------------) + I narvik + 0x00330dc8, // n0x17c7 c0x0000 (---------------) + I naustdal + 0x0030aa88, // n0x17c8 c0x0000 (---------------) + I navuotna + 0x0032624b, // n0x17c9 c0x0000 (---------------) + I nedre-eiker + 0x00226685, // n0x17ca c0x0000 (---------------) + I nesna + 0x0022b6c8, // n0x17cb c0x0000 (---------------) + I nesodden + 0x00205e8c, // n0x17cc c0x0000 (---------------) + I nesoddtangen + 0x002b8407, // n0x17cd c0x0000 (---------------) + I nesseby + 0x0024fdc6, // n0x17ce c0x0000 (---------------) + I nesset + 0x0022eac8, // n0x17cf c0x0000 (---------------) + I nissedal + 0x00279b48, // n0x17d0 c0x0000 (---------------) + I nittedal + 0x3ee46d02, // n0x17d1 c0x00fb (n0x1968-n0x1969) + I nl + 0x002bdf0b, // n0x17d2 c0x0000 (---------------) + I nord-aurdal + 0x00397549, // n0x17d3 c0x0000 (---------------) + I nord-fron + 0x00343249, // n0x17d4 c0x0000 (---------------) + I nord-odal + 0x00382d47, // n0x17d5 c0x0000 (---------------) + I norddal + 0x00248908, // n0x17d6 c0x0000 (---------------) + I nordkapp + 0x3f31fdc8, // n0x17d7 c0x00fc (n0x1969-n0x196d) o I nordland + 0x0026ba8b, // n0x17d8 c0x0000 (---------------) + I nordre-land + 0x00286149, // n0x17d9 c0x0000 (---------------) + I nordreisa + 0x0021194d, // n0x17da c0x0000 (---------------) + I nore-og-uvdal + 0x003289c8, // n0x17db c0x0000 (---------------) + I notodden + 0x0032d988, // n0x17dc c0x0000 (---------------) + I notteroy + 0x3f601542, // n0x17dd c0x00fd (n0x196d-n0x196e) + I nt + 0x003a40c4, // n0x17de c0x0000 (---------------) + I odda + 0x3fa0ce82, // n0x17df c0x00fe (n0x196e-n0x196f) + I of + 0x002ee346, // n0x17e0 c0x0000 (---------------) + I oksnes + 0x3fe02102, // n0x17e1 c0x00ff (n0x196f-n0x1970) + I ol + 0x0030604a, // n0x17e2 c0x0000 (---------------) + I omasvuotna + 0x00357206, // n0x17e3 c0x0000 (---------------) + I oppdal + 0x00221288, // n0x17e4 c0x0000 (---------------) + I oppegard + 0x002566c8, // n0x17e5 c0x0000 (---------------) + I orkanger + 0x002eadc6, // n0x17e6 c0x0000 (---------------) + I orkdal + 0x003389c6, // n0x17e7 c0x0000 (---------------) + I orland + 0x002e6086, // n0x17e8 c0x0000 (---------------) + I orskog + 0x0027aec5, // n0x17e9 c0x0000 (---------------) + I orsta + 0x00240e04, // n0x17ea c0x0000 (---------------) + I osen + 0x402c5e84, // n0x17eb c0x0100 (n0x1970-n0x1971) + I oslo + 0x00334dc6, // n0x17ec c0x0000 (---------------) + I osoyro + 0x0024afc7, // n0x17ed c0x0000 (---------------) + I osteroy + 0x40798d87, // n0x17ee c0x0101 (n0x1971-n0x1972) o I ostfold + 0x002cf14b, // n0x17ef c0x0000 (---------------) + I ostre-toten + 0x0026abc9, // n0x17f0 c0x0000 (---------------) + I overhalla + 0x0026864a, // n0x17f1 c0x0000 (---------------) + I ovre-eiker + 0x00319a44, // n0x17f2 c0x0000 (---------------) + I oyer + 0x0026b288, // n0x17f3 c0x0000 (---------------) + I oygarden + 0x0026f10d, // n0x17f4 c0x0000 (---------------) + I oystre-slidre + 0x002dfc09, // n0x17f5 c0x0000 (---------------) + I porsanger + 0x002dfe48, // n0x17f6 c0x0000 (---------------) + I porsangu + 0x002e00c9, // n0x17f7 c0x0000 (---------------) + I porsgrunn + 0x002e17c4, // n0x17f8 c0x0000 (---------------) + I priv + 0x00205504, // n0x17f9 c0x0000 (---------------) + I rade + 0x0027f9c5, // n0x17fa c0x0000 (---------------) + I radoy + 0x0027700b, // n0x17fb c0x0000 (---------------) + I rahkkeravju + 0x002afe46, // n0x17fc c0x0000 (---------------) + I raholt + 0x00334c05, // n0x17fd c0x0000 (---------------) + I raisa + 0x00356cc9, // n0x17fe c0x0000 (---------------) + I rakkestad + 0x00226888, // n0x17ff c0x0000 (---------------) + I ralingen + 0x002a0c04, // n0x1800 c0x0000 (---------------) + I rana + 0x0022a609, // n0x1801 c0x0000 (---------------) + I randaberg + 0x00248145, // n0x1802 c0x0000 (---------------) + I rauma + 0x002b9988, // n0x1803 c0x0000 (---------------) + I rendalen + 0x00208c87, // n0x1804 c0x0000 (---------------) + I rennebu + 0x00312f48, // n0x1805 c0x0000 (---------------) + I rennesoy + 0x0027ff86, // n0x1806 c0x0000 (---------------) + I rindal + 0x0037b2c7, // n0x1807 c0x0000 (---------------) + I ringebu + 0x0020f789, // n0x1808 c0x0000 (---------------) + I ringerike + 0x00245d09, // n0x1809 c0x0000 (---------------) + I ringsaker + 0x00277785, // n0x180a c0x0000 (---------------) + I risor + 0x003789c5, // n0x180b c0x0000 (---------------) + I rissa + 0x40a24dc2, // n0x180c c0x0102 (n0x1972-n0x1973) + I rl + 0x002f9c84, // n0x180d c0x0000 (---------------) + I roan + 0x0029e885, // n0x180e c0x0000 (---------------) + I rodoy + 0x003017c6, // n0x180f c0x0000 (---------------) + I rollag + 0x0031abc5, // n0x1810 c0x0000 (---------------) + I romsa + 0x00253187, // n0x1811 c0x0000 (---------------) + I romskog + 0x00297a45, // n0x1812 c0x0000 (---------------) + I roros + 0x00276844, // n0x1813 c0x0000 (---------------) + I rost + 0x003306c6, // n0x1814 c0x0000 (---------------) + I royken + 0x0032ad87, // n0x1815 c0x0000 (---------------) + I royrvik + 0x0024a186, // n0x1816 c0x0000 (---------------) + I ruovat + 0x003314c5, // n0x1817 c0x0000 (---------------) + I rygge + 0x0030a688, // n0x1818 c0x0000 (---------------) + I salangen + 0x00226e05, // n0x1819 c0x0000 (---------------) + I salat + 0x00312807, // n0x181a c0x0000 (---------------) + I saltdal + 0x00344a49, // n0x181b c0x0000 (---------------) + I samnanger + 0x003310ca, // n0x181c c0x0000 (---------------) + I sandefjord + 0x00348847, // n0x181d c0x0000 (---------------) + I sandnes + 0x0034884c, // n0x181e c0x0000 (---------------) + I sandnessjoen + 0x00229386, // n0x181f c0x0000 (---------------) + I sandoy + 0x002285c9, // n0x1820 c0x0000 (---------------) + I sarpsborg + 0x0032b205, // n0x1821 c0x0000 (---------------) + I sauda + 0x0034f988, // n0x1822 c0x0000 (---------------) + I sauherad + 0x00212383, // n0x1823 c0x0000 (---------------) + I sel + 0x00212385, // n0x1824 c0x0000 (---------------) + I selbu + 0x00335945, // n0x1825 c0x0000 (---------------) + I selje + 0x0023c187, // n0x1826 c0x0000 (---------------) + I seljord + 0x40e10842, // n0x1827 c0x0103 (n0x1973-n0x1974) + I sf + 0x0023ba87, // n0x1828 c0x0000 (---------------) + I siellak + 0x002c6246, // n0x1829 c0x0000 (---------------) + I sigdal + 0x00220e06, // n0x182a c0x0000 (---------------) + I siljan + 0x002ccf46, // n0x182b c0x0000 (---------------) + I sirdal + 0x00279a86, // n0x182c c0x0000 (---------------) + I skanit + 0x00307ec8, // n0x182d c0x0000 (---------------) + I skanland + 0x0024e845, // n0x182e c0x0000 (---------------) + I skaun + 0x0024cb87, // n0x182f c0x0000 (---------------) + I skedsmo + 0x0024cb8d, // n0x1830 c0x0000 (---------------) + I skedsmokorset + 0x00208503, // n0x1831 c0x0000 (---------------) + I ski + 0x00208505, // n0x1832 c0x0000 (---------------) + I skien + 0x00229a87, // n0x1833 c0x0000 (---------------) + I skierva + 0x002d3188, // n0x1834 c0x0000 (---------------) + I skiptvet + 0x00229645, // n0x1835 c0x0000 (---------------) + I skjak + 0x00230988, // n0x1836 c0x0000 (---------------) + I skjervoy + 0x0026dfc6, // n0x1837 c0x0000 (---------------) + I skodje + 0x00262fc7, // n0x1838 c0x0000 (---------------) + I slattum + 0x002c1cc5, // n0x1839 c0x0000 (---------------) + I smola + 0x00226706, // n0x183a c0x0000 (---------------) + I snaase + 0x00360ac5, // n0x183b c0x0000 (---------------) + I snasa + 0x002bcd4a, // n0x183c c0x0000 (---------------) + I snillfjord + 0x00373786, // n0x183d c0x0000 (---------------) + I snoasa + 0x00234a47, // n0x183e c0x0000 (---------------) + I sogndal + 0x002bd505, // n0x183f c0x0000 (---------------) + I sogne + 0x002d8a87, // n0x1840 c0x0000 (---------------) + I sokndal + 0x002e0984, // n0x1841 c0x0000 (---------------) + I sola + 0x002e2a46, // n0x1842 c0x0000 (---------------) + I solund + 0x0035bc85, // n0x1843 c0x0000 (---------------) + I somna + 0x002b800b, // n0x1844 c0x0000 (---------------) + I sondre-land + 0x003533c9, // n0x1845 c0x0000 (---------------) + I songdalen + 0x002da24a, // n0x1846 c0x0000 (---------------) + I sor-aurdal + 0x00277808, // n0x1847 c0x0000 (---------------) + I sor-fron + 0x003177c8, // n0x1848 c0x0000 (---------------) + I sor-odal + 0x002ef68c, // n0x1849 c0x0000 (---------------) + I sor-varanger + 0x002efec7, // n0x184a c0x0000 (---------------) + I sorfold + 0x002f2488, // n0x184b c0x0000 (---------------) + I sorreisa + 0x002fa788, // n0x184c c0x0000 (---------------) + I sortland + 0x002fc305, // n0x184d c0x0000 (---------------) + I sorum + 0x002bf48a, // n0x184e c0x0000 (---------------) + I spjelkavik + 0x00332909, // n0x184f c0x0000 (---------------) + I spydeberg + 0x41202602, // n0x1850 c0x0104 (n0x1974-n0x1975) + I st + 0x00202606, // n0x1851 c0x0000 (---------------) + I stange + 0x0020a204, // n0x1852 c0x0000 (---------------) + I stat + 0x002de689, // n0x1853 c0x0000 (---------------) + I stathelle + 0x00254209, // n0x1854 c0x0000 (---------------) + I stavanger + 0x0021b107, // n0x1855 c0x0000 (---------------) + I stavern + 0x0024f3c7, // n0x1856 c0x0000 (---------------) + I steigen + 0x00280c09, // n0x1857 c0x0000 (---------------) + I steinkjer + 0x0038d988, // n0x1858 c0x0000 (---------------) + I stjordal + 0x0038d98f, // n0x1859 c0x0000 (---------------) + I stjordalshalsen + 0x00275c46, // n0x185a c0x0000 (---------------) + I stokke + 0x0024280b, // n0x185b c0x0000 (---------------) + I stor-elvdal + 0x0035b185, // n0x185c c0x0000 (---------------) + I stord + 0x0035b187, // n0x185d c0x0000 (---------------) + I stordal + 0x0037c2c9, // n0x185e c0x0000 (---------------) + I storfjord + 0x0022a586, // n0x185f c0x0000 (---------------) + I strand + 0x0022a587, // n0x1860 c0x0000 (---------------) + I stranda + 0x003a37c5, // n0x1861 c0x0000 (---------------) + I stryn + 0x00237984, // n0x1862 c0x0000 (---------------) + I sula + 0x00235406, // n0x1863 c0x0000 (---------------) + I suldal + 0x00200704, // n0x1864 c0x0000 (---------------) + I sund + 0x0030d887, // n0x1865 c0x0000 (---------------) + I sunndal + 0x002e9388, // n0x1866 c0x0000 (---------------) + I surnadal + 0x416eaf48, // n0x1867 c0x0105 (n0x1975-n0x1976) + I svalbard + 0x002eb545, // n0x1868 c0x0000 (---------------) + I sveio + 0x002eb687, // n0x1869 c0x0000 (---------------) + I svelvik + 0x003684c9, // n0x186a c0x0000 (---------------) + I sykkylven + 0x00203c44, // n0x186b c0x0000 (---------------) + I tana + 0x00203c48, // n0x186c c0x0000 (---------------) + I tananger + 0x41a64dc8, // n0x186d c0x0106 (n0x1976-n0x1978) o I telemark + 0x00219dc4, // n0x186e c0x0000 (---------------) + I time + 0x00238488, // n0x186f c0x0000 (---------------) + I tingvoll + 0x002dca04, // n0x1870 c0x0000 (---------------) + I tinn + 0x0023e5c9, // n0x1871 c0x0000 (---------------) + I tjeldsund + 0x0036e185, // n0x1872 c0x0000 (---------------) + I tjome + 0x41e00c82, // n0x1873 c0x0107 (n0x1978-n0x1979) + I tm + 0x00275c85, // n0x1874 c0x0000 (---------------) + I tokke + 0x00221f05, // n0x1875 c0x0000 (---------------) + I tolga + 0x0035ebc8, // n0x1876 c0x0000 (---------------) + I tonsberg + 0x00239f07, // n0x1877 c0x0000 (---------------) + I torsken + 0x42203902, // n0x1878 c0x0108 (n0x1979-n0x197a) + I tr + 0x002cb4c5, // n0x1879 c0x0000 (---------------) + I trana + 0x002847c6, // n0x187a c0x0000 (---------------) + I tranby + 0x002960c6, // n0x187b c0x0000 (---------------) + I tranoy + 0x002f9c48, // n0x187c c0x0000 (---------------) + I troandin + 0x002fe2c8, // n0x187d c0x0000 (---------------) + I trogstad + 0x0031ab86, // n0x187e c0x0000 (---------------) + I tromsa + 0x00322446, // n0x187f c0x0000 (---------------) + I tromso + 0x00357709, // n0x1880 c0x0000 (---------------) + I trondheim + 0x00358346, // n0x1881 c0x0000 (---------------) + I trysil + 0x0024910b, // n0x1882 c0x0000 (---------------) + I tvedestrand + 0x0024fbc5, // n0x1883 c0x0000 (---------------) + I tydal + 0x0021f706, // n0x1884 c0x0000 (---------------) + I tynset + 0x0039f5c8, // n0x1885 c0x0000 (---------------) + I tysfjord + 0x00233406, // n0x1886 c0x0000 (---------------) + I tysnes + 0x00236546, // n0x1887 c0x0000 (---------------) + I tysvar + 0x00215b8a, // n0x1888 c0x0000 (---------------) + I ullensaker + 0x00343e0a, // n0x1889 c0x0000 (---------------) + I ullensvang + 0x0028d385, // n0x188a c0x0000 (---------------) + I ulvik + 0x002c9407, // n0x188b c0x0000 (---------------) + I unjarga + 0x00341f46, // n0x188c c0x0000 (---------------) + I utsira + 0x42600c02, // n0x188d c0x0109 (n0x197a-n0x197b) + I va + 0x00229bc7, // n0x188e c0x0000 (---------------) + I vaapste + 0x00274545, // n0x188f c0x0000 (---------------) + I vadso + 0x003120c4, // n0x1890 c0x0000 (---------------) + I vaga + 0x003120c5, // n0x1891 c0x0000 (---------------) + I vagan + 0x00319946, // n0x1892 c0x0000 (---------------) + I vagsoy + 0x0032e2c7, // n0x1893 c0x0000 (---------------) + I vaksdal + 0x00216c85, // n0x1894 c0x0000 (---------------) + I valle + 0x002542c4, // n0x1895 c0x0000 (---------------) + I vang + 0x00270708, // n0x1896 c0x0000 (---------------) + I vanylven + 0x00236605, // n0x1897 c0x0000 (---------------) + I vardo + 0x00293687, // n0x1898 c0x0000 (---------------) + I varggat + 0x00358ac5, // n0x1899 c0x0000 (---------------) + I varoy + 0x00214ac5, // n0x189a c0x0000 (---------------) + I vefsn + 0x0023dfc4, // n0x189b c0x0000 (---------------) + I vega + 0x0028c9c9, // n0x189c c0x0000 (---------------) + I vegarshei + 0x002e24c8, // n0x189d c0x0000 (---------------) + I vennesla + 0x00372686, // n0x189e c0x0000 (---------------) + I verdal + 0x00342546, // n0x189f c0x0000 (---------------) + I verran + 0x00219ac6, // n0x18a0 c0x0000 (---------------) + I vestby + 0x42b9be88, // n0x18a1 c0x010a (n0x197b-n0x197c) o I vestfold + 0x002ef507, // n0x18a2 c0x0000 (---------------) + I vestnes + 0x002ef98d, // n0x18a3 c0x0000 (---------------) + I vestre-slidre + 0x002f008c, // n0x18a4 c0x0000 (---------------) + I vestre-toten + 0x002f0689, // n0x18a5 c0x0000 (---------------) + I vestvagoy + 0x002f08c9, // n0x18a6 c0x0000 (---------------) + I vevelstad + 0x42f4d602, // n0x18a7 c0x010b (n0x197c-n0x197d) + I vf + 0x0039adc3, // n0x18a8 c0x0000 (---------------) + I vgs + 0x002065c3, // n0x18a9 c0x0000 (---------------) + I vik + 0x00353605, // n0x18aa c0x0000 (---------------) + I vikna + 0x003834ca, // n0x18ab c0x0000 (---------------) + I vindafjord + 0x0031aa46, // n0x18ac c0x0000 (---------------) + I voagat + 0x002f8945, // n0x18ad c0x0000 (---------------) + I volda + 0x002fbc44, // n0x18ae c0x0000 (---------------) + I voss + 0x002fbc4b, // n0x18af c0x0000 (---------------) + I vossevangen + 0x0030f7cc, // n0x18b0 c0x0000 (---------------) + I xn--andy-ira + 0x0031000c, // n0x18b1 c0x0000 (---------------) + I xn--asky-ira + 0x00310315, // n0x18b2 c0x0000 (---------------) + I xn--aurskog-hland-jnb + 0x003138cd, // n0x18b3 c0x0000 (---------------) + I xn--avery-yua + 0x00314e0f, // n0x18b4 c0x0000 (---------------) + I xn--bdddj-mrabd + 0x003151d2, // n0x18b5 c0x0000 (---------------) + I xn--bearalvhki-y4a + 0x0031564f, // n0x18b6 c0x0000 (---------------) + I xn--berlevg-jxa + 0x00315a12, // n0x18b7 c0x0000 (---------------) + I xn--bhcavuotna-s4a + 0x00315e93, // n0x18b8 c0x0000 (---------------) + I xn--bhccavuotna-k7a + 0x0031634d, // n0x18b9 c0x0000 (---------------) + I xn--bidr-5nac + 0x0031690d, // n0x18ba c0x0000 (---------------) + I xn--bievt-0qa + 0x00316c8e, // n0x18bb c0x0000 (---------------) + I xn--bjarky-fya + 0x0031714e, // n0x18bc c0x0000 (---------------) + I xn--bjddar-pta + 0x003179cc, // n0x18bd c0x0000 (---------------) + I xn--blt-elab + 0x00317d4c, // n0x18be c0x0000 (---------------) + I xn--bmlo-gra + 0x0031818b, // n0x18bf c0x0000 (---------------) + I xn--bod-2na + 0x0031850e, // n0x18c0 c0x0000 (---------------) + I xn--brnny-wuac + 0x00319f52, // n0x18c1 c0x0000 (---------------) + I xn--brnnysund-m8ac + 0x0031a80c, // n0x18c2 c0x0000 (---------------) + I xn--brum-voa + 0x0031af50, // n0x18c3 c0x0000 (---------------) + I xn--btsfjord-9za + 0x0032b352, // n0x18c4 c0x0000 (---------------) + I xn--davvenjrga-y4a + 0x0032c20c, // n0x18c5 c0x0000 (---------------) + I xn--dnna-gra + 0x0032c8cd, // n0x18c6 c0x0000 (---------------) + I xn--drbak-wua + 0x0032cc0c, // n0x18c7 c0x0000 (---------------) + I xn--dyry-ira + 0x0032e751, // n0x18c8 c0x0000 (---------------) + I xn--eveni-0qa01ga + 0x0032f70d, // n0x18c9 c0x0000 (---------------) + I xn--finny-yua + 0x00332e4d, // n0x18ca c0x0000 (---------------) + I xn--fjord-lra + 0x0033344a, // n0x18cb c0x0000 (---------------) + I xn--fl-zia + 0x003336cc, // n0x18cc c0x0000 (---------------) + I xn--flor-jra + 0x00333fcc, // n0x18cd c0x0000 (---------------) + I xn--frde-gra + 0x0033490c, // n0x18ce c0x0000 (---------------) + I xn--frna-woa + 0x0033518c, // n0x18cf c0x0000 (---------------) + I xn--frya-hra + 0x00338b53, // n0x18d0 c0x0000 (---------------) + I xn--ggaviika-8ya47h + 0x00339150, // n0x18d1 c0x0000 (---------------) + I xn--gildeskl-g0a + 0x00339550, // n0x18d2 c0x0000 (---------------) + I xn--givuotna-8ya + 0x00339e4d, // n0x18d3 c0x0000 (---------------) + I xn--gjvik-wua + 0x0033a44c, // n0x18d4 c0x0000 (---------------) + I xn--gls-elac + 0x0033b409, // n0x18d5 c0x0000 (---------------) + I xn--h-2fa + 0x0033d90d, // n0x18d6 c0x0000 (---------------) + I xn--hbmer-xqa + 0x0033dc53, // n0x18d7 c0x0000 (---------------) + I xn--hcesuolo-7ya35b + 0x0033e851, // n0x18d8 c0x0000 (---------------) + I xn--hgebostad-g3a + 0x0033ec93, // n0x18d9 c0x0000 (---------------) + I xn--hmmrfeasta-s4ac + 0x0033fb8f, // n0x18da c0x0000 (---------------) + I xn--hnefoss-q1a + 0x0033ff4c, // n0x18db c0x0000 (---------------) + I xn--hobl-ira + 0x0034024f, // n0x18dc c0x0000 (---------------) + I xn--holtlen-hxa + 0x0034060d, // n0x18dd c0x0000 (---------------) + I xn--hpmir-xqa + 0x00340c0f, // n0x18de c0x0000 (---------------) + I xn--hyanger-q1a + 0x00340fd0, // n0x18df c0x0000 (---------------) + I xn--hylandet-54a + 0x00341a4e, // n0x18e0 c0x0000 (---------------) + I xn--indery-fya + 0x00344c8e, // n0x18e1 c0x0000 (---------------) + I xn--jlster-bya + 0x003453d0, // n0x18e2 c0x0000 (---------------) + I xn--jrpeland-54a + 0x0034650d, // n0x18e3 c0x0000 (---------------) + I xn--karmy-yua + 0x00346e8e, // n0x18e4 c0x0000 (---------------) + I xn--kfjord-iua + 0x0034720c, // n0x18e5 c0x0000 (---------------) + I xn--klbu-woa + 0x003482d3, // n0x18e6 c0x0000 (---------------) + I xn--koluokta-7ya57h + 0x00349f8e, // n0x18e7 c0x0000 (---------------) + I xn--krager-gya + 0x0034bb50, // n0x18e8 c0x0000 (---------------) + I xn--kranghke-b0a + 0x0034bf51, // n0x18e9 c0x0000 (---------------) + I xn--krdsherad-m8a + 0x0034c38f, // n0x18ea c0x0000 (---------------) + I xn--krehamn-dxa + 0x0034c753, // n0x18eb c0x0000 (---------------) + I xn--krjohka-hwab49j + 0x0034d18d, // n0x18ec c0x0000 (---------------) + I xn--ksnes-uua + 0x0034d4cf, // n0x18ed c0x0000 (---------------) + I xn--kvfjord-nxa + 0x0034d88e, // n0x18ee c0x0000 (---------------) + I xn--kvitsy-fya + 0x0034e0d0, // n0x18ef c0x0000 (---------------) + I xn--kvnangen-k0a + 0x0034e4c9, // n0x18f0 c0x0000 (---------------) + I xn--l-1fa + 0x00350310, // n0x18f1 c0x0000 (---------------) + I xn--laheadju-7ya + 0x0035094f, // n0x18f2 c0x0000 (---------------) + I xn--langevg-jxa + 0x00350fcf, // n0x18f3 c0x0000 (---------------) + I xn--ldingen-q1a + 0x00351392, // n0x18f4 c0x0000 (---------------) + I xn--leagaviika-52b + 0x00355b4e, // n0x18f5 c0x0000 (---------------) + I xn--lesund-hua + 0x0035644d, // n0x18f6 c0x0000 (---------------) + I xn--lgrd-poac + 0x00357a8d, // n0x18f7 c0x0000 (---------------) + I xn--lhppi-xqa + 0x00357dcd, // n0x18f8 c0x0000 (---------------) + I xn--linds-pra + 0x0035918d, // n0x18f9 c0x0000 (---------------) + I xn--loabt-0qa + 0x003594cd, // n0x18fa c0x0000 (---------------) + I xn--lrdal-sra + 0x00359810, // n0x18fb c0x0000 (---------------) + I xn--lrenskog-54a + 0x00359c0b, // n0x18fc c0x0000 (---------------) + I xn--lt-liac + 0x0035a1cc, // n0x18fd c0x0000 (---------------) + I xn--lten-gra + 0x0035a54c, // n0x18fe c0x0000 (---------------) + I xn--lury-ira + 0x0035a84c, // n0x18ff c0x0000 (---------------) + I xn--mely-ira + 0x0035ab4e, // n0x1900 c0x0000 (---------------) + I xn--merker-kua + 0x00366d90, // n0x1901 c0x0000 (---------------) + I xn--mjndalen-64a + 0x00368c92, // n0x1902 c0x0000 (---------------) + I xn--mlatvuopmi-s4a + 0x0036910b, // n0x1903 c0x0000 (---------------) + I xn--mli-tla + 0x00369b8e, // n0x1904 c0x0000 (---------------) + I xn--mlselv-iua + 0x00369f0e, // n0x1905 c0x0000 (---------------) + I xn--moreke-jua + 0x0036ac0e, // n0x1906 c0x0000 (---------------) + I xn--mosjen-eya + 0x0036b34b, // n0x1907 c0x0000 (---------------) + I xn--mot-tla + 0x4336b916, // n0x1908 c0x010c (n0x197d-n0x197f) o I xn--mre-og-romsdal-qqb + 0x0036c98d, // n0x1909 c0x0000 (---------------) + I xn--msy-ula0h + 0x0036d554, // n0x190a c0x0000 (---------------) + I xn--mtta-vrjjat-k7af + 0x0036e84d, // n0x190b c0x0000 (---------------) + I xn--muost-0qa + 0x00370215, // n0x190c c0x0000 (---------------) + I xn--nmesjevuemie-tcba + 0x0037160d, // n0x190d c0x0000 (---------------) + I xn--nry-yla5g + 0x00371f8f, // n0x190e c0x0000 (---------------) + I xn--nttery-byae + 0x0037280f, // n0x190f c0x0000 (---------------) + I xn--nvuotna-hwa + 0x0037638f, // n0x1910 c0x0000 (---------------) + I xn--oppegrd-ixa + 0x0037674e, // n0x1911 c0x0000 (---------------) + I xn--ostery-fya + 0x0037778d, // n0x1912 c0x0000 (---------------) + I xn--osyro-wua + 0x0037a291, // n0x1913 c0x0000 (---------------) + I xn--porsgu-sta26f + 0x0037cdcc, // n0x1914 c0x0000 (---------------) + I xn--rady-ira + 0x0037d0cc, // n0x1915 c0x0000 (---------------) + I xn--rdal-poa + 0x0037d3cb, // n0x1916 c0x0000 (---------------) + I xn--rde-ula + 0x0037d98c, // n0x1917 c0x0000 (---------------) + I xn--rdy-0nab + 0x0037dd4f, // n0x1918 c0x0000 (---------------) + I xn--rennesy-v1a + 0x0037e112, // n0x1919 c0x0000 (---------------) + I xn--rhkkervju-01af + 0x0037eacd, // n0x191a c0x0000 (---------------) + I xn--rholt-mra + 0x0037fa8c, // n0x191b c0x0000 (---------------) + I xn--risa-5na + 0x0037ff0c, // n0x191c c0x0000 (---------------) + I xn--risr-ira + 0x0038020d, // n0x191d c0x0000 (---------------) + I xn--rland-uua + 0x0038054f, // n0x191e c0x0000 (---------------) + I xn--rlingen-mxa + 0x0038090e, // n0x191f c0x0000 (---------------) + I xn--rmskog-bya + 0x0038318c, // n0x1920 c0x0000 (---------------) + I xn--rros-gra + 0x0038374d, // n0x1921 c0x0000 (---------------) + I xn--rskog-uua + 0x00383a8b, // n0x1922 c0x0000 (---------------) + I xn--rst-0na + 0x0038404c, // n0x1923 c0x0000 (---------------) + I xn--rsta-fra + 0x003845cd, // n0x1924 c0x0000 (---------------) + I xn--ryken-vua + 0x0038490e, // n0x1925 c0x0000 (---------------) + I xn--ryrvik-bya + 0x00384d89, // n0x1926 c0x0000 (---------------) + I xn--s-1fa + 0x00385a93, // n0x1927 c0x0000 (---------------) + I xn--sandnessjen-ogb + 0x0038650d, // n0x1928 c0x0000 (---------------) + I xn--sandy-yua + 0x0038684d, // n0x1929 c0x0000 (---------------) + I xn--seral-lra + 0x00386e4c, // n0x192a c0x0000 (---------------) + I xn--sgne-gra + 0x003872ce, // n0x192b c0x0000 (---------------) + I xn--skierv-uta + 0x00388d4f, // n0x192c c0x0000 (---------------) + I xn--skjervy-v1a + 0x0038910c, // n0x192d c0x0000 (---------------) + I xn--skjk-soa + 0x0038940d, // n0x192e c0x0000 (---------------) + I xn--sknit-yqa + 0x0038974f, // n0x192f c0x0000 (---------------) + I xn--sknland-fxa + 0x00389b0c, // n0x1930 c0x0000 (---------------) + I xn--slat-5na + 0x0038a20c, // n0x1931 c0x0000 (---------------) + I xn--slt-elab + 0x0038a5cc, // n0x1932 c0x0000 (---------------) + I xn--smla-hra + 0x0038a8cc, // n0x1933 c0x0000 (---------------) + I xn--smna-gra + 0x0038af8d, // n0x1934 c0x0000 (---------------) + I xn--snase-nra + 0x0038b2d2, // n0x1935 c0x0000 (---------------) + I xn--sndre-land-0cb + 0x0038b94c, // n0x1936 c0x0000 (---------------) + I xn--snes-poa + 0x0038bc4c, // n0x1937 c0x0000 (---------------) + I xn--snsa-roa + 0x0038bf51, // n0x1938 c0x0000 (---------------) + I xn--sr-aurdal-l8a + 0x0038c38f, // n0x1939 c0x0000 (---------------) + I xn--sr-fron-q1a + 0x0038c74f, // n0x193a c0x0000 (---------------) + I xn--sr-odal-q1a + 0x0038cb13, // n0x193b c0x0000 (---------------) + I xn--sr-varanger-ggb + 0x0038e38e, // n0x193c c0x0000 (---------------) + I xn--srfold-bya + 0x0038e90f, // n0x193d c0x0000 (---------------) + I xn--srreisa-q1a + 0x0038eccc, // n0x193e c0x0000 (---------------) + I xn--srum-gra + 0x4378f00e, // n0x193f c0x010d (n0x197f-n0x1980) o I xn--stfold-9xa + 0x0038f38f, // n0x1940 c0x0000 (---------------) + I xn--stjrdal-s1a + 0x0038f756, // n0x1941 c0x0000 (---------------) + I xn--stjrdalshalsen-sqb + 0x00390252, // n0x1942 c0x0000 (---------------) + I xn--stre-toten-zcb + 0x003918cc, // n0x1943 c0x0000 (---------------) + I xn--tjme-hra + 0x0039208f, // n0x1944 c0x0000 (---------------) + I xn--tnsberg-q1a + 0x0039270d, // n0x1945 c0x0000 (---------------) + I xn--trany-yua + 0x00392a4f, // n0x1946 c0x0000 (---------------) + I xn--trgstad-r1a + 0x00392e0c, // n0x1947 c0x0000 (---------------) + I xn--trna-woa + 0x0039310d, // n0x1948 c0x0000 (---------------) + I xn--troms-zua + 0x0039344d, // n0x1949 c0x0000 (---------------) + I xn--tysvr-vra + 0x00394cce, // n0x194a c0x0000 (---------------) + I xn--unjrga-rta + 0x0039604c, // n0x194b c0x0000 (---------------) + I xn--vads-jra + 0x0039634c, // n0x194c c0x0000 (---------------) + I xn--vard-jra + 0x00396650, // n0x194d c0x0000 (---------------) + I xn--vegrshei-c0a + 0x0039a251, // n0x194e c0x0000 (---------------) + I xn--vestvgy-ixa6o + 0x0039a68b, // n0x194f c0x0000 (---------------) + I xn--vg-yiab + 0x0039a9cc, // n0x1950 c0x0000 (---------------) + I xn--vgan-qoa + 0x0039acce, // n0x1951 c0x0000 (---------------) + I xn--vgsy-qoa0j + 0x0039c391, // n0x1952 c0x0000 (---------------) + I xn--vre-eiker-k8a + 0x0039c7ce, // n0x1953 c0x0000 (---------------) + I xn--vrggt-xqad + 0x0039cb4d, // n0x1954 c0x0000 (---------------) + I xn--vry-yla5g + 0x003a10cb, // n0x1955 c0x0000 (---------------) + I xn--yer-zna + 0x003a19cf, // n0x1956 c0x0000 (---------------) + I xn--ygarden-p1a + 0x003a2a94, // n0x1957 c0x0000 (---------------) + I xn--ystre-slidre-ujb + 0x00245dc2, // n0x1958 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1959 c0x0000 (---------------) + I gs + 0x00202ac3, // n0x195a c0x0000 (---------------) + I nes + 0x00245dc2, // n0x195b c0x0000 (---------------) + I gs + 0x00202ac3, // n0x195c c0x0000 (---------------) + I nes + 0x00245dc2, // n0x195d c0x0000 (---------------) + I gs + 0x00209f02, // n0x195e c0x0000 (---------------) + I os + 0x00363d45, // n0x195f c0x0000 (---------------) + I valer + 0x0039c08c, // n0x1960 c0x0000 (---------------) + I xn--vler-qoa + 0x00245dc2, // n0x1961 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1962 c0x0000 (---------------) + I gs + 0x00209f02, // n0x1963 c0x0000 (---------------) + I os + 0x00245dc2, // n0x1964 c0x0000 (---------------) + I gs + 0x00293485, // n0x1965 c0x0000 (---------------) + I heroy + 0x003310c5, // n0x1966 c0x0000 (---------------) + I sande + 0x00245dc2, // n0x1967 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1968 c0x0000 (---------------) + I gs + 0x0020f682, // n0x1969 c0x0000 (---------------) + I bo + 0x00293485, // n0x196a c0x0000 (---------------) + I heroy + 0x00313e09, // n0x196b c0x0000 (---------------) + I xn--b-5ga + 0x0033e54c, // n0x196c c0x0000 (---------------) + I xn--hery-ira + 0x00245dc2, // n0x196d c0x0000 (---------------) + I gs + 0x00245dc2, // n0x196e c0x0000 (---------------) + I gs + 0x00245dc2, // n0x196f c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1970 c0x0000 (---------------) + I gs + 0x00363d45, // n0x1971 c0x0000 (---------------) + I valer + 0x00245dc2, // n0x1972 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1973 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1974 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1975 c0x0000 (---------------) + I gs + 0x0020f682, // n0x1976 c0x0000 (---------------) + I bo + 0x00313e09, // n0x1977 c0x0000 (---------------) + I xn--b-5ga + 0x00245dc2, // n0x1978 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x1979 c0x0000 (---------------) + I gs + 0x00245dc2, // n0x197a c0x0000 (---------------) + I gs + 0x003310c5, // n0x197b c0x0000 (---------------) + I sande + 0x00245dc2, // n0x197c c0x0000 (---------------) + I gs + 0x003310c5, // n0x197d c0x0000 (---------------) + I sande + 0x0033e54c, // n0x197e c0x0000 (---------------) + I xn--hery-ira + 0x0039c08c, // n0x197f c0x0000 (---------------) + I xn--vler-qoa + 0x00331a83, // n0x1980 c0x0000 (---------------) + I biz + 0x00233243, // n0x1981 c0x0000 (---------------) + I com + 0x00239103, // n0x1982 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1983 c0x0000 (---------------) + I gov + 0x00201844, // n0x1984 c0x0000 (---------------) + I info + 0x00223b43, // n0x1985 c0x0000 (---------------) + I net + 0x00228743, // n0x1986 c0x0000 (---------------) + I org + 0x00128008, // n0x1987 c0x0000 (---------------) + merseine + 0x000aa184, // n0x1988 c0x0000 (---------------) + mine + 0x0015cc08, // n0x1989 c0x0000 (---------------) + shacknet + 0x00200342, // n0x198a c0x0000 (---------------) + I ac + 0x4460ce42, // n0x198b c0x0111 (n0x199a-n0x199b) + I co + 0x00244b03, // n0x198c c0x0000 (---------------) + I cri + 0x0024f084, // n0x198d c0x0000 (---------------) + I geek + 0x002060c3, // n0x198e c0x0000 (---------------) + I gen + 0x00342404, // n0x198f c0x0000 (---------------) + I govt + 0x002ae586, // n0x1990 c0x0000 (---------------) + I health + 0x00205c03, // n0x1991 c0x0000 (---------------) + I iwi + 0x002ea604, // n0x1992 c0x0000 (---------------) + I kiwi + 0x002719c5, // n0x1993 c0x0000 (---------------) + I maori + 0x00207dc3, // n0x1994 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1995 c0x0000 (---------------) + I net + 0x00228743, // n0x1996 c0x0000 (---------------) + I org + 0x0028458a, // n0x1997 c0x0000 (---------------) + I parliament + 0x00232186, // n0x1998 c0x0000 (---------------) + I school + 0x0036a28c, // n0x1999 c0x0000 (---------------) + I xn--mori-qsa + 0x000fe108, // n0x199a c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x199b c0x0000 (---------------) + I co + 0x00233243, // n0x199c c0x0000 (---------------) + I com + 0x00239103, // n0x199d c0x0000 (---------------) + I edu + 0x0027d903, // n0x199e c0x0000 (---------------) + I gov + 0x00213443, // n0x199f c0x0000 (---------------) + I med + 0x002d1086, // n0x19a0 c0x0000 (---------------) + I museum + 0x00223b43, // n0x19a1 c0x0000 (---------------) + I net + 0x00228743, // n0x19a2 c0x0000 (---------------) + I org + 0x00224b03, // n0x19a3 c0x0000 (---------------) + I pro + 0x000030c2, // n0x19a4 c0x0000 (---------------) + ae + 0x0002f087, // n0x19a5 c0x0000 (---------------) + blogdns + 0x000d4bc8, // n0x19a6 c0x0000 (---------------) + blogsite + 0x0000f9ce, // n0x19a7 c0x0000 (---------------) + bmoattachments + 0x00089f92, // n0x19a8 c0x0000 (---------------) + boldlygoingnowhere + 0x45262e05, // n0x19a9 c0x0114 (n0x19e1-n0x19e3) o I cdn77 + 0x4571d6cc, // n0x19aa c0x0115 (n0x19e3-n0x19e4) o I cdn77-secure + 0x00142e48, // n0x19ab c0x0000 (---------------) + dnsalias + 0x0007cf07, // n0x19ac c0x0000 (---------------) + dnsdojo + 0x0001580b, // n0x19ad c0x0000 (---------------) + doesntexist + 0x0016a789, // n0x19ae c0x0000 (---------------) + dontexist + 0x00142d47, // n0x19af c0x0000 (---------------) + doomdns + 0x0013c907, // n0x19b0 c0x0000 (---------------) + dsmynas + 0x0007ce07, // n0x19b1 c0x0000 (---------------) + duckdns + 0x0000de46, // n0x19b2 c0x0000 (---------------) + dvrdns + 0x00197108, // n0x19b3 c0x0000 (---------------) + dynalias + 0x45c13206, // n0x19b4 c0x0117 (n0x19e5-n0x19e7) + dyndns + 0x000aa38d, // n0x19b5 c0x0000 (---------------) + endofinternet + 0x0006b410, // n0x19b6 c0x0000 (---------------) + endoftheinternet + 0x46005382, // n0x19b7 c0x0118 (n0x19e7-n0x1a1e) + eu + 0x00007d48, // n0x19b8 c0x0000 (---------------) + familyds + 0x00069347, // n0x19b9 c0x0000 (---------------) + from-me + 0x00098349, // n0x19ba c0x0000 (---------------) + game-host + 0x00058186, // n0x19bb c0x0000 (---------------) + gotdns + 0x0000c482, // n0x19bc c0x0000 (---------------) + hk + 0x0014a8ca, // n0x19bd c0x0000 (---------------) + hobby-site + 0x000133c7, // n0x19be c0x0000 (---------------) + homedns + 0x00120a07, // n0x19bf c0x0000 (---------------) + homeftp + 0x000a6dc9, // n0x19c0 c0x0000 (---------------) + homelinux + 0x000a8148, // n0x19c1 c0x0000 (---------------) + homeunix + 0x000e060e, // n0x19c2 c0x0000 (---------------) + is-a-bruinsfan + 0x0000d78e, // n0x19c3 c0x0000 (---------------) + is-a-candidate + 0x0001058f, // n0x19c4 c0x0000 (---------------) + is-a-celticsfan + 0x000110c9, // n0x19c5 c0x0000 (---------------) + is-a-chef + 0x0004ef49, // n0x19c6 c0x0000 (---------------) + is-a-geek + 0x00065e4b, // n0x19c7 c0x0000 (---------------) + is-a-knight + 0x0007df8f, // n0x19c8 c0x0000 (---------------) + is-a-linux-user + 0x0008cbcc, // n0x19c9 c0x0000 (---------------) + is-a-patsfan + 0x000aae0b, // n0x19ca c0x0000 (---------------) + is-a-soxfan + 0x000b9ec8, // n0x19cb c0x0000 (---------------) + is-found + 0x000cf047, // n0x19cc c0x0000 (---------------) + is-lost + 0x0015c0c8, // n0x19cd c0x0000 (---------------) + is-saved + 0x000ea8cb, // n0x19ce c0x0000 (---------------) + is-very-bad + 0x000ed70c, // n0x19cf c0x0000 (---------------) + is-very-evil + 0x000f7c0c, // n0x19d0 c0x0000 (---------------) + is-very-good + 0x0011cc8c, // n0x19d1 c0x0000 (---------------) + is-very-nice + 0x0013aacd, // n0x19d2 c0x0000 (---------------) + is-very-sweet + 0x000862c8, // n0x19d3 c0x0000 (---------------) + isa-geek + 0x0014ee89, // n0x19d4 c0x0000 (---------------) + kicks-ass + 0x001a0e0b, // n0x19d5 c0x0000 (---------------) + misconfused + 0x000dd687, // n0x19d6 c0x0000 (---------------) + podzone + 0x000d4a4a, // n0x19d7 c0x0000 (---------------) + readmyblog + 0x0005abc6, // n0x19d8 c0x0000 (---------------) + selfip + 0x00099d8d, // n0x19d9 c0x0000 (---------------) + sellsyourhome + 0x000ccd88, // n0x19da c0x0000 (---------------) + servebbs + 0x0008bc88, // n0x19db c0x0000 (---------------) + serveftp + 0x00172349, // n0x19dc c0x0000 (---------------) + servegame + 0x000e8a0c, // n0x19dd c0x0000 (---------------) + stuff-4-sale + 0x00002242, // n0x19de c0x0000 (---------------) + us + 0x001267c6, // n0x19df c0x0000 (---------------) + webhop + 0x00000182, // n0x19e0 c0x0000 (---------------) + za + 0x00000141, // n0x19e1 c0x0000 (---------------) + c + 0x00041203, // n0x19e2 c0x0000 (---------------) + rsc + 0x45b81386, // n0x19e3 c0x0116 (n0x19e4-n0x19e5) o I origin + 0x00062f83, // n0x19e4 c0x0000 (---------------) + ssl + 0x00010a42, // n0x19e5 c0x0000 (---------------) + go + 0x000133c4, // n0x19e6 c0x0000 (---------------) + home + 0x00000d02, // n0x19e7 c0x0000 (---------------) + al + 0x000d5e84, // n0x19e8 c0x0000 (---------------) + asso + 0x00000482, // n0x19e9 c0x0000 (---------------) + at + 0x00005782, // n0x19ea c0x0000 (---------------) + au + 0x00002e02, // n0x19eb c0x0000 (---------------) + be + 0x00104a82, // n0x19ec c0x0000 (---------------) + bg + 0x00000e42, // n0x19ed c0x0000 (---------------) + ca + 0x00062e02, // n0x19ee c0x0000 (---------------) + cd + 0x00000382, // n0x19ef c0x0000 (---------------) + ch + 0x0001dac2, // n0x19f0 c0x0000 (---------------) + cn + 0x0003cd42, // n0x19f1 c0x0000 (---------------) + cy + 0x00000142, // n0x19f2 c0x0000 (---------------) + cz + 0x00005582, // n0x19f3 c0x0000 (---------------) + de + 0x000489c2, // n0x19f4 c0x0000 (---------------) + dk + 0x00039103, // n0x19f5 c0x0000 (---------------) + edu + 0x0000cf42, // n0x19f6 c0x0000 (---------------) + ee + 0x00000082, // n0x19f7 c0x0000 (---------------) + es + 0x00001702, // n0x19f8 c0x0000 (---------------) + fi + 0x00040202, // n0x19f9 c0x0000 (---------------) + fr + 0x00008a82, // n0x19fa c0x0000 (---------------) + gr + 0x0000f742, // n0x19fb c0x0000 (---------------) + hr + 0x00024202, // n0x19fc c0x0000 (---------------) + hu + 0x00000042, // n0x19fd c0x0000 (---------------) + ie + 0x000027c2, // n0x19fe c0x0000 (---------------) + il + 0x000012c2, // n0x19ff c0x0000 (---------------) + in + 0x00001503, // n0x1a00 c0x0000 (---------------) + int + 0x00004e82, // n0x1a01 c0x0000 (---------------) + is + 0x000017c2, // n0x1a02 c0x0000 (---------------) + it + 0x000b00c2, // n0x1a03 c0x0000 (---------------) + jp + 0x0000bdc2, // n0x1a04 c0x0000 (---------------) + kr + 0x00008bc2, // n0x1a05 c0x0000 (---------------) + lt + 0x00003842, // n0x1a06 c0x0000 (---------------) + lu + 0x00006582, // n0x1a07 c0x0000 (---------------) + lv + 0x0001a3c2, // n0x1a08 c0x0000 (---------------) + mc + 0x00000982, // n0x1a09 c0x0000 (---------------) + me + 0x00167282, // n0x1a0a c0x0000 (---------------) + mk + 0x00005402, // n0x1a0b c0x0000 (---------------) + mt + 0x00025742, // n0x1a0c c0x0000 (---------------) + my + 0x00023b43, // n0x1a0d c0x0000 (---------------) + net + 0x000026c2, // n0x1a0e c0x0000 (---------------) + ng + 0x00046d02, // n0x1a0f c0x0000 (---------------) + nl + 0x00001382, // n0x1a10 c0x0000 (---------------) + no + 0x00008282, // n0x1a11 c0x0000 (---------------) + nz + 0x00077705, // n0x1a12 c0x0000 (---------------) + paris + 0x00009442, // n0x1a13 c0x0000 (---------------) + pl + 0x000d3242, // n0x1a14 c0x0000 (---------------) + pt + 0x00042ec3, // n0x1a15 c0x0000 (---------------) + q-a + 0x000020c2, // n0x1a16 c0x0000 (---------------) + ro + 0x0000fe82, // n0x1a17 c0x0000 (---------------) + ru + 0x00004ec2, // n0x1a18 c0x0000 (---------------) + se + 0x000091c2, // n0x1a19 c0x0000 (---------------) + si + 0x00008502, // n0x1a1a c0x0000 (---------------) + sk + 0x00003902, // n0x1a1b c0x0000 (---------------) + tr + 0x00001b02, // n0x1a1c c0x0000 (---------------) + uk + 0x00002242, // n0x1a1d c0x0000 (---------------) + us + 0x00216f03, // n0x1a1e c0x0000 (---------------) + I abo + 0x00200342, // n0x1a1f c0x0000 (---------------) + I ac + 0x00233243, // n0x1a20 c0x0000 (---------------) + I com + 0x00239103, // n0x1a21 c0x0000 (---------------) + I edu + 0x00212b03, // n0x1a22 c0x0000 (---------------) + I gob + 0x0020f543, // n0x1a23 c0x0000 (---------------) + I ing + 0x00213443, // n0x1a24 c0x0000 (---------------) + I med + 0x00223b43, // n0x1a25 c0x0000 (---------------) + I net + 0x00201383, // n0x1a26 c0x0000 (---------------) + I nom + 0x00228743, // n0x1a27 c0x0000 (---------------) + I org + 0x002933c3, // n0x1a28 c0x0000 (---------------) + I sld + 0x000fe108, // n0x1a29 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1a2a c0x0000 (---------------) + I com + 0x00239103, // n0x1a2b c0x0000 (---------------) + I edu + 0x00212b03, // n0x1a2c c0x0000 (---------------) + I gob + 0x00207dc3, // n0x1a2d c0x0000 (---------------) + I mil + 0x00223b43, // n0x1a2e c0x0000 (---------------) + I net + 0x00201383, // n0x1a2f c0x0000 (---------------) + I nom + 0x00228743, // n0x1a30 c0x0000 (---------------) + I org + 0x00233243, // n0x1a31 c0x0000 (---------------) + I com + 0x00239103, // n0x1a32 c0x0000 (---------------) + I edu + 0x00228743, // n0x1a33 c0x0000 (---------------) + I org + 0x00233243, // n0x1a34 c0x0000 (---------------) + I com + 0x00239103, // n0x1a35 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1a36 c0x0000 (---------------) + I gov + 0x00200041, // n0x1a37 c0x0000 (---------------) + I i + 0x00207dc3, // n0x1a38 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1a39 c0x0000 (---------------) + I net + 0x0023b383, // n0x1a3a c0x0000 (---------------) + I ngo + 0x00228743, // n0x1a3b c0x0000 (---------------) + I org + 0x00331a83, // n0x1a3c c0x0000 (---------------) + I biz + 0x00233243, // n0x1a3d c0x0000 (---------------) + I com + 0x00239103, // n0x1a3e c0x0000 (---------------) + I edu + 0x00207d43, // n0x1a3f c0x0000 (---------------) + I fam + 0x00212b03, // n0x1a40 c0x0000 (---------------) + I gob + 0x0023c083, // n0x1a41 c0x0000 (---------------) + I gok + 0x0024ed83, // n0x1a42 c0x0000 (---------------) + I gon + 0x002a4d03, // n0x1a43 c0x0000 (---------------) + I gop + 0x0024e183, // n0x1a44 c0x0000 (---------------) + I gos + 0x0027d903, // n0x1a45 c0x0000 (---------------) + I gov + 0x00201844, // n0x1a46 c0x0000 (---------------) + I info + 0x00223b43, // n0x1a47 c0x0000 (---------------) + I net + 0x00228743, // n0x1a48 c0x0000 (---------------) + I org + 0x0021e243, // n0x1a49 c0x0000 (---------------) + I web + 0x002f4bc4, // n0x1a4a c0x0000 (---------------) + I agro + 0x0022e4c3, // n0x1a4b c0x0000 (---------------) + I aid + 0x00001d43, // n0x1a4c c0x0000 (---------------) + art + 0x00200c43, // n0x1a4d c0x0000 (---------------) + I atm + 0x00255b88, // n0x1a4e c0x0000 (---------------) + I augustow + 0x00229f44, // n0x1a4f c0x0000 (---------------) + I auto + 0x002278ca, // n0x1a50 c0x0000 (---------------) + I babia-gora + 0x002067c6, // n0x1a51 c0x0000 (---------------) + I bedzin + 0x00396fc7, // n0x1a52 c0x0000 (---------------) + I beskidy + 0x0022248a, // n0x1a53 c0x0000 (---------------) + I bialowieza + 0x00275b09, // n0x1a54 c0x0000 (---------------) + I bialystok + 0x003a2f47, // n0x1a55 c0x0000 (---------------) + I bielawa + 0x0020000a, // n0x1a56 c0x0000 (---------------) + I bieszczady + 0x00331a83, // n0x1a57 c0x0000 (---------------) + I biz + 0x0037714b, // n0x1a58 c0x0000 (---------------) + I boleslawiec + 0x00302649, // n0x1a59 c0x0000 (---------------) + I bydgoszcz + 0x00219bc5, // n0x1a5a c0x0000 (---------------) + I bytom + 0x002cd6c7, // n0x1a5b c0x0000 (---------------) + I cieszyn + 0x0000ce42, // n0x1a5c c0x0000 (---------------) + co + 0x00233243, // n0x1a5d c0x0000 (---------------) + I com + 0x00355907, // n0x1a5e c0x0000 (---------------) + I czeladz + 0x00357445, // n0x1a5f c0x0000 (---------------) + I czest + 0x002bdbc9, // n0x1a60 c0x0000 (---------------) + I dlugoleka + 0x00239103, // n0x1a61 c0x0000 (---------------) + I edu + 0x00226486, // n0x1a62 c0x0000 (---------------) + I elblag + 0x002bca03, // n0x1a63 c0x0000 (---------------) + I elk + 0x000c62c3, // n0x1a64 c0x0000 (---------------) + gda + 0x000faa86, // n0x1a65 c0x0000 (---------------) + gdansk + 0x00129846, // n0x1a66 c0x0000 (---------------) + gdynia + 0x00005b87, // n0x1a67 c0x0000 (---------------) + gliwice + 0x002114c6, // n0x1a68 c0x0000 (---------------) + I glogow + 0x00215f85, // n0x1a69 c0x0000 (---------------) + I gmina + 0x00382c07, // n0x1a6a c0x0000 (---------------) + I gniezno + 0x00334fc7, // n0x1a6b c0x0000 (---------------) + I gorlice + 0x47e7d903, // n0x1a6c c0x011f (n0x1aef-n0x1b1e) + I gov + 0x0032c447, // n0x1a6d c0x0000 (---------------) + I grajewo + 0x0035d983, // n0x1a6e c0x0000 (---------------) + I gsm + 0x00309a05, // n0x1a6f c0x0000 (---------------) + I ilawa + 0x00201844, // n0x1a70 c0x0000 (---------------) + I info + 0x003a5288, // n0x1a71 c0x0000 (---------------) + I jaworzno + 0x002af58c, // n0x1a72 c0x0000 (---------------) + I jelenia-gora + 0x002adc45, // n0x1a73 c0x0000 (---------------) + I jgora + 0x0031fb46, // n0x1a74 c0x0000 (---------------) + I kalisz + 0x003557c7, // n0x1a75 c0x0000 (---------------) + I karpacz + 0x0038d447, // n0x1a76 c0x0000 (---------------) + I kartuzy + 0x0020d0c7, // n0x1a77 c0x0000 (---------------) + I kaszuby + 0x00211dc8, // n0x1a78 c0x0000 (---------------) + I katowice + 0x00264f8f, // n0x1a79 c0x0000 (---------------) + I kazimierz-dolny + 0x00248845, // n0x1a7a c0x0000 (---------------) + I kepno + 0x00244c07, // n0x1a7b c0x0000 (---------------) + I ketrzyn + 0x0039d947, // n0x1a7c c0x0000 (---------------) + I klodzko + 0x002a63ca, // n0x1a7d c0x0000 (---------------) + I kobierzyce + 0x0033c289, // n0x1a7e c0x0000 (---------------) + I kolobrzeg + 0x002ca585, // n0x1a7f c0x0000 (---------------) + I konin + 0x002caf0a, // n0x1a80 c0x0000 (---------------) + I konskowola + 0x00126686, // n0x1a81 c0x0000 (---------------) + krakow + 0x002bca85, // n0x1a82 c0x0000 (---------------) + I kutno + 0x00369344, // n0x1a83 c0x0000 (---------------) + I lapy + 0x00269d86, // n0x1a84 c0x0000 (---------------) + I lebork + 0x0023eb07, // n0x1a85 c0x0000 (---------------) + I legnica + 0x00233647, // n0x1a86 c0x0000 (---------------) + I lezajsk + 0x0022b388, // n0x1a87 c0x0000 (---------------) + I limanowa + 0x00214d05, // n0x1a88 c0x0000 (---------------) + I lomza + 0x00357346, // n0x1a89 c0x0000 (---------------) + I lowicz + 0x0038dec5, // n0x1a8a c0x0000 (---------------) + I lubin + 0x0036e405, // n0x1a8b c0x0000 (---------------) + I lukow + 0x00218c84, // n0x1a8c c0x0000 (---------------) + I mail + 0x002eacc7, // n0x1a8d c0x0000 (---------------) + I malbork + 0x00307d0a, // n0x1a8e c0x0000 (---------------) + I malopolska + 0x0020a788, // n0x1a8f c0x0000 (---------------) + I mazowsze + 0x002ea246, // n0x1a90 c0x0000 (---------------) + I mazury + 0x00013443, // n0x1a91 c0x0000 (---------------) + med + 0x00303545, // n0x1a92 c0x0000 (---------------) + I media + 0x00231c86, // n0x1a93 c0x0000 (---------------) + I miasta + 0x003a5a46, // n0x1a94 c0x0000 (---------------) + I mielec + 0x0026c8c6, // n0x1a95 c0x0000 (---------------) + I mielno + 0x00207dc3, // n0x1a96 c0x0000 (---------------) + I mil + 0x0037ed47, // n0x1a97 c0x0000 (---------------) + I mragowo + 0x0039d8c5, // n0x1a98 c0x0000 (---------------) + I naklo + 0x00223b43, // n0x1a99 c0x0000 (---------------) + I net + 0x003a31cd, // n0x1a9a c0x0000 (---------------) + I nieruchomosci + 0x00201383, // n0x1a9b c0x0000 (---------------) + I nom + 0x0022b488, // n0x1a9c c0x0000 (---------------) + I nowaruda + 0x0039f444, // n0x1a9d c0x0000 (---------------) + I nysa + 0x00276b05, // n0x1a9e c0x0000 (---------------) + I olawa + 0x002a62c6, // n0x1a9f c0x0000 (---------------) + I olecko + 0x0023b746, // n0x1aa0 c0x0000 (---------------) + I olkusz + 0x0021f607, // n0x1aa1 c0x0000 (---------------) + I olsztyn + 0x0023c3c7, // n0x1aa2 c0x0000 (---------------) + I opoczno + 0x0024d4c5, // n0x1aa3 c0x0000 (---------------) + I opole + 0x00228743, // n0x1aa4 c0x0000 (---------------) + I org + 0x0036c1c7, // n0x1aa5 c0x0000 (---------------) + I ostroda + 0x002c9009, // n0x1aa6 c0x0000 (---------------) + I ostroleka + 0x0020c949, // n0x1aa7 c0x0000 (---------------) + I ostrowiec + 0x0020e80a, // n0x1aa8 c0x0000 (---------------) + I ostrowwlkp + 0x00247682, // n0x1aa9 c0x0000 (---------------) + I pc + 0x003099c4, // n0x1aaa c0x0000 (---------------) + I pila + 0x002d7704, // n0x1aab c0x0000 (---------------) + I pisz + 0x00213bc7, // n0x1aac c0x0000 (---------------) + I podhale + 0x0023b948, // n0x1aad c0x0000 (---------------) + I podlasie + 0x002de109, // n0x1aae c0x0000 (---------------) + I polkowice + 0x002083c9, // n0x1aaf c0x0000 (---------------) + I pomorskie + 0x002decc7, // n0x1ab0 c0x0000 (---------------) + I pomorze + 0x00248346, // n0x1ab1 c0x0000 (---------------) + I powiat + 0x000e0386, // n0x1ab2 c0x0000 (---------------) + poznan + 0x002e17c4, // n0x1ab3 c0x0000 (---------------) + I priv + 0x002e194a, // n0x1ab4 c0x0000 (---------------) + I prochowice + 0x002e52c8, // n0x1ab5 c0x0000 (---------------) + I pruszkow + 0x002e5f49, // n0x1ab6 c0x0000 (---------------) + I przeworsk + 0x00297506, // n0x1ab7 c0x0000 (---------------) + I pulawy + 0x00301145, // n0x1ab8 c0x0000 (---------------) + I radom + 0x0020a648, // n0x1ab9 c0x0000 (---------------) + I rawa-maz + 0x002c410a, // n0x1aba c0x0000 (---------------) + I realestate + 0x00286903, // n0x1abb c0x0000 (---------------) + I rel + 0x0034f406, // n0x1abc c0x0000 (---------------) + I rybnik + 0x002dedc7, // n0x1abd c0x0000 (---------------) + I rzeszow + 0x0020b905, // n0x1abe c0x0000 (---------------) + I sanok + 0x00225d45, // n0x1abf c0x0000 (---------------) + I sejny + 0x00246b03, // n0x1ac0 c0x0000 (---------------) + I sex + 0x00357184, // n0x1ac1 c0x0000 (---------------) + I shop + 0x00373445, // n0x1ac2 c0x0000 (---------------) + I sklep + 0x00284a47, // n0x1ac3 c0x0000 (---------------) + I skoczow + 0x002e2605, // n0x1ac4 c0x0000 (---------------) + I slask + 0x002d1f86, // n0x1ac5 c0x0000 (---------------) + I slupsk + 0x000ee485, // n0x1ac6 c0x0000 (---------------) + sopot + 0x0021d283, // n0x1ac7 c0x0000 (---------------) + I sos + 0x002b7589, // n0x1ac8 c0x0000 (---------------) + I sosnowiec + 0x002768cc, // n0x1ac9 c0x0000 (---------------) + I stalowa-wola + 0x002a294c, // n0x1aca c0x0000 (---------------) + I starachowice + 0x002caac8, // n0x1acb c0x0000 (---------------) + I stargard + 0x00265cc7, // n0x1acc c0x0000 (---------------) + I suwalki + 0x002ebf88, // n0x1acd c0x0000 (---------------) + I swidnica + 0x002ec58a, // n0x1ace c0x0000 (---------------) + I swiebodzin + 0x002ecf0b, // n0x1acf c0x0000 (---------------) + I swinoujscie + 0x00302788, // n0x1ad0 c0x0000 (---------------) + I szczecin + 0x0031fc48, // n0x1ad1 c0x0000 (---------------) + I szczytno + 0x00294c06, // n0x1ad2 c0x0000 (---------------) + I szkola + 0x00249ec5, // n0x1ad3 c0x0000 (---------------) + I targi + 0x0022afca, // n0x1ad4 c0x0000 (---------------) + I tarnobrzeg + 0x002247c5, // n0x1ad5 c0x0000 (---------------) + I tgory + 0x00200c82, // n0x1ad6 c0x0000 (---------------) + I tm + 0x002c1b87, // n0x1ad7 c0x0000 (---------------) + I tourism + 0x002a3206, // n0x1ad8 c0x0000 (---------------) + I travel + 0x0034fe45, // n0x1ad9 c0x0000 (---------------) + I turek + 0x002ee009, // n0x1ada c0x0000 (---------------) + I turystyka + 0x003091c5, // n0x1adb c0x0000 (---------------) + I tychy + 0x00287385, // n0x1adc c0x0000 (---------------) + I ustka + 0x003095c9, // n0x1add c0x0000 (---------------) + I walbrzych + 0x00231b06, // n0x1ade c0x0000 (---------------) + I warmia + 0x0023f588, // n0x1adf c0x0000 (---------------) + I warszawa + 0x0025a5c3, // n0x1ae0 c0x0000 (---------------) + I waw + 0x00211606, // n0x1ae1 c0x0000 (---------------) + I wegrow + 0x00275046, // n0x1ae2 c0x0000 (---------------) + I wielun + 0x002fe645, // n0x1ae3 c0x0000 (---------------) + I wlocl + 0x002fe649, // n0x1ae4 c0x0000 (---------------) + I wloclawek + 0x002b2bc9, // n0x1ae5 c0x0000 (---------------) + I wodzislaw + 0x00253507, // n0x1ae6 c0x0000 (---------------) + I wolomin + 0x000fe4c4, // n0x1ae7 c0x0000 (---------------) + wroc + 0x002fe4c7, // n0x1ae8 c0x0000 (---------------) + I wroclaw + 0x002082c9, // n0x1ae9 c0x0000 (---------------) + I zachpomor + 0x00222685, // n0x1aea c0x0000 (---------------) + I zagan + 0x00138388, // n0x1aeb c0x0000 (---------------) + zakopane + 0x00353e05, // n0x1aec c0x0000 (---------------) + I zarow + 0x00223c05, // n0x1aed c0x0000 (---------------) + I zgora + 0x0022f4c9, // n0x1aee c0x0000 (---------------) + I zgorzelec + 0x00208082, // n0x1aef c0x0000 (---------------) + I ap + 0x0022e2c4, // n0x1af0 c0x0000 (---------------) + I griw + 0x00205c82, // n0x1af1 c0x0000 (---------------) + I ic + 0x00204e82, // n0x1af2 c0x0000 (---------------) + I is + 0x00269b45, // n0x1af3 c0x0000 (---------------) + I kmpsp + 0x002ce008, // n0x1af4 c0x0000 (---------------) + I konsulat + 0x0036ff85, // n0x1af5 c0x0000 (---------------) + I kppsp + 0x002bf3c3, // n0x1af6 c0x0000 (---------------) + I kwp + 0x002bf3c5, // n0x1af7 c0x0000 (---------------) + I kwpsp + 0x002cda83, // n0x1af8 c0x0000 (---------------) + I mup + 0x00212002, // n0x1af9 c0x0000 (---------------) + I mw + 0x00267184, // n0x1afa c0x0000 (---------------) + I oirm + 0x002e7a03, // n0x1afb c0x0000 (---------------) + I oum + 0x0020aac2, // n0x1afc c0x0000 (---------------) + I pa + 0x002e3144, // n0x1afd c0x0000 (---------------) + I pinb + 0x002d7d03, // n0x1afe c0x0000 (---------------) + I piw + 0x00206ec2, // n0x1aff c0x0000 (---------------) + I po + 0x00208103, // n0x1b00 c0x0000 (---------------) + I psp + 0x0028e544, // n0x1b01 c0x0000 (---------------) + I psse + 0x002b68c3, // n0x1b02 c0x0000 (---------------) + I pup + 0x00234584, // n0x1b03 c0x0000 (---------------) + I rzgw + 0x00201002, // n0x1b04 c0x0000 (---------------) + I sa + 0x00272743, // n0x1b05 c0x0000 (---------------) + I sdn + 0x002176c3, // n0x1b06 c0x0000 (---------------) + I sko + 0x00205f02, // n0x1b07 c0x0000 (---------------) + I so + 0x00332d82, // n0x1b08 c0x0000 (---------------) + I sr + 0x002b2a09, // n0x1b09 c0x0000 (---------------) + I starostwo + 0x00204682, // n0x1b0a c0x0000 (---------------) + I ug + 0x0028ab04, // n0x1b0b c0x0000 (---------------) + I ugim + 0x002053c2, // n0x1b0c c0x0000 (---------------) + I um + 0x0020a4c4, // n0x1b0d c0x0000 (---------------) + I umig + 0x00248304, // n0x1b0e c0x0000 (---------------) + I upow + 0x002e4644, // n0x1b0f c0x0000 (---------------) + I uppo + 0x00202242, // n0x1b10 c0x0000 (---------------) + I us + 0x002431c2, // n0x1b11 c0x0000 (---------------) + I uw + 0x0020fec3, // n0x1b12 c0x0000 (---------------) + I uzs + 0x002ecb83, // n0x1b13 c0x0000 (---------------) + I wif + 0x00244204, // n0x1b14 c0x0000 (---------------) + I wiih + 0x0025cd84, // n0x1b15 c0x0000 (---------------) + I winb + 0x002c8f84, // n0x1b16 c0x0000 (---------------) + I wios + 0x002cae04, // n0x1b17 c0x0000 (---------------) + I witd + 0x002fdb43, // n0x1b18 c0x0000 (---------------) + I wiw + 0x002f2083, // n0x1b19 c0x0000 (---------------) + I wsa + 0x00326604, // n0x1b1a c0x0000 (---------------) + I wskr + 0x002ffa04, // n0x1b1b c0x0000 (---------------) + I wuoz + 0x002ffd06, // n0x1b1c c0x0000 (---------------) + I wzmiuw + 0x00262bc2, // n0x1b1d c0x0000 (---------------) + I zp + 0x0020ce42, // n0x1b1e c0x0000 (---------------) + I co + 0x00239103, // n0x1b1f c0x0000 (---------------) + I edu + 0x0027d903, // n0x1b20 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1b21 c0x0000 (---------------) + I net + 0x00228743, // n0x1b22 c0x0000 (---------------) + I org + 0x00200342, // n0x1b23 c0x0000 (---------------) + I ac + 0x00331a83, // n0x1b24 c0x0000 (---------------) + I biz + 0x00233243, // n0x1b25 c0x0000 (---------------) + I com + 0x00239103, // n0x1b26 c0x0000 (---------------) + I edu + 0x002025c3, // n0x1b27 c0x0000 (---------------) + I est + 0x0027d903, // n0x1b28 c0x0000 (---------------) + I gov + 0x00201844, // n0x1b29 c0x0000 (---------------) + I info + 0x002b2cc4, // n0x1b2a c0x0000 (---------------) + I isla + 0x00200904, // n0x1b2b c0x0000 (---------------) + I name + 0x00223b43, // n0x1b2c c0x0000 (---------------) + I net + 0x00228743, // n0x1b2d c0x0000 (---------------) + I org + 0x00224b03, // n0x1b2e c0x0000 (---------------) + I pro + 0x002e2004, // n0x1b2f c0x0000 (---------------) + I prof + 0x002b5b43, // n0x1b30 c0x0000 (---------------) + I aca + 0x002049c3, // n0x1b31 c0x0000 (---------------) + I bar + 0x002168c3, // n0x1b32 c0x0000 (---------------) + I cpa + 0x00213083, // n0x1b33 c0x0000 (---------------) + I eng + 0x002b1983, // n0x1b34 c0x0000 (---------------) + I jur + 0x00271c03, // n0x1b35 c0x0000 (---------------) + I law + 0x00213443, // n0x1b36 c0x0000 (---------------) + I med + 0x00233243, // n0x1b37 c0x0000 (---------------) + I com + 0x00239103, // n0x1b38 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1b39 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1b3a c0x0000 (---------------) + I net + 0x00228743, // n0x1b3b c0x0000 (---------------) + I org + 0x002db743, // n0x1b3c c0x0000 (---------------) + I plo + 0x002363c3, // n0x1b3d c0x0000 (---------------) + I sec + 0x000fe108, // n0x1b3e c0x0000 (---------------) + blogspot + 0x00233243, // n0x1b3f c0x0000 (---------------) + I com + 0x00239103, // n0x1b40 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1b41 c0x0000 (---------------) + I gov + 0x00201503, // n0x1b42 c0x0000 (---------------) + I int + 0x00223b43, // n0x1b43 c0x0000 (---------------) + I net + 0x00242144, // n0x1b44 c0x0000 (---------------) + I nome + 0x00228743, // n0x1b45 c0x0000 (---------------) + I org + 0x002a0ec4, // n0x1b46 c0x0000 (---------------) + I publ + 0x002b8e45, // n0x1b47 c0x0000 (---------------) + I belau + 0x0020ce42, // n0x1b48 c0x0000 (---------------) + I co + 0x002024c2, // n0x1b49 c0x0000 (---------------) + I ed + 0x00210a42, // n0x1b4a c0x0000 (---------------) + I go + 0x00202ac2, // n0x1b4b c0x0000 (---------------) + I ne + 0x00200dc2, // n0x1b4c c0x0000 (---------------) + I or + 0x00233243, // n0x1b4d c0x0000 (---------------) + I com + 0x0023c344, // n0x1b4e c0x0000 (---------------) + I coop + 0x00239103, // n0x1b4f c0x0000 (---------------) + I edu + 0x0027d903, // n0x1b50 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1b51 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1b52 c0x0000 (---------------) + I net + 0x00228743, // n0x1b53 c0x0000 (---------------) + I org + 0x000fe108, // n0x1b54 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1b55 c0x0000 (---------------) + I com + 0x00239103, // n0x1b56 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1b57 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1b58 c0x0000 (---------------) + I mil + 0x00200904, // n0x1b59 c0x0000 (---------------) + I name + 0x00223b43, // n0x1b5a c0x0000 (---------------) + I net + 0x00228743, // n0x1b5b c0x0000 (---------------) + I org + 0x00217283, // n0x1b5c c0x0000 (---------------) + I sch + 0x002d5e84, // n0x1b5d c0x0000 (---------------) + I asso + 0x000fe108, // n0x1b5e c0x0000 (---------------) + blogspot + 0x00233243, // n0x1b5f c0x0000 (---------------) + I com + 0x00201383, // n0x1b60 c0x0000 (---------------) + I nom + 0x0024b944, // n0x1b61 c0x0000 (---------------) + I arts + 0x000fe108, // n0x1b62 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1b63 c0x0000 (---------------) + I com + 0x0024dcc4, // n0x1b64 c0x0000 (---------------) + I firm + 0x00201844, // n0x1b65 c0x0000 (---------------) + I info + 0x00201383, // n0x1b66 c0x0000 (---------------) + I nom + 0x00201542, // n0x1b67 c0x0000 (---------------) + I nt + 0x00228743, // n0x1b68 c0x0000 (---------------) + I org + 0x0022c2c3, // n0x1b69 c0x0000 (---------------) + I rec + 0x00364cc5, // n0x1b6a c0x0000 (---------------) + I store + 0x00200c82, // n0x1b6b c0x0000 (---------------) + I tm + 0x002ffb43, // n0x1b6c c0x0000 (---------------) + I www + 0x00200342, // n0x1b6d c0x0000 (---------------) + I ac + 0x000fe108, // n0x1b6e c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x1b6f c0x0000 (---------------) + I co + 0x00239103, // n0x1b70 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1b71 c0x0000 (---------------) + I gov + 0x002012c2, // n0x1b72 c0x0000 (---------------) + I in + 0x00228743, // n0x1b73 c0x0000 (---------------) + I org + 0x00200342, // n0x1b74 c0x0000 (---------------) + I ac + 0x002001c7, // n0x1b75 c0x0000 (---------------) + I adygeya + 0x0028c445, // n0x1b76 c0x0000 (---------------) + I altai + 0x00295084, // n0x1b77 c0x0000 (---------------) + I amur + 0x0037ca86, // n0x1b78 c0x0000 (---------------) + I amursk + 0x00236d0b, // n0x1b79 c0x0000 (---------------) + I arkhangelsk + 0x0025a349, // n0x1b7a c0x0000 (---------------) + I astrakhan + 0x0031fa86, // n0x1b7b c0x0000 (---------------) + I baikal + 0x00324289, // n0x1b7c c0x0000 (---------------) + I bashkiria + 0x002d4488, // n0x1b7d c0x0000 (---------------) + I belgorod + 0x00204ac3, // n0x1b7e c0x0000 (---------------) + I bir + 0x000fe108, // n0x1b7f c0x0000 (---------------) + blogspot + 0x00229507, // n0x1b80 c0x0000 (---------------) + I bryansk + 0x0034ac88, // n0x1b81 c0x0000 (---------------) + I buryatia + 0x00329bc3, // n0x1b82 c0x0000 (---------------) + I cbg + 0x00264784, // n0x1b83 c0x0000 (---------------) + I chel + 0x0026dd8b, // n0x1b84 c0x0000 (---------------) + I chelyabinsk + 0x002b0305, // n0x1b85 c0x0000 (---------------) + I chita + 0x002be488, // n0x1b86 c0x0000 (---------------) + I chukotka + 0x003364c9, // n0x1b87 c0x0000 (---------------) + I chuvashia + 0x0025cd03, // n0x1b88 c0x0000 (---------------) + I cmw + 0x00233243, // n0x1b89 c0x0000 (---------------) + I com + 0x00202508, // n0x1b8a c0x0000 (---------------) + I dagestan + 0x002eb107, // n0x1b8b c0x0000 (---------------) + I dudinka + 0x00327d86, // n0x1b8c c0x0000 (---------------) + I e-burg + 0x00239103, // n0x1b8d c0x0000 (---------------) + I edu + 0x00384f47, // n0x1b8e c0x0000 (---------------) + I fareast + 0x0027d903, // n0x1b8f c0x0000 (---------------) + I gov + 0x00289106, // n0x1b90 c0x0000 (---------------) + I grozny + 0x00201503, // n0x1b91 c0x0000 (---------------) + I int + 0x00230847, // n0x1b92 c0x0000 (---------------) + I irkutsk + 0x00288007, // n0x1b93 c0x0000 (---------------) + I ivanovo + 0x00385f47, // n0x1b94 c0x0000 (---------------) + I izhevsk + 0x002eac45, // n0x1b95 c0x0000 (---------------) + I jamal + 0x0020b483, // n0x1b96 c0x0000 (---------------) + I jar + 0x0020c3cb, // n0x1b97 c0x0000 (---------------) + I joshkar-ola + 0x00332448, // n0x1b98 c0x0000 (---------------) + I k-uralsk + 0x00225688, // n0x1b99 c0x0000 (---------------) + I kalmykia + 0x00250706, // n0x1b9a c0x0000 (---------------) + I kaluga + 0x0021a349, // n0x1b9b c0x0000 (---------------) + I kamchatka + 0x00325cc7, // n0x1b9c c0x0000 (---------------) + I karelia + 0x002f8c85, // n0x1b9d c0x0000 (---------------) + I kazan + 0x00314984, // n0x1b9e c0x0000 (---------------) + I kchr + 0x00275d48, // n0x1b9f c0x0000 (---------------) + I kemerovo + 0x002338ca, // n0x1ba0 c0x0000 (---------------) + I khabarovsk + 0x00233b09, // n0x1ba1 c0x0000 (---------------) + I khakassia + 0x0024f143, // n0x1ba2 c0x0000 (---------------) + I khv + 0x0027f805, // n0x1ba3 c0x0000 (---------------) + I kirov + 0x00272ac3, // n0x1ba4 c0x0000 (---------------) + I kms + 0x002a6c46, // n0x1ba5 c0x0000 (---------------) + I koenig + 0x0039b084, // n0x1ba6 c0x0000 (---------------) + I komi + 0x002fe848, // n0x1ba7 c0x0000 (---------------) + I kostroma + 0x003860cb, // n0x1ba8 c0x0000 (---------------) + I krasnoyarsk + 0x0033c145, // n0x1ba9 c0x0000 (---------------) + I kuban + 0x002b8bc6, // n0x1baa c0x0000 (---------------) + I kurgan + 0x002ba785, // n0x1bab c0x0000 (---------------) + I kursk + 0x002bb788, // n0x1bac c0x0000 (---------------) + I kustanai + 0x002bcbc7, // n0x1bad c0x0000 (---------------) + I kuzbass + 0x00211c47, // n0x1bae c0x0000 (---------------) + I lipetsk + 0x002274c7, // n0x1baf c0x0000 (---------------) + I magadan + 0x00219cc4, // n0x1bb0 c0x0000 (---------------) + I mari + 0x00222947, // n0x1bb1 c0x0000 (---------------) + I mari-el + 0x0027c146, // n0x1bb2 c0x0000 (---------------) + I marine + 0x00207dc3, // n0x1bb3 c0x0000 (---------------) + I mil + 0x002c6f48, // n0x1bb4 c0x0000 (---------------) + I mordovia + 0x00253203, // n0x1bb5 c0x0000 (---------------) + I msk + 0x002cde48, // n0x1bb6 c0x0000 (---------------) + I murmansk + 0x002d3ac5, // n0x1bb7 c0x0000 (---------------) + I mytis + 0x0030ac08, // n0x1bb8 c0x0000 (---------------) + I nakhodka + 0x00239307, // n0x1bb9 c0x0000 (---------------) + I nalchik + 0x00223b43, // n0x1bba c0x0000 (---------------) + I net + 0x00391fc3, // n0x1bbb c0x0000 (---------------) + I nkz + 0x0028bac4, // n0x1bbc c0x0000 (---------------) + I nnov + 0x00373307, // n0x1bbd c0x0000 (---------------) + I norilsk + 0x00206143, // n0x1bbe c0x0000 (---------------) + I nov + 0x002880cb, // n0x1bbf c0x0000 (---------------) + I novosibirsk + 0x00217683, // n0x1bc0 c0x0000 (---------------) + I nsk + 0x002531c4, // n0x1bc1 c0x0000 (---------------) + I omsk + 0x00364d48, // n0x1bc2 c0x0000 (---------------) + I orenburg + 0x00228743, // n0x1bc3 c0x0000 (---------------) + I org + 0x002d8045, // n0x1bc4 c0x0000 (---------------) + I oryol + 0x00297b05, // n0x1bc5 c0x0000 (---------------) + I oskol + 0x0039d7c6, // n0x1bc6 c0x0000 (---------------) + I palana + 0x00212605, // n0x1bc7 c0x0000 (---------------) + I penza + 0x002d3e84, // n0x1bc8 c0x0000 (---------------) + I perm + 0x002080c2, // n0x1bc9 c0x0000 (---------------) + I pp + 0x002e6203, // n0x1bca c0x0000 (---------------) + I ptz + 0x003693ca, // n0x1bcb c0x0000 (---------------) + I pyatigorsk + 0x0038fd03, // n0x1bcc c0x0000 (---------------) + I rnd + 0x002d2fc9, // n0x1bcd c0x0000 (---------------) + I rubtsovsk + 0x00249886, // n0x1bce c0x0000 (---------------) + I ryazan + 0x0021c788, // n0x1bcf c0x0000 (---------------) + I sakhalin + 0x0028e086, // n0x1bd0 c0x0000 (---------------) + I samara + 0x0021adc7, // n0x1bd1 c0x0000 (---------------) + I saratov + 0x002c9c88, // n0x1bd2 c0x0000 (---------------) + I simbirsk + 0x0034b188, // n0x1bd3 c0x0000 (---------------) + I smolensk + 0x002d6803, // n0x1bd4 c0x0000 (---------------) + I snz + 0x00269c03, // n0x1bd5 c0x0000 (---------------) + I spb + 0x00220649, // n0x1bd6 c0x0000 (---------------) + I stavropol + 0x002490c3, // n0x1bd7 c0x0000 (---------------) + I stv + 0x00341e46, // n0x1bd8 c0x0000 (---------------) + I surgut + 0x0028c0c6, // n0x1bd9 c0x0000 (---------------) + I syzran + 0x00317446, // n0x1bda c0x0000 (---------------) + I tambov + 0x0036bec9, // n0x1bdb c0x0000 (---------------) + I tatarstan + 0x002fdf44, // n0x1bdc c0x0000 (---------------) + I test + 0x0020ae83, // n0x1bdd c0x0000 (---------------) + I tom + 0x00332345, // n0x1bde c0x0000 (---------------) + I tomsk + 0x0030d249, // n0x1bdf c0x0000 (---------------) + I tsaritsyn + 0x00211d43, // n0x1be0 c0x0000 (---------------) + I tsk + 0x0035bb44, // n0x1be1 c0x0000 (---------------) + I tula + 0x002ef044, // n0x1be2 c0x0000 (---------------) + I tuva + 0x00360d84, // n0x1be3 c0x0000 (---------------) + I tver + 0x00321446, // n0x1be4 c0x0000 (---------------) + I tyumen + 0x0020d2c3, // n0x1be5 c0x0000 (---------------) + I udm + 0x0020d2c8, // n0x1be6 c0x0000 (---------------) + I udmurtia + 0x00259f88, // n0x1be7 c0x0000 (---------------) + I ulan-ude + 0x0033b846, // n0x1be8 c0x0000 (---------------) + I vdonsk + 0x002f8a8b, // n0x1be9 c0x0000 (---------------) + I vladikavkaz + 0x002f8dc8, // n0x1bea c0x0000 (---------------) + I vladimir + 0x002f8fcb, // n0x1beb c0x0000 (---------------) + I vladivostok + 0x002fb449, // n0x1bec c0x0000 (---------------) + I volgograd + 0x002fa987, // n0x1bed c0x0000 (---------------) + I vologda + 0x002fb8c8, // n0x1bee c0x0000 (---------------) + I voronezh + 0x002fd583, // n0x1bef c0x0000 (---------------) + I vrn + 0x00398fc6, // n0x1bf0 c0x0000 (---------------) + I vyatka + 0x0020bb07, // n0x1bf1 c0x0000 (---------------) + I yakutia + 0x002991c5, // n0x1bf2 c0x0000 (---------------) + I yamal + 0x00344f89, // n0x1bf3 c0x0000 (---------------) + I yaroslavl + 0x0031310d, // n0x1bf4 c0x0000 (---------------) + I yekaterinburg + 0x0021c5d1, // n0x1bf5 c0x0000 (---------------) + I yuzhno-sakhalinsk + 0x00237d05, // n0x1bf6 c0x0000 (---------------) + I zgrad + 0x00200342, // n0x1bf7 c0x0000 (---------------) + I ac + 0x0020ce42, // n0x1bf8 c0x0000 (---------------) + I co + 0x00233243, // n0x1bf9 c0x0000 (---------------) + I com + 0x00239103, // n0x1bfa c0x0000 (---------------) + I edu + 0x002aebc4, // n0x1bfb c0x0000 (---------------) + I gouv + 0x0027d903, // n0x1bfc c0x0000 (---------------) + I gov + 0x00201503, // n0x1bfd c0x0000 (---------------) + I int + 0x00207dc3, // n0x1bfe c0x0000 (---------------) + I mil + 0x00223b43, // n0x1bff c0x0000 (---------------) + I net + 0x00233243, // n0x1c00 c0x0000 (---------------) + I com + 0x00239103, // n0x1c01 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1c02 c0x0000 (---------------) + I gov + 0x00213443, // n0x1c03 c0x0000 (---------------) + I med + 0x00223b43, // n0x1c04 c0x0000 (---------------) + I net + 0x00228743, // n0x1c05 c0x0000 (---------------) + I org + 0x0028f343, // n0x1c06 c0x0000 (---------------) + I pub + 0x00217283, // n0x1c07 c0x0000 (---------------) + I sch + 0x00233243, // n0x1c08 c0x0000 (---------------) + I com + 0x00239103, // n0x1c09 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1c0a c0x0000 (---------------) + I gov + 0x00223b43, // n0x1c0b c0x0000 (---------------) + I net + 0x00228743, // n0x1c0c c0x0000 (---------------) + I org + 0x00233243, // n0x1c0d c0x0000 (---------------) + I com + 0x00239103, // n0x1c0e c0x0000 (---------------) + I edu + 0x0027d903, // n0x1c0f c0x0000 (---------------) + I gov + 0x00223b43, // n0x1c10 c0x0000 (---------------) + I net + 0x00228743, // n0x1c11 c0x0000 (---------------) + I org + 0x00233243, // n0x1c12 c0x0000 (---------------) + I com + 0x00239103, // n0x1c13 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1c14 c0x0000 (---------------) + I gov + 0x00201844, // n0x1c15 c0x0000 (---------------) + I info + 0x00213443, // n0x1c16 c0x0000 (---------------) + I med + 0x00223b43, // n0x1c17 c0x0000 (---------------) + I net + 0x00228743, // n0x1c18 c0x0000 (---------------) + I org + 0x002203c2, // n0x1c19 c0x0000 (---------------) + I tv + 0x002001c1, // n0x1c1a c0x0000 (---------------) + I a + 0x00200342, // n0x1c1b c0x0000 (---------------) + I ac + 0x00200001, // n0x1c1c c0x0000 (---------------) + I b + 0x00314f02, // n0x1c1d c0x0000 (---------------) + I bd + 0x000fe108, // n0x1c1e c0x0000 (---------------) + blogspot + 0x00220945, // n0x1c1f c0x0000 (---------------) + I brand + 0x00200141, // n0x1c20 c0x0000 (---------------) + I c + 0x00033243, // n0x1c21 c0x0000 (---------------) + com + 0x00200201, // n0x1c22 c0x0000 (---------------) + I d + 0x00200081, // n0x1c23 c0x0000 (---------------) + I e + 0x00201701, // n0x1c24 c0x0000 (---------------) + I f + 0x00233802, // n0x1c25 c0x0000 (---------------) + I fh + 0x00233804, // n0x1c26 c0x0000 (---------------) + I fhsk + 0x00363cc3, // n0x1c27 c0x0000 (---------------) + I fhv + 0x00200281, // n0x1c28 c0x0000 (---------------) + I g + 0x002003c1, // n0x1c29 c0x0000 (---------------) + I h + 0x00200041, // n0x1c2a c0x0000 (---------------) + I i + 0x00201b41, // n0x1c2b c0x0000 (---------------) + I k + 0x002f2d87, // n0x1c2c c0x0000 (---------------) + I komforb + 0x002d704f, // n0x1c2d c0x0000 (---------------) + I kommunalforbund + 0x002bf6c6, // n0x1c2e c0x0000 (---------------) + I komvux + 0x00200d41, // n0x1c2f c0x0000 (---------------) + I l + 0x00268a06, // n0x1c30 c0x0000 (---------------) + I lanbib + 0x00200441, // n0x1c31 c0x0000 (---------------) + I m + 0x00200781, // n0x1c32 c0x0000 (---------------) + I n + 0x0032158e, // n0x1c33 c0x0000 (---------------) + I naturbruksgymn + 0x00200dc1, // n0x1c34 c0x0000 (---------------) + I o + 0x00228743, // n0x1c35 c0x0000 (---------------) + I org + 0x00200581, // n0x1c36 c0x0000 (---------------) + I p + 0x002a4d85, // n0x1c37 c0x0000 (---------------) + I parti + 0x002080c2, // n0x1c38 c0x0000 (---------------) + I pp + 0x00246a05, // n0x1c39 c0x0000 (---------------) + I press + 0x002006c1, // n0x1c3a c0x0000 (---------------) + I r + 0x002000c1, // n0x1c3b c0x0000 (---------------) + I s + 0x002004c1, // n0x1c3c c0x0000 (---------------) + I t + 0x00200c82, // n0x1c3d c0x0000 (---------------) + I tm + 0x00200741, // n0x1c3e c0x0000 (---------------) + I u + 0x00201c41, // n0x1c3f c0x0000 (---------------) + I w + 0x00200a01, // n0x1c40 c0x0000 (---------------) + I x + 0x00200241, // n0x1c41 c0x0000 (---------------) + I y + 0x00200101, // n0x1c42 c0x0000 (---------------) + I z + 0x000fe108, // n0x1c43 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1c44 c0x0000 (---------------) + I com + 0x00239103, // n0x1c45 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1c46 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1c47 c0x0000 (---------------) + I net + 0x00228743, // n0x1c48 c0x0000 (---------------) + I org + 0x0021e783, // n0x1c49 c0x0000 (---------------) + I per + 0x00233243, // n0x1c4a c0x0000 (---------------) + I com + 0x0027d903, // n0x1c4b c0x0000 (---------------) + I gov + 0x0008e988, // n0x1c4c c0x0000 (---------------) + hashbang + 0x00207dc3, // n0x1c4d c0x0000 (---------------) + I mil + 0x00223b43, // n0x1c4e c0x0000 (---------------) + I net + 0x00228743, // n0x1c4f c0x0000 (---------------) + I org + 0x014d8c48, // n0x1c50 c0x0005 (---------------)* o platform + 0x000fe108, // n0x1c51 c0x0000 (---------------) + blogspot + 0x000fe108, // n0x1c52 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1c53 c0x0000 (---------------) + I com + 0x00239103, // n0x1c54 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1c55 c0x0000 (---------------) + I gov + 0x00223b43, // n0x1c56 c0x0000 (---------------) + I net + 0x00228743, // n0x1c57 c0x0000 (---------------) + I org + 0x00201d43, // n0x1c58 c0x0000 (---------------) + I art + 0x000fe108, // n0x1c59 c0x0000 (---------------) + blogspot + 0x00233243, // n0x1c5a c0x0000 (---------------) + I com + 0x00239103, // n0x1c5b c0x0000 (---------------) + I edu + 0x002aebc4, // n0x1c5c c0x0000 (---------------) + I gouv + 0x00228743, // n0x1c5d c0x0000 (---------------) + I org + 0x00299705, // n0x1c5e c0x0000 (---------------) + I perso + 0x00309e44, // n0x1c5f c0x0000 (---------------) + I univ + 0x00233243, // n0x1c60 c0x0000 (---------------) + I com + 0x00223b43, // n0x1c61 c0x0000 (---------------) + I net + 0x00228743, // n0x1c62 c0x0000 (---------------) + I org + 0x0020ce42, // n0x1c63 c0x0000 (---------------) + I co + 0x00233243, // n0x1c64 c0x0000 (---------------) + I com + 0x002378c9, // n0x1c65 c0x0000 (---------------) + I consulado + 0x00239103, // n0x1c66 c0x0000 (---------------) + I edu + 0x0023b489, // n0x1c67 c0x0000 (---------------) + I embaixada + 0x0027d903, // n0x1c68 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1c69 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1c6a c0x0000 (---------------) + I net + 0x00228743, // n0x1c6b c0x0000 (---------------) + I org + 0x002e15c8, // n0x1c6c c0x0000 (---------------) + I principe + 0x00213547, // n0x1c6d c0x0000 (---------------) + I saotome + 0x00364cc5, // n0x1c6e c0x0000 (---------------) + I store + 0x002001c7, // n0x1c6f c0x0000 (---------------) + I adygeya + 0x00236d0b, // n0x1c70 c0x0000 (---------------) + I arkhangelsk + 0x0020eb88, // n0x1c71 c0x0000 (---------------) + I balashov + 0x00324289, // n0x1c72 c0x0000 (---------------) + I bashkiria + 0x00229507, // n0x1c73 c0x0000 (---------------) + I bryansk + 0x00202508, // n0x1c74 c0x0000 (---------------) + I dagestan + 0x00289106, // n0x1c75 c0x0000 (---------------) + I grozny + 0x00288007, // n0x1c76 c0x0000 (---------------) + I ivanovo + 0x00225688, // n0x1c77 c0x0000 (---------------) + I kalmykia + 0x00250706, // n0x1c78 c0x0000 (---------------) + I kaluga + 0x00325cc7, // n0x1c79 c0x0000 (---------------) + I karelia + 0x00233b09, // n0x1c7a c0x0000 (---------------) + I khakassia + 0x0037d749, // n0x1c7b c0x0000 (---------------) + I krasnodar + 0x002b8bc6, // n0x1c7c c0x0000 (---------------) + I kurgan + 0x002b9ac5, // n0x1c7d c0x0000 (---------------) + I lenug + 0x002c6f48, // n0x1c7e c0x0000 (---------------) + I mordovia + 0x00253203, // n0x1c7f c0x0000 (---------------) + I msk + 0x002cde48, // n0x1c80 c0x0000 (---------------) + I murmansk + 0x00239307, // n0x1c81 c0x0000 (---------------) + I nalchik + 0x00206143, // n0x1c82 c0x0000 (---------------) + I nov + 0x00355647, // n0x1c83 c0x0000 (---------------) + I obninsk + 0x00212605, // n0x1c84 c0x0000 (---------------) + I penza + 0x002dda88, // n0x1c85 c0x0000 (---------------) + I pokrovsk + 0x00274605, // n0x1c86 c0x0000 (---------------) + I sochi + 0x00269c03, // n0x1c87 c0x0000 (---------------) + I spb + 0x0034f6c9, // n0x1c88 c0x0000 (---------------) + I togliatti + 0x002ab687, // n0x1c89 c0x0000 (---------------) + I troitsk + 0x0035bb44, // n0x1c8a c0x0000 (---------------) + I tula + 0x002ef044, // n0x1c8b c0x0000 (---------------) + I tuva + 0x002f8a8b, // n0x1c8c c0x0000 (---------------) + I vladikavkaz + 0x002f8dc8, // n0x1c8d c0x0000 (---------------) + I vladimir + 0x002fa987, // n0x1c8e c0x0000 (---------------) + I vologda + 0x00233243, // n0x1c8f c0x0000 (---------------) + I com + 0x00239103, // n0x1c90 c0x0000 (---------------) + I edu + 0x00212b03, // n0x1c91 c0x0000 (---------------) + I gob + 0x00228743, // n0x1c92 c0x0000 (---------------) + I org + 0x002437c3, // n0x1c93 c0x0000 (---------------) + I red + 0x0027d903, // n0x1c94 c0x0000 (---------------) + I gov + 0x00233243, // n0x1c95 c0x0000 (---------------) + I com + 0x00239103, // n0x1c96 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1c97 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1c98 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1c99 c0x0000 (---------------) + I net + 0x00228743, // n0x1c9a c0x0000 (---------------) + I org + 0x00200342, // n0x1c9b c0x0000 (---------------) + I ac + 0x0020ce42, // n0x1c9c c0x0000 (---------------) + I co + 0x00228743, // n0x1c9d c0x0000 (---------------) + I org + 0x000fe108, // n0x1c9e c0x0000 (---------------) + blogspot + 0x00200342, // n0x1c9f c0x0000 (---------------) + I ac + 0x0020ce42, // n0x1ca0 c0x0000 (---------------) + I co + 0x00210a42, // n0x1ca1 c0x0000 (---------------) + I go + 0x002012c2, // n0x1ca2 c0x0000 (---------------) + I in + 0x00207dc2, // n0x1ca3 c0x0000 (---------------) + I mi + 0x00223b43, // n0x1ca4 c0x0000 (---------------) + I net + 0x00200dc2, // n0x1ca5 c0x0000 (---------------) + I or + 0x00200342, // n0x1ca6 c0x0000 (---------------) + I ac + 0x00331a83, // n0x1ca7 c0x0000 (---------------) + I biz + 0x0020ce42, // n0x1ca8 c0x0000 (---------------) + I co + 0x00233243, // n0x1ca9 c0x0000 (---------------) + I com + 0x00239103, // n0x1caa c0x0000 (---------------) + I edu + 0x00210a42, // n0x1cab c0x0000 (---------------) + I go + 0x0027d903, // n0x1cac c0x0000 (---------------) + I gov + 0x00201503, // n0x1cad c0x0000 (---------------) + I int + 0x00207dc3, // n0x1cae c0x0000 (---------------) + I mil + 0x00200904, // n0x1caf c0x0000 (---------------) + I name + 0x00223b43, // n0x1cb0 c0x0000 (---------------) + I net + 0x0021b843, // n0x1cb1 c0x0000 (---------------) + I nic + 0x00228743, // n0x1cb2 c0x0000 (---------------) + I org + 0x002fdf44, // n0x1cb3 c0x0000 (---------------) + I test + 0x0021e243, // n0x1cb4 c0x0000 (---------------) + I web + 0x0027d903, // n0x1cb5 c0x0000 (---------------) + I gov + 0x0020ce42, // n0x1cb6 c0x0000 (---------------) + I co + 0x00233243, // n0x1cb7 c0x0000 (---------------) + I com + 0x00239103, // n0x1cb8 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1cb9 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1cba c0x0000 (---------------) + I mil + 0x00223b43, // n0x1cbb c0x0000 (---------------) + I net + 0x00201383, // n0x1cbc c0x0000 (---------------) + I nom + 0x00228743, // n0x1cbd c0x0000 (---------------) + I org + 0x00391d87, // n0x1cbe c0x0000 (---------------) + I agrinet + 0x00233243, // n0x1cbf c0x0000 (---------------) + I com + 0x00225c07, // n0x1cc0 c0x0000 (---------------) + I defense + 0x0025d446, // n0x1cc1 c0x0000 (---------------) + I edunet + 0x00215c43, // n0x1cc2 c0x0000 (---------------) + I ens + 0x00201703, // n0x1cc3 c0x0000 (---------------) + I fin + 0x0027d903, // n0x1cc4 c0x0000 (---------------) + I gov + 0x00221b03, // n0x1cc5 c0x0000 (---------------) + I ind + 0x00201844, // n0x1cc6 c0x0000 (---------------) + I info + 0x0036cdc4, // n0x1cc7 c0x0000 (---------------) + I intl + 0x002d8e06, // n0x1cc8 c0x0000 (---------------) + I mincom + 0x0021a903, // n0x1cc9 c0x0000 (---------------) + I nat + 0x00223b43, // n0x1cca c0x0000 (---------------) + I net + 0x00228743, // n0x1ccb c0x0000 (---------------) + I org + 0x00299705, // n0x1ccc c0x0000 (---------------) + I perso + 0x0020e5c4, // n0x1ccd c0x0000 (---------------) + I rnrt + 0x002300c3, // n0x1cce c0x0000 (---------------) + I rns + 0x0037ba43, // n0x1ccf c0x0000 (---------------) + I rnu + 0x002c1b87, // n0x1cd0 c0x0000 (---------------) + I tourism + 0x00208c05, // n0x1cd1 c0x0000 (---------------) + I turen + 0x00233243, // n0x1cd2 c0x0000 (---------------) + I com + 0x00239103, // n0x1cd3 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1cd4 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1cd5 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1cd6 c0x0000 (---------------) + I net + 0x00228743, // n0x1cd7 c0x0000 (---------------) + I org + 0x00202f02, // n0x1cd8 c0x0000 (---------------) + I av + 0x002ccec3, // n0x1cd9 c0x0000 (---------------) + I bbs + 0x00286003, // n0x1cda c0x0000 (---------------) + I bel + 0x00331a83, // n0x1cdb c0x0000 (---------------) + I biz + 0x51e33243, // n0x1cdc c0x0147 (n0x1ced-n0x1cee) + I com + 0x0026ab42, // n0x1cdd c0x0000 (---------------) + I dr + 0x00239103, // n0x1cde c0x0000 (---------------) + I edu + 0x002060c3, // n0x1cdf c0x0000 (---------------) + I gen + 0x0027d903, // n0x1ce0 c0x0000 (---------------) + I gov + 0x00201844, // n0x1ce1 c0x0000 (---------------) + I info + 0x00332603, // n0x1ce2 c0x0000 (---------------) + I k12 + 0x00248843, // n0x1ce3 c0x0000 (---------------) + I kep + 0x00207dc3, // n0x1ce4 c0x0000 (---------------) + I mil + 0x00200904, // n0x1ce5 c0x0000 (---------------) + I name + 0x522095c2, // n0x1ce6 c0x0148 (n0x1cee-n0x1cef) + I nc + 0x00223b43, // n0x1ce7 c0x0000 (---------------) + I net + 0x00228743, // n0x1ce8 c0x0000 (---------------) + I org + 0x00206ec3, // n0x1ce9 c0x0000 (---------------) + I pol + 0x0022ce43, // n0x1cea c0x0000 (---------------) + I tel + 0x002203c2, // n0x1ceb c0x0000 (---------------) + I tv + 0x0021e243, // n0x1cec c0x0000 (---------------) + I web + 0x000fe108, // n0x1ced c0x0000 (---------------) + blogspot + 0x0027d903, // n0x1cee c0x0000 (---------------) + I gov + 0x002e2dc4, // n0x1cef c0x0000 (---------------) + I aero + 0x00331a83, // n0x1cf0 c0x0000 (---------------) + I biz + 0x0020ce42, // n0x1cf1 c0x0000 (---------------) + I co + 0x00233243, // n0x1cf2 c0x0000 (---------------) + I com + 0x0023c344, // n0x1cf3 c0x0000 (---------------) + I coop + 0x00239103, // n0x1cf4 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1cf5 c0x0000 (---------------) + I gov + 0x00201844, // n0x1cf6 c0x0000 (---------------) + I info + 0x00201503, // n0x1cf7 c0x0000 (---------------) + I int + 0x002e35c4, // n0x1cf8 c0x0000 (---------------) + I jobs + 0x0020bf04, // n0x1cf9 c0x0000 (---------------) + I mobi + 0x002d1086, // n0x1cfa c0x0000 (---------------) + I museum + 0x00200904, // n0x1cfb c0x0000 (---------------) + I name + 0x00223b43, // n0x1cfc c0x0000 (---------------) + I net + 0x00228743, // n0x1cfd c0x0000 (---------------) + I org + 0x00224b03, // n0x1cfe c0x0000 (---------------) + I pro + 0x002a3206, // n0x1cff c0x0000 (---------------) + I travel + 0x000569cb, // n0x1d00 c0x0000 (---------------) + better-than + 0x00013206, // n0x1d01 c0x0000 (---------------) + dyndns + 0x0001e08a, // n0x1d02 c0x0000 (---------------) + on-the-web + 0x000fd64a, // n0x1d03 c0x0000 (---------------) + worse-than + 0x000fe108, // n0x1d04 c0x0000 (---------------) + blogspot + 0x00378c44, // n0x1d05 c0x0000 (---------------) + I club + 0x00233243, // n0x1d06 c0x0000 (---------------) + I com + 0x00331a44, // n0x1d07 c0x0000 (---------------) + I ebiz + 0x00239103, // n0x1d08 c0x0000 (---------------) + I edu + 0x00298344, // n0x1d09 c0x0000 (---------------) + I game + 0x0027d903, // n0x1d0a c0x0000 (---------------) + I gov + 0x0020de03, // n0x1d0b c0x0000 (---------------) + I idv + 0x00207dc3, // n0x1d0c c0x0000 (---------------) + I mil + 0x00223b43, // n0x1d0d c0x0000 (---------------) + I net + 0x00228743, // n0x1d0e c0x0000 (---------------) + I org + 0x00322ccb, // n0x1d0f c0x0000 (---------------) + I xn--czrw28b + 0x0039378a, // n0x1d10 c0x0000 (---------------) + I xn--uc0atv + 0x003a448c, // n0x1d11 c0x0000 (---------------) + I xn--zf0ao64a + 0x00200342, // n0x1d12 c0x0000 (---------------) + I ac + 0x0020ce42, // n0x1d13 c0x0000 (---------------) + I co + 0x00210a42, // n0x1d14 c0x0000 (---------------) + I go + 0x00234305, // n0x1d15 c0x0000 (---------------) + I hotel + 0x00201844, // n0x1d16 c0x0000 (---------------) + I info + 0x00200982, // n0x1d17 c0x0000 (---------------) + I me + 0x00207dc3, // n0x1d18 c0x0000 (---------------) + I mil + 0x0020bf04, // n0x1d19 c0x0000 (---------------) + I mobi + 0x00202ac2, // n0x1d1a c0x0000 (---------------) + I ne + 0x00200dc2, // n0x1d1b c0x0000 (---------------) + I or + 0x00207f02, // n0x1d1c c0x0000 (---------------) + I sc + 0x002203c2, // n0x1d1d c0x0000 (---------------) + I tv + 0x00131a83, // n0x1d1e c0x0000 (---------------) + biz + 0x002ad149, // n0x1d1f c0x0000 (---------------) + I cherkassy + 0x0028bf48, // n0x1d20 c0x0000 (---------------) + I cherkasy + 0x0027d789, // n0x1d21 c0x0000 (---------------) + I chernigov + 0x00287e49, // n0x1d22 c0x0000 (---------------) + I chernihiv + 0x00374f4a, // n0x1d23 c0x0000 (---------------) + I chernivtsi + 0x003682ca, // n0x1d24 c0x0000 (---------------) + I chernovtsy + 0x0020d082, // n0x1d25 c0x0000 (---------------) + I ck + 0x0021dac2, // n0x1d26 c0x0000 (---------------) + I cn + 0x0000ce42, // n0x1d27 c0x0000 (---------------) + co + 0x00233243, // n0x1d28 c0x0000 (---------------) + I com + 0x002051c2, // n0x1d29 c0x0000 (---------------) + I cr + 0x00244dc6, // n0x1d2a c0x0000 (---------------) + I crimea + 0x00350e42, // n0x1d2b c0x0000 (---------------) + I cv + 0x0020df02, // n0x1d2c c0x0000 (---------------) + I dn + 0x0022978e, // n0x1d2d c0x0000 (---------------) + I dnepropetrovsk + 0x0027278e, // n0x1d2e c0x0000 (---------------) + I dnipropetrovsk + 0x0027d607, // n0x1d2f c0x0000 (---------------) + I dominic + 0x00311587, // n0x1d30 c0x0000 (---------------) + I donetsk + 0x002d73c2, // n0x1d31 c0x0000 (---------------) + I dp + 0x00239103, // n0x1d32 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1d33 c0x0000 (---------------) + I gov + 0x00201a82, // n0x1d34 c0x0000 (---------------) + I if + 0x002012c2, // n0x1d35 c0x0000 (---------------) + I in + 0x0024008f, // n0x1d36 c0x0000 (---------------) + I ivano-frankivsk + 0x0021c802, // n0x1d37 c0x0000 (---------------) + I kh + 0x00234cc7, // n0x1d38 c0x0000 (---------------) + I kharkiv + 0x0023fa47, // n0x1d39 c0x0000 (---------------) + I kharkov + 0x00240407, // n0x1d3a c0x0000 (---------------) + I kherson + 0x002408cc, // n0x1d3b c0x0000 (---------------) + I khmelnitskiy + 0x0024aacc, // n0x1d3c c0x0000 (---------------) + I khmelnytskyi + 0x00202984, // n0x1d3d c0x0000 (---------------) + I kiev + 0x0027f80a, // n0x1d3e c0x0000 (---------------) + I kirovograd + 0x00238982, // n0x1d3f c0x0000 (---------------) + I km + 0x0020bdc2, // n0x1d40 c0x0000 (---------------) + I kr + 0x002b3084, // n0x1d41 c0x0000 (---------------) + I krym + 0x00255342, // n0x1d42 c0x0000 (---------------) + I ks + 0x002bd642, // n0x1d43 c0x0000 (---------------) + I kv + 0x0024ad04, // n0x1d44 c0x0000 (---------------) + I kyiv + 0x0021b942, // n0x1d45 c0x0000 (---------------) + I lg + 0x00208bc2, // n0x1d46 c0x0000 (---------------) + I lt + 0x00250787, // n0x1d47 c0x0000 (---------------) + I lugansk + 0x00234bc5, // n0x1d48 c0x0000 (---------------) + I lutsk + 0x00206582, // n0x1d49 c0x0000 (---------------) + I lv + 0x00240004, // n0x1d4a c0x0000 (---------------) + I lviv + 0x00367282, // n0x1d4b c0x0000 (---------------) + I mk + 0x00358908, // n0x1d4c c0x0000 (---------------) + I mykolaiv + 0x00223b43, // n0x1d4d c0x0000 (---------------) + I net + 0x00202f88, // n0x1d4e c0x0000 (---------------) + I nikolaev + 0x00205f42, // n0x1d4f c0x0000 (---------------) + I od + 0x0023a445, // n0x1d50 c0x0000 (---------------) + I odesa + 0x00370ec6, // n0x1d51 c0x0000 (---------------) + I odessa + 0x00228743, // n0x1d52 c0x0000 (---------------) + I org + 0x00209442, // n0x1d53 c0x0000 (---------------) + I pl + 0x002de347, // n0x1d54 c0x0000 (---------------) + I poltava + 0x000080c2, // n0x1d55 c0x0000 (---------------) + pp + 0x002e1805, // n0x1d56 c0x0000 (---------------) + I rivne + 0x0038a0c5, // n0x1d57 c0x0000 (---------------) + I rovno + 0x0020b7c2, // n0x1d58 c0x0000 (---------------) + I rv + 0x002286c2, // n0x1d59 c0x0000 (---------------) + I sb + 0x00206d0a, // n0x1d5a c0x0000 (---------------) + I sebastopol + 0x0024d34a, // n0x1d5b c0x0000 (---------------) + I sevastopol + 0x00213e02, // n0x1d5c c0x0000 (---------------) + I sm + 0x00358884, // n0x1d5d c0x0000 (---------------) + I sumy + 0x00200a82, // n0x1d5e c0x0000 (---------------) + I te + 0x00309888, // n0x1d5f c0x0000 (---------------) + I ternopil + 0x0020fec2, // n0x1d60 c0x0000 (---------------) + I uz + 0x0029e748, // n0x1d61 c0x0000 (---------------) + I uzhgorod + 0x002f5bc7, // n0x1d62 c0x0000 (---------------) + I vinnica + 0x002f6789, // n0x1d63 c0x0000 (---------------) + I vinnytsia + 0x00202f42, // n0x1d64 c0x0000 (---------------) + I vn + 0x002fb685, // n0x1d65 c0x0000 (---------------) + I volyn + 0x0028c405, // n0x1d66 c0x0000 (---------------) + I yalta + 0x002c4dcb, // n0x1d67 c0x0000 (---------------) + I zaporizhzhe + 0x002c580c, // n0x1d68 c0x0000 (---------------) + I zaporizhzhia + 0x002306c8, // n0x1d69 c0x0000 (---------------) + I zhitomir + 0x002fba48, // n0x1d6a c0x0000 (---------------) + I zhytomyr + 0x00262bc2, // n0x1d6b c0x0000 (---------------) + I zp + 0x0021f6c2, // n0x1d6c c0x0000 (---------------) + I zt + 0x00200342, // n0x1d6d c0x0000 (---------------) + I ac + 0x000fe108, // n0x1d6e c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x1d6f c0x0000 (---------------) + I co + 0x00233243, // n0x1d70 c0x0000 (---------------) + I com + 0x00210a42, // n0x1d71 c0x0000 (---------------) + I go + 0x00202ac2, // n0x1d72 c0x0000 (---------------) + I ne + 0x00200dc2, // n0x1d73 c0x0000 (---------------) + I or + 0x00228743, // n0x1d74 c0x0000 (---------------) + I org + 0x00207f02, // n0x1d75 c0x0000 (---------------) + I sc + 0x00200342, // n0x1d76 c0x0000 (---------------) + I ac + 0x5420ce42, // n0x1d77 c0x0150 (n0x1d81-n0x1d82) + I co + 0x5467d903, // n0x1d78 c0x0151 (n0x1d82-n0x1d83) + I gov + 0x00312883, // n0x1d79 c0x0000 (---------------) + I ltd + 0x00200982, // n0x1d7a c0x0000 (---------------) + I me + 0x00223b43, // n0x1d7b c0x0000 (---------------) + I net + 0x0038dd03, // n0x1d7c c0x0000 (---------------) + I nhs + 0x00228743, // n0x1d7d c0x0000 (---------------) + I org + 0x002d96c3, // n0x1d7e c0x0000 (---------------) + I plc + 0x002207c6, // n0x1d7f c0x0000 (---------------) + I police + 0x01617283, // n0x1d80 c0x0005 (---------------)* o I sch + 0x000fe108, // n0x1d81 c0x0000 (---------------) + blogspot + 0x0000b747, // n0x1d82 c0x0000 (---------------) + service + 0x54e02942, // n0x1d83 c0x0153 (n0x1dc2-n0x1dc5) + I ak + 0x55200d02, // n0x1d84 c0x0154 (n0x1dc5-n0x1dc8) + I al + 0x55601d42, // n0x1d85 c0x0155 (n0x1dc8-n0x1dcb) + I ar + 0x55a03302, // n0x1d86 c0x0156 (n0x1dcb-n0x1dce) + I as + 0x55e03442, // n0x1d87 c0x0157 (n0x1dce-n0x1dd1) + I az + 0x56200e42, // n0x1d88 c0x0158 (n0x1dd1-n0x1dd4) + I ca + 0x5660ce42, // n0x1d89 c0x0159 (n0x1dd4-n0x1dd7) + I co + 0x56a2af82, // n0x1d8a c0x015a (n0x1dd7-n0x1dda) + I ct + 0x56e23882, // n0x1d8b c0x015b (n0x1dda-n0x1ddd) + I dc + 0x57205582, // n0x1d8c c0x015c (n0x1ddd-n0x1de0) + I de + 0x00272783, // n0x1d8d c0x0000 (---------------) + I dni + 0x00210083, // n0x1d8e c0x0000 (---------------) + I fed + 0x57617402, // n0x1d8f c0x015d (n0x1de0-n0x1de3) + I fl + 0x57a01bc2, // n0x1d90 c0x015e (n0x1de3-n0x1de6) + I ga + 0x57e0efc2, // n0x1d91 c0x015f (n0x1de6-n0x1de9) + I gu + 0x582003c2, // n0x1d92 c0x0160 (n0x1de9-n0x1deb) + I hi + 0x586019c2, // n0x1d93 c0x0161 (n0x1deb-n0x1dee) + I ia + 0x58a0d9c2, // n0x1d94 c0x0162 (n0x1dee-n0x1df1) + I id + 0x58e027c2, // n0x1d95 c0x0163 (n0x1df1-n0x1df4) + I il + 0x592012c2, // n0x1d96 c0x0164 (n0x1df4-n0x1df7) + I in + 0x000b1f45, // n0x1d97 c0x0000 (---------------) + is-by + 0x00226dc3, // n0x1d98 c0x0000 (---------------) + I isa + 0x0033c884, // n0x1d99 c0x0000 (---------------) + I kids + 0x59655342, // n0x1d9a c0x0165 (n0x1df7-n0x1dfa) + I ks + 0x59a36f82, // n0x1d9b c0x0166 (n0x1dfa-n0x1dfd) + I ky + 0x59e03082, // n0x1d9c c0x0167 (n0x1dfd-n0x1e00) + I la + 0x0007938b, // n0x1d9d c0x0000 (---------------) + land-4-sale + 0x5a200442, // n0x1d9e c0x0168 (n0x1e00-n0x1e03) + I ma + 0x5aa4dd82, // n0x1d9f c0x016a (n0x1e06-n0x1e09) + I md + 0x5ae00982, // n0x1da0 c0x016b (n0x1e09-n0x1e0c) + I me + 0x5b207dc2, // n0x1da1 c0x016c (n0x1e0c-n0x1e0f) + I mi + 0x5b623b02, // n0x1da2 c0x016d (n0x1e0f-n0x1e12) + I mn + 0x5ba08442, // n0x1da3 c0x016e (n0x1e12-n0x1e15) + I mo + 0x5be10f42, // n0x1da4 c0x016f (n0x1e15-n0x1e18) + I ms + 0x5c205402, // n0x1da5 c0x0170 (n0x1e18-n0x1e1b) + I mt + 0x5c6095c2, // n0x1da6 c0x0171 (n0x1e1b-n0x1e1e) + I nc + 0x5ca00782, // n0x1da7 c0x0172 (n0x1e1e-n0x1e20) + I nd + 0x5ce02ac2, // n0x1da8 c0x0173 (n0x1e20-n0x1e23) + I ne + 0x5d202e82, // n0x1da9 c0x0174 (n0x1e23-n0x1e26) + I nh + 0x5d601082, // n0x1daa c0x0175 (n0x1e26-n0x1e29) + I nj + 0x5da2b882, // n0x1dab c0x0176 (n0x1e29-n0x1e2c) + I nm + 0x00360a83, // n0x1dac c0x0000 (---------------) + I nsn + 0x5de09842, // n0x1dad c0x0177 (n0x1e2c-n0x1e2f) + I nv + 0x5e21c582, // n0x1dae c0x0178 (n0x1e2f-n0x1e32) + I ny + 0x5e609342, // n0x1daf c0x0179 (n0x1e32-n0x1e35) + I oh + 0x5ea035c2, // n0x1db0 c0x017a (n0x1e35-n0x1e38) + I ok + 0x5ee00dc2, // n0x1db1 c0x017b (n0x1e38-n0x1e3b) + I or + 0x5f20aac2, // n0x1db2 c0x017c (n0x1e3b-n0x1e3e) + I pa + 0x5f604e02, // n0x1db3 c0x017d (n0x1e3e-n0x1e41) + I pr + 0x5fa04e42, // n0x1db4 c0x017e (n0x1e41-n0x1e44) + I ri + 0x5fe07f02, // n0x1db5 c0x017f (n0x1e44-n0x1e47) + I sc + 0x6022b2c2, // n0x1db6 c0x0180 (n0x1e47-n0x1e49) + I sd + 0x000e8a0c, // n0x1db7 c0x0000 (---------------) + stuff-4-sale + 0x6064fd82, // n0x1db8 c0x0181 (n0x1e49-n0x1e4c) + I tn + 0x60a73102, // n0x1db9 c0x0182 (n0x1e4c-n0x1e4f) + I tx + 0x60e03f42, // n0x1dba c0x0183 (n0x1e4f-n0x1e52) + I ut + 0x61200c02, // n0x1dbb c0x0184 (n0x1e52-n0x1e55) + I va + 0x616065c2, // n0x1dbc c0x0185 (n0x1e55-n0x1e58) + I vi + 0x61a6a302, // n0x1dbd c0x0186 (n0x1e58-n0x1e5b) + I vt + 0x61e01c42, // n0x1dbe c0x0187 (n0x1e5b-n0x1e5e) + I wa + 0x62205c42, // n0x1dbf c0x0188 (n0x1e5e-n0x1e61) + I wi + 0x626753c2, // n0x1dc0 c0x0189 (n0x1e61-n0x1e62) + I wv + 0x62a71c82, // n0x1dc1 c0x018a (n0x1e62-n0x1e65) + I wy + 0x0022f6c2, // n0x1dc2 c0x0000 (---------------) + I cc + 0x00332603, // n0x1dc3 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dc4 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dc5 c0x0000 (---------------) + I cc + 0x00332603, // n0x1dc6 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dc7 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dc8 c0x0000 (---------------) + I cc + 0x00332603, // n0x1dc9 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dca c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dcb c0x0000 (---------------) + I cc + 0x00332603, // n0x1dcc c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dcd c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dce c0x0000 (---------------) + I cc + 0x00332603, // n0x1dcf c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dd0 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dd1 c0x0000 (---------------) + I cc + 0x00332603, // n0x1dd2 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dd3 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dd4 c0x0000 (---------------) + I cc + 0x00332603, // n0x1dd5 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dd6 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dd7 c0x0000 (---------------) + I cc + 0x00332603, // n0x1dd8 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dd9 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dda c0x0000 (---------------) + I cc + 0x00332603, // n0x1ddb c0x0000 (---------------) + I k12 + 0x00272043, // n0x1ddc c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1ddd c0x0000 (---------------) + I cc + 0x00332603, // n0x1dde c0x0000 (---------------) + I k12 + 0x00272043, // n0x1ddf c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1de0 c0x0000 (---------------) + I cc + 0x00332603, // n0x1de1 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1de2 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1de3 c0x0000 (---------------) + I cc + 0x00332603, // n0x1de4 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1de5 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1de6 c0x0000 (---------------) + I cc + 0x00332603, // n0x1de7 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1de8 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1de9 c0x0000 (---------------) + I cc + 0x00272043, // n0x1dea c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1deb c0x0000 (---------------) + I cc + 0x00332603, // n0x1dec c0x0000 (---------------) + I k12 + 0x00272043, // n0x1ded c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dee c0x0000 (---------------) + I cc + 0x00332603, // n0x1def c0x0000 (---------------) + I k12 + 0x00272043, // n0x1df0 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1df1 c0x0000 (---------------) + I cc + 0x00332603, // n0x1df2 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1df3 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1df4 c0x0000 (---------------) + I cc + 0x00332603, // n0x1df5 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1df6 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1df7 c0x0000 (---------------) + I cc + 0x00332603, // n0x1df8 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1df9 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dfa c0x0000 (---------------) + I cc + 0x00332603, // n0x1dfb c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dfc c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1dfd c0x0000 (---------------) + I cc + 0x00332603, // n0x1dfe c0x0000 (---------------) + I k12 + 0x00272043, // n0x1dff c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e00 c0x0000 (---------------) + I cc + 0x5a732603, // n0x1e01 c0x0169 (n0x1e03-n0x1e06) + I k12 + 0x00272043, // n0x1e02 c0x0000 (---------------) + I lib + 0x00305c04, // n0x1e03 c0x0000 (---------------) + I chtr + 0x0028be46, // n0x1e04 c0x0000 (---------------) + I paroch + 0x002e62c3, // n0x1e05 c0x0000 (---------------) + I pvt + 0x0022f6c2, // n0x1e06 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e07 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e08 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e09 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e0a c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e0b c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e0c c0x0000 (---------------) + I cc + 0x00332603, // n0x1e0d c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e0e c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e0f c0x0000 (---------------) + I cc + 0x00332603, // n0x1e10 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e11 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e12 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e13 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e14 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e15 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e16 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e17 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e18 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e19 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e1a c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e1b c0x0000 (---------------) + I cc + 0x00332603, // n0x1e1c c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e1d c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e1e c0x0000 (---------------) + I cc + 0x00272043, // n0x1e1f c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e20 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e21 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e22 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e23 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e24 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e25 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e26 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e27 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e28 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e29 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e2a c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e2b c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e2c c0x0000 (---------------) + I cc + 0x00332603, // n0x1e2d c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e2e c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e2f c0x0000 (---------------) + I cc + 0x00332603, // n0x1e30 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e31 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e32 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e33 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e34 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e35 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e36 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e37 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e38 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e39 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e3a c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e3b c0x0000 (---------------) + I cc + 0x00332603, // n0x1e3c c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e3d c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e3e c0x0000 (---------------) + I cc + 0x00332603, // n0x1e3f c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e40 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e41 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e42 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e43 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e44 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e45 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e46 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e47 c0x0000 (---------------) + I cc + 0x00272043, // n0x1e48 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e49 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e4a c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e4b c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e4c c0x0000 (---------------) + I cc + 0x00332603, // n0x1e4d c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e4e c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e4f c0x0000 (---------------) + I cc + 0x00332603, // n0x1e50 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e51 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e52 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e53 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e54 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e55 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e56 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e57 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e58 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e59 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e5a c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e5b c0x0000 (---------------) + I cc + 0x00332603, // n0x1e5c c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e5d c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e5e c0x0000 (---------------) + I cc + 0x00332603, // n0x1e5f c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e60 c0x0000 (---------------) + I lib + 0x0022f6c2, // n0x1e61 c0x0000 (---------------) + I cc + 0x0022f6c2, // n0x1e62 c0x0000 (---------------) + I cc + 0x00332603, // n0x1e63 c0x0000 (---------------) + I k12 + 0x00272043, // n0x1e64 c0x0000 (---------------) + I lib + 0x63233243, // n0x1e65 c0x018c (n0x1e6b-n0x1e6c) + I com + 0x00239103, // n0x1e66 c0x0000 (---------------) + I edu + 0x00255e83, // n0x1e67 c0x0000 (---------------) + I gub + 0x00207dc3, // n0x1e68 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1e69 c0x0000 (---------------) + I net + 0x00228743, // n0x1e6a c0x0000 (---------------) + I org + 0x000fe108, // n0x1e6b c0x0000 (---------------) + blogspot + 0x0020ce42, // n0x1e6c c0x0000 (---------------) + I co + 0x00233243, // n0x1e6d c0x0000 (---------------) + I com + 0x00223b43, // n0x1e6e c0x0000 (---------------) + I net + 0x00228743, // n0x1e6f c0x0000 (---------------) + I org + 0x00233243, // n0x1e70 c0x0000 (---------------) + I com + 0x00239103, // n0x1e71 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1e72 c0x0000 (---------------) + I gov + 0x00207dc3, // n0x1e73 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1e74 c0x0000 (---------------) + I net + 0x00228743, // n0x1e75 c0x0000 (---------------) + I org + 0x0024b944, // n0x1e76 c0x0000 (---------------) + I arts + 0x0020ce42, // n0x1e77 c0x0000 (---------------) + I co + 0x00233243, // n0x1e78 c0x0000 (---------------) + I com + 0x003830c3, // n0x1e79 c0x0000 (---------------) + I e12 + 0x00239103, // n0x1e7a c0x0000 (---------------) + I edu + 0x0024dcc4, // n0x1e7b c0x0000 (---------------) + I firm + 0x00212b03, // n0x1e7c c0x0000 (---------------) + I gob + 0x0027d903, // n0x1e7d c0x0000 (---------------) + I gov + 0x00201844, // n0x1e7e c0x0000 (---------------) + I info + 0x00201503, // n0x1e7f c0x0000 (---------------) + I int + 0x00207dc3, // n0x1e80 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1e81 c0x0000 (---------------) + I net + 0x00228743, // n0x1e82 c0x0000 (---------------) + I org + 0x0022c2c3, // n0x1e83 c0x0000 (---------------) + I rec + 0x00364cc5, // n0x1e84 c0x0000 (---------------) + I store + 0x00243703, // n0x1e85 c0x0000 (---------------) + I tec + 0x0021e243, // n0x1e86 c0x0000 (---------------) + I web + 0x0020ce42, // n0x1e87 c0x0000 (---------------) + I co + 0x00233243, // n0x1e88 c0x0000 (---------------) + I com + 0x00332603, // n0x1e89 c0x0000 (---------------) + I k12 + 0x00223b43, // n0x1e8a c0x0000 (---------------) + I net + 0x00228743, // n0x1e8b c0x0000 (---------------) + I org + 0x00200342, // n0x1e8c c0x0000 (---------------) + I ac + 0x00331a83, // n0x1e8d c0x0000 (---------------) + I biz + 0x000fe108, // n0x1e8e c0x0000 (---------------) + blogspot + 0x00233243, // n0x1e8f c0x0000 (---------------) + I com + 0x00239103, // n0x1e90 c0x0000 (---------------) + I edu + 0x0027d903, // n0x1e91 c0x0000 (---------------) + I gov + 0x002ae586, // n0x1e92 c0x0000 (---------------) + I health + 0x00201844, // n0x1e93 c0x0000 (---------------) + I info + 0x00201503, // n0x1e94 c0x0000 (---------------) + I int + 0x00200904, // n0x1e95 c0x0000 (---------------) + I name + 0x00223b43, // n0x1e96 c0x0000 (---------------) + I net + 0x00228743, // n0x1e97 c0x0000 (---------------) + I org + 0x00224b03, // n0x1e98 c0x0000 (---------------) + I pro + 0x00233243, // n0x1e99 c0x0000 (---------------) + I com + 0x00239103, // n0x1e9a c0x0000 (---------------) + I edu + 0x00223b43, // n0x1e9b c0x0000 (---------------) + I net + 0x00228743, // n0x1e9c c0x0000 (---------------) + I org + 0x00233243, // n0x1e9d c0x0000 (---------------) + I com + 0x00013206, // n0x1e9e c0x0000 (---------------) + dyndns + 0x00239103, // n0x1e9f c0x0000 (---------------) + I edu + 0x0027d903, // n0x1ea0 c0x0000 (---------------) + I gov + 0x000d1e46, // n0x1ea1 c0x0000 (---------------) + mypets + 0x00223b43, // n0x1ea2 c0x0000 (---------------) + I net + 0x00228743, // n0x1ea3 c0x0000 (---------------) + I org + 0x0030ba08, // n0x1ea4 c0x0000 (---------------) + I xn--80au + 0x0030e409, // n0x1ea5 c0x0000 (---------------) + I xn--90azh + 0x0031b349, // n0x1ea6 c0x0000 (---------------) + I xn--c1avg + 0x0032a188, // n0x1ea7 c0x0000 (---------------) + I xn--d1at + 0x00372e88, // n0x1ea8 c0x0000 (---------------) + I xn--o1ac + 0x00372e89, // n0x1ea9 c0x0000 (---------------) + I xn--o1ach + 0x00200342, // n0x1eaa c0x0000 (---------------) + I ac + 0x00208a45, // n0x1eab c0x0000 (---------------) + I agric + 0x00239743, // n0x1eac c0x0000 (---------------) + I alt + 0x65a0ce42, // n0x1ead c0x0196 (n0x1ebb-n0x1ebc) + I co + 0x00239103, // n0x1eae c0x0000 (---------------) + I edu + 0x0027d903, // n0x1eaf c0x0000 (---------------) + I gov + 0x0037bc87, // n0x1eb0 c0x0000 (---------------) + I grondar + 0x00271c03, // n0x1eb1 c0x0000 (---------------) + I law + 0x00207dc3, // n0x1eb2 c0x0000 (---------------) + I mil + 0x00223b43, // n0x1eb3 c0x0000 (---------------) + I net + 0x0023b383, // n0x1eb4 c0x0000 (---------------) + I ngo + 0x00210383, // n0x1eb5 c0x0000 (---------------) + I nis + 0x00201383, // n0x1eb6 c0x0000 (---------------) + I nom + 0x00228743, // n0x1eb7 c0x0000 (---------------) + I org + 0x00232186, // n0x1eb8 c0x0000 (---------------) + I school + 0x00200c82, // n0x1eb9 c0x0000 (---------------) + I tm + 0x0021e243, // n0x1eba c0x0000 (---------------) + I web + 0x000fe108, // n0x1ebb c0x0000 (---------------) + blogspot +} + +// children is the list of nodes' children, the parent's wildcard bit and the +// parent's node type. If a node has no children then their children index +// will be in the range [0, 6), depending on the wildcard bit and node type. +// +// The layout within the uint32, from MSB to LSB, is: +// [ 1 bits] unused +// [ 1 bits] wildcard bit +// [ 2 bits] node type +// [14 bits] high nodes index (exclusive) of children +// [14 bits] low nodes index (inclusive) of children +var children = [...]uint32{ + 0x00000000, // c0x0000 (---------------) + + 0x10000000, // c0x0001 (---------------) ! + 0x20000000, // c0x0002 (---------------) o + 0x40000000, // c0x0003 (---------------)* + + 0x50000000, // c0x0004 (---------------)* ! + 0x60000000, // c0x0005 (---------------)* o + 0x01834607, // c0x0006 (n0x0607-n0x060d) + + 0x0183860d, // c0x0007 (n0x060d-n0x060e) + + 0x0185860e, // c0x0008 (n0x060e-n0x0616) + + 0x019b4616, // c0x0009 (n0x0616-n0x066d) + + 0x019c866d, // c0x000a (n0x066d-n0x0672) + + 0x019dc672, // c0x000b (n0x0672-n0x0677) + + 0x019ec677, // c0x000c (n0x0677-n0x067b) + + 0x01a0867b, // c0x000d (n0x067b-n0x0682) + + 0x01a0c682, // c0x000e (n0x0682-n0x0683) + + 0x01a24683, // c0x000f (n0x0683-n0x0689) + + 0x01a48689, // c0x0010 (n0x0689-n0x0692) + + 0x01a4c692, // c0x0011 (n0x0692-n0x0693) + + 0x01a64693, // c0x0012 (n0x0693-n0x0699) + + 0x01a68699, // c0x0013 (n0x0699-n0x069a) + + 0x01a8469a, // c0x0014 (n0x069a-n0x06a1) + + 0x01a886a1, // c0x0015 (n0x06a1-n0x06a2) + + 0x01ad06a2, // c0x0016 (n0x06a2-n0x06b4) + + 0x01ad46b4, // c0x0017 (n0x06b4-n0x06b5) + + 0x01af46b5, // c0x0018 (n0x06b5-n0x06bd) + + 0x01b086bd, // c0x0019 (n0x06bd-n0x06c2) + + 0x01b0c6c2, // c0x001a (n0x06c2-n0x06c3) + + 0x01b3c6c3, // c0x001b (n0x06c3-n0x06cf) + + 0x01b686cf, // c0x001c (n0x06cf-n0x06da) + + 0x01b906da, // c0x001d (n0x06da-n0x06e4) + + 0x01b986e4, // c0x001e (n0x06e4-n0x06e6) + + 0x01b9c6e6, // c0x001f (n0x06e6-n0x06e7) + + 0x01c306e7, // c0x0020 (n0x06e7-n0x070c) + + 0x01c4470c, // c0x0021 (n0x070c-n0x0711) + + 0x01c58711, // c0x0022 (n0x0711-n0x0716) + + 0x01c78716, // c0x0023 (n0x0716-n0x071e) + + 0x01c8871e, // c0x0024 (n0x071e-n0x0722) + + 0x01c9c722, // c0x0025 (n0x0722-n0x0727) + + 0x01cc0727, // c0x0026 (n0x0727-n0x0730) + + 0x01dd8730, // c0x0027 (n0x0730-n0x0776) + + 0x01ddc776, // c0x0028 (n0x0776-n0x0777) + + 0x01df0777, // c0x0029 (n0x0777-n0x077c) + + 0x01e0477c, // c0x002a (n0x077c-n0x0781) + + 0x01e0c781, // c0x002b (n0x0781-n0x0783) + + 0x01e1c783, // c0x002c (n0x0783-n0x0787) + + 0x01e20787, // c0x002d (n0x0787-n0x0788) + + 0x01e38788, // c0x002e (n0x0788-n0x078e) + + 0x01e7c78e, // c0x002f (n0x078e-n0x079f) + + 0x01e8c79f, // c0x0030 (n0x079f-n0x07a3) + + 0x01e907a3, // c0x0031 (n0x07a3-n0x07a4) + + 0x01e947a4, // c0x0032 (n0x07a4-n0x07a5) + + 0x01e987a5, // c0x0033 (n0x07a5-n0x07a6) + + 0x01ed47a6, // c0x0034 (n0x07a6-n0x07b5) + + 0x61ed87b5, // c0x0035 (n0x07b5-n0x07b6)* o + 0x01eec7b6, // c0x0036 (n0x07b6-n0x07bb) + + 0x01efc7bb, // c0x0037 (n0x07bb-n0x07bf) + + 0x01fb07bf, // c0x0038 (n0x07bf-n0x07ec) + + 0x21fb47ec, // c0x0039 (n0x07ec-n0x07ed) o + 0x01fb87ed, // c0x003a (n0x07ed-n0x07ee) + + 0x01fbc7ee, // c0x003b (n0x07ee-n0x07ef) + + 0x21fc07ef, // c0x003c (n0x07ef-n0x07f0) o + 0x21fc47f0, // c0x003d (n0x07f0-n0x07f1) o + 0x01ff87f1, // c0x003e (n0x07f1-n0x07fe) + + 0x01ffc7fe, // c0x003f (n0x07fe-n0x07ff) + + 0x023447ff, // c0x0040 (n0x07ff-n0x08d1) + + 0x2238c8d1, // c0x0041 (n0x08d1-n0x08e3) o + 0x023b08e3, // c0x0042 (n0x08e3-n0x08ec) + + 0x023b88ec, // c0x0043 (n0x08ec-n0x08ee) + + 0x223bc8ee, // c0x0044 (n0x08ee-n0x08ef) o + 0x223c08ef, // c0x0045 (n0x08ef-n0x08f0) o + 0x023dc8f0, // c0x0046 (n0x08f0-n0x08f7) + + 0x023f48f7, // c0x0047 (n0x08f7-n0x08fd) + + 0x023f88fd, // c0x0048 (n0x08fd-n0x08fe) + + 0x024088fe, // c0x0049 (n0x08fe-n0x0902) + + 0x02410902, // c0x004a (n0x0902-n0x0904) + + 0x22444904, // c0x004b (n0x0904-n0x0911) o + 0x02448911, // c0x004c (n0x0911-n0x0912) + + 0x02450912, // c0x004d (n0x0912-n0x0914) + + 0x02470914, // c0x004e (n0x0914-n0x091c) + + 0x0247491c, // c0x004f (n0x091c-n0x091d) + + 0x0248891d, // c0x0050 (n0x091d-n0x0922) + + 0x024b0922, // c0x0051 (n0x0922-n0x092c) + + 0x024d092c, // c0x0052 (n0x092c-n0x0934) + + 0x02500934, // c0x0053 (n0x0934-n0x0940) + + 0x02528940, // c0x0054 (n0x0940-n0x094a) + + 0x0252c94a, // c0x0055 (n0x094a-n0x094b) + + 0x0255094b, // c0x0056 (n0x094b-n0x0954) + + 0x02554954, // c0x0057 (n0x0954-n0x0955) + + 0x02568955, // c0x0058 (n0x0955-n0x095a) + + 0x0256c95a, // c0x0059 (n0x095a-n0x095b) + + 0x0258c95b, // c0x005a (n0x095b-n0x0963) + + 0x02598963, // c0x005b (n0x0963-n0x0966) + + 0x025f8966, // c0x005c (n0x0966-n0x097e) + + 0x0261497e, // c0x005d (n0x097e-n0x0985) + + 0x02620985, // c0x005e (n0x0985-n0x0988) + + 0x02634988, // c0x005f (n0x0988-n0x098d) + + 0x0264c98d, // c0x0060 (n0x098d-n0x0993) + + 0x02660993, // c0x0061 (n0x0993-n0x0998) + + 0x02678998, // c0x0062 (n0x0998-n0x099e) + + 0x0269099e, // c0x0063 (n0x099e-n0x09a4) + + 0x026a89a4, // c0x0064 (n0x09a4-n0x09aa) + + 0x026c49aa, // c0x0065 (n0x09aa-n0x09b1) + + 0x026dc9b1, // c0x0066 (n0x09b1-n0x09b7) + + 0x0273c9b7, // c0x0067 (n0x09b7-n0x09cf) + + 0x027549cf, // c0x0068 (n0x09cf-n0x09d5) + + 0x027689d5, // c0x0069 (n0x09d5-n0x09da) + + 0x027ac9da, // c0x006a (n0x09da-n0x09eb) + + 0x0282c9eb, // c0x006b (n0x09eb-n0x0a0b) + + 0x02858a0b, // c0x006c (n0x0a0b-n0x0a16) + + 0x0285ca16, // c0x006d (n0x0a16-n0x0a17) + + 0x02864a17, // c0x006e (n0x0a17-n0x0a19) + + 0x02884a19, // c0x006f (n0x0a19-n0x0a21) + + 0x02888a21, // c0x0070 (n0x0a21-n0x0a22) + + 0x028a4a22, // c0x0071 (n0x0a22-n0x0a29) + + 0x028aca29, // c0x0072 (n0x0a29-n0x0a2b) + + 0x028e0a2b, // c0x0073 (n0x0a2b-n0x0a38) + + 0x02908a38, // c0x0074 (n0x0a38-n0x0a42) + + 0x0290ca42, // c0x0075 (n0x0a42-n0x0a43) + + 0x02924a43, // c0x0076 (n0x0a43-n0x0a49) + + 0x0293ca49, // c0x0077 (n0x0a49-n0x0a4f) + + 0x02960a4f, // c0x0078 (n0x0a4f-n0x0a58) + + 0x02980a58, // c0x0079 (n0x0a58-n0x0a60) + + 0x02f44a60, // c0x007a (n0x0a60-n0x0bd1) + + 0x02f50bd1, // c0x007b (n0x0bd1-n0x0bd4) + + 0x02f70bd4, // c0x007c (n0x0bd4-n0x0bdc) + + 0x0312cbdc, // c0x007d (n0x0bdc-n0x0c4b) + + 0x031fcc4b, // c0x007e (n0x0c4b-n0x0c7f) + + 0x0326cc7f, // c0x007f (n0x0c7f-n0x0c9b) + + 0x032c4c9b, // c0x0080 (n0x0c9b-n0x0cb1) + + 0x033accb1, // c0x0081 (n0x0cb1-n0x0ceb) + + 0x03404ceb, // c0x0082 (n0x0ceb-n0x0d01) + + 0x03440d01, // c0x0083 (n0x0d01-n0x0d10) + + 0x0353cd10, // c0x0084 (n0x0d10-n0x0d4f) + + 0x03608d4f, // c0x0085 (n0x0d4f-n0x0d82) + + 0x036a0d82, // c0x0086 (n0x0d82-n0x0da8) + + 0x03730da8, // c0x0087 (n0x0da8-n0x0dcc) + + 0x03794dcc, // c0x0088 (n0x0dcc-n0x0de5) + + 0x039ccde5, // c0x0089 (n0x0de5-n0x0e73) + + 0x03a84e73, // c0x008a (n0x0e73-n0x0ea1) + + 0x03b50ea1, // c0x008b (n0x0ea1-n0x0ed4) + + 0x03b9ced4, // c0x008c (n0x0ed4-n0x0ee7) + + 0x03c24ee7, // c0x008d (n0x0ee7-n0x0f09) + + 0x03c60f09, // c0x008e (n0x0f09-n0x0f18) + + 0x03cb0f18, // c0x008f (n0x0f18-n0x0f2c) + + 0x03d28f2c, // c0x0090 (n0x0f2c-n0x0f4a) + + 0x63d2cf4a, // c0x0091 (n0x0f4a-n0x0f4b)* o + 0x63d30f4b, // c0x0092 (n0x0f4b-n0x0f4c)* o + 0x63d34f4c, // c0x0093 (n0x0f4c-n0x0f4d)* o + 0x03db0f4d, // c0x0094 (n0x0f4d-n0x0f6c) + + 0x03e18f6c, // c0x0095 (n0x0f6c-n0x0f86) + + 0x03e94f86, // c0x0096 (n0x0f86-n0x0fa5) + + 0x03f0cfa5, // c0x0097 (n0x0fa5-n0x0fc3) + + 0x03f90fc3, // c0x0098 (n0x0fc3-n0x0fe4) + + 0x03ffcfe4, // c0x0099 (n0x0fe4-n0x0fff) + + 0x04128fff, // c0x009a (n0x0fff-n0x104a) + + 0x0418104a, // c0x009b (n0x104a-n0x1060) + + 0x64185060, // c0x009c (n0x1060-n0x1061)* o + 0x0421d061, // c0x009d (n0x1061-n0x1087) + + 0x042a5087, // c0x009e (n0x1087-n0x10a9) + + 0x042f10a9, // c0x009f (n0x10a9-n0x10bc) + + 0x043590bc, // c0x00a0 (n0x10bc-n0x10d6) + + 0x044010d6, // c0x00a1 (n0x10d6-n0x1100) + + 0x044c9100, // c0x00a2 (n0x1100-n0x1132) + + 0x04531132, // c0x00a3 (n0x1132-n0x114c) + + 0x0464514c, // c0x00a4 (n0x114c-n0x1191) + + 0x64649191, // c0x00a5 (n0x1191-n0x1192)* o + 0x6464d192, // c0x00a6 (n0x1192-n0x1193)* o + 0x046a9193, // c0x00a7 (n0x1193-n0x11aa) + + 0x047051aa, // c0x00a8 (n0x11aa-n0x11c1) + + 0x047951c1, // c0x00a9 (n0x11c1-n0x11e5) + + 0x048111e5, // c0x00aa (n0x11e5-n0x1204) + + 0x04855204, // c0x00ab (n0x1204-n0x1215) + + 0x04939215, // c0x00ac (n0x1215-n0x124e) + + 0x0496d24e, // c0x00ad (n0x124e-n0x125b) + + 0x049cd25b, // c0x00ae (n0x125b-n0x1273) + + 0x04a41273, // c0x00af (n0x1273-n0x1290) + + 0x04ac9290, // c0x00b0 (n0x1290-n0x12b2) + + 0x04b092b2, // c0x00b1 (n0x12b2-n0x12c2) + + 0x04b792c2, // c0x00b2 (n0x12c2-n0x12de) + + 0x64b7d2de, // c0x00b3 (n0x12de-n0x12df)* o + 0x64b812df, // c0x00b4 (n0x12df-n0x12e0)* o + 0x24b852e0, // c0x00b5 (n0x12e0-n0x12e1) o + 0x04b9d2e1, // c0x00b6 (n0x12e1-n0x12e7) + + 0x04bb92e7, // c0x00b7 (n0x12e7-n0x12ee) + + 0x04bfd2ee, // c0x00b8 (n0x12ee-n0x12ff) + + 0x04c0d2ff, // c0x00b9 (n0x12ff-n0x1303) + + 0x04c25303, // c0x00ba (n0x1303-n0x1309) + + 0x04c9d309, // c0x00bb (n0x1309-n0x1327) + + 0x04cb1327, // c0x00bc (n0x1327-n0x132c) + + 0x04cc932c, // c0x00bd (n0x132c-n0x1332) + + 0x04ced332, // c0x00be (n0x1332-n0x133b) + + 0x04d0133b, // c0x00bf (n0x133b-n0x1340) + + 0x04d19340, // c0x00c0 (n0x1340-n0x1346) + + 0x04d1d346, // c0x00c1 (n0x1346-n0x1347) + + 0x04d59347, // c0x00c2 (n0x1347-n0x1356) + + 0x04d6d356, // c0x00c3 (n0x1356-n0x135b) + + 0x04d7535b, // c0x00c4 (n0x135b-n0x135d) + + 0x04d7d35d, // c0x00c5 (n0x135d-n0x135f) + + 0x04d8135f, // c0x00c6 (n0x135f-n0x1360) + + 0x04da5360, // c0x00c7 (n0x1360-n0x1369) + + 0x04dc9369, // c0x00c8 (n0x1369-n0x1372) + + 0x04de1372, // c0x00c9 (n0x1372-n0x1378) + + 0x04de9378, // c0x00ca (n0x1378-n0x137a) + + 0x04ded37a, // c0x00cb (n0x137a-n0x137b) + + 0x04e2137b, // c0x00cc (n0x137b-n0x1388) + + 0x04e45388, // c0x00cd (n0x1388-n0x1391) + + 0x04e65391, // c0x00ce (n0x1391-n0x1399) + + 0x04e81399, // c0x00cf (n0x1399-n0x13a0) + + 0x04e913a0, // c0x00d0 (n0x13a0-n0x13a4) + + 0x04ea53a4, // c0x00d1 (n0x13a4-n0x13a9) + + 0x04ea93a9, // c0x00d2 (n0x13a9-n0x13aa) + + 0x04eb13aa, // c0x00d3 (n0x13aa-n0x13ac) + + 0x04ec53ac, // c0x00d4 (n0x13ac-n0x13b1) + + 0x04ed53b1, // c0x00d5 (n0x13b1-n0x13b5) + + 0x04ed93b5, // c0x00d6 (n0x13b5-n0x13b6) + + 0x04ef53b6, // c0x00d7 (n0x13b6-n0x13bd) + + 0x057853bd, // c0x00d8 (n0x13bd-n0x15e1) + + 0x057bd5e1, // c0x00d9 (n0x15e1-n0x15ef) + + 0x057e95ef, // c0x00da (n0x15ef-n0x15fa) + + 0x058015fa, // c0x00db (n0x15fa-n0x1600) + + 0x05821600, // c0x00dc (n0x1600-n0x1608) + + 0x65825608, // c0x00dd (n0x1608-n0x1609)* o + 0x05869609, // c0x00de (n0x1609-n0x161a) + + 0x0587161a, // c0x00df (n0x161a-n0x161c) + + 0x2587561c, // c0x00e0 (n0x161c-n0x161d) o + 0x2587961d, // c0x00e1 (n0x161d-n0x161e) o + 0x0587d61e, // c0x00e2 (n0x161e-n0x161f) + + 0x0595161f, // c0x00e3 (n0x161f-n0x1654) + + 0x25955654, // c0x00e4 (n0x1654-n0x1655) o + 0x2595d655, // c0x00e5 (n0x1655-n0x1657) o + 0x25965657, // c0x00e6 (n0x1657-n0x1659) o + 0x25971659, // c0x00e7 (n0x1659-n0x165c) o + 0x0599965c, // c0x00e8 (n0x165c-n0x1666) + + 0x059c1666, // c0x00e9 (n0x1666-n0x1670) + + 0x059c5670, // c0x00ea (n0x1670-n0x1671) + + 0x259fd671, // c0x00eb (n0x1671-n0x167f) o + 0x05a0967f, // c0x00ec (n0x167f-n0x1682) + + 0x06561682, // c0x00ed (n0x1682-n0x1958) + + 0x06565958, // c0x00ee (n0x1958-n0x1959) + + 0x06569959, // c0x00ef (n0x1959-n0x195a) + + 0x2656d95a, // c0x00f0 (n0x195a-n0x195b) o + 0x0657195b, // c0x00f1 (n0x195b-n0x195c) + + 0x2657595c, // c0x00f2 (n0x195c-n0x195d) o + 0x0657995d, // c0x00f3 (n0x195d-n0x195e) + + 0x2658595e, // c0x00f4 (n0x195e-n0x1961) o + 0x06589961, // c0x00f5 (n0x1961-n0x1962) + + 0x0658d962, // c0x00f6 (n0x1962-n0x1963) + + 0x26591963, // c0x00f7 (n0x1963-n0x1964) o + 0x06595964, // c0x00f8 (n0x1964-n0x1965) + + 0x2659d965, // c0x00f9 (n0x1965-n0x1967) o + 0x065a1967, // c0x00fa (n0x1967-n0x1968) + + 0x065a5968, // c0x00fb (n0x1968-n0x1969) + + 0x265b5969, // c0x00fc (n0x1969-n0x196d) o + 0x065b996d, // c0x00fd (n0x196d-n0x196e) + + 0x065bd96e, // c0x00fe (n0x196e-n0x196f) + + 0x065c196f, // c0x00ff (n0x196f-n0x1970) + + 0x065c5970, // c0x0100 (n0x1970-n0x1971) + + 0x265c9971, // c0x0101 (n0x1971-n0x1972) o + 0x065cd972, // c0x0102 (n0x1972-n0x1973) + + 0x065d1973, // c0x0103 (n0x1973-n0x1974) + + 0x065d5974, // c0x0104 (n0x1974-n0x1975) + + 0x065d9975, // c0x0105 (n0x1975-n0x1976) + + 0x265e1976, // c0x0106 (n0x1976-n0x1978) o + 0x065e5978, // c0x0107 (n0x1978-n0x1979) + + 0x065e9979, // c0x0108 (n0x1979-n0x197a) + + 0x065ed97a, // c0x0109 (n0x197a-n0x197b) + + 0x265f197b, // c0x010a (n0x197b-n0x197c) o + 0x065f597c, // c0x010b (n0x197c-n0x197d) + + 0x265fd97d, // c0x010c (n0x197d-n0x197f) o + 0x2660197f, // c0x010d (n0x197f-n0x1980) o + 0x0661d980, // c0x010e (n0x1980-n0x1987) + + 0x06629987, // c0x010f (n0x1987-n0x198a) + + 0x0666998a, // c0x0110 (n0x198a-n0x199a) + + 0x0666d99a, // c0x0111 (n0x199a-n0x199b) + + 0x0669199b, // c0x0112 (n0x199b-n0x19a4) + + 0x067859a4, // c0x0113 (n0x19a4-n0x19e1) + + 0x2678d9e1, // c0x0114 (n0x19e1-n0x19e3) o + 0x267919e3, // c0x0115 (n0x19e3-n0x19e4) o + 0x267959e4, // c0x0116 (n0x19e4-n0x19e5) o + 0x0679d9e5, // c0x0117 (n0x19e5-n0x19e7) + + 0x068799e7, // c0x0118 (n0x19e7-n0x1a1e) + + 0x068a5a1e, // c0x0119 (n0x1a1e-n0x1a29) + + 0x068c5a29, // c0x011a (n0x1a29-n0x1a31) + + 0x068d1a31, // c0x011b (n0x1a31-n0x1a34) + + 0x068f1a34, // c0x011c (n0x1a34-n0x1a3c) + + 0x06929a3c, // c0x011d (n0x1a3c-n0x1a4a) + + 0x06bbda4a, // c0x011e (n0x1a4a-n0x1aef) + + 0x06c79aef, // c0x011f (n0x1aef-n0x1b1e) + + 0x06c8db1e, // c0x0120 (n0x1b1e-n0x1b23) + + 0x06cc1b23, // c0x0121 (n0x1b23-n0x1b30) + + 0x06cddb30, // c0x0122 (n0x1b30-n0x1b37) + + 0x06cf9b37, // c0x0123 (n0x1b37-n0x1b3e) + + 0x06d1db3e, // c0x0124 (n0x1b3e-n0x1b47) + + 0x06d35b47, // c0x0125 (n0x1b47-n0x1b4d) + + 0x06d51b4d, // c0x0126 (n0x1b4d-n0x1b54) + + 0x06d75b54, // c0x0127 (n0x1b54-n0x1b5d) + + 0x06d85b5d, // c0x0128 (n0x1b5d-n0x1b61) + + 0x06db5b61, // c0x0129 (n0x1b61-n0x1b6d) + + 0x06dd1b6d, // c0x012a (n0x1b6d-n0x1b74) + + 0x06fddb74, // c0x012b (n0x1b74-n0x1bf7) + + 0x07001bf7, // c0x012c (n0x1bf7-n0x1c00) + + 0x07021c00, // c0x012d (n0x1c00-n0x1c08) + + 0x07035c08, // c0x012e (n0x1c08-n0x1c0d) + + 0x07049c0d, // c0x012f (n0x1c0d-n0x1c12) + + 0x07069c12, // c0x0130 (n0x1c12-n0x1c1a) + + 0x0710dc1a, // c0x0131 (n0x1c1a-n0x1c43) + + 0x07129c43, // c0x0132 (n0x1c43-n0x1c4a) + + 0x07145c4a, // c0x0133 (n0x1c4a-n0x1c51) + + 0x07149c51, // c0x0134 (n0x1c51-n0x1c52) + + 0x0714dc52, // c0x0135 (n0x1c52-n0x1c53) + + 0x07161c53, // c0x0136 (n0x1c53-n0x1c58) + + 0x07181c58, // c0x0137 (n0x1c58-n0x1c60) + + 0x0718dc60, // c0x0138 (n0x1c60-n0x1c63) + + 0x071bdc63, // c0x0139 (n0x1c63-n0x1c6f) + + 0x0723dc6f, // c0x013a (n0x1c6f-n0x1c8f) + + 0x07251c8f, // c0x013b (n0x1c8f-n0x1c94) + + 0x07255c94, // c0x013c (n0x1c94-n0x1c95) + + 0x0726dc95, // c0x013d (n0x1c95-n0x1c9b) + + 0x07279c9b, // c0x013e (n0x1c9b-n0x1c9e) + + 0x0727dc9e, // c0x013f (n0x1c9e-n0x1c9f) + + 0x07299c9f, // c0x0140 (n0x1c9f-n0x1ca6) + + 0x072d5ca6, // c0x0141 (n0x1ca6-n0x1cb5) + + 0x072d9cb5, // c0x0142 (n0x1cb5-n0x1cb6) + + 0x072f9cb6, // c0x0143 (n0x1cb6-n0x1cbe) + + 0x07349cbe, // c0x0144 (n0x1cbe-n0x1cd2) + + 0x07361cd2, // c0x0145 (n0x1cd2-n0x1cd8) + + 0x073b5cd8, // c0x0146 (n0x1cd8-n0x1ced) + + 0x073b9ced, // c0x0147 (n0x1ced-n0x1cee) + + 0x073bdcee, // c0x0148 (n0x1cee-n0x1cef) + + 0x07401cef, // c0x0149 (n0x1cef-n0x1d00) + + 0x07411d00, // c0x014a (n0x1d00-n0x1d04) + + 0x07449d04, // c0x014b (n0x1d04-n0x1d12) + + 0x07479d12, // c0x014c (n0x1d12-n0x1d1e) + + 0x075b5d1e, // c0x014d (n0x1d1e-n0x1d6d) + + 0x075d9d6d, // c0x014e (n0x1d6d-n0x1d76) + + 0x07605d76, // c0x014f (n0x1d76-n0x1d81) + + 0x07609d81, // c0x0150 (n0x1d81-n0x1d82) + + 0x0760dd82, // c0x0151 (n0x1d82-n0x1d83) + + 0x07709d83, // c0x0152 (n0x1d83-n0x1dc2) + + 0x07715dc2, // c0x0153 (n0x1dc2-n0x1dc5) + + 0x07721dc5, // c0x0154 (n0x1dc5-n0x1dc8) + + 0x0772ddc8, // c0x0155 (n0x1dc8-n0x1dcb) + + 0x07739dcb, // c0x0156 (n0x1dcb-n0x1dce) + + 0x07745dce, // c0x0157 (n0x1dce-n0x1dd1) + + 0x07751dd1, // c0x0158 (n0x1dd1-n0x1dd4) + + 0x0775ddd4, // c0x0159 (n0x1dd4-n0x1dd7) + + 0x07769dd7, // c0x015a (n0x1dd7-n0x1dda) + + 0x07775dda, // c0x015b (n0x1dda-n0x1ddd) + + 0x07781ddd, // c0x015c (n0x1ddd-n0x1de0) + + 0x0778dde0, // c0x015d (n0x1de0-n0x1de3) + + 0x07799de3, // c0x015e (n0x1de3-n0x1de6) + + 0x077a5de6, // c0x015f (n0x1de6-n0x1de9) + + 0x077adde9, // c0x0160 (n0x1de9-n0x1deb) + + 0x077b9deb, // c0x0161 (n0x1deb-n0x1dee) + + 0x077c5dee, // c0x0162 (n0x1dee-n0x1df1) + + 0x077d1df1, // c0x0163 (n0x1df1-n0x1df4) + + 0x077dddf4, // c0x0164 (n0x1df4-n0x1df7) + + 0x077e9df7, // c0x0165 (n0x1df7-n0x1dfa) + + 0x077f5dfa, // c0x0166 (n0x1dfa-n0x1dfd) + + 0x07801dfd, // c0x0167 (n0x1dfd-n0x1e00) + + 0x0780de00, // c0x0168 (n0x1e00-n0x1e03) + + 0x07819e03, // c0x0169 (n0x1e03-n0x1e06) + + 0x07825e06, // c0x016a (n0x1e06-n0x1e09) + + 0x07831e09, // c0x016b (n0x1e09-n0x1e0c) + + 0x0783de0c, // c0x016c (n0x1e0c-n0x1e0f) + + 0x07849e0f, // c0x016d (n0x1e0f-n0x1e12) + + 0x07855e12, // c0x016e (n0x1e12-n0x1e15) + + 0x07861e15, // c0x016f (n0x1e15-n0x1e18) + + 0x0786de18, // c0x0170 (n0x1e18-n0x1e1b) + + 0x07879e1b, // c0x0171 (n0x1e1b-n0x1e1e) + + 0x07881e1e, // c0x0172 (n0x1e1e-n0x1e20) + + 0x0788de20, // c0x0173 (n0x1e20-n0x1e23) + + 0x07899e23, // c0x0174 (n0x1e23-n0x1e26) + + 0x078a5e26, // c0x0175 (n0x1e26-n0x1e29) + + 0x078b1e29, // c0x0176 (n0x1e29-n0x1e2c) + + 0x078bde2c, // c0x0177 (n0x1e2c-n0x1e2f) + + 0x078c9e2f, // c0x0178 (n0x1e2f-n0x1e32) + + 0x078d5e32, // c0x0179 (n0x1e32-n0x1e35) + + 0x078e1e35, // c0x017a (n0x1e35-n0x1e38) + + 0x078ede38, // c0x017b (n0x1e38-n0x1e3b) + + 0x078f9e3b, // c0x017c (n0x1e3b-n0x1e3e) + + 0x07905e3e, // c0x017d (n0x1e3e-n0x1e41) + + 0x07911e41, // c0x017e (n0x1e41-n0x1e44) + + 0x0791de44, // c0x017f (n0x1e44-n0x1e47) + + 0x07925e47, // c0x0180 (n0x1e47-n0x1e49) + + 0x07931e49, // c0x0181 (n0x1e49-n0x1e4c) + + 0x0793de4c, // c0x0182 (n0x1e4c-n0x1e4f) + + 0x07949e4f, // c0x0183 (n0x1e4f-n0x1e52) + + 0x07955e52, // c0x0184 (n0x1e52-n0x1e55) + + 0x07961e55, // c0x0185 (n0x1e55-n0x1e58) + + 0x0796de58, // c0x0186 (n0x1e58-n0x1e5b) + + 0x07979e5b, // c0x0187 (n0x1e5b-n0x1e5e) + + 0x07985e5e, // c0x0188 (n0x1e5e-n0x1e61) + + 0x07989e61, // c0x0189 (n0x1e61-n0x1e62) + + 0x07995e62, // c0x018a (n0x1e62-n0x1e65) + + 0x079ade65, // c0x018b (n0x1e65-n0x1e6b) + + 0x079b1e6b, // c0x018c (n0x1e6b-n0x1e6c) + + 0x079c1e6c, // c0x018d (n0x1e6c-n0x1e70) + + 0x079d9e70, // c0x018e (n0x1e70-n0x1e76) + + 0x07a1de76, // c0x018f (n0x1e76-n0x1e87) + + 0x07a31e87, // c0x0190 (n0x1e87-n0x1e8c) + + 0x07a65e8c, // c0x0191 (n0x1e8c-n0x1e99) + + 0x07a75e99, // c0x0192 (n0x1e99-n0x1e9d) + + 0x07a91e9d, // c0x0193 (n0x1e9d-n0x1ea4) + + 0x07aa9ea4, // c0x0194 (n0x1ea4-n0x1eaa) + + 0x27aedeaa, // c0x0195 (n0x1eaa-n0x1ebb) o + 0x07af1ebb, // c0x0196 (n0x1ebb-n0x1ebc) + +} + +// max children 406 (capacity 511) +// max text offset 26999 (capacity 32767) +// max text length 36 (capacity 63) +// max hi 7868 (capacity 16383) +// max lo 7867 (capacity 16383) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/table_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/table_test.go new file mode 100644 index 00000000..33820b03 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/publicsuffix/table_test.go @@ -0,0 +1,15715 @@ +// generated by go run gen.go; DO NOT EDIT + +package publicsuffix + +var rules = [...]string{ + "ac", + "com.ac", + "edu.ac", + "gov.ac", + "net.ac", + "mil.ac", + "org.ac", + "ad", + "nom.ad", + "ae", + "co.ae", + "net.ae", + "org.ae", + "sch.ae", + "ac.ae", + "gov.ae", + "mil.ae", + "aero", + "accident-investigation.aero", + "accident-prevention.aero", + "aerobatic.aero", + "aeroclub.aero", + "aerodrome.aero", + "agents.aero", + "aircraft.aero", + "airline.aero", + "airport.aero", + "air-surveillance.aero", + "airtraffic.aero", + "air-traffic-control.aero", + "ambulance.aero", + "amusement.aero", + "association.aero", + "author.aero", + "ballooning.aero", + "broker.aero", + "caa.aero", + "cargo.aero", + "catering.aero", + "certification.aero", + "championship.aero", + "charter.aero", + "civilaviation.aero", + "club.aero", + "conference.aero", + "consultant.aero", + "consulting.aero", + "control.aero", + "council.aero", + "crew.aero", + "design.aero", + "dgca.aero", + "educator.aero", + "emergency.aero", + "engine.aero", + "engineer.aero", + "entertainment.aero", + "equipment.aero", + "exchange.aero", + "express.aero", + "federation.aero", + "flight.aero", + "freight.aero", + "fuel.aero", + "gliding.aero", + "government.aero", + "groundhandling.aero", + "group.aero", + "hanggliding.aero", + "homebuilt.aero", + "insurance.aero", + "journal.aero", + "journalist.aero", + "leasing.aero", + "logistics.aero", + "magazine.aero", + "maintenance.aero", + "media.aero", + "microlight.aero", + "modelling.aero", + "navigation.aero", + "parachuting.aero", + "paragliding.aero", + "passenger-association.aero", + "pilot.aero", + "press.aero", + "production.aero", + "recreation.aero", + "repbody.aero", + "res.aero", + "research.aero", + "rotorcraft.aero", + "safety.aero", + "scientist.aero", + "services.aero", + "show.aero", + "skydiving.aero", + "software.aero", + "student.aero", + "trader.aero", + "trading.aero", + "trainer.aero", + "union.aero", + "workinggroup.aero", + "works.aero", + "af", + "gov.af", + "com.af", + "org.af", + "net.af", + "edu.af", + "ag", + "com.ag", + "org.ag", + "net.ag", + "co.ag", + "nom.ag", + "ai", + "off.ai", + "com.ai", + "net.ai", + "org.ai", + "al", + "com.al", + "edu.al", + "gov.al", + "mil.al", + "net.al", + "org.al", + "am", + "ao", + "ed.ao", + "gv.ao", + "og.ao", + "co.ao", + "pb.ao", + "it.ao", + "aq", + "ar", + "com.ar", + "edu.ar", + "gob.ar", + "gov.ar", + "int.ar", + "mil.ar", + "net.ar", + "org.ar", + "tur.ar", + "arpa", + "e164.arpa", + "in-addr.arpa", + "ip6.arpa", + "iris.arpa", + "uri.arpa", + "urn.arpa", + "as", + "gov.as", + "asia", + "at", + "ac.at", + "co.at", + "gv.at", + "or.at", + "au", + "com.au", + "net.au", + "org.au", + "edu.au", + "gov.au", + "asn.au", + "id.au", + "info.au", + "conf.au", + "oz.au", + "act.au", + "nsw.au", + "nt.au", + "qld.au", + "sa.au", + "tas.au", + "vic.au", + "wa.au", + "act.edu.au", + "nsw.edu.au", + "nt.edu.au", + "qld.edu.au", + "sa.edu.au", + "tas.edu.au", + "vic.edu.au", + "wa.edu.au", + "qld.gov.au", + "sa.gov.au", + "tas.gov.au", + "vic.gov.au", + "wa.gov.au", + "aw", + "com.aw", + "ax", + "az", + "com.az", + "net.az", + "int.az", + "gov.az", + "org.az", + "edu.az", + "info.az", + "pp.az", + "mil.az", + "name.az", + "pro.az", + "biz.az", + "ba", + "org.ba", + "net.ba", + "edu.ba", + "gov.ba", + "mil.ba", + "unsa.ba", + "unbi.ba", + "co.ba", + "com.ba", + "rs.ba", + "bb", + "biz.bb", + "co.bb", + "com.bb", + "edu.bb", + "gov.bb", + "info.bb", + "net.bb", + "org.bb", + "store.bb", + "tv.bb", + "*.bd", + "be", + "ac.be", + "bf", + "gov.bf", + "bg", + "a.bg", + "b.bg", + "c.bg", + "d.bg", + "e.bg", + "f.bg", + "g.bg", + "h.bg", + "i.bg", + "j.bg", + "k.bg", + "l.bg", + "m.bg", + "n.bg", + "o.bg", + "p.bg", + "q.bg", + "r.bg", + "s.bg", + "t.bg", + "u.bg", + "v.bg", + "w.bg", + "x.bg", + "y.bg", + "z.bg", + "0.bg", + "1.bg", + "2.bg", + "3.bg", + "4.bg", + "5.bg", + "6.bg", + "7.bg", + "8.bg", + "9.bg", + "bh", + "com.bh", + "edu.bh", + "net.bh", + "org.bh", + "gov.bh", + "bi", + "co.bi", + "com.bi", + "edu.bi", + "or.bi", + "org.bi", + "biz", + "bj", + "asso.bj", + "barreau.bj", + "gouv.bj", + "bm", + "com.bm", + "edu.bm", + "gov.bm", + "net.bm", + "org.bm", + "*.bn", + "bo", + "com.bo", + "edu.bo", + "gov.bo", + "gob.bo", + "int.bo", + "org.bo", + "net.bo", + "mil.bo", + "tv.bo", + "br", + "adm.br", + "adv.br", + "agr.br", + "am.br", + "arq.br", + "art.br", + "ato.br", + "b.br", + "bio.br", + "blog.br", + "bmd.br", + "cim.br", + "cng.br", + "cnt.br", + "com.br", + "coop.br", + "ecn.br", + "eco.br", + "edu.br", + "emp.br", + "eng.br", + "esp.br", + "etc.br", + "eti.br", + "far.br", + "flog.br", + "fm.br", + "fnd.br", + "fot.br", + "fst.br", + "g12.br", + "ggf.br", + "gov.br", + "imb.br", + "ind.br", + "inf.br", + "jor.br", + "jus.br", + "leg.br", + "lel.br", + "mat.br", + "med.br", + "mil.br", + "mp.br", + "mus.br", + "net.br", + "*.nom.br", + "not.br", + "ntr.br", + "odo.br", + "org.br", + "ppg.br", + "pro.br", + "psc.br", + "psi.br", + "qsl.br", + "radio.br", + "rec.br", + "slg.br", + "srv.br", + "taxi.br", + "teo.br", + "tmp.br", + "trd.br", + "tur.br", + "tv.br", + "vet.br", + "vlog.br", + "wiki.br", + "zlg.br", + "bs", + "com.bs", + "net.bs", + "org.bs", + "edu.bs", + "gov.bs", + "bt", + "com.bt", + "edu.bt", + "gov.bt", + "net.bt", + "org.bt", + "bv", + "bw", + "co.bw", + "org.bw", + "by", + "gov.by", + "mil.by", + "com.by", + "of.by", + "bz", + "com.bz", + "net.bz", + "org.bz", + "edu.bz", + "gov.bz", + "ca", + "ab.ca", + "bc.ca", + "mb.ca", + "nb.ca", + "nf.ca", + "nl.ca", + "ns.ca", + "nt.ca", + "nu.ca", + "on.ca", + "pe.ca", + "qc.ca", + "sk.ca", + "yk.ca", + "gc.ca", + "cat", + "cc", + "cd", + "gov.cd", + "cf", + "cg", + "ch", + "ci", + "org.ci", + "or.ci", + "com.ci", + "co.ci", + "edu.ci", + "ed.ci", + "ac.ci", + "net.ci", + "go.ci", + "asso.ci", + "xn--aroport-bya.ci", + "int.ci", + "presse.ci", + "md.ci", + "gouv.ci", + "*.ck", + "!www.ck", + "cl", + "gov.cl", + "gob.cl", + "co.cl", + "mil.cl", + "cm", + "co.cm", + "com.cm", + "gov.cm", + "net.cm", + "cn", + "ac.cn", + "com.cn", + "edu.cn", + "gov.cn", + "net.cn", + "org.cn", + "mil.cn", + "xn--55qx5d.cn", + "xn--io0a7i.cn", + "xn--od0alg.cn", + "ah.cn", + "bj.cn", + "cq.cn", + "fj.cn", + "gd.cn", + "gs.cn", + "gz.cn", + "gx.cn", + "ha.cn", + "hb.cn", + "he.cn", + "hi.cn", + "hl.cn", + "hn.cn", + "jl.cn", + "js.cn", + "jx.cn", + "ln.cn", + "nm.cn", + "nx.cn", + "qh.cn", + "sc.cn", + "sd.cn", + "sh.cn", + "sn.cn", + "sx.cn", + "tj.cn", + "xj.cn", + "xz.cn", + "yn.cn", + "zj.cn", + "hk.cn", + "mo.cn", + "tw.cn", + "co", + "arts.co", + "com.co", + "edu.co", + "firm.co", + "gov.co", + "info.co", + "int.co", + "mil.co", + "net.co", + "nom.co", + "org.co", + "rec.co", + "web.co", + "com", + "coop", + "cr", + "ac.cr", + "co.cr", + "ed.cr", + "fi.cr", + "go.cr", + "or.cr", + "sa.cr", + "cu", + "com.cu", + "edu.cu", + "org.cu", + "net.cu", + "gov.cu", + "inf.cu", + "cv", + "cw", + "com.cw", + "edu.cw", + "net.cw", + "org.cw", + "cx", + "gov.cx", + "ac.cy", + "biz.cy", + "com.cy", + "ekloges.cy", + "gov.cy", + "ltd.cy", + "name.cy", + "net.cy", + "org.cy", + "parliament.cy", + "press.cy", + "pro.cy", + "tm.cy", + "cz", + "de", + "dj", + "dk", + "dm", + "com.dm", + "net.dm", + "org.dm", + "edu.dm", + "gov.dm", + "do", + "art.do", + "com.do", + "edu.do", + "gob.do", + "gov.do", + "mil.do", + "net.do", + "org.do", + "sld.do", + "web.do", + "dz", + "com.dz", + "org.dz", + "net.dz", + "gov.dz", + "edu.dz", + "asso.dz", + "pol.dz", + "art.dz", + "ec", + "com.ec", + "info.ec", + "net.ec", + "fin.ec", + "k12.ec", + "med.ec", + "pro.ec", + "org.ec", + "edu.ec", + "gov.ec", + "gob.ec", + "mil.ec", + "edu", + "ee", + "edu.ee", + "gov.ee", + "riik.ee", + "lib.ee", + "med.ee", + "com.ee", + "pri.ee", + "aip.ee", + "org.ee", + "fie.ee", + "eg", + "com.eg", + "edu.eg", + "eun.eg", + "gov.eg", + "mil.eg", + "name.eg", + "net.eg", + "org.eg", + "sci.eg", + "*.er", + "es", + "com.es", + "nom.es", + "org.es", + "gob.es", + "edu.es", + "et", + "com.et", + "gov.et", + "org.et", + "edu.et", + "biz.et", + "name.et", + "info.et", + "net.et", + "eu", + "fi", + "aland.fi", + "*.fj", + "*.fk", + "fm", + "fo", + "fr", + "com.fr", + "asso.fr", + "nom.fr", + "prd.fr", + "presse.fr", + "tm.fr", + "aeroport.fr", + "assedic.fr", + "avocat.fr", + "avoues.fr", + "cci.fr", + "chambagri.fr", + "chirurgiens-dentistes.fr", + "experts-comptables.fr", + "geometre-expert.fr", + "gouv.fr", + "greta.fr", + "huissier-justice.fr", + "medecin.fr", + "notaires.fr", + "pharmacien.fr", + "port.fr", + "veterinaire.fr", + "ga", + "gb", + "gd", + "ge", + "com.ge", + "edu.ge", + "gov.ge", + "org.ge", + "mil.ge", + "net.ge", + "pvt.ge", + "gf", + "gg", + "co.gg", + "net.gg", + "org.gg", + "gh", + "com.gh", + "edu.gh", + "gov.gh", + "org.gh", + "mil.gh", + "gi", + "com.gi", + "ltd.gi", + "gov.gi", + "mod.gi", + "edu.gi", + "org.gi", + "gl", + "co.gl", + "com.gl", + "edu.gl", + "net.gl", + "org.gl", + "gm", + "gn", + "ac.gn", + "com.gn", + "edu.gn", + "gov.gn", + "org.gn", + "net.gn", + "gov", + "gp", + "com.gp", + "net.gp", + "mobi.gp", + "edu.gp", + "org.gp", + "asso.gp", + "gq", + "gr", + "com.gr", + "edu.gr", + "net.gr", + "org.gr", + "gov.gr", + "gs", + "gt", + "com.gt", + "edu.gt", + "gob.gt", + "ind.gt", + "mil.gt", + "net.gt", + "org.gt", + "*.gu", + "gw", + "gy", + "co.gy", + "com.gy", + "edu.gy", + "gov.gy", + "net.gy", + "org.gy", + "hk", + "com.hk", + "edu.hk", + "gov.hk", + "idv.hk", + "net.hk", + "org.hk", + "xn--55qx5d.hk", + "xn--wcvs22d.hk", + "xn--lcvr32d.hk", + "xn--mxtq1m.hk", + "xn--gmqw5a.hk", + "xn--ciqpn.hk", + "xn--gmq050i.hk", + "xn--zf0avx.hk", + "xn--io0a7i.hk", + "xn--mk0axi.hk", + "xn--od0alg.hk", + "xn--od0aq3b.hk", + "xn--tn0ag.hk", + "xn--uc0atv.hk", + "xn--uc0ay4a.hk", + "hm", + "hn", + "com.hn", + "edu.hn", + "org.hn", + "net.hn", + "mil.hn", + "gob.hn", + "hr", + "iz.hr", + "from.hr", + "name.hr", + "com.hr", + "ht", + "com.ht", + "shop.ht", + "firm.ht", + "info.ht", + "adult.ht", + "net.ht", + "pro.ht", + "org.ht", + "med.ht", + "art.ht", + "coop.ht", + "pol.ht", + "asso.ht", + "edu.ht", + "rel.ht", + "gouv.ht", + "perso.ht", + "hu", + "co.hu", + "info.hu", + "org.hu", + "priv.hu", + "sport.hu", + "tm.hu", + "2000.hu", + "agrar.hu", + "bolt.hu", + "casino.hu", + "city.hu", + "erotica.hu", + "erotika.hu", + "film.hu", + "forum.hu", + "games.hu", + "hotel.hu", + "ingatlan.hu", + "jogasz.hu", + "konyvelo.hu", + "lakas.hu", + "media.hu", + "news.hu", + "reklam.hu", + "sex.hu", + "shop.hu", + "suli.hu", + "szex.hu", + "tozsde.hu", + "utazas.hu", + "video.hu", + "id", + "ac.id", + "biz.id", + "co.id", + "desa.id", + "go.id", + "mil.id", + "my.id", + "net.id", + "or.id", + "sch.id", + "web.id", + "ie", + "gov.ie", + "il", + "ac.il", + "co.il", + "gov.il", + "idf.il", + "k12.il", + "muni.il", + "net.il", + "org.il", + "im", + "ac.im", + "co.im", + "com.im", + "ltd.co.im", + "net.im", + "org.im", + "plc.co.im", + "tt.im", + "tv.im", + "in", + "co.in", + "firm.in", + "net.in", + "org.in", + "gen.in", + "ind.in", + "nic.in", + "ac.in", + "edu.in", + "res.in", + "gov.in", + "mil.in", + "info", + "int", + "eu.int", + "io", + "com.io", + "iq", + "gov.iq", + "edu.iq", + "mil.iq", + "com.iq", + "org.iq", + "net.iq", + "ir", + "ac.ir", + "co.ir", + "gov.ir", + "id.ir", + "net.ir", + "org.ir", + "sch.ir", + "xn--mgba3a4f16a.ir", + "xn--mgba3a4fra.ir", + "is", + "net.is", + "com.is", + "edu.is", + "gov.is", + "org.is", + "int.is", + "it", + "gov.it", + "edu.it", + "abr.it", + "abruzzo.it", + "aosta-valley.it", + "aostavalley.it", + "bas.it", + "basilicata.it", + "cal.it", + "calabria.it", + "cam.it", + "campania.it", + "emilia-romagna.it", + "emiliaromagna.it", + "emr.it", + "friuli-v-giulia.it", + "friuli-ve-giulia.it", + "friuli-vegiulia.it", + "friuli-venezia-giulia.it", + "friuli-veneziagiulia.it", + "friuli-vgiulia.it", + "friuliv-giulia.it", + "friulive-giulia.it", + "friulivegiulia.it", + "friulivenezia-giulia.it", + "friuliveneziagiulia.it", + "friulivgiulia.it", + "fvg.it", + "laz.it", + "lazio.it", + "lig.it", + "liguria.it", + "lom.it", + "lombardia.it", + "lombardy.it", + "lucania.it", + "mar.it", + "marche.it", + "mol.it", + "molise.it", + "piedmont.it", + "piemonte.it", + "pmn.it", + "pug.it", + "puglia.it", + "sar.it", + "sardegna.it", + "sardinia.it", + "sic.it", + "sicilia.it", + "sicily.it", + "taa.it", + "tos.it", + "toscana.it", + "trentino-a-adige.it", + "trentino-aadige.it", + "trentino-alto-adige.it", + "trentino-altoadige.it", + "trentino-s-tirol.it", + "trentino-stirol.it", + "trentino-sud-tirol.it", + "trentino-sudtirol.it", + "trentino-sued-tirol.it", + "trentino-suedtirol.it", + "trentinoa-adige.it", + "trentinoaadige.it", + "trentinoalto-adige.it", + "trentinoaltoadige.it", + "trentinos-tirol.it", + "trentinostirol.it", + "trentinosud-tirol.it", + "trentinosudtirol.it", + "trentinosued-tirol.it", + "trentinosuedtirol.it", + "tuscany.it", + "umb.it", + "umbria.it", + "val-d-aosta.it", + "val-daosta.it", + "vald-aosta.it", + "valdaosta.it", + "valle-aosta.it", + "valle-d-aosta.it", + "valle-daosta.it", + "valleaosta.it", + "valled-aosta.it", + "valledaosta.it", + "vallee-aoste.it", + "valleeaoste.it", + "vao.it", + "vda.it", + "ven.it", + "veneto.it", + "ag.it", + "agrigento.it", + "al.it", + "alessandria.it", + "alto-adige.it", + "altoadige.it", + "an.it", + "ancona.it", + "andria-barletta-trani.it", + "andria-trani-barletta.it", + "andriabarlettatrani.it", + "andriatranibarletta.it", + "ao.it", + "aosta.it", + "aoste.it", + "ap.it", + "aq.it", + "aquila.it", + "ar.it", + "arezzo.it", + "ascoli-piceno.it", + "ascolipiceno.it", + "asti.it", + "at.it", + "av.it", + "avellino.it", + "ba.it", + "balsan.it", + "bari.it", + "barletta-trani-andria.it", + "barlettatraniandria.it", + "belluno.it", + "benevento.it", + "bergamo.it", + "bg.it", + "bi.it", + "biella.it", + "bl.it", + "bn.it", + "bo.it", + "bologna.it", + "bolzano.it", + "bozen.it", + "br.it", + "brescia.it", + "brindisi.it", + "bs.it", + "bt.it", + "bz.it", + "ca.it", + "cagliari.it", + "caltanissetta.it", + "campidano-medio.it", + "campidanomedio.it", + "campobasso.it", + "carbonia-iglesias.it", + "carboniaiglesias.it", + "carrara-massa.it", + "carraramassa.it", + "caserta.it", + "catania.it", + "catanzaro.it", + "cb.it", + "ce.it", + "cesena-forli.it", + "cesenaforli.it", + "ch.it", + "chieti.it", + "ci.it", + "cl.it", + "cn.it", + "co.it", + "como.it", + "cosenza.it", + "cr.it", + "cremona.it", + "crotone.it", + "cs.it", + "ct.it", + "cuneo.it", + "cz.it", + "dell-ogliastra.it", + "dellogliastra.it", + "en.it", + "enna.it", + "fc.it", + "fe.it", + "fermo.it", + "ferrara.it", + "fg.it", + "fi.it", + "firenze.it", + "florence.it", + "fm.it", + "foggia.it", + "forli-cesena.it", + "forlicesena.it", + "fr.it", + "frosinone.it", + "ge.it", + "genoa.it", + "genova.it", + "go.it", + "gorizia.it", + "gr.it", + "grosseto.it", + "iglesias-carbonia.it", + "iglesiascarbonia.it", + "im.it", + "imperia.it", + "is.it", + "isernia.it", + "kr.it", + "la-spezia.it", + "laquila.it", + "laspezia.it", + "latina.it", + "lc.it", + "le.it", + "lecce.it", + "lecco.it", + "li.it", + "livorno.it", + "lo.it", + "lodi.it", + "lt.it", + "lu.it", + "lucca.it", + "macerata.it", + "mantova.it", + "massa-carrara.it", + "massacarrara.it", + "matera.it", + "mb.it", + "mc.it", + "me.it", + "medio-campidano.it", + "mediocampidano.it", + "messina.it", + "mi.it", + "milan.it", + "milano.it", + "mn.it", + "mo.it", + "modena.it", + "monza-brianza.it", + "monza-e-della-brianza.it", + "monza.it", + "monzabrianza.it", + "monzaebrianza.it", + "monzaedellabrianza.it", + "ms.it", + "mt.it", + "na.it", + "naples.it", + "napoli.it", + "no.it", + "novara.it", + "nu.it", + "nuoro.it", + "og.it", + "ogliastra.it", + "olbia-tempio.it", + "olbiatempio.it", + "or.it", + "oristano.it", + "ot.it", + "pa.it", + "padova.it", + "padua.it", + "palermo.it", + "parma.it", + "pavia.it", + "pc.it", + "pd.it", + "pe.it", + "perugia.it", + "pesaro-urbino.it", + "pesarourbino.it", + "pescara.it", + "pg.it", + "pi.it", + "piacenza.it", + "pisa.it", + "pistoia.it", + "pn.it", + "po.it", + "pordenone.it", + "potenza.it", + "pr.it", + "prato.it", + "pt.it", + "pu.it", + "pv.it", + "pz.it", + "ra.it", + "ragusa.it", + "ravenna.it", + "rc.it", + "re.it", + "reggio-calabria.it", + "reggio-emilia.it", + "reggiocalabria.it", + "reggioemilia.it", + "rg.it", + "ri.it", + "rieti.it", + "rimini.it", + "rm.it", + "rn.it", + "ro.it", + "roma.it", + "rome.it", + "rovigo.it", + "sa.it", + "salerno.it", + "sassari.it", + "savona.it", + "si.it", + "siena.it", + "siracusa.it", + "so.it", + "sondrio.it", + "sp.it", + "sr.it", + "ss.it", + "suedtirol.it", + "sv.it", + "ta.it", + "taranto.it", + "te.it", + "tempio-olbia.it", + "tempioolbia.it", + "teramo.it", + "terni.it", + "tn.it", + "to.it", + "torino.it", + "tp.it", + "tr.it", + "trani-andria-barletta.it", + "trani-barletta-andria.it", + "traniandriabarletta.it", + "tranibarlettaandria.it", + "trapani.it", + "trentino.it", + "trento.it", + "treviso.it", + "trieste.it", + "ts.it", + "turin.it", + "tv.it", + "ud.it", + "udine.it", + "urbino-pesaro.it", + "urbinopesaro.it", + "va.it", + "varese.it", + "vb.it", + "vc.it", + "ve.it", + "venezia.it", + "venice.it", + "verbania.it", + "vercelli.it", + "verona.it", + "vi.it", + "vibo-valentia.it", + "vibovalentia.it", + "vicenza.it", + "viterbo.it", + "vr.it", + "vs.it", + "vt.it", + "vv.it", + "je", + "co.je", + "net.je", + "org.je", + "*.jm", + "jo", + "com.jo", + "org.jo", + "net.jo", + "edu.jo", + "sch.jo", + "gov.jo", + "mil.jo", + "name.jo", + "jobs", + "jp", + "ac.jp", + "ad.jp", + "co.jp", + "ed.jp", + "go.jp", + "gr.jp", + "lg.jp", + "ne.jp", + "or.jp", + "aichi.jp", + "akita.jp", + "aomori.jp", + "chiba.jp", + "ehime.jp", + "fukui.jp", + "fukuoka.jp", + "fukushima.jp", + "gifu.jp", + "gunma.jp", + "hiroshima.jp", + "hokkaido.jp", + "hyogo.jp", + "ibaraki.jp", + "ishikawa.jp", + "iwate.jp", + "kagawa.jp", + "kagoshima.jp", + "kanagawa.jp", + "kochi.jp", + "kumamoto.jp", + "kyoto.jp", + "mie.jp", + "miyagi.jp", + "miyazaki.jp", + "nagano.jp", + "nagasaki.jp", + "nara.jp", + "niigata.jp", + "oita.jp", + "okayama.jp", + "okinawa.jp", + "osaka.jp", + "saga.jp", + "saitama.jp", + "shiga.jp", + "shimane.jp", + "shizuoka.jp", + "tochigi.jp", + "tokushima.jp", + "tokyo.jp", + "tottori.jp", + "toyama.jp", + "wakayama.jp", + "yamagata.jp", + "yamaguchi.jp", + "yamanashi.jp", + "xn--4pvxs.jp", + "xn--vgu402c.jp", + "xn--c3s14m.jp", + "xn--f6qx53a.jp", + "xn--8pvr4u.jp", + "xn--uist22h.jp", + "xn--djrs72d6uy.jp", + "xn--mkru45i.jp", + "xn--0trq7p7nn.jp", + "xn--8ltr62k.jp", + "xn--2m4a15e.jp", + "xn--efvn9s.jp", + "xn--32vp30h.jp", + "xn--4it797k.jp", + "xn--1lqs71d.jp", + "xn--5rtp49c.jp", + "xn--5js045d.jp", + "xn--ehqz56n.jp", + "xn--1lqs03n.jp", + "xn--qqqt11m.jp", + "xn--kbrq7o.jp", + "xn--pssu33l.jp", + "xn--ntsq17g.jp", + "xn--uisz3g.jp", + "xn--6btw5a.jp", + "xn--1ctwo.jp", + "xn--6orx2r.jp", + "xn--rht61e.jp", + "xn--rht27z.jp", + "xn--djty4k.jp", + "xn--nit225k.jp", + "xn--rht3d.jp", + "xn--klty5x.jp", + "xn--kltx9a.jp", + "xn--kltp7d.jp", + "xn--uuwu58a.jp", + "xn--zbx025d.jp", + "xn--ntso0iqx3a.jp", + "xn--elqq16h.jp", + "xn--4it168d.jp", + "xn--klt787d.jp", + "xn--rny31h.jp", + "xn--7t0a264c.jp", + "xn--5rtq34k.jp", + "xn--k7yn95e.jp", + "xn--tor131o.jp", + "xn--d5qv7z876c.jp", + "*.kawasaki.jp", + "*.kitakyushu.jp", + "*.kobe.jp", + "*.nagoya.jp", + "*.sapporo.jp", + "*.sendai.jp", + "*.yokohama.jp", + "!city.kawasaki.jp", + "!city.kitakyushu.jp", + "!city.kobe.jp", + "!city.nagoya.jp", + "!city.sapporo.jp", + "!city.sendai.jp", + "!city.yokohama.jp", + "aisai.aichi.jp", + "ama.aichi.jp", + "anjo.aichi.jp", + "asuke.aichi.jp", + "chiryu.aichi.jp", + "chita.aichi.jp", + "fuso.aichi.jp", + "gamagori.aichi.jp", + "handa.aichi.jp", + "hazu.aichi.jp", + "hekinan.aichi.jp", + "higashiura.aichi.jp", + "ichinomiya.aichi.jp", + "inazawa.aichi.jp", + "inuyama.aichi.jp", + "isshiki.aichi.jp", + "iwakura.aichi.jp", + "kanie.aichi.jp", + "kariya.aichi.jp", + "kasugai.aichi.jp", + "kira.aichi.jp", + "kiyosu.aichi.jp", + "komaki.aichi.jp", + "konan.aichi.jp", + "kota.aichi.jp", + "mihama.aichi.jp", + "miyoshi.aichi.jp", + "nishio.aichi.jp", + "nisshin.aichi.jp", + "obu.aichi.jp", + "oguchi.aichi.jp", + "oharu.aichi.jp", + "okazaki.aichi.jp", + "owariasahi.aichi.jp", + "seto.aichi.jp", + "shikatsu.aichi.jp", + "shinshiro.aichi.jp", + "shitara.aichi.jp", + "tahara.aichi.jp", + "takahama.aichi.jp", + "tobishima.aichi.jp", + "toei.aichi.jp", + "togo.aichi.jp", + "tokai.aichi.jp", + "tokoname.aichi.jp", + "toyoake.aichi.jp", + "toyohashi.aichi.jp", + "toyokawa.aichi.jp", + "toyone.aichi.jp", + "toyota.aichi.jp", + "tsushima.aichi.jp", + "yatomi.aichi.jp", + "akita.akita.jp", + "daisen.akita.jp", + "fujisato.akita.jp", + "gojome.akita.jp", + "hachirogata.akita.jp", + "happou.akita.jp", + "higashinaruse.akita.jp", + "honjo.akita.jp", + "honjyo.akita.jp", + "ikawa.akita.jp", + "kamikoani.akita.jp", + "kamioka.akita.jp", + "katagami.akita.jp", + "kazuno.akita.jp", + "kitaakita.akita.jp", + "kosaka.akita.jp", + "kyowa.akita.jp", + "misato.akita.jp", + "mitane.akita.jp", + "moriyoshi.akita.jp", + "nikaho.akita.jp", + "noshiro.akita.jp", + "odate.akita.jp", + "oga.akita.jp", + "ogata.akita.jp", + "semboku.akita.jp", + "yokote.akita.jp", + "yurihonjo.akita.jp", + "aomori.aomori.jp", + "gonohe.aomori.jp", + "hachinohe.aomori.jp", + "hashikami.aomori.jp", + "hiranai.aomori.jp", + "hirosaki.aomori.jp", + "itayanagi.aomori.jp", + "kuroishi.aomori.jp", + "misawa.aomori.jp", + "mutsu.aomori.jp", + "nakadomari.aomori.jp", + "noheji.aomori.jp", + "oirase.aomori.jp", + "owani.aomori.jp", + "rokunohe.aomori.jp", + "sannohe.aomori.jp", + "shichinohe.aomori.jp", + "shingo.aomori.jp", + "takko.aomori.jp", + "towada.aomori.jp", + "tsugaru.aomori.jp", + "tsuruta.aomori.jp", + "abiko.chiba.jp", + "asahi.chiba.jp", + "chonan.chiba.jp", + "chosei.chiba.jp", + "choshi.chiba.jp", + "chuo.chiba.jp", + "funabashi.chiba.jp", + "futtsu.chiba.jp", + "hanamigawa.chiba.jp", + "ichihara.chiba.jp", + "ichikawa.chiba.jp", + "ichinomiya.chiba.jp", + "inzai.chiba.jp", + "isumi.chiba.jp", + "kamagaya.chiba.jp", + "kamogawa.chiba.jp", + "kashiwa.chiba.jp", + "katori.chiba.jp", + "katsuura.chiba.jp", + "kimitsu.chiba.jp", + "kisarazu.chiba.jp", + "kozaki.chiba.jp", + "kujukuri.chiba.jp", + "kyonan.chiba.jp", + "matsudo.chiba.jp", + "midori.chiba.jp", + "mihama.chiba.jp", + "minamiboso.chiba.jp", + "mobara.chiba.jp", + "mutsuzawa.chiba.jp", + "nagara.chiba.jp", + "nagareyama.chiba.jp", + "narashino.chiba.jp", + "narita.chiba.jp", + "noda.chiba.jp", + "oamishirasato.chiba.jp", + "omigawa.chiba.jp", + "onjuku.chiba.jp", + "otaki.chiba.jp", + "sakae.chiba.jp", + "sakura.chiba.jp", + "shimofusa.chiba.jp", + "shirako.chiba.jp", + "shiroi.chiba.jp", + "shisui.chiba.jp", + "sodegaura.chiba.jp", + "sosa.chiba.jp", + "tako.chiba.jp", + "tateyama.chiba.jp", + "togane.chiba.jp", + "tohnosho.chiba.jp", + "tomisato.chiba.jp", + "urayasu.chiba.jp", + "yachimata.chiba.jp", + "yachiyo.chiba.jp", + "yokaichiba.chiba.jp", + "yokoshibahikari.chiba.jp", + "yotsukaido.chiba.jp", + "ainan.ehime.jp", + "honai.ehime.jp", + "ikata.ehime.jp", + "imabari.ehime.jp", + "iyo.ehime.jp", + "kamijima.ehime.jp", + "kihoku.ehime.jp", + "kumakogen.ehime.jp", + "masaki.ehime.jp", + "matsuno.ehime.jp", + "matsuyama.ehime.jp", + "namikata.ehime.jp", + "niihama.ehime.jp", + "ozu.ehime.jp", + "saijo.ehime.jp", + "seiyo.ehime.jp", + "shikokuchuo.ehime.jp", + "tobe.ehime.jp", + "toon.ehime.jp", + "uchiko.ehime.jp", + "uwajima.ehime.jp", + "yawatahama.ehime.jp", + "echizen.fukui.jp", + "eiheiji.fukui.jp", + "fukui.fukui.jp", + "ikeda.fukui.jp", + "katsuyama.fukui.jp", + "mihama.fukui.jp", + "minamiechizen.fukui.jp", + "obama.fukui.jp", + "ohi.fukui.jp", + "ono.fukui.jp", + "sabae.fukui.jp", + "sakai.fukui.jp", + "takahama.fukui.jp", + "tsuruga.fukui.jp", + "wakasa.fukui.jp", + "ashiya.fukuoka.jp", + "buzen.fukuoka.jp", + "chikugo.fukuoka.jp", + "chikuho.fukuoka.jp", + "chikujo.fukuoka.jp", + "chikushino.fukuoka.jp", + "chikuzen.fukuoka.jp", + "chuo.fukuoka.jp", + "dazaifu.fukuoka.jp", + "fukuchi.fukuoka.jp", + "hakata.fukuoka.jp", + "higashi.fukuoka.jp", + "hirokawa.fukuoka.jp", + "hisayama.fukuoka.jp", + "iizuka.fukuoka.jp", + "inatsuki.fukuoka.jp", + "kaho.fukuoka.jp", + "kasuga.fukuoka.jp", + "kasuya.fukuoka.jp", + "kawara.fukuoka.jp", + "keisen.fukuoka.jp", + "koga.fukuoka.jp", + "kurate.fukuoka.jp", + "kurogi.fukuoka.jp", + "kurume.fukuoka.jp", + "minami.fukuoka.jp", + "miyako.fukuoka.jp", + "miyama.fukuoka.jp", + "miyawaka.fukuoka.jp", + "mizumaki.fukuoka.jp", + "munakata.fukuoka.jp", + "nakagawa.fukuoka.jp", + "nakama.fukuoka.jp", + "nishi.fukuoka.jp", + "nogata.fukuoka.jp", + "ogori.fukuoka.jp", + "okagaki.fukuoka.jp", + "okawa.fukuoka.jp", + "oki.fukuoka.jp", + "omuta.fukuoka.jp", + "onga.fukuoka.jp", + "onojo.fukuoka.jp", + "oto.fukuoka.jp", + "saigawa.fukuoka.jp", + "sasaguri.fukuoka.jp", + "shingu.fukuoka.jp", + "shinyoshitomi.fukuoka.jp", + "shonai.fukuoka.jp", + "soeda.fukuoka.jp", + "sue.fukuoka.jp", + "tachiarai.fukuoka.jp", + "tagawa.fukuoka.jp", + "takata.fukuoka.jp", + "toho.fukuoka.jp", + "toyotsu.fukuoka.jp", + "tsuiki.fukuoka.jp", + "ukiha.fukuoka.jp", + "umi.fukuoka.jp", + "usui.fukuoka.jp", + "yamada.fukuoka.jp", + "yame.fukuoka.jp", + "yanagawa.fukuoka.jp", + "yukuhashi.fukuoka.jp", + "aizubange.fukushima.jp", + "aizumisato.fukushima.jp", + "aizuwakamatsu.fukushima.jp", + "asakawa.fukushima.jp", + "bandai.fukushima.jp", + "date.fukushima.jp", + "fukushima.fukushima.jp", + "furudono.fukushima.jp", + "futaba.fukushima.jp", + "hanawa.fukushima.jp", + "higashi.fukushima.jp", + "hirata.fukushima.jp", + "hirono.fukushima.jp", + "iitate.fukushima.jp", + "inawashiro.fukushima.jp", + "ishikawa.fukushima.jp", + "iwaki.fukushima.jp", + "izumizaki.fukushima.jp", + "kagamiishi.fukushima.jp", + "kaneyama.fukushima.jp", + "kawamata.fukushima.jp", + "kitakata.fukushima.jp", + "kitashiobara.fukushima.jp", + "koori.fukushima.jp", + "koriyama.fukushima.jp", + "kunimi.fukushima.jp", + "miharu.fukushima.jp", + "mishima.fukushima.jp", + "namie.fukushima.jp", + "nango.fukushima.jp", + "nishiaizu.fukushima.jp", + "nishigo.fukushima.jp", + "okuma.fukushima.jp", + "omotego.fukushima.jp", + "ono.fukushima.jp", + "otama.fukushima.jp", + "samegawa.fukushima.jp", + "shimogo.fukushima.jp", + "shirakawa.fukushima.jp", + "showa.fukushima.jp", + "soma.fukushima.jp", + "sukagawa.fukushima.jp", + "taishin.fukushima.jp", + "tamakawa.fukushima.jp", + "tanagura.fukushima.jp", + "tenei.fukushima.jp", + "yabuki.fukushima.jp", + "yamato.fukushima.jp", + "yamatsuri.fukushima.jp", + "yanaizu.fukushima.jp", + "yugawa.fukushima.jp", + "anpachi.gifu.jp", + "ena.gifu.jp", + "gifu.gifu.jp", + "ginan.gifu.jp", + "godo.gifu.jp", + "gujo.gifu.jp", + "hashima.gifu.jp", + "hichiso.gifu.jp", + "hida.gifu.jp", + "higashishirakawa.gifu.jp", + "ibigawa.gifu.jp", + "ikeda.gifu.jp", + "kakamigahara.gifu.jp", + "kani.gifu.jp", + "kasahara.gifu.jp", + "kasamatsu.gifu.jp", + "kawaue.gifu.jp", + "kitagata.gifu.jp", + "mino.gifu.jp", + "minokamo.gifu.jp", + "mitake.gifu.jp", + "mizunami.gifu.jp", + "motosu.gifu.jp", + "nakatsugawa.gifu.jp", + "ogaki.gifu.jp", + "sakahogi.gifu.jp", + "seki.gifu.jp", + "sekigahara.gifu.jp", + "shirakawa.gifu.jp", + "tajimi.gifu.jp", + "takayama.gifu.jp", + "tarui.gifu.jp", + "toki.gifu.jp", + "tomika.gifu.jp", + "wanouchi.gifu.jp", + "yamagata.gifu.jp", + "yaotsu.gifu.jp", + "yoro.gifu.jp", + "annaka.gunma.jp", + "chiyoda.gunma.jp", + "fujioka.gunma.jp", + "higashiagatsuma.gunma.jp", + "isesaki.gunma.jp", + "itakura.gunma.jp", + "kanna.gunma.jp", + "kanra.gunma.jp", + "katashina.gunma.jp", + "kawaba.gunma.jp", + "kiryu.gunma.jp", + "kusatsu.gunma.jp", + "maebashi.gunma.jp", + "meiwa.gunma.jp", + "midori.gunma.jp", + "minakami.gunma.jp", + "naganohara.gunma.jp", + "nakanojo.gunma.jp", + "nanmoku.gunma.jp", + "numata.gunma.jp", + "oizumi.gunma.jp", + "ora.gunma.jp", + "ota.gunma.jp", + "shibukawa.gunma.jp", + "shimonita.gunma.jp", + "shinto.gunma.jp", + "showa.gunma.jp", + "takasaki.gunma.jp", + "takayama.gunma.jp", + "tamamura.gunma.jp", + "tatebayashi.gunma.jp", + "tomioka.gunma.jp", + "tsukiyono.gunma.jp", + "tsumagoi.gunma.jp", + "ueno.gunma.jp", + "yoshioka.gunma.jp", + "asaminami.hiroshima.jp", + "daiwa.hiroshima.jp", + "etajima.hiroshima.jp", + "fuchu.hiroshima.jp", + "fukuyama.hiroshima.jp", + "hatsukaichi.hiroshima.jp", + "higashihiroshima.hiroshima.jp", + "hongo.hiroshima.jp", + "jinsekikogen.hiroshima.jp", + "kaita.hiroshima.jp", + "kui.hiroshima.jp", + "kumano.hiroshima.jp", + "kure.hiroshima.jp", + "mihara.hiroshima.jp", + "miyoshi.hiroshima.jp", + "naka.hiroshima.jp", + "onomichi.hiroshima.jp", + "osakikamijima.hiroshima.jp", + "otake.hiroshima.jp", + "saka.hiroshima.jp", + "sera.hiroshima.jp", + "seranishi.hiroshima.jp", + "shinichi.hiroshima.jp", + "shobara.hiroshima.jp", + "takehara.hiroshima.jp", + "abashiri.hokkaido.jp", + "abira.hokkaido.jp", + "aibetsu.hokkaido.jp", + "akabira.hokkaido.jp", + "akkeshi.hokkaido.jp", + "asahikawa.hokkaido.jp", + "ashibetsu.hokkaido.jp", + "ashoro.hokkaido.jp", + "assabu.hokkaido.jp", + "atsuma.hokkaido.jp", + "bibai.hokkaido.jp", + "biei.hokkaido.jp", + "bifuka.hokkaido.jp", + "bihoro.hokkaido.jp", + "biratori.hokkaido.jp", + "chippubetsu.hokkaido.jp", + "chitose.hokkaido.jp", + "date.hokkaido.jp", + "ebetsu.hokkaido.jp", + "embetsu.hokkaido.jp", + "eniwa.hokkaido.jp", + "erimo.hokkaido.jp", + "esan.hokkaido.jp", + "esashi.hokkaido.jp", + "fukagawa.hokkaido.jp", + "fukushima.hokkaido.jp", + "furano.hokkaido.jp", + "furubira.hokkaido.jp", + "haboro.hokkaido.jp", + "hakodate.hokkaido.jp", + "hamatonbetsu.hokkaido.jp", + "hidaka.hokkaido.jp", + "higashikagura.hokkaido.jp", + "higashikawa.hokkaido.jp", + "hiroo.hokkaido.jp", + "hokuryu.hokkaido.jp", + "hokuto.hokkaido.jp", + "honbetsu.hokkaido.jp", + "horokanai.hokkaido.jp", + "horonobe.hokkaido.jp", + "ikeda.hokkaido.jp", + "imakane.hokkaido.jp", + "ishikari.hokkaido.jp", + "iwamizawa.hokkaido.jp", + "iwanai.hokkaido.jp", + "kamifurano.hokkaido.jp", + "kamikawa.hokkaido.jp", + "kamishihoro.hokkaido.jp", + "kamisunagawa.hokkaido.jp", + "kamoenai.hokkaido.jp", + "kayabe.hokkaido.jp", + "kembuchi.hokkaido.jp", + "kikonai.hokkaido.jp", + "kimobetsu.hokkaido.jp", + "kitahiroshima.hokkaido.jp", + "kitami.hokkaido.jp", + "kiyosato.hokkaido.jp", + "koshimizu.hokkaido.jp", + "kunneppu.hokkaido.jp", + "kuriyama.hokkaido.jp", + "kuromatsunai.hokkaido.jp", + "kushiro.hokkaido.jp", + "kutchan.hokkaido.jp", + "kyowa.hokkaido.jp", + "mashike.hokkaido.jp", + "matsumae.hokkaido.jp", + "mikasa.hokkaido.jp", + "minamifurano.hokkaido.jp", + "mombetsu.hokkaido.jp", + "moseushi.hokkaido.jp", + "mukawa.hokkaido.jp", + "muroran.hokkaido.jp", + "naie.hokkaido.jp", + "nakagawa.hokkaido.jp", + "nakasatsunai.hokkaido.jp", + "nakatombetsu.hokkaido.jp", + "nanae.hokkaido.jp", + "nanporo.hokkaido.jp", + "nayoro.hokkaido.jp", + "nemuro.hokkaido.jp", + "niikappu.hokkaido.jp", + "niki.hokkaido.jp", + "nishiokoppe.hokkaido.jp", + "noboribetsu.hokkaido.jp", + "numata.hokkaido.jp", + "obihiro.hokkaido.jp", + "obira.hokkaido.jp", + "oketo.hokkaido.jp", + "okoppe.hokkaido.jp", + "otaru.hokkaido.jp", + "otobe.hokkaido.jp", + "otofuke.hokkaido.jp", + "otoineppu.hokkaido.jp", + "oumu.hokkaido.jp", + "ozora.hokkaido.jp", + "pippu.hokkaido.jp", + "rankoshi.hokkaido.jp", + "rebun.hokkaido.jp", + "rikubetsu.hokkaido.jp", + "rishiri.hokkaido.jp", + "rishirifuji.hokkaido.jp", + "saroma.hokkaido.jp", + "sarufutsu.hokkaido.jp", + "shakotan.hokkaido.jp", + "shari.hokkaido.jp", + "shibecha.hokkaido.jp", + "shibetsu.hokkaido.jp", + "shikabe.hokkaido.jp", + "shikaoi.hokkaido.jp", + "shimamaki.hokkaido.jp", + "shimizu.hokkaido.jp", + "shimokawa.hokkaido.jp", + "shinshinotsu.hokkaido.jp", + "shintoku.hokkaido.jp", + "shiranuka.hokkaido.jp", + "shiraoi.hokkaido.jp", + "shiriuchi.hokkaido.jp", + "sobetsu.hokkaido.jp", + "sunagawa.hokkaido.jp", + "taiki.hokkaido.jp", + "takasu.hokkaido.jp", + "takikawa.hokkaido.jp", + "takinoue.hokkaido.jp", + "teshikaga.hokkaido.jp", + "tobetsu.hokkaido.jp", + "tohma.hokkaido.jp", + "tomakomai.hokkaido.jp", + "tomari.hokkaido.jp", + "toya.hokkaido.jp", + "toyako.hokkaido.jp", + "toyotomi.hokkaido.jp", + "toyoura.hokkaido.jp", + "tsubetsu.hokkaido.jp", + "tsukigata.hokkaido.jp", + "urakawa.hokkaido.jp", + "urausu.hokkaido.jp", + "uryu.hokkaido.jp", + "utashinai.hokkaido.jp", + "wakkanai.hokkaido.jp", + "wassamu.hokkaido.jp", + "yakumo.hokkaido.jp", + "yoichi.hokkaido.jp", + "aioi.hyogo.jp", + "akashi.hyogo.jp", + "ako.hyogo.jp", + "amagasaki.hyogo.jp", + "aogaki.hyogo.jp", + "asago.hyogo.jp", + "ashiya.hyogo.jp", + "awaji.hyogo.jp", + "fukusaki.hyogo.jp", + "goshiki.hyogo.jp", + "harima.hyogo.jp", + "himeji.hyogo.jp", + "ichikawa.hyogo.jp", + "inagawa.hyogo.jp", + "itami.hyogo.jp", + "kakogawa.hyogo.jp", + "kamigori.hyogo.jp", + "kamikawa.hyogo.jp", + "kasai.hyogo.jp", + "kasuga.hyogo.jp", + "kawanishi.hyogo.jp", + "miki.hyogo.jp", + "minamiawaji.hyogo.jp", + "nishinomiya.hyogo.jp", + "nishiwaki.hyogo.jp", + "ono.hyogo.jp", + "sanda.hyogo.jp", + "sannan.hyogo.jp", + "sasayama.hyogo.jp", + "sayo.hyogo.jp", + "shingu.hyogo.jp", + "shinonsen.hyogo.jp", + "shiso.hyogo.jp", + "sumoto.hyogo.jp", + "taishi.hyogo.jp", + "taka.hyogo.jp", + "takarazuka.hyogo.jp", + "takasago.hyogo.jp", + "takino.hyogo.jp", + "tamba.hyogo.jp", + "tatsuno.hyogo.jp", + "toyooka.hyogo.jp", + "yabu.hyogo.jp", + "yashiro.hyogo.jp", + "yoka.hyogo.jp", + "yokawa.hyogo.jp", + "ami.ibaraki.jp", + "asahi.ibaraki.jp", + "bando.ibaraki.jp", + "chikusei.ibaraki.jp", + "daigo.ibaraki.jp", + "fujishiro.ibaraki.jp", + "hitachi.ibaraki.jp", + "hitachinaka.ibaraki.jp", + "hitachiomiya.ibaraki.jp", + "hitachiota.ibaraki.jp", + "ibaraki.ibaraki.jp", + "ina.ibaraki.jp", + "inashiki.ibaraki.jp", + "itako.ibaraki.jp", + "iwama.ibaraki.jp", + "joso.ibaraki.jp", + "kamisu.ibaraki.jp", + "kasama.ibaraki.jp", + "kashima.ibaraki.jp", + "kasumigaura.ibaraki.jp", + "koga.ibaraki.jp", + "miho.ibaraki.jp", + "mito.ibaraki.jp", + "moriya.ibaraki.jp", + "naka.ibaraki.jp", + "namegata.ibaraki.jp", + "oarai.ibaraki.jp", + "ogawa.ibaraki.jp", + "omitama.ibaraki.jp", + "ryugasaki.ibaraki.jp", + "sakai.ibaraki.jp", + "sakuragawa.ibaraki.jp", + "shimodate.ibaraki.jp", + "shimotsuma.ibaraki.jp", + "shirosato.ibaraki.jp", + "sowa.ibaraki.jp", + "suifu.ibaraki.jp", + "takahagi.ibaraki.jp", + "tamatsukuri.ibaraki.jp", + "tokai.ibaraki.jp", + "tomobe.ibaraki.jp", + "tone.ibaraki.jp", + "toride.ibaraki.jp", + "tsuchiura.ibaraki.jp", + "tsukuba.ibaraki.jp", + "uchihara.ibaraki.jp", + "ushiku.ibaraki.jp", + "yachiyo.ibaraki.jp", + "yamagata.ibaraki.jp", + "yawara.ibaraki.jp", + "yuki.ibaraki.jp", + "anamizu.ishikawa.jp", + "hakui.ishikawa.jp", + "hakusan.ishikawa.jp", + "kaga.ishikawa.jp", + "kahoku.ishikawa.jp", + "kanazawa.ishikawa.jp", + "kawakita.ishikawa.jp", + "komatsu.ishikawa.jp", + "nakanoto.ishikawa.jp", + "nanao.ishikawa.jp", + "nomi.ishikawa.jp", + "nonoichi.ishikawa.jp", + "noto.ishikawa.jp", + "shika.ishikawa.jp", + "suzu.ishikawa.jp", + "tsubata.ishikawa.jp", + "tsurugi.ishikawa.jp", + "uchinada.ishikawa.jp", + "wajima.ishikawa.jp", + "fudai.iwate.jp", + "fujisawa.iwate.jp", + "hanamaki.iwate.jp", + "hiraizumi.iwate.jp", + "hirono.iwate.jp", + "ichinohe.iwate.jp", + "ichinoseki.iwate.jp", + "iwaizumi.iwate.jp", + "iwate.iwate.jp", + "joboji.iwate.jp", + "kamaishi.iwate.jp", + "kanegasaki.iwate.jp", + "karumai.iwate.jp", + "kawai.iwate.jp", + "kitakami.iwate.jp", + "kuji.iwate.jp", + "kunohe.iwate.jp", + "kuzumaki.iwate.jp", + "miyako.iwate.jp", + "mizusawa.iwate.jp", + "morioka.iwate.jp", + "ninohe.iwate.jp", + "noda.iwate.jp", + "ofunato.iwate.jp", + "oshu.iwate.jp", + "otsuchi.iwate.jp", + "rikuzentakata.iwate.jp", + "shiwa.iwate.jp", + "shizukuishi.iwate.jp", + "sumita.iwate.jp", + "tanohata.iwate.jp", + "tono.iwate.jp", + "yahaba.iwate.jp", + "yamada.iwate.jp", + "ayagawa.kagawa.jp", + "higashikagawa.kagawa.jp", + "kanonji.kagawa.jp", + "kotohira.kagawa.jp", + "manno.kagawa.jp", + "marugame.kagawa.jp", + "mitoyo.kagawa.jp", + "naoshima.kagawa.jp", + "sanuki.kagawa.jp", + "tadotsu.kagawa.jp", + "takamatsu.kagawa.jp", + "tonosho.kagawa.jp", + "uchinomi.kagawa.jp", + "utazu.kagawa.jp", + "zentsuji.kagawa.jp", + "akune.kagoshima.jp", + "amami.kagoshima.jp", + "hioki.kagoshima.jp", + "isa.kagoshima.jp", + "isen.kagoshima.jp", + "izumi.kagoshima.jp", + "kagoshima.kagoshima.jp", + "kanoya.kagoshima.jp", + "kawanabe.kagoshima.jp", + "kinko.kagoshima.jp", + "kouyama.kagoshima.jp", + "makurazaki.kagoshima.jp", + "matsumoto.kagoshima.jp", + "minamitane.kagoshima.jp", + "nakatane.kagoshima.jp", + "nishinoomote.kagoshima.jp", + "satsumasendai.kagoshima.jp", + "soo.kagoshima.jp", + "tarumizu.kagoshima.jp", + "yusui.kagoshima.jp", + "aikawa.kanagawa.jp", + "atsugi.kanagawa.jp", + "ayase.kanagawa.jp", + "chigasaki.kanagawa.jp", + "ebina.kanagawa.jp", + "fujisawa.kanagawa.jp", + "hadano.kanagawa.jp", + "hakone.kanagawa.jp", + "hiratsuka.kanagawa.jp", + "isehara.kanagawa.jp", + "kaisei.kanagawa.jp", + "kamakura.kanagawa.jp", + "kiyokawa.kanagawa.jp", + "matsuda.kanagawa.jp", + "minamiashigara.kanagawa.jp", + "miura.kanagawa.jp", + "nakai.kanagawa.jp", + "ninomiya.kanagawa.jp", + "odawara.kanagawa.jp", + "oi.kanagawa.jp", + "oiso.kanagawa.jp", + "sagamihara.kanagawa.jp", + "samukawa.kanagawa.jp", + "tsukui.kanagawa.jp", + "yamakita.kanagawa.jp", + "yamato.kanagawa.jp", + "yokosuka.kanagawa.jp", + "yugawara.kanagawa.jp", + "zama.kanagawa.jp", + "zushi.kanagawa.jp", + "aki.kochi.jp", + "geisei.kochi.jp", + "hidaka.kochi.jp", + "higashitsuno.kochi.jp", + "ino.kochi.jp", + "kagami.kochi.jp", + "kami.kochi.jp", + "kitagawa.kochi.jp", + "kochi.kochi.jp", + "mihara.kochi.jp", + "motoyama.kochi.jp", + "muroto.kochi.jp", + "nahari.kochi.jp", + "nakamura.kochi.jp", + "nankoku.kochi.jp", + "nishitosa.kochi.jp", + "niyodogawa.kochi.jp", + "ochi.kochi.jp", + "okawa.kochi.jp", + "otoyo.kochi.jp", + "otsuki.kochi.jp", + "sakawa.kochi.jp", + "sukumo.kochi.jp", + "susaki.kochi.jp", + "tosa.kochi.jp", + "tosashimizu.kochi.jp", + "toyo.kochi.jp", + "tsuno.kochi.jp", + "umaji.kochi.jp", + "yasuda.kochi.jp", + "yusuhara.kochi.jp", + "amakusa.kumamoto.jp", + "arao.kumamoto.jp", + "aso.kumamoto.jp", + "choyo.kumamoto.jp", + "gyokuto.kumamoto.jp", + "hitoyoshi.kumamoto.jp", + "kamiamakusa.kumamoto.jp", + "kashima.kumamoto.jp", + "kikuchi.kumamoto.jp", + "kosa.kumamoto.jp", + "kumamoto.kumamoto.jp", + "mashiki.kumamoto.jp", + "mifune.kumamoto.jp", + "minamata.kumamoto.jp", + "minamioguni.kumamoto.jp", + "nagasu.kumamoto.jp", + "nishihara.kumamoto.jp", + "oguni.kumamoto.jp", + "ozu.kumamoto.jp", + "sumoto.kumamoto.jp", + "takamori.kumamoto.jp", + "uki.kumamoto.jp", + "uto.kumamoto.jp", + "yamaga.kumamoto.jp", + "yamato.kumamoto.jp", + "yatsushiro.kumamoto.jp", + "ayabe.kyoto.jp", + "fukuchiyama.kyoto.jp", + "higashiyama.kyoto.jp", + "ide.kyoto.jp", + "ine.kyoto.jp", + "joyo.kyoto.jp", + "kameoka.kyoto.jp", + "kamo.kyoto.jp", + "kita.kyoto.jp", + "kizu.kyoto.jp", + "kumiyama.kyoto.jp", + "kyotamba.kyoto.jp", + "kyotanabe.kyoto.jp", + "kyotango.kyoto.jp", + "maizuru.kyoto.jp", + "minami.kyoto.jp", + "minamiyamashiro.kyoto.jp", + "miyazu.kyoto.jp", + "muko.kyoto.jp", + "nagaokakyo.kyoto.jp", + "nakagyo.kyoto.jp", + "nantan.kyoto.jp", + "oyamazaki.kyoto.jp", + "sakyo.kyoto.jp", + "seika.kyoto.jp", + "tanabe.kyoto.jp", + "uji.kyoto.jp", + "ujitawara.kyoto.jp", + "wazuka.kyoto.jp", + "yamashina.kyoto.jp", + "yawata.kyoto.jp", + "asahi.mie.jp", + "inabe.mie.jp", + "ise.mie.jp", + "kameyama.mie.jp", + "kawagoe.mie.jp", + "kiho.mie.jp", + "kisosaki.mie.jp", + "kiwa.mie.jp", + "komono.mie.jp", + "kumano.mie.jp", + "kuwana.mie.jp", + "matsusaka.mie.jp", + "meiwa.mie.jp", + "mihama.mie.jp", + "minamiise.mie.jp", + "misugi.mie.jp", + "miyama.mie.jp", + "nabari.mie.jp", + "shima.mie.jp", + "suzuka.mie.jp", + "tado.mie.jp", + "taiki.mie.jp", + "taki.mie.jp", + "tamaki.mie.jp", + "toba.mie.jp", + "tsu.mie.jp", + "udono.mie.jp", + "ureshino.mie.jp", + "watarai.mie.jp", + "yokkaichi.mie.jp", + "furukawa.miyagi.jp", + "higashimatsushima.miyagi.jp", + "ishinomaki.miyagi.jp", + "iwanuma.miyagi.jp", + "kakuda.miyagi.jp", + "kami.miyagi.jp", + "kawasaki.miyagi.jp", + "kesennuma.miyagi.jp", + "marumori.miyagi.jp", + "matsushima.miyagi.jp", + "minamisanriku.miyagi.jp", + "misato.miyagi.jp", + "murata.miyagi.jp", + "natori.miyagi.jp", + "ogawara.miyagi.jp", + "ohira.miyagi.jp", + "onagawa.miyagi.jp", + "osaki.miyagi.jp", + "rifu.miyagi.jp", + "semine.miyagi.jp", + "shibata.miyagi.jp", + "shichikashuku.miyagi.jp", + "shikama.miyagi.jp", + "shiogama.miyagi.jp", + "shiroishi.miyagi.jp", + "tagajo.miyagi.jp", + "taiwa.miyagi.jp", + "tome.miyagi.jp", + "tomiya.miyagi.jp", + "wakuya.miyagi.jp", + "watari.miyagi.jp", + "yamamoto.miyagi.jp", + "zao.miyagi.jp", + "aya.miyazaki.jp", + "ebino.miyazaki.jp", + "gokase.miyazaki.jp", + "hyuga.miyazaki.jp", + "kadogawa.miyazaki.jp", + "kawaminami.miyazaki.jp", + "kijo.miyazaki.jp", + "kitagawa.miyazaki.jp", + "kitakata.miyazaki.jp", + "kitaura.miyazaki.jp", + "kobayashi.miyazaki.jp", + "kunitomi.miyazaki.jp", + "kushima.miyazaki.jp", + "mimata.miyazaki.jp", + "miyakonojo.miyazaki.jp", + "miyazaki.miyazaki.jp", + "morotsuka.miyazaki.jp", + "nichinan.miyazaki.jp", + "nishimera.miyazaki.jp", + "nobeoka.miyazaki.jp", + "saito.miyazaki.jp", + "shiiba.miyazaki.jp", + "shintomi.miyazaki.jp", + "takaharu.miyazaki.jp", + "takanabe.miyazaki.jp", + "takazaki.miyazaki.jp", + "tsuno.miyazaki.jp", + "achi.nagano.jp", + "agematsu.nagano.jp", + "anan.nagano.jp", + "aoki.nagano.jp", + "asahi.nagano.jp", + "azumino.nagano.jp", + "chikuhoku.nagano.jp", + "chikuma.nagano.jp", + "chino.nagano.jp", + "fujimi.nagano.jp", + "hakuba.nagano.jp", + "hara.nagano.jp", + "hiraya.nagano.jp", + "iida.nagano.jp", + "iijima.nagano.jp", + "iiyama.nagano.jp", + "iizuna.nagano.jp", + "ikeda.nagano.jp", + "ikusaka.nagano.jp", + "ina.nagano.jp", + "karuizawa.nagano.jp", + "kawakami.nagano.jp", + "kiso.nagano.jp", + "kisofukushima.nagano.jp", + "kitaaiki.nagano.jp", + "komagane.nagano.jp", + "komoro.nagano.jp", + "matsukawa.nagano.jp", + "matsumoto.nagano.jp", + "miasa.nagano.jp", + "minamiaiki.nagano.jp", + "minamimaki.nagano.jp", + "minamiminowa.nagano.jp", + "minowa.nagano.jp", + "miyada.nagano.jp", + "miyota.nagano.jp", + "mochizuki.nagano.jp", + "nagano.nagano.jp", + "nagawa.nagano.jp", + "nagiso.nagano.jp", + "nakagawa.nagano.jp", + "nakano.nagano.jp", + "nozawaonsen.nagano.jp", + "obuse.nagano.jp", + "ogawa.nagano.jp", + "okaya.nagano.jp", + "omachi.nagano.jp", + "omi.nagano.jp", + "ookuwa.nagano.jp", + "ooshika.nagano.jp", + "otaki.nagano.jp", + "otari.nagano.jp", + "sakae.nagano.jp", + "sakaki.nagano.jp", + "saku.nagano.jp", + "sakuho.nagano.jp", + "shimosuwa.nagano.jp", + "shinanomachi.nagano.jp", + "shiojiri.nagano.jp", + "suwa.nagano.jp", + "suzaka.nagano.jp", + "takagi.nagano.jp", + "takamori.nagano.jp", + "takayama.nagano.jp", + "tateshina.nagano.jp", + "tatsuno.nagano.jp", + "togakushi.nagano.jp", + "togura.nagano.jp", + "tomi.nagano.jp", + "ueda.nagano.jp", + "wada.nagano.jp", + "yamagata.nagano.jp", + "yamanouchi.nagano.jp", + "yasaka.nagano.jp", + "yasuoka.nagano.jp", + "chijiwa.nagasaki.jp", + "futsu.nagasaki.jp", + "goto.nagasaki.jp", + "hasami.nagasaki.jp", + "hirado.nagasaki.jp", + "iki.nagasaki.jp", + "isahaya.nagasaki.jp", + "kawatana.nagasaki.jp", + "kuchinotsu.nagasaki.jp", + "matsuura.nagasaki.jp", + "nagasaki.nagasaki.jp", + "obama.nagasaki.jp", + "omura.nagasaki.jp", + "oseto.nagasaki.jp", + "saikai.nagasaki.jp", + "sasebo.nagasaki.jp", + "seihi.nagasaki.jp", + "shimabara.nagasaki.jp", + "shinkamigoto.nagasaki.jp", + "togitsu.nagasaki.jp", + "tsushima.nagasaki.jp", + "unzen.nagasaki.jp", + "ando.nara.jp", + "gose.nara.jp", + "heguri.nara.jp", + "higashiyoshino.nara.jp", + "ikaruga.nara.jp", + "ikoma.nara.jp", + "kamikitayama.nara.jp", + "kanmaki.nara.jp", + "kashiba.nara.jp", + "kashihara.nara.jp", + "katsuragi.nara.jp", + "kawai.nara.jp", + "kawakami.nara.jp", + "kawanishi.nara.jp", + "koryo.nara.jp", + "kurotaki.nara.jp", + "mitsue.nara.jp", + "miyake.nara.jp", + "nara.nara.jp", + "nosegawa.nara.jp", + "oji.nara.jp", + "ouda.nara.jp", + "oyodo.nara.jp", + "sakurai.nara.jp", + "sango.nara.jp", + "shimoichi.nara.jp", + "shimokitayama.nara.jp", + "shinjo.nara.jp", + "soni.nara.jp", + "takatori.nara.jp", + "tawaramoto.nara.jp", + "tenkawa.nara.jp", + "tenri.nara.jp", + "uda.nara.jp", + "yamatokoriyama.nara.jp", + "yamatotakada.nara.jp", + "yamazoe.nara.jp", + "yoshino.nara.jp", + "aga.niigata.jp", + "agano.niigata.jp", + "gosen.niigata.jp", + "itoigawa.niigata.jp", + "izumozaki.niigata.jp", + "joetsu.niigata.jp", + "kamo.niigata.jp", + "kariwa.niigata.jp", + "kashiwazaki.niigata.jp", + "minamiuonuma.niigata.jp", + "mitsuke.niigata.jp", + "muika.niigata.jp", + "murakami.niigata.jp", + "myoko.niigata.jp", + "nagaoka.niigata.jp", + "niigata.niigata.jp", + "ojiya.niigata.jp", + "omi.niigata.jp", + "sado.niigata.jp", + "sanjo.niigata.jp", + "seiro.niigata.jp", + "seirou.niigata.jp", + "sekikawa.niigata.jp", + "shibata.niigata.jp", + "tagami.niigata.jp", + "tainai.niigata.jp", + "tochio.niigata.jp", + "tokamachi.niigata.jp", + "tsubame.niigata.jp", + "tsunan.niigata.jp", + "uonuma.niigata.jp", + "yahiko.niigata.jp", + "yoita.niigata.jp", + "yuzawa.niigata.jp", + "beppu.oita.jp", + "bungoono.oita.jp", + "bungotakada.oita.jp", + "hasama.oita.jp", + "hiji.oita.jp", + "himeshima.oita.jp", + "hita.oita.jp", + "kamitsue.oita.jp", + "kokonoe.oita.jp", + "kuju.oita.jp", + "kunisaki.oita.jp", + "kusu.oita.jp", + "oita.oita.jp", + "saiki.oita.jp", + "taketa.oita.jp", + "tsukumi.oita.jp", + "usa.oita.jp", + "usuki.oita.jp", + "yufu.oita.jp", + "akaiwa.okayama.jp", + "asakuchi.okayama.jp", + "bizen.okayama.jp", + "hayashima.okayama.jp", + "ibara.okayama.jp", + "kagamino.okayama.jp", + "kasaoka.okayama.jp", + "kibichuo.okayama.jp", + "kumenan.okayama.jp", + "kurashiki.okayama.jp", + "maniwa.okayama.jp", + "misaki.okayama.jp", + "nagi.okayama.jp", + "niimi.okayama.jp", + "nishiawakura.okayama.jp", + "okayama.okayama.jp", + "satosho.okayama.jp", + "setouchi.okayama.jp", + "shinjo.okayama.jp", + "shoo.okayama.jp", + "soja.okayama.jp", + "takahashi.okayama.jp", + "tamano.okayama.jp", + "tsuyama.okayama.jp", + "wake.okayama.jp", + "yakage.okayama.jp", + "aguni.okinawa.jp", + "ginowan.okinawa.jp", + "ginoza.okinawa.jp", + "gushikami.okinawa.jp", + "haebaru.okinawa.jp", + "higashi.okinawa.jp", + "hirara.okinawa.jp", + "iheya.okinawa.jp", + "ishigaki.okinawa.jp", + "ishikawa.okinawa.jp", + "itoman.okinawa.jp", + "izena.okinawa.jp", + "kadena.okinawa.jp", + "kin.okinawa.jp", + "kitadaito.okinawa.jp", + "kitanakagusuku.okinawa.jp", + "kumejima.okinawa.jp", + "kunigami.okinawa.jp", + "minamidaito.okinawa.jp", + "motobu.okinawa.jp", + "nago.okinawa.jp", + "naha.okinawa.jp", + "nakagusuku.okinawa.jp", + "nakijin.okinawa.jp", + "nanjo.okinawa.jp", + "nishihara.okinawa.jp", + "ogimi.okinawa.jp", + "okinawa.okinawa.jp", + "onna.okinawa.jp", + "shimoji.okinawa.jp", + "taketomi.okinawa.jp", + "tarama.okinawa.jp", + "tokashiki.okinawa.jp", + "tomigusuku.okinawa.jp", + "tonaki.okinawa.jp", + "urasoe.okinawa.jp", + "uruma.okinawa.jp", + "yaese.okinawa.jp", + "yomitan.okinawa.jp", + "yonabaru.okinawa.jp", + "yonaguni.okinawa.jp", + "zamami.okinawa.jp", + "abeno.osaka.jp", + "chihayaakasaka.osaka.jp", + "chuo.osaka.jp", + "daito.osaka.jp", + "fujiidera.osaka.jp", + "habikino.osaka.jp", + "hannan.osaka.jp", + "higashiosaka.osaka.jp", + "higashisumiyoshi.osaka.jp", + "higashiyodogawa.osaka.jp", + "hirakata.osaka.jp", + "ibaraki.osaka.jp", + "ikeda.osaka.jp", + "izumi.osaka.jp", + "izumiotsu.osaka.jp", + "izumisano.osaka.jp", + "kadoma.osaka.jp", + "kaizuka.osaka.jp", + "kanan.osaka.jp", + "kashiwara.osaka.jp", + "katano.osaka.jp", + "kawachinagano.osaka.jp", + "kishiwada.osaka.jp", + "kita.osaka.jp", + "kumatori.osaka.jp", + "matsubara.osaka.jp", + "minato.osaka.jp", + "minoh.osaka.jp", + "misaki.osaka.jp", + "moriguchi.osaka.jp", + "neyagawa.osaka.jp", + "nishi.osaka.jp", + "nose.osaka.jp", + "osakasayama.osaka.jp", + "sakai.osaka.jp", + "sayama.osaka.jp", + "sennan.osaka.jp", + "settsu.osaka.jp", + "shijonawate.osaka.jp", + "shimamoto.osaka.jp", + "suita.osaka.jp", + "tadaoka.osaka.jp", + "taishi.osaka.jp", + "tajiri.osaka.jp", + "takaishi.osaka.jp", + "takatsuki.osaka.jp", + "tondabayashi.osaka.jp", + "toyonaka.osaka.jp", + "toyono.osaka.jp", + "yao.osaka.jp", + "ariake.saga.jp", + "arita.saga.jp", + "fukudomi.saga.jp", + "genkai.saga.jp", + "hamatama.saga.jp", + "hizen.saga.jp", + "imari.saga.jp", + "kamimine.saga.jp", + "kanzaki.saga.jp", + "karatsu.saga.jp", + "kashima.saga.jp", + "kitagata.saga.jp", + "kitahata.saga.jp", + "kiyama.saga.jp", + "kouhoku.saga.jp", + "kyuragi.saga.jp", + "nishiarita.saga.jp", + "ogi.saga.jp", + "omachi.saga.jp", + "ouchi.saga.jp", + "saga.saga.jp", + "shiroishi.saga.jp", + "taku.saga.jp", + "tara.saga.jp", + "tosu.saga.jp", + "yoshinogari.saga.jp", + "arakawa.saitama.jp", + "asaka.saitama.jp", + "chichibu.saitama.jp", + "fujimi.saitama.jp", + "fujimino.saitama.jp", + "fukaya.saitama.jp", + "hanno.saitama.jp", + "hanyu.saitama.jp", + "hasuda.saitama.jp", + "hatogaya.saitama.jp", + "hatoyama.saitama.jp", + "hidaka.saitama.jp", + "higashichichibu.saitama.jp", + "higashimatsuyama.saitama.jp", + "honjo.saitama.jp", + "ina.saitama.jp", + "iruma.saitama.jp", + "iwatsuki.saitama.jp", + "kamiizumi.saitama.jp", + "kamikawa.saitama.jp", + "kamisato.saitama.jp", + "kasukabe.saitama.jp", + "kawagoe.saitama.jp", + "kawaguchi.saitama.jp", + "kawajima.saitama.jp", + "kazo.saitama.jp", + "kitamoto.saitama.jp", + "koshigaya.saitama.jp", + "kounosu.saitama.jp", + "kuki.saitama.jp", + "kumagaya.saitama.jp", + "matsubushi.saitama.jp", + "minano.saitama.jp", + "misato.saitama.jp", + "miyashiro.saitama.jp", + "miyoshi.saitama.jp", + "moroyama.saitama.jp", + "nagatoro.saitama.jp", + "namegawa.saitama.jp", + "niiza.saitama.jp", + "ogano.saitama.jp", + "ogawa.saitama.jp", + "ogose.saitama.jp", + "okegawa.saitama.jp", + "omiya.saitama.jp", + "otaki.saitama.jp", + "ranzan.saitama.jp", + "ryokami.saitama.jp", + "saitama.saitama.jp", + "sakado.saitama.jp", + "satte.saitama.jp", + "sayama.saitama.jp", + "shiki.saitama.jp", + "shiraoka.saitama.jp", + "soka.saitama.jp", + "sugito.saitama.jp", + "toda.saitama.jp", + "tokigawa.saitama.jp", + "tokorozawa.saitama.jp", + "tsurugashima.saitama.jp", + "urawa.saitama.jp", + "warabi.saitama.jp", + "yashio.saitama.jp", + "yokoze.saitama.jp", + "yono.saitama.jp", + "yorii.saitama.jp", + "yoshida.saitama.jp", + "yoshikawa.saitama.jp", + "yoshimi.saitama.jp", + "aisho.shiga.jp", + "gamo.shiga.jp", + "higashiomi.shiga.jp", + "hikone.shiga.jp", + "koka.shiga.jp", + "konan.shiga.jp", + "kosei.shiga.jp", + "koto.shiga.jp", + "kusatsu.shiga.jp", + "maibara.shiga.jp", + "moriyama.shiga.jp", + "nagahama.shiga.jp", + "nishiazai.shiga.jp", + "notogawa.shiga.jp", + "omihachiman.shiga.jp", + "otsu.shiga.jp", + "ritto.shiga.jp", + "ryuoh.shiga.jp", + "takashima.shiga.jp", + "takatsuki.shiga.jp", + "torahime.shiga.jp", + "toyosato.shiga.jp", + "yasu.shiga.jp", + "akagi.shimane.jp", + "ama.shimane.jp", + "gotsu.shimane.jp", + "hamada.shimane.jp", + "higashiizumo.shimane.jp", + "hikawa.shimane.jp", + "hikimi.shimane.jp", + "izumo.shimane.jp", + "kakinoki.shimane.jp", + "masuda.shimane.jp", + "matsue.shimane.jp", + "misato.shimane.jp", + "nishinoshima.shimane.jp", + "ohda.shimane.jp", + "okinoshima.shimane.jp", + "okuizumo.shimane.jp", + "shimane.shimane.jp", + "tamayu.shimane.jp", + "tsuwano.shimane.jp", + "unnan.shimane.jp", + "yakumo.shimane.jp", + "yasugi.shimane.jp", + "yatsuka.shimane.jp", + "arai.shizuoka.jp", + "atami.shizuoka.jp", + "fuji.shizuoka.jp", + "fujieda.shizuoka.jp", + "fujikawa.shizuoka.jp", + "fujinomiya.shizuoka.jp", + "fukuroi.shizuoka.jp", + "gotemba.shizuoka.jp", + "haibara.shizuoka.jp", + "hamamatsu.shizuoka.jp", + "higashiizu.shizuoka.jp", + "ito.shizuoka.jp", + "iwata.shizuoka.jp", + "izu.shizuoka.jp", + "izunokuni.shizuoka.jp", + "kakegawa.shizuoka.jp", + "kannami.shizuoka.jp", + "kawanehon.shizuoka.jp", + "kawazu.shizuoka.jp", + "kikugawa.shizuoka.jp", + "kosai.shizuoka.jp", + "makinohara.shizuoka.jp", + "matsuzaki.shizuoka.jp", + "minamiizu.shizuoka.jp", + "mishima.shizuoka.jp", + "morimachi.shizuoka.jp", + "nishiizu.shizuoka.jp", + "numazu.shizuoka.jp", + "omaezaki.shizuoka.jp", + "shimada.shizuoka.jp", + "shimizu.shizuoka.jp", + "shimoda.shizuoka.jp", + "shizuoka.shizuoka.jp", + "susono.shizuoka.jp", + "yaizu.shizuoka.jp", + "yoshida.shizuoka.jp", + "ashikaga.tochigi.jp", + "bato.tochigi.jp", + "haga.tochigi.jp", + "ichikai.tochigi.jp", + "iwafune.tochigi.jp", + "kaminokawa.tochigi.jp", + "kanuma.tochigi.jp", + "karasuyama.tochigi.jp", + "kuroiso.tochigi.jp", + "mashiko.tochigi.jp", + "mibu.tochigi.jp", + "moka.tochigi.jp", + "motegi.tochigi.jp", + "nasu.tochigi.jp", + "nasushiobara.tochigi.jp", + "nikko.tochigi.jp", + "nishikata.tochigi.jp", + "nogi.tochigi.jp", + "ohira.tochigi.jp", + "ohtawara.tochigi.jp", + "oyama.tochigi.jp", + "sakura.tochigi.jp", + "sano.tochigi.jp", + "shimotsuke.tochigi.jp", + "shioya.tochigi.jp", + "takanezawa.tochigi.jp", + "tochigi.tochigi.jp", + "tsuga.tochigi.jp", + "ujiie.tochigi.jp", + "utsunomiya.tochigi.jp", + "yaita.tochigi.jp", + "aizumi.tokushima.jp", + "anan.tokushima.jp", + "ichiba.tokushima.jp", + "itano.tokushima.jp", + "kainan.tokushima.jp", + "komatsushima.tokushima.jp", + "matsushige.tokushima.jp", + "mima.tokushima.jp", + "minami.tokushima.jp", + "miyoshi.tokushima.jp", + "mugi.tokushima.jp", + "nakagawa.tokushima.jp", + "naruto.tokushima.jp", + "sanagochi.tokushima.jp", + "shishikui.tokushima.jp", + "tokushima.tokushima.jp", + "wajiki.tokushima.jp", + "adachi.tokyo.jp", + "akiruno.tokyo.jp", + "akishima.tokyo.jp", + "aogashima.tokyo.jp", + "arakawa.tokyo.jp", + "bunkyo.tokyo.jp", + "chiyoda.tokyo.jp", + "chofu.tokyo.jp", + "chuo.tokyo.jp", + "edogawa.tokyo.jp", + "fuchu.tokyo.jp", + "fussa.tokyo.jp", + "hachijo.tokyo.jp", + "hachioji.tokyo.jp", + "hamura.tokyo.jp", + "higashikurume.tokyo.jp", + "higashimurayama.tokyo.jp", + "higashiyamato.tokyo.jp", + "hino.tokyo.jp", + "hinode.tokyo.jp", + "hinohara.tokyo.jp", + "inagi.tokyo.jp", + "itabashi.tokyo.jp", + "katsushika.tokyo.jp", + "kita.tokyo.jp", + "kiyose.tokyo.jp", + "kodaira.tokyo.jp", + "koganei.tokyo.jp", + "kokubunji.tokyo.jp", + "komae.tokyo.jp", + "koto.tokyo.jp", + "kouzushima.tokyo.jp", + "kunitachi.tokyo.jp", + "machida.tokyo.jp", + "meguro.tokyo.jp", + "minato.tokyo.jp", + "mitaka.tokyo.jp", + "mizuho.tokyo.jp", + "musashimurayama.tokyo.jp", + "musashino.tokyo.jp", + "nakano.tokyo.jp", + "nerima.tokyo.jp", + "ogasawara.tokyo.jp", + "okutama.tokyo.jp", + "ome.tokyo.jp", + "oshima.tokyo.jp", + "ota.tokyo.jp", + "setagaya.tokyo.jp", + "shibuya.tokyo.jp", + "shinagawa.tokyo.jp", + "shinjuku.tokyo.jp", + "suginami.tokyo.jp", + "sumida.tokyo.jp", + "tachikawa.tokyo.jp", + "taito.tokyo.jp", + "tama.tokyo.jp", + "toshima.tokyo.jp", + "chizu.tottori.jp", + "hino.tottori.jp", + "kawahara.tottori.jp", + "koge.tottori.jp", + "kotoura.tottori.jp", + "misasa.tottori.jp", + "nanbu.tottori.jp", + "nichinan.tottori.jp", + "sakaiminato.tottori.jp", + "tottori.tottori.jp", + "wakasa.tottori.jp", + "yazu.tottori.jp", + "yonago.tottori.jp", + "asahi.toyama.jp", + "fuchu.toyama.jp", + "fukumitsu.toyama.jp", + "funahashi.toyama.jp", + "himi.toyama.jp", + "imizu.toyama.jp", + "inami.toyama.jp", + "johana.toyama.jp", + "kamiichi.toyama.jp", + "kurobe.toyama.jp", + "nakaniikawa.toyama.jp", + "namerikawa.toyama.jp", + "nanto.toyama.jp", + "nyuzen.toyama.jp", + "oyabe.toyama.jp", + "taira.toyama.jp", + "takaoka.toyama.jp", + "tateyama.toyama.jp", + "toga.toyama.jp", + "tonami.toyama.jp", + "toyama.toyama.jp", + "unazuki.toyama.jp", + "uozu.toyama.jp", + "yamada.toyama.jp", + "arida.wakayama.jp", + "aridagawa.wakayama.jp", + "gobo.wakayama.jp", + "hashimoto.wakayama.jp", + "hidaka.wakayama.jp", + "hirogawa.wakayama.jp", + "inami.wakayama.jp", + "iwade.wakayama.jp", + "kainan.wakayama.jp", + "kamitonda.wakayama.jp", + "katsuragi.wakayama.jp", + "kimino.wakayama.jp", + "kinokawa.wakayama.jp", + "kitayama.wakayama.jp", + "koya.wakayama.jp", + "koza.wakayama.jp", + "kozagawa.wakayama.jp", + "kudoyama.wakayama.jp", + "kushimoto.wakayama.jp", + "mihama.wakayama.jp", + "misato.wakayama.jp", + "nachikatsuura.wakayama.jp", + "shingu.wakayama.jp", + "shirahama.wakayama.jp", + "taiji.wakayama.jp", + "tanabe.wakayama.jp", + "wakayama.wakayama.jp", + "yuasa.wakayama.jp", + "yura.wakayama.jp", + "asahi.yamagata.jp", + "funagata.yamagata.jp", + "higashine.yamagata.jp", + "iide.yamagata.jp", + "kahoku.yamagata.jp", + "kaminoyama.yamagata.jp", + "kaneyama.yamagata.jp", + "kawanishi.yamagata.jp", + "mamurogawa.yamagata.jp", + "mikawa.yamagata.jp", + "murayama.yamagata.jp", + "nagai.yamagata.jp", + "nakayama.yamagata.jp", + "nanyo.yamagata.jp", + "nishikawa.yamagata.jp", + "obanazawa.yamagata.jp", + "oe.yamagata.jp", + "oguni.yamagata.jp", + "ohkura.yamagata.jp", + "oishida.yamagata.jp", + "sagae.yamagata.jp", + "sakata.yamagata.jp", + "sakegawa.yamagata.jp", + "shinjo.yamagata.jp", + "shirataka.yamagata.jp", + "shonai.yamagata.jp", + "takahata.yamagata.jp", + "tendo.yamagata.jp", + "tozawa.yamagata.jp", + "tsuruoka.yamagata.jp", + "yamagata.yamagata.jp", + "yamanobe.yamagata.jp", + "yonezawa.yamagata.jp", + "yuza.yamagata.jp", + "abu.yamaguchi.jp", + "hagi.yamaguchi.jp", + "hikari.yamaguchi.jp", + "hofu.yamaguchi.jp", + "iwakuni.yamaguchi.jp", + "kudamatsu.yamaguchi.jp", + "mitou.yamaguchi.jp", + "nagato.yamaguchi.jp", + "oshima.yamaguchi.jp", + "shimonoseki.yamaguchi.jp", + "shunan.yamaguchi.jp", + "tabuse.yamaguchi.jp", + "tokuyama.yamaguchi.jp", + "toyota.yamaguchi.jp", + "ube.yamaguchi.jp", + "yuu.yamaguchi.jp", + "chuo.yamanashi.jp", + "doshi.yamanashi.jp", + "fuefuki.yamanashi.jp", + "fujikawa.yamanashi.jp", + "fujikawaguchiko.yamanashi.jp", + "fujiyoshida.yamanashi.jp", + "hayakawa.yamanashi.jp", + "hokuto.yamanashi.jp", + "ichikawamisato.yamanashi.jp", + "kai.yamanashi.jp", + "kofu.yamanashi.jp", + "koshu.yamanashi.jp", + "kosuge.yamanashi.jp", + "minami-alps.yamanashi.jp", + "minobu.yamanashi.jp", + "nakamichi.yamanashi.jp", + "nanbu.yamanashi.jp", + "narusawa.yamanashi.jp", + "nirasaki.yamanashi.jp", + "nishikatsura.yamanashi.jp", + "oshino.yamanashi.jp", + "otsuki.yamanashi.jp", + "showa.yamanashi.jp", + "tabayama.yamanashi.jp", + "tsuru.yamanashi.jp", + "uenohara.yamanashi.jp", + "yamanakako.yamanashi.jp", + "yamanashi.yamanashi.jp", + "*.ke", + "kg", + "org.kg", + "net.kg", + "com.kg", + "edu.kg", + "gov.kg", + "mil.kg", + "*.kh", + "ki", + "edu.ki", + "biz.ki", + "net.ki", + "org.ki", + "gov.ki", + "info.ki", + "com.ki", + "km", + "org.km", + "nom.km", + "gov.km", + "prd.km", + "tm.km", + "edu.km", + "mil.km", + "ass.km", + "com.km", + "coop.km", + "asso.km", + "presse.km", + "medecin.km", + "notaires.km", + "pharmaciens.km", + "veterinaire.km", + "gouv.km", + "kn", + "net.kn", + "org.kn", + "edu.kn", + "gov.kn", + "kp", + "com.kp", + "edu.kp", + "gov.kp", + "org.kp", + "rep.kp", + "tra.kp", + "kr", + "ac.kr", + "co.kr", + "es.kr", + "go.kr", + "hs.kr", + "kg.kr", + "mil.kr", + "ms.kr", + "ne.kr", + "or.kr", + "pe.kr", + "re.kr", + "sc.kr", + "busan.kr", + "chungbuk.kr", + "chungnam.kr", + "daegu.kr", + "daejeon.kr", + "gangwon.kr", + "gwangju.kr", + "gyeongbuk.kr", + "gyeonggi.kr", + "gyeongnam.kr", + "incheon.kr", + "jeju.kr", + "jeonbuk.kr", + "jeonnam.kr", + "seoul.kr", + "ulsan.kr", + "*.kw", + "ky", + "edu.ky", + "gov.ky", + "com.ky", + "org.ky", + "net.ky", + "kz", + "org.kz", + "edu.kz", + "net.kz", + "gov.kz", + "mil.kz", + "com.kz", + "la", + "int.la", + "net.la", + "info.la", + "edu.la", + "gov.la", + "per.la", + "com.la", + "org.la", + "lb", + "com.lb", + "edu.lb", + "gov.lb", + "net.lb", + "org.lb", + "lc", + "com.lc", + "net.lc", + "co.lc", + "org.lc", + "edu.lc", + "gov.lc", + "li", + "lk", + "gov.lk", + "sch.lk", + "net.lk", + "int.lk", + "com.lk", + "org.lk", + "edu.lk", + "ngo.lk", + "soc.lk", + "web.lk", + "ltd.lk", + "assn.lk", + "grp.lk", + "hotel.lk", + "ac.lk", + "lr", + "com.lr", + "edu.lr", + "gov.lr", + "org.lr", + "net.lr", + "ls", + "co.ls", + "org.ls", + "lt", + "gov.lt", + "lu", + "lv", + "com.lv", + "edu.lv", + "gov.lv", + "org.lv", + "mil.lv", + "id.lv", + "net.lv", + "asn.lv", + "conf.lv", + "ly", + "com.ly", + "net.ly", + "gov.ly", + "plc.ly", + "edu.ly", + "sch.ly", + "med.ly", + "org.ly", + "id.ly", + "ma", + "co.ma", + "net.ma", + "gov.ma", + "org.ma", + "ac.ma", + "press.ma", + "mc", + "tm.mc", + "asso.mc", + "md", + "me", + "co.me", + "net.me", + "org.me", + "edu.me", + "ac.me", + "gov.me", + "its.me", + "priv.me", + "mg", + "org.mg", + "nom.mg", + "gov.mg", + "prd.mg", + "tm.mg", + "edu.mg", + "mil.mg", + "com.mg", + "co.mg", + "mh", + "mil", + "mk", + "com.mk", + "org.mk", + "net.mk", + "edu.mk", + "gov.mk", + "inf.mk", + "name.mk", + "ml", + "com.ml", + "edu.ml", + "gouv.ml", + "gov.ml", + "net.ml", + "org.ml", + "presse.ml", + "*.mm", + "mn", + "gov.mn", + "edu.mn", + "org.mn", + "mo", + "com.mo", + "net.mo", + "org.mo", + "edu.mo", + "gov.mo", + "mobi", + "mp", + "mq", + "mr", + "gov.mr", + "ms", + "com.ms", + "edu.ms", + "gov.ms", + "net.ms", + "org.ms", + "mt", + "com.mt", + "edu.mt", + "net.mt", + "org.mt", + "mu", + "com.mu", + "net.mu", + "org.mu", + "gov.mu", + "ac.mu", + "co.mu", + "or.mu", + "museum", + "academy.museum", + "agriculture.museum", + "air.museum", + "airguard.museum", + "alabama.museum", + "alaska.museum", + "amber.museum", + "ambulance.museum", + "american.museum", + "americana.museum", + "americanantiques.museum", + "americanart.museum", + "amsterdam.museum", + "and.museum", + "annefrank.museum", + "anthro.museum", + "anthropology.museum", + "antiques.museum", + "aquarium.museum", + "arboretum.museum", + "archaeological.museum", + "archaeology.museum", + "architecture.museum", + "art.museum", + "artanddesign.museum", + "artcenter.museum", + "artdeco.museum", + "arteducation.museum", + "artgallery.museum", + "arts.museum", + "artsandcrafts.museum", + "asmatart.museum", + "assassination.museum", + "assisi.museum", + "association.museum", + "astronomy.museum", + "atlanta.museum", + "austin.museum", + "australia.museum", + "automotive.museum", + "aviation.museum", + "axis.museum", + "badajoz.museum", + "baghdad.museum", + "bahn.museum", + "bale.museum", + "baltimore.museum", + "barcelona.museum", + "baseball.museum", + "basel.museum", + "baths.museum", + "bauern.museum", + "beauxarts.museum", + "beeldengeluid.museum", + "bellevue.museum", + "bergbau.museum", + "berkeley.museum", + "berlin.museum", + "bern.museum", + "bible.museum", + "bilbao.museum", + "bill.museum", + "birdart.museum", + "birthplace.museum", + "bonn.museum", + "boston.museum", + "botanical.museum", + "botanicalgarden.museum", + "botanicgarden.museum", + "botany.museum", + "brandywinevalley.museum", + "brasil.museum", + "bristol.museum", + "british.museum", + "britishcolumbia.museum", + "broadcast.museum", + "brunel.museum", + "brussel.museum", + "brussels.museum", + "bruxelles.museum", + "building.museum", + "burghof.museum", + "bus.museum", + "bushey.museum", + "cadaques.museum", + "california.museum", + "cambridge.museum", + "can.museum", + "canada.museum", + "capebreton.museum", + "carrier.museum", + "cartoonart.museum", + "casadelamoneda.museum", + "castle.museum", + "castres.museum", + "celtic.museum", + "center.museum", + "chattanooga.museum", + "cheltenham.museum", + "chesapeakebay.museum", + "chicago.museum", + "children.museum", + "childrens.museum", + "childrensgarden.museum", + "chiropractic.museum", + "chocolate.museum", + "christiansburg.museum", + "cincinnati.museum", + "cinema.museum", + "circus.museum", + "civilisation.museum", + "civilization.museum", + "civilwar.museum", + "clinton.museum", + "clock.museum", + "coal.museum", + "coastaldefence.museum", + "cody.museum", + "coldwar.museum", + "collection.museum", + "colonialwilliamsburg.museum", + "coloradoplateau.museum", + "columbia.museum", + "columbus.museum", + "communication.museum", + "communications.museum", + "community.museum", + "computer.museum", + "computerhistory.museum", + "xn--comunicaes-v6a2o.museum", + "contemporary.museum", + "contemporaryart.museum", + "convent.museum", + "copenhagen.museum", + "corporation.museum", + "xn--correios-e-telecomunicaes-ghc29a.museum", + "corvette.museum", + "costume.museum", + "countryestate.museum", + "county.museum", + "crafts.museum", + "cranbrook.museum", + "creation.museum", + "cultural.museum", + "culturalcenter.museum", + "culture.museum", + "cyber.museum", + "cymru.museum", + "dali.museum", + "dallas.museum", + "database.museum", + "ddr.museum", + "decorativearts.museum", + "delaware.museum", + "delmenhorst.museum", + "denmark.museum", + "depot.museum", + "design.museum", + "detroit.museum", + "dinosaur.museum", + "discovery.museum", + "dolls.museum", + "donostia.museum", + "durham.museum", + "eastafrica.museum", + "eastcoast.museum", + "education.museum", + "educational.museum", + "egyptian.museum", + "eisenbahn.museum", + "elburg.museum", + "elvendrell.museum", + "embroidery.museum", + "encyclopedic.museum", + "england.museum", + "entomology.museum", + "environment.museum", + "environmentalconservation.museum", + "epilepsy.museum", + "essex.museum", + "estate.museum", + "ethnology.museum", + "exeter.museum", + "exhibition.museum", + "family.museum", + "farm.museum", + "farmequipment.museum", + "farmers.museum", + "farmstead.museum", + "field.museum", + "figueres.museum", + "filatelia.museum", + "film.museum", + "fineart.museum", + "finearts.museum", + "finland.museum", + "flanders.museum", + "florida.museum", + "force.museum", + "fortmissoula.museum", + "fortworth.museum", + "foundation.museum", + "francaise.museum", + "frankfurt.museum", + "franziskaner.museum", + "freemasonry.museum", + "freiburg.museum", + "fribourg.museum", + "frog.museum", + "fundacio.museum", + "furniture.museum", + "gallery.museum", + "garden.museum", + "gateway.museum", + "geelvinck.museum", + "gemological.museum", + "geology.museum", + "georgia.museum", + "giessen.museum", + "glas.museum", + "glass.museum", + "gorge.museum", + "grandrapids.museum", + "graz.museum", + "guernsey.museum", + "halloffame.museum", + "hamburg.museum", + "handson.museum", + "harvestcelebration.museum", + "hawaii.museum", + "health.museum", + "heimatunduhren.museum", + "hellas.museum", + "helsinki.museum", + "hembygdsforbund.museum", + "heritage.museum", + "histoire.museum", + "historical.museum", + "historicalsociety.museum", + "historichouses.museum", + "historisch.museum", + "historisches.museum", + "history.museum", + "historyofscience.museum", + "horology.museum", + "house.museum", + "humanities.museum", + "illustration.museum", + "imageandsound.museum", + "indian.museum", + "indiana.museum", + "indianapolis.museum", + "indianmarket.museum", + "intelligence.museum", + "interactive.museum", + "iraq.museum", + "iron.museum", + "isleofman.museum", + "jamison.museum", + "jefferson.museum", + "jerusalem.museum", + "jewelry.museum", + "jewish.museum", + "jewishart.museum", + "jfk.museum", + "journalism.museum", + "judaica.museum", + "judygarland.museum", + "juedisches.museum", + "juif.museum", + "karate.museum", + "karikatur.museum", + "kids.museum", + "koebenhavn.museum", + "koeln.museum", + "kunst.museum", + "kunstsammlung.museum", + "kunstunddesign.museum", + "labor.museum", + "labour.museum", + "lajolla.museum", + "lancashire.museum", + "landes.museum", + "lans.museum", + "xn--lns-qla.museum", + "larsson.museum", + "lewismiller.museum", + "lincoln.museum", + "linz.museum", + "living.museum", + "livinghistory.museum", + "localhistory.museum", + "london.museum", + "losangeles.museum", + "louvre.museum", + "loyalist.museum", + "lucerne.museum", + "luxembourg.museum", + "luzern.museum", + "mad.museum", + "madrid.museum", + "mallorca.museum", + "manchester.museum", + "mansion.museum", + "mansions.museum", + "manx.museum", + "marburg.museum", + "maritime.museum", + "maritimo.museum", + "maryland.museum", + "marylhurst.museum", + "media.museum", + "medical.museum", + "medizinhistorisches.museum", + "meeres.museum", + "memorial.museum", + "mesaverde.museum", + "michigan.museum", + "midatlantic.museum", + "military.museum", + "mill.museum", + "miners.museum", + "mining.museum", + "minnesota.museum", + "missile.museum", + "missoula.museum", + "modern.museum", + "moma.museum", + "money.museum", + "monmouth.museum", + "monticello.museum", + "montreal.museum", + "moscow.museum", + "motorcycle.museum", + "muenchen.museum", + "muenster.museum", + "mulhouse.museum", + "muncie.museum", + "museet.museum", + "museumcenter.museum", + "museumvereniging.museum", + "music.museum", + "national.museum", + "nationalfirearms.museum", + "nationalheritage.museum", + "nativeamerican.museum", + "naturalhistory.museum", + "naturalhistorymuseum.museum", + "naturalsciences.museum", + "nature.museum", + "naturhistorisches.museum", + "natuurwetenschappen.museum", + "naumburg.museum", + "naval.museum", + "nebraska.museum", + "neues.museum", + "newhampshire.museum", + "newjersey.museum", + "newmexico.museum", + "newport.museum", + "newspaper.museum", + "newyork.museum", + "niepce.museum", + "norfolk.museum", + "north.museum", + "nrw.museum", + "nuernberg.museum", + "nuremberg.museum", + "nyc.museum", + "nyny.museum", + "oceanographic.museum", + "oceanographique.museum", + "omaha.museum", + "online.museum", + "ontario.museum", + "openair.museum", + "oregon.museum", + "oregontrail.museum", + "otago.museum", + "oxford.museum", + "pacific.museum", + "paderborn.museum", + "palace.museum", + "paleo.museum", + "palmsprings.museum", + "panama.museum", + "paris.museum", + "pasadena.museum", + "pharmacy.museum", + "philadelphia.museum", + "philadelphiaarea.museum", + "philately.museum", + "phoenix.museum", + "photography.museum", + "pilots.museum", + "pittsburgh.museum", + "planetarium.museum", + "plantation.museum", + "plants.museum", + "plaza.museum", + "portal.museum", + "portland.museum", + "portlligat.museum", + "posts-and-telecommunications.museum", + "preservation.museum", + "presidio.museum", + "press.museum", + "project.museum", + "public.museum", + "pubol.museum", + "quebec.museum", + "railroad.museum", + "railway.museum", + "research.museum", + "resistance.museum", + "riodejaneiro.museum", + "rochester.museum", + "rockart.museum", + "roma.museum", + "russia.museum", + "saintlouis.museum", + "salem.museum", + "salvadordali.museum", + "salzburg.museum", + "sandiego.museum", + "sanfrancisco.museum", + "santabarbara.museum", + "santacruz.museum", + "santafe.museum", + "saskatchewan.museum", + "satx.museum", + "savannahga.museum", + "schlesisches.museum", + "schoenbrunn.museum", + "schokoladen.museum", + "school.museum", + "schweiz.museum", + "science.museum", + "scienceandhistory.museum", + "scienceandindustry.museum", + "sciencecenter.museum", + "sciencecenters.museum", + "science-fiction.museum", + "sciencehistory.museum", + "sciences.museum", + "sciencesnaturelles.museum", + "scotland.museum", + "seaport.museum", + "settlement.museum", + "settlers.museum", + "shell.museum", + "sherbrooke.museum", + "sibenik.museum", + "silk.museum", + "ski.museum", + "skole.museum", + "society.museum", + "sologne.museum", + "soundandvision.museum", + "southcarolina.museum", + "southwest.museum", + "space.museum", + "spy.museum", + "square.museum", + "stadt.museum", + "stalbans.museum", + "starnberg.museum", + "state.museum", + "stateofdelaware.museum", + "station.museum", + "steam.museum", + "steiermark.museum", + "stjohn.museum", + "stockholm.museum", + "stpetersburg.museum", + "stuttgart.museum", + "suisse.museum", + "surgeonshall.museum", + "surrey.museum", + "svizzera.museum", + "sweden.museum", + "sydney.museum", + "tank.museum", + "tcm.museum", + "technology.museum", + "telekommunikation.museum", + "television.museum", + "texas.museum", + "textile.museum", + "theater.museum", + "time.museum", + "timekeeping.museum", + "topology.museum", + "torino.museum", + "touch.museum", + "town.museum", + "transport.museum", + "tree.museum", + "trolley.museum", + "trust.museum", + "trustee.museum", + "uhren.museum", + "ulm.museum", + "undersea.museum", + "university.museum", + "usa.museum", + "usantiques.museum", + "usarts.museum", + "uscountryestate.museum", + "usculture.museum", + "usdecorativearts.museum", + "usgarden.museum", + "ushistory.museum", + "ushuaia.museum", + "uslivinghistory.museum", + "utah.museum", + "uvic.museum", + "valley.museum", + "vantaa.museum", + "versailles.museum", + "viking.museum", + "village.museum", + "virginia.museum", + "virtual.museum", + "virtuel.museum", + "vlaanderen.museum", + "volkenkunde.museum", + "wales.museum", + "wallonie.museum", + "war.museum", + "washingtondc.museum", + "watchandclock.museum", + "watch-and-clock.museum", + "western.museum", + "westfalen.museum", + "whaling.museum", + "wildlife.museum", + "williamsburg.museum", + "windmill.museum", + "workshop.museum", + "york.museum", + "yorkshire.museum", + "yosemite.museum", + "youth.museum", + "zoological.museum", + "zoology.museum", + "xn--9dbhblg6di.museum", + "xn--h1aegh.museum", + "mv", + "aero.mv", + "biz.mv", + "com.mv", + "coop.mv", + "edu.mv", + "gov.mv", + "info.mv", + "int.mv", + "mil.mv", + "museum.mv", + "name.mv", + "net.mv", + "org.mv", + "pro.mv", + "mw", + "ac.mw", + "biz.mw", + "co.mw", + "com.mw", + "coop.mw", + "edu.mw", + "gov.mw", + "int.mw", + "museum.mw", + "net.mw", + "org.mw", + "mx", + "com.mx", + "org.mx", + "gob.mx", + "edu.mx", + "net.mx", + "my", + "com.my", + "net.my", + "org.my", + "gov.my", + "edu.my", + "mil.my", + "name.my", + "*.mz", + "!teledata.mz", + "na", + "info.na", + "pro.na", + "name.na", + "school.na", + "or.na", + "dr.na", + "us.na", + "mx.na", + "ca.na", + "in.na", + "cc.na", + "tv.na", + "ws.na", + "mobi.na", + "co.na", + "com.na", + "org.na", + "name", + "nc", + "asso.nc", + "ne", + "net", + "nf", + "com.nf", + "net.nf", + "per.nf", + "rec.nf", + "web.nf", + "arts.nf", + "firm.nf", + "info.nf", + "other.nf", + "store.nf", + "ng", + "com.ng", + "edu.ng", + "gov.ng", + "i.ng", + "mil.ng", + "mobi.ng", + "name.ng", + "net.ng", + "org.ng", + "sch.ng", + "com.ni", + "gob.ni", + "edu.ni", + "org.ni", + "nom.ni", + "net.ni", + "mil.ni", + "co.ni", + "biz.ni", + "web.ni", + "int.ni", + "ac.ni", + "in.ni", + "info.ni", + "nl", + "bv.nl", + "no", + "fhs.no", + "vgs.no", + "fylkesbibl.no", + "folkebibl.no", + "museum.no", + "idrett.no", + "priv.no", + "mil.no", + "stat.no", + "dep.no", + "kommune.no", + "herad.no", + "aa.no", + "ah.no", + "bu.no", + "fm.no", + "hl.no", + "hm.no", + "jan-mayen.no", + "mr.no", + "nl.no", + "nt.no", + "of.no", + "ol.no", + "oslo.no", + "rl.no", + "sf.no", + "st.no", + "svalbard.no", + "tm.no", + "tr.no", + "va.no", + "vf.no", + "gs.aa.no", + "gs.ah.no", + "gs.bu.no", + "gs.fm.no", + "gs.hl.no", + "gs.hm.no", + "gs.jan-mayen.no", + "gs.mr.no", + "gs.nl.no", + "gs.nt.no", + "gs.of.no", + "gs.ol.no", + "gs.oslo.no", + "gs.rl.no", + "gs.sf.no", + "gs.st.no", + "gs.svalbard.no", + "gs.tm.no", + "gs.tr.no", + "gs.va.no", + "gs.vf.no", + "akrehamn.no", + "xn--krehamn-dxa.no", + "algard.no", + "xn--lgrd-poac.no", + "arna.no", + "brumunddal.no", + "bryne.no", + "bronnoysund.no", + "xn--brnnysund-m8ac.no", + "drobak.no", + "xn--drbak-wua.no", + "egersund.no", + "fetsund.no", + "floro.no", + "xn--flor-jra.no", + "fredrikstad.no", + "hokksund.no", + "honefoss.no", + "xn--hnefoss-q1a.no", + "jessheim.no", + "jorpeland.no", + "xn--jrpeland-54a.no", + "kirkenes.no", + "kopervik.no", + "krokstadelva.no", + "langevag.no", + "xn--langevg-jxa.no", + "leirvik.no", + "mjondalen.no", + "xn--mjndalen-64a.no", + "mo-i-rana.no", + "mosjoen.no", + "xn--mosjen-eya.no", + "nesoddtangen.no", + "orkanger.no", + "osoyro.no", + "xn--osyro-wua.no", + "raholt.no", + "xn--rholt-mra.no", + "sandnessjoen.no", + "xn--sandnessjen-ogb.no", + "skedsmokorset.no", + "slattum.no", + "spjelkavik.no", + "stathelle.no", + "stavern.no", + "stjordalshalsen.no", + "xn--stjrdalshalsen-sqb.no", + "tananger.no", + "tranby.no", + "vossevangen.no", + "afjord.no", + "xn--fjord-lra.no", + "agdenes.no", + "al.no", + "xn--l-1fa.no", + "alesund.no", + "xn--lesund-hua.no", + "alstahaug.no", + "alta.no", + "xn--lt-liac.no", + "alaheadju.no", + "xn--laheadju-7ya.no", + "alvdal.no", + "amli.no", + "xn--mli-tla.no", + "amot.no", + "xn--mot-tla.no", + "andebu.no", + "andoy.no", + "xn--andy-ira.no", + "andasuolo.no", + "ardal.no", + "xn--rdal-poa.no", + "aremark.no", + "arendal.no", + "xn--s-1fa.no", + "aseral.no", + "xn--seral-lra.no", + "asker.no", + "askim.no", + "askvoll.no", + "askoy.no", + "xn--asky-ira.no", + "asnes.no", + "xn--snes-poa.no", + "audnedaln.no", + "aukra.no", + "aure.no", + "aurland.no", + "aurskog-holand.no", + "xn--aurskog-hland-jnb.no", + "austevoll.no", + "austrheim.no", + "averoy.no", + "xn--avery-yua.no", + "balestrand.no", + "ballangen.no", + "balat.no", + "xn--blt-elab.no", + "balsfjord.no", + "bahccavuotna.no", + "xn--bhccavuotna-k7a.no", + "bamble.no", + "bardu.no", + "beardu.no", + "beiarn.no", + "bajddar.no", + "xn--bjddar-pta.no", + "baidar.no", + "xn--bidr-5nac.no", + "berg.no", + "bergen.no", + "berlevag.no", + "xn--berlevg-jxa.no", + "bearalvahki.no", + "xn--bearalvhki-y4a.no", + "bindal.no", + "birkenes.no", + "bjarkoy.no", + "xn--bjarky-fya.no", + "bjerkreim.no", + "bjugn.no", + "bodo.no", + "xn--bod-2na.no", + "badaddja.no", + "xn--bdddj-mrabd.no", + "budejju.no", + "bokn.no", + "bremanger.no", + "bronnoy.no", + "xn--brnny-wuac.no", + "bygland.no", + "bykle.no", + "barum.no", + "xn--brum-voa.no", + "bo.telemark.no", + "xn--b-5ga.telemark.no", + "bo.nordland.no", + "xn--b-5ga.nordland.no", + "bievat.no", + "xn--bievt-0qa.no", + "bomlo.no", + "xn--bmlo-gra.no", + "batsfjord.no", + "xn--btsfjord-9za.no", + "bahcavuotna.no", + "xn--bhcavuotna-s4a.no", + "dovre.no", + "drammen.no", + "drangedal.no", + "dyroy.no", + "xn--dyry-ira.no", + "donna.no", + "xn--dnna-gra.no", + "eid.no", + "eidfjord.no", + "eidsberg.no", + "eidskog.no", + "eidsvoll.no", + "eigersund.no", + "elverum.no", + "enebakk.no", + "engerdal.no", + "etne.no", + "etnedal.no", + "evenes.no", + "evenassi.no", + "xn--eveni-0qa01ga.no", + "evje-og-hornnes.no", + "farsund.no", + "fauske.no", + "fuossko.no", + "fuoisku.no", + "fedje.no", + "fet.no", + "finnoy.no", + "xn--finny-yua.no", + "fitjar.no", + "fjaler.no", + "fjell.no", + "flakstad.no", + "flatanger.no", + "flekkefjord.no", + "flesberg.no", + "flora.no", + "fla.no", + "xn--fl-zia.no", + "folldal.no", + "forsand.no", + "fosnes.no", + "frei.no", + "frogn.no", + "froland.no", + "frosta.no", + "frana.no", + "xn--frna-woa.no", + "froya.no", + "xn--frya-hra.no", + "fusa.no", + "fyresdal.no", + "forde.no", + "xn--frde-gra.no", + "gamvik.no", + "gangaviika.no", + "xn--ggaviika-8ya47h.no", + "gaular.no", + "gausdal.no", + "gildeskal.no", + "xn--gildeskl-g0a.no", + "giske.no", + "gjemnes.no", + "gjerdrum.no", + "gjerstad.no", + "gjesdal.no", + "gjovik.no", + "xn--gjvik-wua.no", + "gloppen.no", + "gol.no", + "gran.no", + "grane.no", + "granvin.no", + "gratangen.no", + "grimstad.no", + "grong.no", + "kraanghke.no", + "xn--kranghke-b0a.no", + "grue.no", + "gulen.no", + "hadsel.no", + "halden.no", + "halsa.no", + "hamar.no", + "hamaroy.no", + "habmer.no", + "xn--hbmer-xqa.no", + "hapmir.no", + "xn--hpmir-xqa.no", + "hammerfest.no", + "hammarfeasta.no", + "xn--hmmrfeasta-s4ac.no", + "haram.no", + "hareid.no", + "harstad.no", + "hasvik.no", + "aknoluokta.no", + "xn--koluokta-7ya57h.no", + "hattfjelldal.no", + "aarborte.no", + "haugesund.no", + "hemne.no", + "hemnes.no", + "hemsedal.no", + "heroy.more-og-romsdal.no", + "xn--hery-ira.xn--mre-og-romsdal-qqb.no", + "heroy.nordland.no", + "xn--hery-ira.nordland.no", + "hitra.no", + "hjartdal.no", + "hjelmeland.no", + "hobol.no", + "xn--hobl-ira.no", + "hof.no", + "hol.no", + "hole.no", + "holmestrand.no", + "holtalen.no", + "xn--holtlen-hxa.no", + "hornindal.no", + "horten.no", + "hurdal.no", + "hurum.no", + "hvaler.no", + "hyllestad.no", + "hagebostad.no", + "xn--hgebostad-g3a.no", + "hoyanger.no", + "xn--hyanger-q1a.no", + "hoylandet.no", + "xn--hylandet-54a.no", + "ha.no", + "xn--h-2fa.no", + "ibestad.no", + "inderoy.no", + "xn--indery-fya.no", + "iveland.no", + "jevnaker.no", + "jondal.no", + "jolster.no", + "xn--jlster-bya.no", + "karasjok.no", + "karasjohka.no", + "xn--krjohka-hwab49j.no", + "karlsoy.no", + "galsa.no", + "xn--gls-elac.no", + "karmoy.no", + "xn--karmy-yua.no", + "kautokeino.no", + "guovdageaidnu.no", + "klepp.no", + "klabu.no", + "xn--klbu-woa.no", + "kongsberg.no", + "kongsvinger.no", + "kragero.no", + "xn--krager-gya.no", + "kristiansand.no", + "kristiansund.no", + "krodsherad.no", + "xn--krdsherad-m8a.no", + "kvalsund.no", + "rahkkeravju.no", + "xn--rhkkervju-01af.no", + "kvam.no", + "kvinesdal.no", + "kvinnherad.no", + "kviteseid.no", + "kvitsoy.no", + "xn--kvitsy-fya.no", + "kvafjord.no", + "xn--kvfjord-nxa.no", + "giehtavuoatna.no", + "kvanangen.no", + "xn--kvnangen-k0a.no", + "navuotna.no", + "xn--nvuotna-hwa.no", + "kafjord.no", + "xn--kfjord-iua.no", + "gaivuotna.no", + "xn--givuotna-8ya.no", + "larvik.no", + "lavangen.no", + "lavagis.no", + "loabat.no", + "xn--loabt-0qa.no", + "lebesby.no", + "davvesiida.no", + "leikanger.no", + "leirfjord.no", + "leka.no", + "leksvik.no", + "lenvik.no", + "leangaviika.no", + "xn--leagaviika-52b.no", + "lesja.no", + "levanger.no", + "lier.no", + "lierne.no", + "lillehammer.no", + "lillesand.no", + "lindesnes.no", + "lindas.no", + "xn--linds-pra.no", + "lom.no", + "loppa.no", + "lahppi.no", + "xn--lhppi-xqa.no", + "lund.no", + "lunner.no", + "luroy.no", + "xn--lury-ira.no", + "luster.no", + "lyngdal.no", + "lyngen.no", + "ivgu.no", + "lardal.no", + "lerdal.no", + "xn--lrdal-sra.no", + "lodingen.no", + "xn--ldingen-q1a.no", + "lorenskog.no", + "xn--lrenskog-54a.no", + "loten.no", + "xn--lten-gra.no", + "malvik.no", + "masoy.no", + "xn--msy-ula0h.no", + "muosat.no", + "xn--muost-0qa.no", + "mandal.no", + "marker.no", + "marnardal.no", + "masfjorden.no", + "meland.no", + "meldal.no", + "melhus.no", + "meloy.no", + "xn--mely-ira.no", + "meraker.no", + "xn--merker-kua.no", + "moareke.no", + "xn--moreke-jua.no", + "midsund.no", + "midtre-gauldal.no", + "modalen.no", + "modum.no", + "molde.no", + "moskenes.no", + "moss.no", + "mosvik.no", + "malselv.no", + "xn--mlselv-iua.no", + "malatvuopmi.no", + "xn--mlatvuopmi-s4a.no", + "namdalseid.no", + "aejrie.no", + "namsos.no", + "namsskogan.no", + "naamesjevuemie.no", + "xn--nmesjevuemie-tcba.no", + "laakesvuemie.no", + "nannestad.no", + "narvik.no", + "narviika.no", + "naustdal.no", + "nedre-eiker.no", + "nes.akershus.no", + "nes.buskerud.no", + "nesna.no", + "nesodden.no", + "nesseby.no", + "unjarga.no", + "xn--unjrga-rta.no", + "nesset.no", + "nissedal.no", + "nittedal.no", + "nord-aurdal.no", + "nord-fron.no", + "nord-odal.no", + "norddal.no", + "nordkapp.no", + "davvenjarga.no", + "xn--davvenjrga-y4a.no", + "nordre-land.no", + "nordreisa.no", + "raisa.no", + "xn--risa-5na.no", + "nore-og-uvdal.no", + "notodden.no", + "naroy.no", + "xn--nry-yla5g.no", + "notteroy.no", + "xn--nttery-byae.no", + "odda.no", + "oksnes.no", + "xn--ksnes-uua.no", + "oppdal.no", + "oppegard.no", + "xn--oppegrd-ixa.no", + "orkdal.no", + "orland.no", + "xn--rland-uua.no", + "orskog.no", + "xn--rskog-uua.no", + "orsta.no", + "xn--rsta-fra.no", + "os.hedmark.no", + "os.hordaland.no", + "osen.no", + "osteroy.no", + "xn--ostery-fya.no", + "ostre-toten.no", + "xn--stre-toten-zcb.no", + "overhalla.no", + "ovre-eiker.no", + "xn--vre-eiker-k8a.no", + "oyer.no", + "xn--yer-zna.no", + "oygarden.no", + "xn--ygarden-p1a.no", + "oystre-slidre.no", + "xn--ystre-slidre-ujb.no", + "porsanger.no", + "porsangu.no", + "xn--porsgu-sta26f.no", + "porsgrunn.no", + "radoy.no", + "xn--rady-ira.no", + "rakkestad.no", + "rana.no", + "ruovat.no", + "randaberg.no", + "rauma.no", + "rendalen.no", + "rennebu.no", + "rennesoy.no", + "xn--rennesy-v1a.no", + "rindal.no", + "ringebu.no", + "ringerike.no", + "ringsaker.no", + "rissa.no", + "risor.no", + "xn--risr-ira.no", + "roan.no", + "rollag.no", + "rygge.no", + "ralingen.no", + "xn--rlingen-mxa.no", + "rodoy.no", + "xn--rdy-0nab.no", + "romskog.no", + "xn--rmskog-bya.no", + "roros.no", + "xn--rros-gra.no", + "rost.no", + "xn--rst-0na.no", + "royken.no", + "xn--ryken-vua.no", + "royrvik.no", + "xn--ryrvik-bya.no", + "rade.no", + "xn--rde-ula.no", + "salangen.no", + "siellak.no", + "saltdal.no", + "salat.no", + "xn--slt-elab.no", + "xn--slat-5na.no", + "samnanger.no", + "sande.more-og-romsdal.no", + "sande.xn--mre-og-romsdal-qqb.no", + "sande.vestfold.no", + "sandefjord.no", + "sandnes.no", + "sandoy.no", + "xn--sandy-yua.no", + "sarpsborg.no", + "sauda.no", + "sauherad.no", + "sel.no", + "selbu.no", + "selje.no", + "seljord.no", + "sigdal.no", + "siljan.no", + "sirdal.no", + "skaun.no", + "skedsmo.no", + "ski.no", + "skien.no", + "skiptvet.no", + "skjervoy.no", + "xn--skjervy-v1a.no", + "skierva.no", + "xn--skierv-uta.no", + "skjak.no", + "xn--skjk-soa.no", + "skodje.no", + "skanland.no", + "xn--sknland-fxa.no", + "skanit.no", + "xn--sknit-yqa.no", + "smola.no", + "xn--smla-hra.no", + "snillfjord.no", + "snasa.no", + "xn--snsa-roa.no", + "snoasa.no", + "snaase.no", + "xn--snase-nra.no", + "sogndal.no", + "sokndal.no", + "sola.no", + "solund.no", + "songdalen.no", + "sortland.no", + "spydeberg.no", + "stange.no", + "stavanger.no", + "steigen.no", + "steinkjer.no", + "stjordal.no", + "xn--stjrdal-s1a.no", + "stokke.no", + "stor-elvdal.no", + "stord.no", + "stordal.no", + "storfjord.no", + "omasvuotna.no", + "strand.no", + "stranda.no", + "stryn.no", + "sula.no", + "suldal.no", + "sund.no", + "sunndal.no", + "surnadal.no", + "sveio.no", + "svelvik.no", + "sykkylven.no", + "sogne.no", + "xn--sgne-gra.no", + "somna.no", + "xn--smna-gra.no", + "sondre-land.no", + "xn--sndre-land-0cb.no", + "sor-aurdal.no", + "xn--sr-aurdal-l8a.no", + "sor-fron.no", + "xn--sr-fron-q1a.no", + "sor-odal.no", + "xn--sr-odal-q1a.no", + "sor-varanger.no", + "xn--sr-varanger-ggb.no", + "matta-varjjat.no", + "xn--mtta-vrjjat-k7af.no", + "sorfold.no", + "xn--srfold-bya.no", + "sorreisa.no", + "xn--srreisa-q1a.no", + "sorum.no", + "xn--srum-gra.no", + "tana.no", + "deatnu.no", + "time.no", + "tingvoll.no", + "tinn.no", + "tjeldsund.no", + "dielddanuorri.no", + "tjome.no", + "xn--tjme-hra.no", + "tokke.no", + "tolga.no", + "torsken.no", + "tranoy.no", + "xn--trany-yua.no", + "tromso.no", + "xn--troms-zua.no", + "tromsa.no", + "romsa.no", + "trondheim.no", + "troandin.no", + "trysil.no", + "trana.no", + "xn--trna-woa.no", + "trogstad.no", + "xn--trgstad-r1a.no", + "tvedestrand.no", + "tydal.no", + "tynset.no", + "tysfjord.no", + "divtasvuodna.no", + "divttasvuotna.no", + "tysnes.no", + "tysvar.no", + "xn--tysvr-vra.no", + "tonsberg.no", + "xn--tnsberg-q1a.no", + "ullensaker.no", + "ullensvang.no", + "ulvik.no", + "utsira.no", + "vadso.no", + "xn--vads-jra.no", + "cahcesuolo.no", + "xn--hcesuolo-7ya35b.no", + "vaksdal.no", + "valle.no", + "vang.no", + "vanylven.no", + "vardo.no", + "xn--vard-jra.no", + "varggat.no", + "xn--vrggt-xqad.no", + "vefsn.no", + "vaapste.no", + "vega.no", + "vegarshei.no", + "xn--vegrshei-c0a.no", + "vennesla.no", + "verdal.no", + "verran.no", + "vestby.no", + "vestnes.no", + "vestre-slidre.no", + "vestre-toten.no", + "vestvagoy.no", + "xn--vestvgy-ixa6o.no", + "vevelstad.no", + "vik.no", + "vikna.no", + "vindafjord.no", + "volda.no", + "voss.no", + "varoy.no", + "xn--vry-yla5g.no", + "vagan.no", + "xn--vgan-qoa.no", + "voagat.no", + "vagsoy.no", + "xn--vgsy-qoa0j.no", + "vaga.no", + "xn--vg-yiab.no", + "valer.ostfold.no", + "xn--vler-qoa.xn--stfold-9xa.no", + "valer.hedmark.no", + "xn--vler-qoa.hedmark.no", + "*.np", + "nr", + "biz.nr", + "info.nr", + "gov.nr", + "edu.nr", + "org.nr", + "net.nr", + "com.nr", + "nu", + "nz", + "ac.nz", + "co.nz", + "cri.nz", + "geek.nz", + "gen.nz", + "govt.nz", + "health.nz", + "iwi.nz", + "kiwi.nz", + "maori.nz", + "mil.nz", + "xn--mori-qsa.nz", + "net.nz", + "org.nz", + "parliament.nz", + "school.nz", + "om", + "co.om", + "com.om", + "edu.om", + "gov.om", + "med.om", + "museum.om", + "net.om", + "org.om", + "pro.om", + "org", + "pa", + "ac.pa", + "gob.pa", + "com.pa", + "org.pa", + "sld.pa", + "edu.pa", + "net.pa", + "ing.pa", + "abo.pa", + "med.pa", + "nom.pa", + "pe", + "edu.pe", + "gob.pe", + "nom.pe", + "mil.pe", + "org.pe", + "com.pe", + "net.pe", + "pf", + "com.pf", + "org.pf", + "edu.pf", + "*.pg", + "ph", + "com.ph", + "net.ph", + "org.ph", + "gov.ph", + "edu.ph", + "ngo.ph", + "mil.ph", + "i.ph", + "pk", + "com.pk", + "net.pk", + "edu.pk", + "org.pk", + "fam.pk", + "biz.pk", + "web.pk", + "gov.pk", + "gob.pk", + "gok.pk", + "gon.pk", + "gop.pk", + "gos.pk", + "info.pk", + "pl", + "com.pl", + "net.pl", + "org.pl", + "aid.pl", + "agro.pl", + "atm.pl", + "auto.pl", + "biz.pl", + "edu.pl", + "gmina.pl", + "gsm.pl", + "info.pl", + "mail.pl", + "miasta.pl", + "media.pl", + "mil.pl", + "nieruchomosci.pl", + "nom.pl", + "pc.pl", + "powiat.pl", + "priv.pl", + "realestate.pl", + "rel.pl", + "sex.pl", + "shop.pl", + "sklep.pl", + "sos.pl", + "szkola.pl", + "targi.pl", + "tm.pl", + "tourism.pl", + "travel.pl", + "turystyka.pl", + "gov.pl", + "ap.gov.pl", + "ic.gov.pl", + "is.gov.pl", + "us.gov.pl", + "kmpsp.gov.pl", + "kppsp.gov.pl", + "kwpsp.gov.pl", + "psp.gov.pl", + "wskr.gov.pl", + "kwp.gov.pl", + "mw.gov.pl", + "ug.gov.pl", + "um.gov.pl", + "umig.gov.pl", + "ugim.gov.pl", + "upow.gov.pl", + "uw.gov.pl", + "starostwo.gov.pl", + "pa.gov.pl", + "po.gov.pl", + "psse.gov.pl", + "pup.gov.pl", + "rzgw.gov.pl", + "sa.gov.pl", + "so.gov.pl", + "sr.gov.pl", + "wsa.gov.pl", + "sko.gov.pl", + "uzs.gov.pl", + "wiih.gov.pl", + "winb.gov.pl", + "pinb.gov.pl", + "wios.gov.pl", + "witd.gov.pl", + "wzmiuw.gov.pl", + "piw.gov.pl", + "wiw.gov.pl", + "griw.gov.pl", + "wif.gov.pl", + "oum.gov.pl", + "sdn.gov.pl", + "zp.gov.pl", + "uppo.gov.pl", + "mup.gov.pl", + "wuoz.gov.pl", + "konsulat.gov.pl", + "oirm.gov.pl", + "augustow.pl", + "babia-gora.pl", + "bedzin.pl", + "beskidy.pl", + "bialowieza.pl", + "bialystok.pl", + "bielawa.pl", + "bieszczady.pl", + "boleslawiec.pl", + "bydgoszcz.pl", + "bytom.pl", + "cieszyn.pl", + "czeladz.pl", + "czest.pl", + "dlugoleka.pl", + "elblag.pl", + "elk.pl", + "glogow.pl", + "gniezno.pl", + "gorlice.pl", + "grajewo.pl", + "ilawa.pl", + "jaworzno.pl", + "jelenia-gora.pl", + "jgora.pl", + "kalisz.pl", + "kazimierz-dolny.pl", + "karpacz.pl", + "kartuzy.pl", + "kaszuby.pl", + "katowice.pl", + "kepno.pl", + "ketrzyn.pl", + "klodzko.pl", + "kobierzyce.pl", + "kolobrzeg.pl", + "konin.pl", + "konskowola.pl", + "kutno.pl", + "lapy.pl", + "lebork.pl", + "legnica.pl", + "lezajsk.pl", + "limanowa.pl", + "lomza.pl", + "lowicz.pl", + "lubin.pl", + "lukow.pl", + "malbork.pl", + "malopolska.pl", + "mazowsze.pl", + "mazury.pl", + "mielec.pl", + "mielno.pl", + "mragowo.pl", + "naklo.pl", + "nowaruda.pl", + "nysa.pl", + "olawa.pl", + "olecko.pl", + "olkusz.pl", + "olsztyn.pl", + "opoczno.pl", + "opole.pl", + "ostroda.pl", + "ostroleka.pl", + "ostrowiec.pl", + "ostrowwlkp.pl", + "pila.pl", + "pisz.pl", + "podhale.pl", + "podlasie.pl", + "polkowice.pl", + "pomorze.pl", + "pomorskie.pl", + "prochowice.pl", + "pruszkow.pl", + "przeworsk.pl", + "pulawy.pl", + "radom.pl", + "rawa-maz.pl", + "rybnik.pl", + "rzeszow.pl", + "sanok.pl", + "sejny.pl", + "slask.pl", + "slupsk.pl", + "sosnowiec.pl", + "stalowa-wola.pl", + "skoczow.pl", + "starachowice.pl", + "stargard.pl", + "suwalki.pl", + "swidnica.pl", + "swiebodzin.pl", + "swinoujscie.pl", + "szczecin.pl", + "szczytno.pl", + "tarnobrzeg.pl", + "tgory.pl", + "turek.pl", + "tychy.pl", + "ustka.pl", + "walbrzych.pl", + "warmia.pl", + "warszawa.pl", + "waw.pl", + "wegrow.pl", + "wielun.pl", + "wlocl.pl", + "wloclawek.pl", + "wodzislaw.pl", + "wolomin.pl", + "wroclaw.pl", + "zachpomor.pl", + "zagan.pl", + "zarow.pl", + "zgora.pl", + "zgorzelec.pl", + "pm", + "pn", + "gov.pn", + "co.pn", + "org.pn", + "edu.pn", + "net.pn", + "post", + "pr", + "com.pr", + "net.pr", + "org.pr", + "gov.pr", + "edu.pr", + "isla.pr", + "pro.pr", + "biz.pr", + "info.pr", + "name.pr", + "est.pr", + "prof.pr", + "ac.pr", + "pro", + "aca.pro", + "bar.pro", + "cpa.pro", + "jur.pro", + "law.pro", + "med.pro", + "eng.pro", + "ps", + "edu.ps", + "gov.ps", + "sec.ps", + "plo.ps", + "com.ps", + "org.ps", + "net.ps", + "pt", + "net.pt", + "gov.pt", + "org.pt", + "edu.pt", + "int.pt", + "publ.pt", + "com.pt", + "nome.pt", + "pw", + "co.pw", + "ne.pw", + "or.pw", + "ed.pw", + "go.pw", + "belau.pw", + "py", + "com.py", + "coop.py", + "edu.py", + "gov.py", + "mil.py", + "net.py", + "org.py", + "qa", + "com.qa", + "edu.qa", + "gov.qa", + "mil.qa", + "name.qa", + "net.qa", + "org.qa", + "sch.qa", + "re", + "asso.re", + "com.re", + "nom.re", + "ro", + "arts.ro", + "com.ro", + "firm.ro", + "info.ro", + "nom.ro", + "nt.ro", + "org.ro", + "rec.ro", + "store.ro", + "tm.ro", + "www.ro", + "rs", + "ac.rs", + "co.rs", + "edu.rs", + "gov.rs", + "in.rs", + "org.rs", + "ru", + "ac.ru", + "com.ru", + "edu.ru", + "int.ru", + "net.ru", + "org.ru", + "pp.ru", + "adygeya.ru", + "altai.ru", + "amur.ru", + "arkhangelsk.ru", + "astrakhan.ru", + "bashkiria.ru", + "belgorod.ru", + "bir.ru", + "bryansk.ru", + "buryatia.ru", + "cbg.ru", + "chel.ru", + "chelyabinsk.ru", + "chita.ru", + "chukotka.ru", + "chuvashia.ru", + "dagestan.ru", + "dudinka.ru", + "e-burg.ru", + "grozny.ru", + "irkutsk.ru", + "ivanovo.ru", + "izhevsk.ru", + "jar.ru", + "joshkar-ola.ru", + "kalmykia.ru", + "kaluga.ru", + "kamchatka.ru", + "karelia.ru", + "kazan.ru", + "kchr.ru", + "kemerovo.ru", + "khabarovsk.ru", + "khakassia.ru", + "khv.ru", + "kirov.ru", + "koenig.ru", + "komi.ru", + "kostroma.ru", + "krasnoyarsk.ru", + "kuban.ru", + "kurgan.ru", + "kursk.ru", + "lipetsk.ru", + "magadan.ru", + "mari.ru", + "mari-el.ru", + "marine.ru", + "mordovia.ru", + "msk.ru", + "murmansk.ru", + "nalchik.ru", + "nnov.ru", + "nov.ru", + "novosibirsk.ru", + "nsk.ru", + "omsk.ru", + "orenburg.ru", + "oryol.ru", + "palana.ru", + "penza.ru", + "perm.ru", + "ptz.ru", + "rnd.ru", + "ryazan.ru", + "sakhalin.ru", + "samara.ru", + "saratov.ru", + "simbirsk.ru", + "smolensk.ru", + "spb.ru", + "stavropol.ru", + "stv.ru", + "surgut.ru", + "tambov.ru", + "tatarstan.ru", + "tom.ru", + "tomsk.ru", + "tsaritsyn.ru", + "tsk.ru", + "tula.ru", + "tuva.ru", + "tver.ru", + "tyumen.ru", + "udm.ru", + "udmurtia.ru", + "ulan-ude.ru", + "vladikavkaz.ru", + "vladimir.ru", + "vladivostok.ru", + "volgograd.ru", + "vologda.ru", + "voronezh.ru", + "vrn.ru", + "vyatka.ru", + "yakutia.ru", + "yamal.ru", + "yaroslavl.ru", + "yekaterinburg.ru", + "yuzhno-sakhalinsk.ru", + "amursk.ru", + "baikal.ru", + "cmw.ru", + "fareast.ru", + "jamal.ru", + "kms.ru", + "k-uralsk.ru", + "kustanai.ru", + "kuzbass.ru", + "mytis.ru", + "nakhodka.ru", + "nkz.ru", + "norilsk.ru", + "oskol.ru", + "pyatigorsk.ru", + "rubtsovsk.ru", + "snz.ru", + "syzran.ru", + "vdonsk.ru", + "zgrad.ru", + "gov.ru", + "mil.ru", + "test.ru", + "rw", + "gov.rw", + "net.rw", + "edu.rw", + "ac.rw", + "com.rw", + "co.rw", + "int.rw", + "mil.rw", + "gouv.rw", + "sa", + "com.sa", + "net.sa", + "org.sa", + "gov.sa", + "med.sa", + "pub.sa", + "edu.sa", + "sch.sa", + "sb", + "com.sb", + "edu.sb", + "gov.sb", + "net.sb", + "org.sb", + "sc", + "com.sc", + "gov.sc", + "net.sc", + "org.sc", + "edu.sc", + "sd", + "com.sd", + "net.sd", + "org.sd", + "edu.sd", + "med.sd", + "tv.sd", + "gov.sd", + "info.sd", + "se", + "a.se", + "ac.se", + "b.se", + "bd.se", + "brand.se", + "c.se", + "d.se", + "e.se", + "f.se", + "fh.se", + "fhsk.se", + "fhv.se", + "g.se", + "h.se", + "i.se", + "k.se", + "komforb.se", + "kommunalforbund.se", + "komvux.se", + "l.se", + "lanbib.se", + "m.se", + "n.se", + "naturbruksgymn.se", + "o.se", + "org.se", + "p.se", + "parti.se", + "pp.se", + "press.se", + "r.se", + "s.se", + "t.se", + "tm.se", + "u.se", + "w.se", + "x.se", + "y.se", + "z.se", + "sg", + "com.sg", + "net.sg", + "org.sg", + "gov.sg", + "edu.sg", + "per.sg", + "sh", + "com.sh", + "net.sh", + "gov.sh", + "org.sh", + "mil.sh", + "si", + "sj", + "sk", + "sl", + "com.sl", + "net.sl", + "edu.sl", + "gov.sl", + "org.sl", + "sm", + "sn", + "art.sn", + "com.sn", + "edu.sn", + "gouv.sn", + "org.sn", + "perso.sn", + "univ.sn", + "so", + "com.so", + "net.so", + "org.so", + "sr", + "st", + "co.st", + "com.st", + "consulado.st", + "edu.st", + "embaixada.st", + "gov.st", + "mil.st", + "net.st", + "org.st", + "principe.st", + "saotome.st", + "store.st", + "su", + "adygeya.su", + "arkhangelsk.su", + "balashov.su", + "bashkiria.su", + "bryansk.su", + "dagestan.su", + "grozny.su", + "ivanovo.su", + "kalmykia.su", + "kaluga.su", + "karelia.su", + "khakassia.su", + "krasnodar.su", + "kurgan.su", + "lenug.su", + "mordovia.su", + "msk.su", + "murmansk.su", + "nalchik.su", + "nov.su", + "obninsk.su", + "penza.su", + "pokrovsk.su", + "sochi.su", + "spb.su", + "togliatti.su", + "troitsk.su", + "tula.su", + "tuva.su", + "vladikavkaz.su", + "vladimir.su", + "vologda.su", + "sv", + "com.sv", + "edu.sv", + "gob.sv", + "org.sv", + "red.sv", + "sx", + "gov.sx", + "sy", + "edu.sy", + "gov.sy", + "net.sy", + "mil.sy", + "com.sy", + "org.sy", + "sz", + "co.sz", + "ac.sz", + "org.sz", + "tc", + "td", + "tel", + "tf", + "tg", + "th", + "ac.th", + "co.th", + "go.th", + "in.th", + "mi.th", + "net.th", + "or.th", + "tj", + "ac.tj", + "biz.tj", + "co.tj", + "com.tj", + "edu.tj", + "go.tj", + "gov.tj", + "int.tj", + "mil.tj", + "name.tj", + "net.tj", + "nic.tj", + "org.tj", + "test.tj", + "web.tj", + "tk", + "tl", + "gov.tl", + "tm", + "com.tm", + "co.tm", + "org.tm", + "net.tm", + "nom.tm", + "gov.tm", + "mil.tm", + "edu.tm", + "tn", + "com.tn", + "ens.tn", + "fin.tn", + "gov.tn", + "ind.tn", + "intl.tn", + "nat.tn", + "net.tn", + "org.tn", + "info.tn", + "perso.tn", + "tourism.tn", + "edunet.tn", + "rnrt.tn", + "rns.tn", + "rnu.tn", + "mincom.tn", + "agrinet.tn", + "defense.tn", + "turen.tn", + "to", + "com.to", + "gov.to", + "net.to", + "org.to", + "edu.to", + "mil.to", + "tr", + "com.tr", + "info.tr", + "biz.tr", + "net.tr", + "org.tr", + "web.tr", + "gen.tr", + "tv.tr", + "av.tr", + "dr.tr", + "bbs.tr", + "name.tr", + "tel.tr", + "gov.tr", + "bel.tr", + "pol.tr", + "mil.tr", + "k12.tr", + "edu.tr", + "kep.tr", + "nc.tr", + "gov.nc.tr", + "travel", + "tt", + "co.tt", + "com.tt", + "org.tt", + "net.tt", + "biz.tt", + "info.tt", + "pro.tt", + "int.tt", + "coop.tt", + "jobs.tt", + "mobi.tt", + "travel.tt", + "museum.tt", + "aero.tt", + "name.tt", + "gov.tt", + "edu.tt", + "tv", + "tw", + "edu.tw", + "gov.tw", + "mil.tw", + "com.tw", + "net.tw", + "org.tw", + "idv.tw", + "game.tw", + "ebiz.tw", + "club.tw", + "xn--zf0ao64a.tw", + "xn--uc0atv.tw", + "xn--czrw28b.tw", + "tz", + "ac.tz", + "co.tz", + "go.tz", + "hotel.tz", + "info.tz", + "me.tz", + "mil.tz", + "mobi.tz", + "ne.tz", + "or.tz", + "sc.tz", + "tv.tz", + "ua", + "com.ua", + "edu.ua", + "gov.ua", + "in.ua", + "net.ua", + "org.ua", + "cherkassy.ua", + "cherkasy.ua", + "chernigov.ua", + "chernihiv.ua", + "chernivtsi.ua", + "chernovtsy.ua", + "ck.ua", + "cn.ua", + "cr.ua", + "crimea.ua", + "cv.ua", + "dn.ua", + "dnepropetrovsk.ua", + "dnipropetrovsk.ua", + "dominic.ua", + "donetsk.ua", + "dp.ua", + "if.ua", + "ivano-frankivsk.ua", + "kh.ua", + "kharkiv.ua", + "kharkov.ua", + "kherson.ua", + "khmelnitskiy.ua", + "khmelnytskyi.ua", + "kiev.ua", + "kirovograd.ua", + "km.ua", + "kr.ua", + "krym.ua", + "ks.ua", + "kv.ua", + "kyiv.ua", + "lg.ua", + "lt.ua", + "lugansk.ua", + "lutsk.ua", + "lv.ua", + "lviv.ua", + "mk.ua", + "mykolaiv.ua", + "nikolaev.ua", + "od.ua", + "odesa.ua", + "odessa.ua", + "pl.ua", + "poltava.ua", + "rivne.ua", + "rovno.ua", + "rv.ua", + "sb.ua", + "sebastopol.ua", + "sevastopol.ua", + "sm.ua", + "sumy.ua", + "te.ua", + "ternopil.ua", + "uz.ua", + "uzhgorod.ua", + "vinnica.ua", + "vinnytsia.ua", + "vn.ua", + "volyn.ua", + "yalta.ua", + "zaporizhzhe.ua", + "zaporizhzhia.ua", + "zhitomir.ua", + "zhytomyr.ua", + "zp.ua", + "zt.ua", + "ug", + "co.ug", + "or.ug", + "ac.ug", + "sc.ug", + "go.ug", + "ne.ug", + "com.ug", + "org.ug", + "uk", + "ac.uk", + "co.uk", + "gov.uk", + "ltd.uk", + "me.uk", + "net.uk", + "nhs.uk", + "org.uk", + "plc.uk", + "police.uk", + "*.sch.uk", + "us", + "dni.us", + "fed.us", + "isa.us", + "kids.us", + "nsn.us", + "ak.us", + "al.us", + "ar.us", + "as.us", + "az.us", + "ca.us", + "co.us", + "ct.us", + "dc.us", + "de.us", + "fl.us", + "ga.us", + "gu.us", + "hi.us", + "ia.us", + "id.us", + "il.us", + "in.us", + "ks.us", + "ky.us", + "la.us", + "ma.us", + "md.us", + "me.us", + "mi.us", + "mn.us", + "mo.us", + "ms.us", + "mt.us", + "nc.us", + "nd.us", + "ne.us", + "nh.us", + "nj.us", + "nm.us", + "nv.us", + "ny.us", + "oh.us", + "ok.us", + "or.us", + "pa.us", + "pr.us", + "ri.us", + "sc.us", + "sd.us", + "tn.us", + "tx.us", + "ut.us", + "vi.us", + "vt.us", + "va.us", + "wa.us", + "wi.us", + "wv.us", + "wy.us", + "k12.ak.us", + "k12.al.us", + "k12.ar.us", + "k12.as.us", + "k12.az.us", + "k12.ca.us", + "k12.co.us", + "k12.ct.us", + "k12.dc.us", + "k12.de.us", + "k12.fl.us", + "k12.ga.us", + "k12.gu.us", + "k12.ia.us", + "k12.id.us", + "k12.il.us", + "k12.in.us", + "k12.ks.us", + "k12.ky.us", + "k12.la.us", + "k12.ma.us", + "k12.md.us", + "k12.me.us", + "k12.mi.us", + "k12.mn.us", + "k12.mo.us", + "k12.ms.us", + "k12.mt.us", + "k12.nc.us", + "k12.ne.us", + "k12.nh.us", + "k12.nj.us", + "k12.nm.us", + "k12.nv.us", + "k12.ny.us", + "k12.oh.us", + "k12.ok.us", + "k12.or.us", + "k12.pa.us", + "k12.pr.us", + "k12.ri.us", + "k12.sc.us", + "k12.tn.us", + "k12.tx.us", + "k12.ut.us", + "k12.vi.us", + "k12.vt.us", + "k12.va.us", + "k12.wa.us", + "k12.wi.us", + "k12.wy.us", + "cc.ak.us", + "cc.al.us", + "cc.ar.us", + "cc.as.us", + "cc.az.us", + "cc.ca.us", + "cc.co.us", + "cc.ct.us", + "cc.dc.us", + "cc.de.us", + "cc.fl.us", + "cc.ga.us", + "cc.gu.us", + "cc.hi.us", + "cc.ia.us", + "cc.id.us", + "cc.il.us", + "cc.in.us", + "cc.ks.us", + "cc.ky.us", + "cc.la.us", + "cc.ma.us", + "cc.md.us", + "cc.me.us", + "cc.mi.us", + "cc.mn.us", + "cc.mo.us", + "cc.ms.us", + "cc.mt.us", + "cc.nc.us", + "cc.nd.us", + "cc.ne.us", + "cc.nh.us", + "cc.nj.us", + "cc.nm.us", + "cc.nv.us", + "cc.ny.us", + "cc.oh.us", + "cc.ok.us", + "cc.or.us", + "cc.pa.us", + "cc.pr.us", + "cc.ri.us", + "cc.sc.us", + "cc.sd.us", + "cc.tn.us", + "cc.tx.us", + "cc.ut.us", + "cc.vi.us", + "cc.vt.us", + "cc.va.us", + "cc.wa.us", + "cc.wi.us", + "cc.wv.us", + "cc.wy.us", + "lib.ak.us", + "lib.al.us", + "lib.ar.us", + "lib.as.us", + "lib.az.us", + "lib.ca.us", + "lib.co.us", + "lib.ct.us", + "lib.dc.us", + "lib.de.us", + "lib.fl.us", + "lib.ga.us", + "lib.gu.us", + "lib.hi.us", + "lib.ia.us", + "lib.id.us", + "lib.il.us", + "lib.in.us", + "lib.ks.us", + "lib.ky.us", + "lib.la.us", + "lib.ma.us", + "lib.md.us", + "lib.me.us", + "lib.mi.us", + "lib.mn.us", + "lib.mo.us", + "lib.ms.us", + "lib.mt.us", + "lib.nc.us", + "lib.nd.us", + "lib.ne.us", + "lib.nh.us", + "lib.nj.us", + "lib.nm.us", + "lib.nv.us", + "lib.ny.us", + "lib.oh.us", + "lib.ok.us", + "lib.or.us", + "lib.pa.us", + "lib.pr.us", + "lib.ri.us", + "lib.sc.us", + "lib.sd.us", + "lib.tn.us", + "lib.tx.us", + "lib.ut.us", + "lib.vi.us", + "lib.vt.us", + "lib.va.us", + "lib.wa.us", + "lib.wi.us", + "lib.wy.us", + "pvt.k12.ma.us", + "chtr.k12.ma.us", + "paroch.k12.ma.us", + "uy", + "com.uy", + "edu.uy", + "gub.uy", + "mil.uy", + "net.uy", + "org.uy", + "uz", + "co.uz", + "com.uz", + "net.uz", + "org.uz", + "va", + "vc", + "com.vc", + "net.vc", + "org.vc", + "gov.vc", + "mil.vc", + "edu.vc", + "ve", + "arts.ve", + "co.ve", + "com.ve", + "e12.ve", + "edu.ve", + "firm.ve", + "gob.ve", + "gov.ve", + "info.ve", + "int.ve", + "mil.ve", + "net.ve", + "org.ve", + "rec.ve", + "store.ve", + "tec.ve", + "web.ve", + "vg", + "vi", + "co.vi", + "com.vi", + "k12.vi", + "net.vi", + "org.vi", + "vn", + "com.vn", + "net.vn", + "org.vn", + "edu.vn", + "gov.vn", + "int.vn", + "ac.vn", + "biz.vn", + "info.vn", + "name.vn", + "pro.vn", + "health.vn", + "vu", + "com.vu", + "edu.vu", + "net.vu", + "org.vu", + "wf", + "ws", + "com.ws", + "net.ws", + "org.ws", + "gov.ws", + "edu.ws", + "yt", + "xn--mgbaam7a8h", + "xn--y9a3aq", + "xn--54b7fta0cc", + "xn--90ais", + "xn--fiqs8s", + "xn--fiqz9s", + "xn--lgbbat1ad8j", + "xn--wgbh1c", + "xn--node", + "xn--qxam", + "xn--j6w193g", + "xn--h2brj9c", + "xn--mgbbh1a71e", + "xn--fpcrj9c3d", + "xn--gecrj9c", + "xn--s9brj9c", + "xn--45brj9c", + "xn--xkc2dl3a5ee0h", + "xn--mgba3a4f16a", + "xn--mgba3a4fra", + "xn--mgbtx2b", + "xn--mgbayh7gpa", + "xn--3e0b707e", + "xn--80ao21a", + "xn--fzc2c9e2c", + "xn--xkc2al3hye2a", + "xn--mgbc0a9azcg", + "xn--d1alf", + "xn--l1acc", + "xn--mix891f", + "xn--mix082f", + "xn--mgbx4cd0ab", + "xn--mgb9awbf", + "xn--mgbai9azgqp6j", + "xn--mgbai9a5eva00b", + "xn--ygbi2ammx", + "xn--90a3ac", + "xn--o1ac.xn--90a3ac", + "xn--c1avg.xn--90a3ac", + "xn--90azh.xn--90a3ac", + "xn--d1at.xn--90a3ac", + "xn--o1ach.xn--90a3ac", + "xn--80au.xn--90a3ac", + "xn--p1ai", + "xn--wgbl6a", + "xn--mgberp4a5d4ar", + "xn--mgberp4a5d4a87g", + "xn--mgbqly7c0a67fbc", + "xn--mgbqly7cvafr", + "xn--mgbpl2fh", + "xn--yfro4i67o", + "xn--clchc0ea0b2g2a9gcd", + "xn--ogbpf8fl", + "xn--mgbtf8fl", + "xn--o3cw4h", + "xn--pgbs0dh", + "xn--kpry57d", + "xn--kprw13d", + "xn--nnx388a", + "xn--j1amh", + "xn--mgb2ddes", + "xxx", + "*.ye", + "ac.za", + "agric.za", + "alt.za", + "co.za", + "edu.za", + "gov.za", + "grondar.za", + "law.za", + "mil.za", + "net.za", + "ngo.za", + "nis.za", + "nom.za", + "org.za", + "school.za", + "tm.za", + "web.za", + "*.zm", + "*.zw", + "aaa", + "aarp", + "abarth", + "abb", + "abbott", + "abbvie", + "abc", + "able", + "abogado", + "abudhabi", + "academy", + "accenture", + "accountant", + "accountants", + "aco", + "active", + "actor", + "adac", + "ads", + "adult", + "aeg", + "aetna", + "afamilycompany", + "afl", + "africa", + "africamagic", + "agakhan", + "agency", + "aig", + "aigo", + "airbus", + "airforce", + "airtel", + "akdn", + "alfaromeo", + "alibaba", + "alipay", + "allfinanz", + "allstate", + "ally", + "alsace", + "alstom", + "americanexpress", + "americanfamily", + "amex", + "amfam", + "amica", + "amsterdam", + "analytics", + "android", + "anquan", + "anz", + "aol", + "apartments", + "app", + "apple", + "aquarelle", + "arab", + "aramco", + "archi", + "army", + "arte", + "asda", + "associates", + "athleta", + "attorney", + "auction", + "audi", + "audible", + "audio", + "auspost", + "author", + "auto", + "autos", + "avianca", + "aws", + "axa", + "azure", + "baby", + "baidu", + "banamex", + "bananarepublic", + "band", + "bank", + "bar", + "barcelona", + "barclaycard", + "barclays", + "barefoot", + "bargains", + "baseball", + "basketball", + "bauhaus", + "bayern", + "bbc", + "bbt", + "bbva", + "bcg", + "bcn", + "beats", + "beauty", + "beer", + "bentley", + "berlin", + "best", + "bestbuy", + "bet", + "bharti", + "bible", + "bid", + "bike", + "bing", + "bingo", + "bio", + "black", + "blackfriday", + "blanco", + "blockbuster", + "blog", + "bloomberg", + "blue", + "bms", + "bmw", + "bnl", + "bnpparibas", + "boats", + "boehringer", + "bofa", + "bom", + "bond", + "boo", + "book", + "booking", + "boots", + "bosch", + "bostik", + "boston", + "bot", + "boutique", + "box", + "bradesco", + "bridgestone", + "broadway", + "broker", + "brother", + "brussels", + "budapest", + "bugatti", + "build", + "builders", + "business", + "buy", + "buzz", + "bzh", + "cab", + "cafe", + "cal", + "call", + "calvinklein", + "camera", + "camp", + "cancerresearch", + "canon", + "capetown", + "capital", + "capitalone", + "car", + "caravan", + "cards", + "care", + "career", + "careers", + "cars", + "cartier", + "casa", + "case", + "caseih", + "cash", + "casino", + "catering", + "catholic", + "cba", + "cbn", + "cbre", + "cbs", + "ceb", + "center", + "ceo", + "cern", + "cfa", + "cfd", + "chanel", + "channel", + "chase", + "chat", + "cheap", + "chintai", + "chloe", + "christmas", + "chrome", + "chrysler", + "church", + "cipriani", + "circle", + "cisco", + "citadel", + "citi", + "citic", + "city", + "cityeats", + "claims", + "cleaning", + "click", + "clinic", + "clinique", + "clothing", + "cloud", + "club", + "clubmed", + "coach", + "codes", + "coffee", + "college", + "cologne", + "comcast", + "commbank", + "community", + "company", + "compare", + "computer", + "comsec", + "condos", + "construction", + "consulting", + "contact", + "contractors", + "cooking", + "cookingchannel", + "cool", + "corsica", + "country", + "coupon", + "coupons", + "courses", + "credit", + "creditcard", + "creditunion", + "cricket", + "crown", + "crs", + "cruise", + "cruises", + "csc", + "cuisinella", + "cymru", + "cyou", + "dabur", + "dad", + "dance", + "date", + "dating", + "datsun", + "day", + "dclk", + "dds", + "deal", + "dealer", + "deals", + "degree", + "delivery", + "dell", + "deloitte", + "delta", + "democrat", + "dental", + "dentist", + "desi", + "design", + "dev", + "dhl", + "diamonds", + "diet", + "digital", + "direct", + "directory", + "discount", + "discover", + "dish", + "diy", + "dnp", + "docs", + "dodge", + "dog", + "doha", + "domains", + "doosan", + "dot", + "download", + "drive", + "dstv", + "dtv", + "dubai", + "duck", + "dunlop", + "duns", + "dupont", + "durban", + "dvag", + "dwg", + "earth", + "eat", + "edeka", + "education", + "email", + "emerck", + "emerson", + "energy", + "engineer", + "engineering", + "enterprises", + "epost", + "epson", + "equipment", + "ericsson", + "erni", + "esq", + "estate", + "esurance", + "etisalat", + "eurovision", + "eus", + "events", + "everbank", + "exchange", + "expert", + "exposed", + "express", + "extraspace", + "fage", + "fail", + "fairwinds", + "faith", + "family", + "fan", + "fans", + "farm", + "farmers", + "fashion", + "fast", + "fedex", + "feedback", + "ferrari", + "ferrero", + "fiat", + "fidelity", + "fido", + "film", + "final", + "finance", + "financial", + "fire", + "firestone", + "firmdale", + "fish", + "fishing", + "fit", + "fitness", + "flickr", + "flights", + "flir", + "florist", + "flowers", + "flsmidth", + "fly", + "foo", + "foodnetwork", + "football", + "ford", + "forex", + "forsale", + "forum", + "foundation", + "fox", + "free", + "fresenius", + "frl", + "frogans", + "frontdoor", + "frontier", + "ftr", + "fujitsu", + "fujixerox", + "fund", + "furniture", + "futbol", + "fyi", + "gal", + "gallery", + "gallo", + "gallup", + "game", + "games", + "gap", + "garden", + "gbiz", + "gdn", + "gea", + "gent", + "genting", + "george", + "ggee", + "gift", + "gifts", + "gives", + "giving", + "glade", + "glass", + "gle", + "global", + "globo", + "gmail", + "gmo", + "gmx", + "godaddy", + "gold", + "goldpoint", + "golf", + "goo", + "goodhands", + "goodyear", + "goog", + "google", + "gop", + "got", + "gotv", + "grainger", + "graphics", + "gratis", + "green", + "gripe", + "group", + "guardian", + "gucci", + "guge", + "guide", + "guitars", + "guru", + "hair", + "hamburg", + "hangout", + "haus", + "hbo", + "hdfc", + "hdfcbank", + "health", + "healthcare", + "help", + "helsinki", + "here", + "hermes", + "hgtv", + "hiphop", + "hisamitsu", + "hitachi", + "hiv", + "hkt", + "hockey", + "holdings", + "holiday", + "homedepot", + "homegoods", + "homes", + "homesense", + "honda", + "honeywell", + "horse", + "host", + "hosting", + "hot", + "hoteles", + "hotmail", + "house", + "how", + "hsbc", + "htc", + "hughes", + "hyatt", + "hyundai", + "ibm", + "icbc", + "ice", + "icu", + "ieee", + "ifm", + "iinet", + "ikano", + "imamat", + "imdb", + "immo", + "immobilien", + "industries", + "infiniti", + "ing", + "ink", + "institute", + "insurance", + "insure", + "intel", + "international", + "intuit", + "investments", + "ipiranga", + "irish", + "iselect", + "ismaili", + "ist", + "istanbul", + "itau", + "itv", + "iveco", + "iwc", + "jaguar", + "java", + "jcb", + "jcp", + "jeep", + "jetzt", + "jewelry", + "jio", + "jlc", + "jll", + "jmp", + "jnj", + "joburg", + "jot", + "joy", + "jpmorgan", + "jprs", + "juegos", + "juniper", + "kaufen", + "kddi", + "kerryhotels", + "kerrylogistics", + "kerryproperties", + "kfh", + "kia", + "kim", + "kinder", + "kindle", + "kitchen", + "kiwi", + "koeln", + "komatsu", + "kosher", + "kpmg", + "kpn", + "krd", + "kred", + "kuokgroup", + "kyknet", + "kyoto", + "lacaixa", + "ladbrokes", + "lamborghini", + "lamer", + "lancaster", + "lancia", + "lancome", + "land", + "landrover", + "lanxess", + "lasalle", + "lat", + "latino", + "latrobe", + "law", + "lawyer", + "lds", + "lease", + "leclerc", + "lefrak", + "legal", + "lego", + "lexus", + "lgbt", + "liaison", + "lidl", + "life", + "lifeinsurance", + "lifestyle", + "lighting", + "like", + "lilly", + "limited", + "limo", + "lincoln", + "linde", + "link", + "lipsy", + "live", + "living", + "lixil", + "loan", + "loans", + "locker", + "locus", + "loft", + "lol", + "london", + "lotte", + "lotto", + "love", + "lpl", + "lplfinancial", + "ltd", + "ltda", + "lundbeck", + "lupin", + "luxe", + "luxury", + "macys", + "madrid", + "maif", + "maison", + "makeup", + "man", + "management", + "mango", + "market", + "marketing", + "markets", + "marriott", + "marshalls", + "maserati", + "mattel", + "mba", + "mcd", + "mcdonalds", + "mckinsey", + "med", + "media", + "meet", + "melbourne", + "meme", + "memorial", + "men", + "menu", + "meo", + "metlife", + "miami", + "microsoft", + "mini", + "mint", + "mit", + "mitsubishi", + "mlb", + "mls", + "mma", + "mnet", + "mobily", + "moda", + "moe", + "moi", + "mom", + "monash", + "money", + "monster", + "montblanc", + "mopar", + "mormon", + "mortgage", + "moscow", + "moto", + "motorcycles", + "mov", + "movie", + "movistar", + "msd", + "mtn", + "mtpc", + "mtr", + "multichoice", + "mutual", + "mutuelle", + "mzansimagic", + "nab", + "nadex", + "nagoya", + "naspers", + "nationwide", + "natura", + "navy", + "nba", + "nec", + "netbank", + "netflix", + "network", + "neustar", + "new", + "newholland", + "news", + "next", + "nextdirect", + "nexus", + "nfl", + "ngo", + "nhk", + "nico", + "nike", + "nikon", + "ninja", + "nissan", + "nissay", + "nokia", + "northwesternmutual", + "norton", + "now", + "nowruz", + "nowtv", + "nra", + "nrw", + "ntt", + "nyc", + "obi", + "observer", + "off", + "office", + "okinawa", + "olayan", + "olayangroup", + "oldnavy", + "ollo", + "omega", + "one", + "ong", + "onl", + "online", + "onyourside", + "ooo", + "open", + "oracle", + "orange", + "organic", + "orientexpress", + "origins", + "osaka", + "otsuka", + "ott", + "ovh", + "page", + "pamperedchef", + "panasonic", + "panerai", + "paris", + "pars", + "partners", + "parts", + "party", + "passagens", + "pay", + "payu", + "pccw", + "pet", + "pfizer", + "pharmacy", + "philips", + "photo", + "photography", + "photos", + "physio", + "piaget", + "pics", + "pictet", + "pictures", + "pid", + "pin", + "ping", + "pink", + "pioneer", + "pizza", + "place", + "play", + "playstation", + "plumbing", + "plus", + "pnc", + "pohl", + "poker", + "politie", + "porn", + "pramerica", + "praxi", + "press", + "prime", + "prod", + "productions", + "prof", + "progressive", + "promo", + "properties", + "property", + "protection", + "pru", + "prudential", + "pub", + "pwc", + "qpon", + "quebec", + "quest", + "qvc", + "racing", + "raid", + "read", + "realestate", + "realtor", + "realty", + "recipes", + "red", + "redstone", + "redumbrella", + "rehab", + "reise", + "reisen", + "reit", + "reliance", + "ren", + "rent", + "rentals", + "repair", + "report", + "republican", + "rest", + "restaurant", + "review", + "reviews", + "rexroth", + "rich", + "richardli", + "ricoh", + "rightathome", + "ril", + "rio", + "rip", + "rmit", + "rocher", + "rocks", + "rodeo", + "rogers", + "room", + "rsvp", + "ruhr", + "run", + "rwe", + "ryukyu", + "saarland", + "safe", + "safety", + "sakura", + "sale", + "salon", + "samsclub", + "samsung", + "sandvik", + "sandvikcoromant", + "sanofi", + "sap", + "sapo", + "sarl", + "sas", + "save", + "saxo", + "sbi", + "sbs", + "sca", + "scb", + "schaeffler", + "schmidt", + "scholarships", + "school", + "schule", + "schwarz", + "science", + "scjohnson", + "scor", + "scot", + "seat", + "secure", + "security", + "seek", + "select", + "sener", + "services", + "ses", + "seven", + "sew", + "sex", + "sexy", + "sfr", + "shangrila", + "sharp", + "shaw", + "shell", + "shia", + "shiksha", + "shoes", + "shouji", + "show", + "showtime", + "shriram", + "silk", + "sina", + "singles", + "site", + "ski", + "skin", + "sky", + "skype", + "sling", + "smart", + "smile", + "sncf", + "soccer", + "social", + "softbank", + "software", + "sohu", + "solar", + "solutions", + "song", + "sony", + "soy", + "space", + "spiegel", + "spot", + "spreadbetting", + "srl", + "srt", + "stada", + "staples", + "star", + "starhub", + "statebank", + "statefarm", + "statoil", + "stc", + "stcgroup", + "stockholm", + "storage", + "store", + "studio", + "study", + "style", + "sucks", + "supersport", + "supplies", + "supply", + "support", + "surf", + "surgery", + "suzuki", + "swatch", + "swiftcover", + "swiss", + "sydney", + "symantec", + "systems", + "tab", + "taipei", + "talk", + "taobao", + "target", + "tatamotors", + "tatar", + "tattoo", + "tax", + "taxi", + "tci", + "tdk", + "team", + "tech", + "technology", + "telecity", + "telefonica", + "temasek", + "tennis", + "teva", + "thd", + "theater", + "theatre", + "theguardian", + "tiaa", + "tickets", + "tienda", + "tiffany", + "tips", + "tires", + "tirol", + "tjmaxx", + "tjx", + "tkmaxx", + "tmall", + "today", + "tokyo", + "tools", + "top", + "toray", + "toshiba", + "total", + "tours", + "town", + "toyota", + "toys", + "trade", + "trading", + "training", + "travelchannel", + "travelers", + "travelersinsurance", + "trust", + "trv", + "tube", + "tui", + "tunes", + "tushu", + "tvs", + "ubank", + "ubs", + "uconnect", + "unicom", + "university", + "uno", + "uol", + "ups", + "vacations", + "vana", + "vanguard", + "vegas", + "ventures", + "verisign", + "versicherung", + "vet", + "viajes", + "video", + "vig", + "viking", + "villas", + "vin", + "vip", + "virgin", + "visa", + "vision", + "vista", + "vistaprint", + "viva", + "vivo", + "vlaanderen", + "vodka", + "volkswagen", + "volvo", + "vote", + "voting", + "voto", + "voyage", + "vuelos", + "wales", + "walmart", + "walter", + "wang", + "wanggou", + "warman", + "watch", + "watches", + "weather", + "weatherchannel", + "webcam", + "weber", + "website", + "wed", + "wedding", + "weibo", + "weir", + "whoswho", + "wien", + "wiki", + "williamhill", + "win", + "windows", + "wine", + "winners", + "wme", + "wolterskluwer", + "woodside", + "work", + "works", + "world", + "wow", + "wtc", + "wtf", + "xbox", + "xerox", + "xfinity", + "xihuan", + "xin", + "xn--11b4c3d", + "xn--1ck2e1b", + "xn--1qqw23a", + "xn--30rr7y", + "xn--3bst00m", + "xn--3ds443g", + "xn--3oq18vl8pn36a", + "xn--3pxu8k", + "xn--42c2d9a", + "xn--45q11c", + "xn--4gbrim", + "xn--4gq48lf9j", + "xn--55qw42g", + "xn--55qx5d", + "xn--5su34j936bgsg", + "xn--5tzm5g", + "xn--6frz82g", + "xn--6qq986b3xl", + "xn--80adxhks", + "xn--80aqecdr1a", + "xn--80asehdb", + "xn--80aswg", + "xn--8y0a063a", + "xn--9dbq2a", + "xn--9et52u", + "xn--9krt00a", + "xn--b4w605ferd", + "xn--bck1b9a5dre4c", + "xn--c1avg", + "xn--c2br7g", + "xn--cck2b3b", + "xn--cg4bki", + "xn--czr694b", + "xn--czrs0t", + "xn--czru2d", + "xn--d1acj3b", + "xn--eckvdtc9d", + "xn--efvy88h", + "xn--estv75g", + "xn--fct429k", + "xn--fhbei", + "xn--fiq228c5hs", + "xn--fiq64b", + "xn--fjq720a", + "xn--flw351e", + "xn--fzys8d69uvgm", + "xn--g2xx48c", + "xn--gckr3f0f", + "xn--gk3at1e", + "xn--hxt814e", + "xn--i1b6b1a6a2e", + "xn--imr513n", + "xn--io0a7i", + "xn--j1aef", + "xn--jlq61u9w7b", + "xn--jvr189m", + "xn--kcrx77d1x4a", + "xn--kpu716f", + "xn--kput3i", + "xn--mgba3a3ejt", + "xn--mgba7c0bbn0a", + "xn--mgbaakc7dvf", + "xn--mgbab2bd", + "xn--mgbb9fbpob", + "xn--mgbca7dzdo", + "xn--mgbi4ecexp", + "xn--mgbt3dhd", + "xn--mk1bu44c", + "xn--mxtq1m", + "xn--ngbc5azd", + "xn--ngbe9e0a", + "xn--ngbrx", + "xn--nqv7f", + "xn--nqv7fs00ema", + "xn--nyqy26a", + "xn--p1acf", + "xn--pbt977c", + "xn--pssy2u", + "xn--q9jyb4c", + "xn--qcka1pmc", + "xn--rhqv96g", + "xn--rovu88b", + "xn--ses554g", + "xn--t60b56a", + "xn--tckwe", + "xn--tiq49xqyj", + "xn--unup4y", + "xn--vermgensberater-ctb", + "xn--vermgensberatung-pwb", + "xn--vhquv", + "xn--vuq861b", + "xn--w4r85el8fhu5dnra", + "xn--w4rs40l", + "xn--xhq521b", + "xn--zfr164b", + "xperia", + "xyz", + "yachts", + "yahoo", + "yamaxun", + "yandex", + "yodobashi", + "yoga", + "yokohama", + "you", + "youtube", + "yun", + "zappos", + "zara", + "zero", + "zip", + "zippo", + "zone", + "zuerich", + "cloudfront.net", + "ap-northeast-1.compute.amazonaws.com", + "ap-southeast-1.compute.amazonaws.com", + "ap-southeast-2.compute.amazonaws.com", + "cn-north-1.compute.amazonaws.cn", + "compute.amazonaws.cn", + "compute.amazonaws.com", + "compute-1.amazonaws.com", + "eu-west-1.compute.amazonaws.com", + "eu-central-1.compute.amazonaws.com", + "sa-east-1.compute.amazonaws.com", + "us-east-1.amazonaws.com", + "us-gov-west-1.compute.amazonaws.com", + "us-west-1.compute.amazonaws.com", + "us-west-2.compute.amazonaws.com", + "z-1.compute-1.amazonaws.com", + "z-2.compute-1.amazonaws.com", + "elasticbeanstalk.com", + "elb.amazonaws.com", + "s3.amazonaws.com", + "s3-ap-northeast-1.amazonaws.com", + "s3-ap-southeast-1.amazonaws.com", + "s3-ap-southeast-2.amazonaws.com", + "s3-external-1.amazonaws.com", + "s3-external-2.amazonaws.com", + "s3-fips-us-gov-west-1.amazonaws.com", + "s3-eu-central-1.amazonaws.com", + "s3-eu-west-1.amazonaws.com", + "s3-sa-east-1.amazonaws.com", + "s3-us-gov-west-1.amazonaws.com", + "s3-us-west-1.amazonaws.com", + "s3-us-west-2.amazonaws.com", + "s3.cn-north-1.amazonaws.com.cn", + "s3.eu-central-1.amazonaws.com", + "betainabox.com", + "ae.org", + "ar.com", + "br.com", + "cn.com", + "com.de", + "com.se", + "de.com", + "eu.com", + "gb.com", + "gb.net", + "hu.com", + "hu.net", + "jp.net", + "jpn.com", + "kr.com", + "mex.com", + "no.com", + "qc.com", + "ru.com", + "sa.com", + "se.com", + "se.net", + "uk.com", + "uk.net", + "us.com", + "uy.com", + "za.bz", + "za.com", + "africa.com", + "gr.com", + "in.net", + "us.org", + "co.com", + "c.la", + "cloudcontrolled.com", + "cloudcontrolapp.com", + "co.ca", + "co.cz", + "c.cdn77.org", + "cdn77-ssl.net", + "r.cdn77.net", + "rsc.cdn77.org", + "ssl.origin.cdn77-secure.org", + "co.nl", + "co.no", + "*.platform.sh", + "cupcake.is", + "dreamhosters.com", + "mydrobo.com", + "duckdns.org", + "dyndns-at-home.com", + "dyndns-at-work.com", + "dyndns-blog.com", + "dyndns-free.com", + "dyndns-home.com", + "dyndns-ip.com", + "dyndns-mail.com", + "dyndns-office.com", + "dyndns-pics.com", + "dyndns-remote.com", + "dyndns-server.com", + "dyndns-web.com", + "dyndns-wiki.com", + "dyndns-work.com", + "dyndns.biz", + "dyndns.info", + "dyndns.org", + "dyndns.tv", + "at-band-camp.net", + "ath.cx", + "barrel-of-knowledge.info", + "barrell-of-knowledge.info", + "better-than.tv", + "blogdns.com", + "blogdns.net", + "blogdns.org", + "blogsite.org", + "boldlygoingnowhere.org", + "broke-it.net", + "buyshouses.net", + "cechire.com", + "dnsalias.com", + "dnsalias.net", + "dnsalias.org", + "dnsdojo.com", + "dnsdojo.net", + "dnsdojo.org", + "does-it.net", + "doesntexist.com", + "doesntexist.org", + "dontexist.com", + "dontexist.net", + "dontexist.org", + "doomdns.com", + "doomdns.org", + "dvrdns.org", + "dyn-o-saur.com", + "dynalias.com", + "dynalias.net", + "dynalias.org", + "dynathome.net", + "dyndns.ws", + "endofinternet.net", + "endofinternet.org", + "endoftheinternet.org", + "est-a-la-maison.com", + "est-a-la-masion.com", + "est-le-patron.com", + "est-mon-blogueur.com", + "for-better.biz", + "for-more.biz", + "for-our.info", + "for-some.biz", + "for-the.biz", + "forgot.her.name", + "forgot.his.name", + "from-ak.com", + "from-al.com", + "from-ar.com", + "from-az.net", + "from-ca.com", + "from-co.net", + "from-ct.com", + "from-dc.com", + "from-de.com", + "from-fl.com", + "from-ga.com", + "from-hi.com", + "from-ia.com", + "from-id.com", + "from-il.com", + "from-in.com", + "from-ks.com", + "from-ky.com", + "from-la.net", + "from-ma.com", + "from-md.com", + "from-me.org", + "from-mi.com", + "from-mn.com", + "from-mo.com", + "from-ms.com", + "from-mt.com", + "from-nc.com", + "from-nd.com", + "from-ne.com", + "from-nh.com", + "from-nj.com", + "from-nm.com", + "from-nv.com", + "from-ny.net", + "from-oh.com", + "from-ok.com", + "from-or.com", + "from-pa.com", + "from-pr.com", + "from-ri.com", + "from-sc.com", + "from-sd.com", + "from-tn.com", + "from-tx.com", + "from-ut.com", + "from-va.com", + "from-vt.com", + "from-wa.com", + "from-wi.com", + "from-wv.com", + "from-wy.com", + "ftpaccess.cc", + "fuettertdasnetz.de", + "game-host.org", + "game-server.cc", + "getmyip.com", + "gets-it.net", + "go.dyndns.org", + "gotdns.com", + "gotdns.org", + "groks-the.info", + "groks-this.info", + "ham-radio-op.net", + "here-for-more.info", + "hobby-site.com", + "hobby-site.org", + "home.dyndns.org", + "homedns.org", + "homeftp.net", + "homeftp.org", + "homeip.net", + "homelinux.com", + "homelinux.net", + "homelinux.org", + "homeunix.com", + "homeunix.net", + "homeunix.org", + "iamallama.com", + "in-the-band.net", + "is-a-anarchist.com", + "is-a-blogger.com", + "is-a-bookkeeper.com", + "is-a-bruinsfan.org", + "is-a-bulls-fan.com", + "is-a-candidate.org", + "is-a-caterer.com", + "is-a-celticsfan.org", + "is-a-chef.com", + "is-a-chef.net", + "is-a-chef.org", + "is-a-conservative.com", + "is-a-cpa.com", + "is-a-cubicle-slave.com", + "is-a-democrat.com", + "is-a-designer.com", + "is-a-doctor.com", + "is-a-financialadvisor.com", + "is-a-geek.com", + "is-a-geek.net", + "is-a-geek.org", + "is-a-green.com", + "is-a-guru.com", + "is-a-hard-worker.com", + "is-a-hunter.com", + "is-a-knight.org", + "is-a-landscaper.com", + "is-a-lawyer.com", + "is-a-liberal.com", + "is-a-libertarian.com", + "is-a-linux-user.org", + "is-a-llama.com", + "is-a-musician.com", + "is-a-nascarfan.com", + "is-a-nurse.com", + "is-a-painter.com", + "is-a-patsfan.org", + "is-a-personaltrainer.com", + "is-a-photographer.com", + "is-a-player.com", + "is-a-republican.com", + "is-a-rockstar.com", + "is-a-socialist.com", + "is-a-soxfan.org", + "is-a-student.com", + "is-a-teacher.com", + "is-a-techie.com", + "is-a-therapist.com", + "is-an-accountant.com", + "is-an-actor.com", + "is-an-actress.com", + "is-an-anarchist.com", + "is-an-artist.com", + "is-an-engineer.com", + "is-an-entertainer.com", + "is-by.us", + "is-certified.com", + "is-found.org", + "is-gone.com", + "is-into-anime.com", + "is-into-cars.com", + "is-into-cartoons.com", + "is-into-games.com", + "is-leet.com", + "is-lost.org", + "is-not-certified.com", + "is-saved.org", + "is-slick.com", + "is-uberleet.com", + "is-very-bad.org", + "is-very-evil.org", + "is-very-good.org", + "is-very-nice.org", + "is-very-sweet.org", + "is-with-theband.com", + "isa-geek.com", + "isa-geek.net", + "isa-geek.org", + "isa-hockeynut.com", + "issmarterthanyou.com", + "isteingeek.de", + "istmein.de", + "kicks-ass.net", + "kicks-ass.org", + "knowsitall.info", + "land-4-sale.us", + "lebtimnetz.de", + "leitungsen.de", + "likes-pie.com", + "likescandy.com", + "merseine.nu", + "mine.nu", + "misconfused.org", + "mypets.ws", + "myphotos.cc", + "neat-url.com", + "office-on-the.net", + "on-the-web.tv", + "podzone.net", + "podzone.org", + "readmyblog.org", + "saves-the-whales.com", + "scrapper-site.net", + "scrapping.cc", + "selfip.biz", + "selfip.com", + "selfip.info", + "selfip.net", + "selfip.org", + "sells-for-less.com", + "sells-for-u.com", + "sells-it.net", + "sellsyourhome.org", + "servebbs.com", + "servebbs.net", + "servebbs.org", + "serveftp.net", + "serveftp.org", + "servegame.org", + "shacknet.nu", + "simple-url.com", + "space-to-rent.com", + "stuff-4-sale.org", + "stuff-4-sale.us", + "teaches-yoga.com", + "thruhere.net", + "traeumtgerade.de", + "webhop.biz", + "webhop.info", + "webhop.net", + "webhop.org", + "worse-than.tv", + "writesthisblog.com", + "eu.org", + "al.eu.org", + "asso.eu.org", + "at.eu.org", + "au.eu.org", + "be.eu.org", + "bg.eu.org", + "ca.eu.org", + "cd.eu.org", + "ch.eu.org", + "cn.eu.org", + "cy.eu.org", + "cz.eu.org", + "de.eu.org", + "dk.eu.org", + "edu.eu.org", + "ee.eu.org", + "es.eu.org", + "fi.eu.org", + "fr.eu.org", + "gr.eu.org", + "hr.eu.org", + "hu.eu.org", + "ie.eu.org", + "il.eu.org", + "in.eu.org", + "int.eu.org", + "is.eu.org", + "it.eu.org", + "jp.eu.org", + "kr.eu.org", + "lt.eu.org", + "lu.eu.org", + "lv.eu.org", + "mc.eu.org", + "me.eu.org", + "mk.eu.org", + "mt.eu.org", + "my.eu.org", + "net.eu.org", + "ng.eu.org", + "nl.eu.org", + "no.eu.org", + "nz.eu.org", + "paris.eu.org", + "pl.eu.org", + "pt.eu.org", + "q-a.eu.org", + "ro.eu.org", + "ru.eu.org", + "se.eu.org", + "si.eu.org", + "sk.eu.org", + "tr.eu.org", + "uk.eu.org", + "us.eu.org", + "a.ssl.fastly.net", + "b.ssl.fastly.net", + "global.ssl.fastly.net", + "a.prod.fastly.net", + "global.prod.fastly.net", + "firebaseapp.com", + "flynnhub.com", + "service.gov.uk", + "github.io", + "githubusercontent.com", + "ro.com", + "appspot.com", + "blogspot.ae", + "blogspot.al", + "blogspot.am", + "blogspot.ba", + "blogspot.be", + "blogspot.bg", + "blogspot.bj", + "blogspot.ca", + "blogspot.cf", + "blogspot.ch", + "blogspot.cl", + "blogspot.co.at", + "blogspot.co.id", + "blogspot.co.il", + "blogspot.co.ke", + "blogspot.co.nz", + "blogspot.co.uk", + "blogspot.co.za", + "blogspot.com", + "blogspot.com.ar", + "blogspot.com.au", + "blogspot.com.br", + "blogspot.com.by", + "blogspot.com.co", + "blogspot.com.cy", + "blogspot.com.ee", + "blogspot.com.eg", + "blogspot.com.es", + "blogspot.com.mt", + "blogspot.com.ng", + "blogspot.com.tr", + "blogspot.com.uy", + "blogspot.cv", + "blogspot.cz", + "blogspot.de", + "blogspot.dk", + "blogspot.fi", + "blogspot.fr", + "blogspot.gr", + "blogspot.hk", + "blogspot.hr", + "blogspot.hu", + "blogspot.ie", + "blogspot.in", + "blogspot.is", + "blogspot.it", + "blogspot.jp", + "blogspot.kr", + "blogspot.li", + "blogspot.lt", + "blogspot.lu", + "blogspot.md", + "blogspot.mk", + "blogspot.mr", + "blogspot.mx", + "blogspot.my", + "blogspot.nl", + "blogspot.no", + "blogspot.pe", + "blogspot.pt", + "blogspot.qa", + "blogspot.re", + "blogspot.ro", + "blogspot.rs", + "blogspot.ru", + "blogspot.se", + "blogspot.sg", + "blogspot.si", + "blogspot.sk", + "blogspot.sn", + "blogspot.td", + "blogspot.tw", + "blogspot.ug", + "blogspot.vn", + "cloudfunctions.net", + "codespot.com", + "googleapis.com", + "googlecode.com", + "pagespeedmobilizer.com", + "withgoogle.com", + "withyoutube.com", + "hashbang.sh", + "herokuapp.com", + "herokussl.com", + "iki.fi", + "biz.at", + "info.at", + "co.pl", + "azurewebsites.net", + "azure-mobile.net", + "cloudapp.net", + "bmoattachments.org", + "4u.com", + "ngrok.io", + "nfshost.com", + "nyc.mn", + "nid.io", + "operaunite.com", + "outsystemscloud.com", + "pagefrontapp.com", + "art.pl", + "gliwice.pl", + "krakow.pl", + "poznan.pl", + "wroc.pl", + "zakopane.pl", + "pantheon.io", + "gotpantheon.com", + "xen.prgmr.com", + "priv.at", + "qa2.com", + "rackmaze.com", + "rackmaze.net", + "rhcloud.com", + "sandcats.io", + "biz.ua", + "co.ua", + "pp.ua", + "sinaapp.com", + "vipsinaapp.com", + "1kapp.com", + "diskstation.me", + "dscloud.biz", + "dscloud.me", + "dscloud.mobi", + "dsmynas.com", + "dsmynas.net", + "dsmynas.org", + "familyds.com", + "familyds.net", + "familyds.org", + "i234.me", + "myds.me", + "synology.me", + "gda.pl", + "gdansk.pl", + "gdynia.pl", + "med.pl", + "sopot.pl", + "hk.com", + "hk.org", + "ltd.hk", + "inc.hk", + "yolasite.com", + "za.net", + "za.org", +} + +var nodeLabels = [...]string{ + "aaa", + "aarp", + "abarth", + "abb", + "abbott", + "abbvie", + "abc", + "able", + "abogado", + "abudhabi", + "ac", + "academy", + "accenture", + "accountant", + "accountants", + "aco", + "active", + "actor", + "ad", + "adac", + "ads", + "adult", + "ae", + "aeg", + "aero", + "aetna", + "af", + "afamilycompany", + "afl", + "africa", + "africamagic", + "ag", + "agakhan", + "agency", + "ai", + "aig", + "aigo", + "airbus", + "airforce", + "airtel", + "akdn", + "al", + "alfaromeo", + "alibaba", + "alipay", + "allfinanz", + "allstate", + "ally", + "alsace", + "alstom", + "am", + "americanexpress", + "americanfamily", + "amex", + "amfam", + "amica", + "amsterdam", + "analytics", + "android", + "anquan", + "anz", + "ao", + "aol", + "apartments", + "app", + "apple", + "aq", + "aquarelle", + "ar", + "arab", + "aramco", + "archi", + "army", + "arpa", + "arte", + "as", + "asda", + "asia", + "associates", + "at", + "athleta", + "attorney", + "au", + "auction", + "audi", + "audible", + "audio", + "auspost", + "author", + "auto", + "autos", + "avianca", + "aw", + "aws", + "ax", + "axa", + "az", + "azure", + "ba", + "baby", + "baidu", + "banamex", + "bananarepublic", + "band", + "bank", + "bar", + "barcelona", + "barclaycard", + "barclays", + "barefoot", + "bargains", + "baseball", + "basketball", + "bauhaus", + "bayern", + "bb", + "bbc", + "bbt", + "bbva", + "bcg", + "bcn", + "bd", + "be", + "beats", + "beauty", + "beer", + "bentley", + "berlin", + "best", + "bestbuy", + "bet", + "bf", + "bg", + "bh", + "bharti", + "bi", + "bible", + "bid", + "bike", + "bing", + "bingo", + "bio", + "biz", + "bj", + "black", + "blackfriday", + "blanco", + "blockbuster", + "blog", + "bloomberg", + "blue", + "bm", + "bms", + "bmw", + "bn", + "bnl", + "bnpparibas", + "bo", + "boats", + "boehringer", + "bofa", + "bom", + "bond", + "boo", + "book", + "booking", + "boots", + "bosch", + "bostik", + "boston", + "bot", + "boutique", + "box", + "br", + "bradesco", + "bridgestone", + "broadway", + "broker", + "brother", + "brussels", + "bs", + "bt", + "budapest", + "bugatti", + "build", + "builders", + "business", + "buy", + "buzz", + "bv", + "bw", + "by", + "bz", + "bzh", + "ca", + "cab", + "cafe", + "cal", + "call", + "calvinklein", + "camera", + "camp", + "cancerresearch", + "canon", + "capetown", + "capital", + "capitalone", + "car", + "caravan", + "cards", + "care", + "career", + "careers", + "cars", + "cartier", + "casa", + "case", + "caseih", + "cash", + "casino", + "cat", + "catering", + "catholic", + "cba", + "cbn", + "cbre", + "cbs", + "cc", + "cd", + "ceb", + "center", + "ceo", + "cern", + "cf", + "cfa", + "cfd", + "cg", + "ch", + "chanel", + "channel", + "chase", + "chat", + "cheap", + "chintai", + "chloe", + "christmas", + "chrome", + "chrysler", + "church", + "ci", + "cipriani", + "circle", + "cisco", + "citadel", + "citi", + "citic", + "city", + "cityeats", + "ck", + "cl", + "claims", + "cleaning", + "click", + "clinic", + "clinique", + "clothing", + "cloud", + "club", + "clubmed", + "cm", + "cn", + "co", + "coach", + "codes", + "coffee", + "college", + "cologne", + "com", + "comcast", + "commbank", + "community", + "company", + "compare", + "computer", + "comsec", + "condos", + "construction", + "consulting", + "contact", + "contractors", + "cooking", + "cookingchannel", + "cool", + "coop", + "corsica", + "country", + "coupon", + "coupons", + "courses", + "cr", + "credit", + "creditcard", + "creditunion", + "cricket", + "crown", + "crs", + "cruise", + "cruises", + "csc", + "cu", + "cuisinella", + "cv", + "cw", + "cx", + "cy", + "cymru", + "cyou", + "cz", + "dabur", + "dad", + "dance", + "date", + "dating", + "datsun", + "day", + "dclk", + "dds", + "de", + "deal", + "dealer", + "deals", + "degree", + "delivery", + "dell", + "deloitte", + "delta", + "democrat", + "dental", + "dentist", + "desi", + "design", + "dev", + "dhl", + "diamonds", + "diet", + "digital", + "direct", + "directory", + "discount", + "discover", + "dish", + "diy", + "dj", + "dk", + "dm", + "dnp", + "do", + "docs", + "dodge", + "dog", + "doha", + "domains", + "doosan", + "dot", + "download", + "drive", + "dstv", + "dtv", + "dubai", + "duck", + "dunlop", + "duns", + "dupont", + "durban", + "dvag", + "dwg", + "dz", + "earth", + "eat", + "ec", + "edeka", + "edu", + "education", + "ee", + "eg", + "email", + "emerck", + "emerson", + "energy", + "engineer", + "engineering", + "enterprises", + "epost", + "epson", + "equipment", + "er", + "ericsson", + "erni", + "es", + "esq", + "estate", + "esurance", + "et", + "etisalat", + "eu", + "eurovision", + "eus", + "events", + "everbank", + "exchange", + "expert", + "exposed", + "express", + "extraspace", + "fage", + "fail", + "fairwinds", + "faith", + "family", + "fan", + "fans", + "farm", + "farmers", + "fashion", + "fast", + "fedex", + "feedback", + "ferrari", + "ferrero", + "fi", + "fiat", + "fidelity", + "fido", + "film", + "final", + "finance", + "financial", + "fire", + "firestone", + "firmdale", + "fish", + "fishing", + "fit", + "fitness", + "fj", + "fk", + "flickr", + "flights", + "flir", + "florist", + "flowers", + "flsmidth", + "fly", + "fm", + "fo", + "foo", + "foodnetwork", + "football", + "ford", + "forex", + "forsale", + "forum", + "foundation", + "fox", + "fr", + "free", + "fresenius", + "frl", + "frogans", + "frontdoor", + "frontier", + "ftr", + "fujitsu", + "fujixerox", + "fund", + "furniture", + "futbol", + "fyi", + "ga", + "gal", + "gallery", + "gallo", + "gallup", + "game", + "games", + "gap", + "garden", + "gb", + "gbiz", + "gd", + "gdn", + "ge", + "gea", + "gent", + "genting", + "george", + "gf", + "gg", + "ggee", + "gh", + "gi", + "gift", + "gifts", + "gives", + "giving", + "gl", + "glade", + "glass", + "gle", + "global", + "globo", + "gm", + "gmail", + "gmo", + "gmx", + "gn", + "godaddy", + "gold", + "goldpoint", + "golf", + "goo", + "goodhands", + "goodyear", + "goog", + "google", + "gop", + "got", + "gotv", + "gov", + "gp", + "gq", + "gr", + "grainger", + "graphics", + "gratis", + "green", + "gripe", + "group", + "gs", + "gt", + "gu", + "guardian", + "gucci", + "guge", + "guide", + "guitars", + "guru", + "gw", + "gy", + "hair", + "hamburg", + "hangout", + "haus", + "hbo", + "hdfc", + "hdfcbank", + "health", + "healthcare", + "help", + "helsinki", + "here", + "hermes", + "hgtv", + "hiphop", + "hisamitsu", + "hitachi", + "hiv", + "hk", + "hkt", + "hm", + "hn", + "hockey", + "holdings", + "holiday", + "homedepot", + "homegoods", + "homes", + "homesense", + "honda", + "honeywell", + "horse", + "host", + "hosting", + "hot", + "hoteles", + "hotmail", + "house", + "how", + "hr", + "hsbc", + "ht", + "htc", + "hu", + "hughes", + "hyatt", + "hyundai", + "ibm", + "icbc", + "ice", + "icu", + "id", + "ie", + "ieee", + "ifm", + "iinet", + "ikano", + "il", + "im", + "imamat", + "imdb", + "immo", + "immobilien", + "in", + "industries", + "infiniti", + "info", + "ing", + "ink", + "institute", + "insurance", + "insure", + "int", + "intel", + "international", + "intuit", + "investments", + "io", + "ipiranga", + "iq", + "ir", + "irish", + "is", + "iselect", + "ismaili", + "ist", + "istanbul", + "it", + "itau", + "itv", + "iveco", + "iwc", + "jaguar", + "java", + "jcb", + "jcp", + "je", + "jeep", + "jetzt", + "jewelry", + "jio", + "jlc", + "jll", + "jm", + "jmp", + "jnj", + "jo", + "jobs", + "joburg", + "jot", + "joy", + "jp", + "jpmorgan", + "jprs", + "juegos", + "juniper", + "kaufen", + "kddi", + "ke", + "kerryhotels", + "kerrylogistics", + "kerryproperties", + "kfh", + "kg", + "kh", + "ki", + "kia", + "kim", + "kinder", + "kindle", + "kitchen", + "kiwi", + "km", + "kn", + "koeln", + "komatsu", + "kosher", + "kp", + "kpmg", + "kpn", + "kr", + "krd", + "kred", + "kuokgroup", + "kw", + "ky", + "kyknet", + "kyoto", + "kz", + "la", + "lacaixa", + "ladbrokes", + "lamborghini", + "lamer", + "lancaster", + "lancia", + "lancome", + "land", + "landrover", + "lanxess", + "lasalle", + "lat", + "latino", + "latrobe", + "law", + "lawyer", + "lb", + "lc", + "lds", + "lease", + "leclerc", + "lefrak", + "legal", + "lego", + "lexus", + "lgbt", + "li", + "liaison", + "lidl", + "life", + "lifeinsurance", + "lifestyle", + "lighting", + "like", + "lilly", + "limited", + "limo", + "lincoln", + "linde", + "link", + "lipsy", + "live", + "living", + "lixil", + "lk", + "loan", + "loans", + "locker", + "locus", + "loft", + "lol", + "london", + "lotte", + "lotto", + "love", + "lpl", + "lplfinancial", + "lr", + "ls", + "lt", + "ltd", + "ltda", + "lu", + "lundbeck", + "lupin", + "luxe", + "luxury", + "lv", + "ly", + "ma", + "macys", + "madrid", + "maif", + "maison", + "makeup", + "man", + "management", + "mango", + "market", + "marketing", + "markets", + "marriott", + "marshalls", + "maserati", + "mattel", + "mba", + "mc", + "mcd", + "mcdonalds", + "mckinsey", + "md", + "me", + "med", + "media", + "meet", + "melbourne", + "meme", + "memorial", + "men", + "menu", + "meo", + "metlife", + "mg", + "mh", + "miami", + "microsoft", + "mil", + "mini", + "mint", + "mit", + "mitsubishi", + "mk", + "ml", + "mlb", + "mls", + "mm", + "mma", + "mn", + "mnet", + "mo", + "mobi", + "mobily", + "moda", + "moe", + "moi", + "mom", + "monash", + "money", + "monster", + "montblanc", + "mopar", + "mormon", + "mortgage", + "moscow", + "moto", + "motorcycles", + "mov", + "movie", + "movistar", + "mp", + "mq", + "mr", + "ms", + "msd", + "mt", + "mtn", + "mtpc", + "mtr", + "mu", + "multichoice", + "museum", + "mutual", + "mutuelle", + "mv", + "mw", + "mx", + "my", + "mz", + "mzansimagic", + "na", + "nab", + "nadex", + "nagoya", + "name", + "naspers", + "nationwide", + "natura", + "navy", + "nba", + "nc", + "ne", + "nec", + "net", + "netbank", + "netflix", + "network", + "neustar", + "new", + "newholland", + "news", + "next", + "nextdirect", + "nexus", + "nf", + "nfl", + "ng", + "ngo", + "nhk", + "ni", + "nico", + "nike", + "nikon", + "ninja", + "nissan", + "nissay", + "nl", + "no", + "nokia", + "northwesternmutual", + "norton", + "now", + "nowruz", + "nowtv", + "np", + "nr", + "nra", + "nrw", + "ntt", + "nu", + "nyc", + "nz", + "obi", + "observer", + "off", + "office", + "okinawa", + "olayan", + "olayangroup", + "oldnavy", + "ollo", + "om", + "omega", + "one", + "ong", + "onl", + "online", + "onyourside", + "ooo", + "open", + "oracle", + "orange", + "org", + "organic", + "orientexpress", + "origins", + "osaka", + "otsuka", + "ott", + "ovh", + "pa", + "page", + "pamperedchef", + "panasonic", + "panerai", + "paris", + "pars", + "partners", + "parts", + "party", + "passagens", + "pay", + "payu", + "pccw", + "pe", + "pet", + "pf", + "pfizer", + "pg", + "ph", + "pharmacy", + "philips", + "photo", + "photography", + "photos", + "physio", + "piaget", + "pics", + "pictet", + "pictures", + "pid", + "pin", + "ping", + "pink", + "pioneer", + "pizza", + "pk", + "pl", + "place", + "play", + "playstation", + "plumbing", + "plus", + "pm", + "pn", + "pnc", + "pohl", + "poker", + "politie", + "porn", + "post", + "pr", + "pramerica", + "praxi", + "press", + "prime", + "pro", + "prod", + "productions", + "prof", + "progressive", + "promo", + "properties", + "property", + "protection", + "pru", + "prudential", + "ps", + "pt", + "pub", + "pw", + "pwc", + "py", + "qa", + "qpon", + "quebec", + "quest", + "qvc", + "racing", + "raid", + "re", + "read", + "realestate", + "realtor", + "realty", + "recipes", + "red", + "redstone", + "redumbrella", + "rehab", + "reise", + "reisen", + "reit", + "reliance", + "ren", + "rent", + "rentals", + "repair", + "report", + "republican", + "rest", + "restaurant", + "review", + "reviews", + "rexroth", + "rich", + "richardli", + "ricoh", + "rightathome", + "ril", + "rio", + "rip", + "rmit", + "ro", + "rocher", + "rocks", + "rodeo", + "rogers", + "room", + "rs", + "rsvp", + "ru", + "ruhr", + "run", + "rw", + "rwe", + "ryukyu", + "sa", + "saarland", + "safe", + "safety", + "sakura", + "sale", + "salon", + "samsclub", + "samsung", + "sandvik", + "sandvikcoromant", + "sanofi", + "sap", + "sapo", + "sarl", + "sas", + "save", + "saxo", + "sb", + "sbi", + "sbs", + "sc", + "sca", + "scb", + "schaeffler", + "schmidt", + "scholarships", + "school", + "schule", + "schwarz", + "science", + "scjohnson", + "scor", + "scot", + "sd", + "se", + "seat", + "secure", + "security", + "seek", + "select", + "sener", + "services", + "ses", + "seven", + "sew", + "sex", + "sexy", + "sfr", + "sg", + "sh", + "shangrila", + "sharp", + "shaw", + "shell", + "shia", + "shiksha", + "shoes", + "shouji", + "show", + "showtime", + "shriram", + "si", + "silk", + "sina", + "singles", + "site", + "sj", + "sk", + "ski", + "skin", + "sky", + "skype", + "sl", + "sling", + "sm", + "smart", + "smile", + "sn", + "sncf", + "so", + "soccer", + "social", + "softbank", + "software", + "sohu", + "solar", + "solutions", + "song", + "sony", + "soy", + "space", + "spiegel", + "spot", + "spreadbetting", + "sr", + "srl", + "srt", + "st", + "stada", + "staples", + "star", + "starhub", + "statebank", + "statefarm", + "statoil", + "stc", + "stcgroup", + "stockholm", + "storage", + "store", + "studio", + "study", + "style", + "su", + "sucks", + "supersport", + "supplies", + "supply", + "support", + "surf", + "surgery", + "suzuki", + "sv", + "swatch", + "swiftcover", + "swiss", + "sx", + "sy", + "sydney", + "symantec", + "systems", + "sz", + "tab", + "taipei", + "talk", + "taobao", + "target", + "tatamotors", + "tatar", + "tattoo", + "tax", + "taxi", + "tc", + "tci", + "td", + "tdk", + "team", + "tech", + "technology", + "tel", + "telecity", + "telefonica", + "temasek", + "tennis", + "teva", + "tf", + "tg", + "th", + "thd", + "theater", + "theatre", + "theguardian", + "tiaa", + "tickets", + "tienda", + "tiffany", + "tips", + "tires", + "tirol", + "tj", + "tjmaxx", + "tjx", + "tk", + "tkmaxx", + "tl", + "tm", + "tmall", + "tn", + "to", + "today", + "tokyo", + "tools", + "top", + "toray", + "toshiba", + "total", + "tours", + "town", + "toyota", + "toys", + "tr", + "trade", + "trading", + "training", + "travel", + "travelchannel", + "travelers", + "travelersinsurance", + "trust", + "trv", + "tt", + "tube", + "tui", + "tunes", + "tushu", + "tv", + "tvs", + "tw", + "tz", + "ua", + "ubank", + "ubs", + "uconnect", + "ug", + "uk", + "unicom", + "university", + "uno", + "uol", + "ups", + "us", + "uy", + "uz", + "va", + "vacations", + "vana", + "vanguard", + "vc", + "ve", + "vegas", + "ventures", + "verisign", + "versicherung", + "vet", + "vg", + "vi", + "viajes", + "video", + "vig", + "viking", + "villas", + "vin", + "vip", + "virgin", + "visa", + "vision", + "vista", + "vistaprint", + "viva", + "vivo", + "vlaanderen", + "vn", + "vodka", + "volkswagen", + "volvo", + "vote", + "voting", + "voto", + "voyage", + "vu", + "vuelos", + "wales", + "walmart", + "walter", + "wang", + "wanggou", + "warman", + "watch", + "watches", + "weather", + "weatherchannel", + "webcam", + "weber", + "website", + "wed", + "wedding", + "weibo", + "weir", + "wf", + "whoswho", + "wien", + "wiki", + "williamhill", + "win", + "windows", + "wine", + "winners", + "wme", + "wolterskluwer", + "woodside", + "work", + "works", + "world", + "wow", + "ws", + "wtc", + "wtf", + "xbox", + "xerox", + "xfinity", + "xihuan", + "xin", + "xn--11b4c3d", + "xn--1ck2e1b", + "xn--1qqw23a", + "xn--30rr7y", + "xn--3bst00m", + "xn--3ds443g", + "xn--3e0b707e", + "xn--3oq18vl8pn36a", + "xn--3pxu8k", + "xn--42c2d9a", + "xn--45brj9c", + "xn--45q11c", + "xn--4gbrim", + "xn--4gq48lf9j", + "xn--54b7fta0cc", + "xn--55qw42g", + "xn--55qx5d", + "xn--5su34j936bgsg", + "xn--5tzm5g", + "xn--6frz82g", + "xn--6qq986b3xl", + "xn--80adxhks", + "xn--80ao21a", + "xn--80aqecdr1a", + "xn--80asehdb", + "xn--80aswg", + "xn--8y0a063a", + "xn--90a3ac", + "xn--90ais", + "xn--9dbq2a", + "xn--9et52u", + "xn--9krt00a", + "xn--b4w605ferd", + "xn--bck1b9a5dre4c", + "xn--c1avg", + "xn--c2br7g", + "xn--cck2b3b", + "xn--cg4bki", + "xn--clchc0ea0b2g2a9gcd", + "xn--czr694b", + "xn--czrs0t", + "xn--czru2d", + "xn--d1acj3b", + "xn--d1alf", + "xn--eckvdtc9d", + "xn--efvy88h", + "xn--estv75g", + "xn--fct429k", + "xn--fhbei", + "xn--fiq228c5hs", + "xn--fiq64b", + "xn--fiqs8s", + "xn--fiqz9s", + "xn--fjq720a", + "xn--flw351e", + "xn--fpcrj9c3d", + "xn--fzc2c9e2c", + "xn--fzys8d69uvgm", + "xn--g2xx48c", + "xn--gckr3f0f", + "xn--gecrj9c", + "xn--gk3at1e", + "xn--h2brj9c", + "xn--hxt814e", + "xn--i1b6b1a6a2e", + "xn--imr513n", + "xn--io0a7i", + "xn--j1aef", + "xn--j1amh", + "xn--j6w193g", + "xn--jlq61u9w7b", + "xn--jvr189m", + "xn--kcrx77d1x4a", + "xn--kprw13d", + "xn--kpry57d", + "xn--kpu716f", + "xn--kput3i", + "xn--l1acc", + "xn--lgbbat1ad8j", + "xn--mgb2ddes", + "xn--mgb9awbf", + "xn--mgba3a3ejt", + "xn--mgba3a4f16a", + "xn--mgba3a4fra", + "xn--mgba7c0bbn0a", + "xn--mgbaakc7dvf", + "xn--mgbaam7a8h", + "xn--mgbab2bd", + "xn--mgbai9a5eva00b", + "xn--mgbai9azgqp6j", + "xn--mgbayh7gpa", + "xn--mgbb9fbpob", + "xn--mgbbh1a71e", + "xn--mgbc0a9azcg", + "xn--mgbca7dzdo", + "xn--mgberp4a5d4a87g", + "xn--mgberp4a5d4ar", + "xn--mgbi4ecexp", + "xn--mgbpl2fh", + "xn--mgbqly7c0a67fbc", + "xn--mgbqly7cvafr", + "xn--mgbt3dhd", + "xn--mgbtf8fl", + "xn--mgbtx2b", + "xn--mgbx4cd0ab", + "xn--mix082f", + "xn--mix891f", + "xn--mk1bu44c", + "xn--mxtq1m", + "xn--ngbc5azd", + "xn--ngbe9e0a", + "xn--ngbrx", + "xn--nnx388a", + "xn--node", + "xn--nqv7f", + "xn--nqv7fs00ema", + "xn--nyqy26a", + "xn--o3cw4h", + "xn--ogbpf8fl", + "xn--p1acf", + "xn--p1ai", + "xn--pbt977c", + "xn--pgbs0dh", + "xn--pssy2u", + "xn--q9jyb4c", + "xn--qcka1pmc", + "xn--qxam", + "xn--rhqv96g", + "xn--rovu88b", + "xn--s9brj9c", + "xn--ses554g", + "xn--t60b56a", + "xn--tckwe", + "xn--tiq49xqyj", + "xn--unup4y", + "xn--vermgensberater-ctb", + "xn--vermgensberatung-pwb", + "xn--vhquv", + "xn--vuq861b", + "xn--w4r85el8fhu5dnra", + "xn--w4rs40l", + "xn--wgbh1c", + "xn--wgbl6a", + "xn--xhq521b", + "xn--xkc2al3hye2a", + "xn--xkc2dl3a5ee0h", + "xn--y9a3aq", + "xn--yfro4i67o", + "xn--ygbi2ammx", + "xn--zfr164b", + "xperia", + "xxx", + "xyz", + "yachts", + "yahoo", + "yamaxun", + "yandex", + "ye", + "yodobashi", + "yoga", + "yokohama", + "you", + "youtube", + "yt", + "yun", + "za", + "zappos", + "zara", + "zero", + "zip", + "zippo", + "zm", + "zone", + "zuerich", + "zw", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "nom", + "ac", + "blogspot", + "co", + "gov", + "mil", + "net", + "org", + "sch", + "accident-investigation", + "accident-prevention", + "aerobatic", + "aeroclub", + "aerodrome", + "agents", + "air-surveillance", + "air-traffic-control", + "aircraft", + "airline", + "airport", + "airtraffic", + "ambulance", + "amusement", + "association", + "author", + "ballooning", + "broker", + "caa", + "cargo", + "catering", + "certification", + "championship", + "charter", + "civilaviation", + "club", + "conference", + "consultant", + "consulting", + "control", + "council", + "crew", + "design", + "dgca", + "educator", + "emergency", + "engine", + "engineer", + "entertainment", + "equipment", + "exchange", + "express", + "federation", + "flight", + "freight", + "fuel", + "gliding", + "government", + "groundhandling", + "group", + "hanggliding", + "homebuilt", + "insurance", + "journal", + "journalist", + "leasing", + "logistics", + "magazine", + "maintenance", + "media", + "microlight", + "modelling", + "navigation", + "parachuting", + "paragliding", + "passenger-association", + "pilot", + "press", + "production", + "recreation", + "repbody", + "res", + "research", + "rotorcraft", + "safety", + "scientist", + "services", + "show", + "skydiving", + "software", + "student", + "trader", + "trading", + "trainer", + "union", + "workinggroup", + "works", + "com", + "edu", + "gov", + "net", + "org", + "co", + "com", + "net", + "nom", + "org", + "com", + "net", + "off", + "org", + "blogspot", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "blogspot", + "co", + "ed", + "gv", + "it", + "og", + "pb", + "com", + "edu", + "gob", + "gov", + "int", + "mil", + "net", + "org", + "tur", + "blogspot", + "e164", + "in-addr", + "ip6", + "iris", + "uri", + "urn", + "gov", + "ac", + "biz", + "co", + "gv", + "info", + "or", + "priv", + "blogspot", + "act", + "asn", + "com", + "conf", + "edu", + "gov", + "id", + "info", + "net", + "nsw", + "nt", + "org", + "oz", + "qld", + "sa", + "tas", + "vic", + "wa", + "blogspot", + "act", + "nsw", + "nt", + "qld", + "sa", + "tas", + "vic", + "wa", + "qld", + "sa", + "tas", + "vic", + "wa", + "com", + "biz", + "com", + "edu", + "gov", + "info", + "int", + "mil", + "name", + "net", + "org", + "pp", + "pro", + "blogspot", + "co", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "rs", + "unbi", + "unsa", + "biz", + "co", + "com", + "edu", + "gov", + "info", + "net", + "org", + "store", + "tv", + "ac", + "blogspot", + "gov", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "a", + "b", + "blogspot", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "com", + "edu", + "gov", + "net", + "org", + "co", + "com", + "edu", + "or", + "org", + "dscloud", + "dyndns", + "for-better", + "for-more", + "for-some", + "for-the", + "selfip", + "webhop", + "asso", + "barreau", + "blogspot", + "gouv", + "com", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "gob", + "gov", + "int", + "mil", + "net", + "org", + "tv", + "adm", + "adv", + "agr", + "am", + "arq", + "art", + "ato", + "b", + "bio", + "blog", + "bmd", + "cim", + "cng", + "cnt", + "com", + "coop", + "ecn", + "eco", + "edu", + "emp", + "eng", + "esp", + "etc", + "eti", + "far", + "flog", + "fm", + "fnd", + "fot", + "fst", + "g12", + "ggf", + "gov", + "imb", + "ind", + "inf", + "jor", + "jus", + "leg", + "lel", + "mat", + "med", + "mil", + "mp", + "mus", + "net", + "nom", + "not", + "ntr", + "odo", + "org", + "ppg", + "pro", + "psc", + "psi", + "qsl", + "radio", + "rec", + "slg", + "srv", + "taxi", + "teo", + "tmp", + "trd", + "tur", + "tv", + "vet", + "vlog", + "wiki", + "zlg", + "blogspot", + "com", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "gov", + "net", + "org", + "co", + "org", + "com", + "gov", + "mil", + "of", + "blogspot", + "com", + "edu", + "gov", + "net", + "org", + "za", + "ab", + "bc", + "blogspot", + "co", + "gc", + "mb", + "nb", + "nf", + "nl", + "ns", + "nt", + "nu", + "on", + "pe", + "qc", + "sk", + "yk", + "ftpaccess", + "game-server", + "myphotos", + "scrapping", + "gov", + "blogspot", + "blogspot", + "ac", + "asso", + "co", + "com", + "ed", + "edu", + "go", + "gouv", + "int", + "md", + "net", + "or", + "org", + "presse", + "xn--aroport-bya", + "www", + "blogspot", + "co", + "gob", + "gov", + "mil", + "co", + "com", + "gov", + "net", + "ac", + "ah", + "amazonaws", + "bj", + "com", + "cq", + "edu", + "fj", + "gd", + "gov", + "gs", + "gx", + "gz", + "ha", + "hb", + "he", + "hi", + "hk", + "hl", + "hn", + "jl", + "js", + "jx", + "ln", + "mil", + "mo", + "net", + "nm", + "nx", + "org", + "qh", + "sc", + "sd", + "sh", + "sn", + "sx", + "tj", + "tw", + "xj", + "xn--55qx5d", + "xn--io0a7i", + "xn--od0alg", + "xz", + "yn", + "zj", + "compute", + "cn-north-1", + "amazonaws", + "cn-north-1", + "s3", + "arts", + "com", + "edu", + "firm", + "gov", + "info", + "int", + "mil", + "net", + "nom", + "org", + "rec", + "web", + "blogspot", + "1kapp", + "4u", + "africa", + "amazonaws", + "appspot", + "ar", + "betainabox", + "blogdns", + "blogspot", + "br", + "cechire", + "cloudcontrolapp", + "cloudcontrolled", + "cn", + "co", + "codespot", + "de", + "dnsalias", + "dnsdojo", + "doesntexist", + "dontexist", + "doomdns", + "dreamhosters", + "dsmynas", + "dyn-o-saur", + "dynalias", + "dyndns-at-home", + "dyndns-at-work", + "dyndns-blog", + "dyndns-free", + "dyndns-home", + "dyndns-ip", + "dyndns-mail", + "dyndns-office", + "dyndns-pics", + "dyndns-remote", + "dyndns-server", + "dyndns-web", + "dyndns-wiki", + "dyndns-work", + "elasticbeanstalk", + "est-a-la-maison", + "est-a-la-masion", + "est-le-patron", + "est-mon-blogueur", + "eu", + "familyds", + "firebaseapp", + "flynnhub", + "from-ak", + "from-al", + "from-ar", + "from-ca", + "from-ct", + "from-dc", + "from-de", + "from-fl", + "from-ga", + "from-hi", + "from-ia", + "from-id", + "from-il", + "from-in", + "from-ks", + "from-ky", + "from-ma", + "from-md", + "from-mi", + "from-mn", + "from-mo", + "from-ms", + "from-mt", + "from-nc", + "from-nd", + "from-ne", + "from-nh", + "from-nj", + "from-nm", + "from-nv", + "from-oh", + "from-ok", + "from-or", + "from-pa", + "from-pr", + "from-ri", + "from-sc", + "from-sd", + "from-tn", + "from-tx", + "from-ut", + "from-va", + "from-vt", + "from-wa", + "from-wi", + "from-wv", + "from-wy", + "gb", + "getmyip", + "githubusercontent", + "googleapis", + "googlecode", + "gotdns", + "gotpantheon", + "gr", + "herokuapp", + "herokussl", + "hk", + "hobby-site", + "homelinux", + "homeunix", + "hu", + "iamallama", + "is-a-anarchist", + "is-a-blogger", + "is-a-bookkeeper", + "is-a-bulls-fan", + "is-a-caterer", + "is-a-chef", + "is-a-conservative", + "is-a-cpa", + "is-a-cubicle-slave", + "is-a-democrat", + "is-a-designer", + "is-a-doctor", + "is-a-financialadvisor", + "is-a-geek", + "is-a-green", + "is-a-guru", + "is-a-hard-worker", + "is-a-hunter", + "is-a-landscaper", + "is-a-lawyer", + "is-a-liberal", + "is-a-libertarian", + "is-a-llama", + "is-a-musician", + "is-a-nascarfan", + "is-a-nurse", + "is-a-painter", + "is-a-personaltrainer", + "is-a-photographer", + "is-a-player", + "is-a-republican", + "is-a-rockstar", + "is-a-socialist", + "is-a-student", + "is-a-teacher", + "is-a-techie", + "is-a-therapist", + "is-an-accountant", + "is-an-actor", + "is-an-actress", + "is-an-anarchist", + "is-an-artist", + "is-an-engineer", + "is-an-entertainer", + "is-certified", + "is-gone", + "is-into-anime", + "is-into-cars", + "is-into-cartoons", + "is-into-games", + "is-leet", + "is-not-certified", + "is-slick", + "is-uberleet", + "is-with-theband", + "isa-geek", + "isa-hockeynut", + "issmarterthanyou", + "jpn", + "kr", + "likes-pie", + "likescandy", + "mex", + "mydrobo", + "neat-url", + "nfshost", + "no", + "operaunite", + "outsystemscloud", + "pagefrontapp", + "pagespeedmobilizer", + "prgmr", + "qa2", + "qc", + "rackmaze", + "rhcloud", + "ro", + "ru", + "sa", + "saves-the-whales", + "se", + "selfip", + "sells-for-less", + "sells-for-u", + "servebbs", + "simple-url", + "sinaapp", + "space-to-rent", + "teaches-yoga", + "uk", + "us", + "uy", + "vipsinaapp", + "withgoogle", + "withyoutube", + "writesthisblog", + "yolasite", + "za", + "compute", + "compute-1", + "elb", + "eu-central-1", + "s3", + "s3-ap-northeast-1", + "s3-ap-southeast-1", + "s3-ap-southeast-2", + "s3-eu-central-1", + "s3-eu-west-1", + "s3-external-1", + "s3-external-2", + "s3-fips-us-gov-west-1", + "s3-sa-east-1", + "s3-us-gov-west-1", + "s3-us-west-1", + "s3-us-west-2", + "us-east-1", + "ap-northeast-1", + "ap-southeast-1", + "ap-southeast-2", + "eu-central-1", + "eu-west-1", + "sa-east-1", + "us-gov-west-1", + "us-west-1", + "us-west-2", + "z-1", + "z-2", + "s3", + "xen", + "ac", + "co", + "ed", + "fi", + "go", + "or", + "sa", + "com", + "edu", + "gov", + "inf", + "net", + "org", + "blogspot", + "com", + "edu", + "net", + "org", + "ath", + "gov", + "ac", + "biz", + "com", + "ekloges", + "gov", + "ltd", + "name", + "net", + "org", + "parliament", + "press", + "pro", + "tm", + "blogspot", + "blogspot", + "co", + "blogspot", + "com", + "fuettertdasnetz", + "isteingeek", + "istmein", + "lebtimnetz", + "leitungsen", + "traeumtgerade", + "blogspot", + "com", + "edu", + "gov", + "net", + "org", + "art", + "com", + "edu", + "gob", + "gov", + "mil", + "net", + "org", + "sld", + "web", + "art", + "asso", + "com", + "edu", + "gov", + "net", + "org", + "pol", + "com", + "edu", + "fin", + "gob", + "gov", + "info", + "k12", + "med", + "mil", + "net", + "org", + "pro", + "aip", + "com", + "edu", + "fie", + "gov", + "lib", + "med", + "org", + "pri", + "riik", + "blogspot", + "com", + "edu", + "eun", + "gov", + "mil", + "name", + "net", + "org", + "sci", + "blogspot", + "com", + "edu", + "gob", + "nom", + "org", + "blogspot", + "biz", + "com", + "edu", + "gov", + "info", + "name", + "net", + "org", + "aland", + "blogspot", + "iki", + "aeroport", + "assedic", + "asso", + "avocat", + "avoues", + "blogspot", + "cci", + "chambagri", + "chirurgiens-dentistes", + "com", + "experts-comptables", + "geometre-expert", + "gouv", + "greta", + "huissier-justice", + "medecin", + "nom", + "notaires", + "pharmacien", + "port", + "prd", + "presse", + "tm", + "veterinaire", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "pvt", + "co", + "net", + "org", + "com", + "edu", + "gov", + "mil", + "org", + "com", + "edu", + "gov", + "ltd", + "mod", + "org", + "co", + "com", + "edu", + "net", + "org", + "ac", + "com", + "edu", + "gov", + "net", + "org", + "asso", + "com", + "edu", + "mobi", + "net", + "org", + "blogspot", + "com", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "gob", + "ind", + "mil", + "net", + "org", + "co", + "com", + "edu", + "gov", + "net", + "org", + "blogspot", + "com", + "edu", + "gov", + "idv", + "inc", + "ltd", + "net", + "org", + "xn--55qx5d", + "xn--ciqpn", + "xn--gmq050i", + "xn--gmqw5a", + "xn--io0a7i", + "xn--lcvr32d", + "xn--mk0axi", + "xn--mxtq1m", + "xn--od0alg", + "xn--od0aq3b", + "xn--tn0ag", + "xn--uc0atv", + "xn--uc0ay4a", + "xn--wcvs22d", + "xn--zf0avx", + "com", + "edu", + "gob", + "mil", + "net", + "org", + "blogspot", + "com", + "from", + "iz", + "name", + "adult", + "art", + "asso", + "com", + "coop", + "edu", + "firm", + "gouv", + "info", + "med", + "net", + "org", + "perso", + "pol", + "pro", + "rel", + "shop", + "2000", + "agrar", + "blogspot", + "bolt", + "casino", + "city", + "co", + "erotica", + "erotika", + "film", + "forum", + "games", + "hotel", + "info", + "ingatlan", + "jogasz", + "konyvelo", + "lakas", + "media", + "news", + "org", + "priv", + "reklam", + "sex", + "shop", + "sport", + "suli", + "szex", + "tm", + "tozsde", + "utazas", + "video", + "ac", + "biz", + "co", + "desa", + "go", + "mil", + "my", + "net", + "or", + "sch", + "web", + "blogspot", + "blogspot", + "gov", + "ac", + "co", + "gov", + "idf", + "k12", + "muni", + "net", + "org", + "blogspot", + "ac", + "co", + "com", + "net", + "org", + "tt", + "tv", + "ltd", + "plc", + "ac", + "blogspot", + "co", + "edu", + "firm", + "gen", + "gov", + "ind", + "mil", + "net", + "nic", + "org", + "res", + "barrel-of-knowledge", + "barrell-of-knowledge", + "dyndns", + "for-our", + "groks-the", + "groks-this", + "here-for-more", + "knowsitall", + "selfip", + "webhop", + "eu", + "com", + "github", + "ngrok", + "nid", + "pantheon", + "sandcats", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "ac", + "co", + "gov", + "id", + "net", + "org", + "sch", + "xn--mgba3a4f16a", + "xn--mgba3a4fra", + "blogspot", + "com", + "cupcake", + "edu", + "gov", + "int", + "net", + "org", + "abr", + "abruzzo", + "ag", + "agrigento", + "al", + "alessandria", + "alto-adige", + "altoadige", + "an", + "ancona", + "andria-barletta-trani", + "andria-trani-barletta", + "andriabarlettatrani", + "andriatranibarletta", + "ao", + "aosta", + "aosta-valley", + "aostavalley", + "aoste", + "ap", + "aq", + "aquila", + "ar", + "arezzo", + "ascoli-piceno", + "ascolipiceno", + "asti", + "at", + "av", + "avellino", + "ba", + "balsan", + "bari", + "barletta-trani-andria", + "barlettatraniandria", + "bas", + "basilicata", + "belluno", + "benevento", + "bergamo", + "bg", + "bi", + "biella", + "bl", + "blogspot", + "bn", + "bo", + "bologna", + "bolzano", + "bozen", + "br", + "brescia", + "brindisi", + "bs", + "bt", + "bz", + "ca", + "cagliari", + "cal", + "calabria", + "caltanissetta", + "cam", + "campania", + "campidano-medio", + "campidanomedio", + "campobasso", + "carbonia-iglesias", + "carboniaiglesias", + "carrara-massa", + "carraramassa", + "caserta", + "catania", + "catanzaro", + "cb", + "ce", + "cesena-forli", + "cesenaforli", + "ch", + "chieti", + "ci", + "cl", + "cn", + "co", + "como", + "cosenza", + "cr", + "cremona", + "crotone", + "cs", + "ct", + "cuneo", + "cz", + "dell-ogliastra", + "dellogliastra", + "edu", + "emilia-romagna", + "emiliaromagna", + "emr", + "en", + "enna", + "fc", + "fe", + "fermo", + "ferrara", + "fg", + "fi", + "firenze", + "florence", + "fm", + "foggia", + "forli-cesena", + "forlicesena", + "fr", + "friuli-v-giulia", + "friuli-ve-giulia", + "friuli-vegiulia", + "friuli-venezia-giulia", + "friuli-veneziagiulia", + "friuli-vgiulia", + "friuliv-giulia", + "friulive-giulia", + "friulivegiulia", + "friulivenezia-giulia", + "friuliveneziagiulia", + "friulivgiulia", + "frosinone", + "fvg", + "ge", + "genoa", + "genova", + "go", + "gorizia", + "gov", + "gr", + "grosseto", + "iglesias-carbonia", + "iglesiascarbonia", + "im", + "imperia", + "is", + "isernia", + "kr", + "la-spezia", + "laquila", + "laspezia", + "latina", + "laz", + "lazio", + "lc", + "le", + "lecce", + "lecco", + "li", + "lig", + "liguria", + "livorno", + "lo", + "lodi", + "lom", + "lombardia", + "lombardy", + "lt", + "lu", + "lucania", + "lucca", + "macerata", + "mantova", + "mar", + "marche", + "massa-carrara", + "massacarrara", + "matera", + "mb", + "mc", + "me", + "medio-campidano", + "mediocampidano", + "messina", + "mi", + "milan", + "milano", + "mn", + "mo", + "modena", + "mol", + "molise", + "monza", + "monza-brianza", + "monza-e-della-brianza", + "monzabrianza", + "monzaebrianza", + "monzaedellabrianza", + "ms", + "mt", + "na", + "naples", + "napoli", + "no", + "novara", + "nu", + "nuoro", + "og", + "ogliastra", + "olbia-tempio", + "olbiatempio", + "or", + "oristano", + "ot", + "pa", + "padova", + "padua", + "palermo", + "parma", + "pavia", + "pc", + "pd", + "pe", + "perugia", + "pesaro-urbino", + "pesarourbino", + "pescara", + "pg", + "pi", + "piacenza", + "piedmont", + "piemonte", + "pisa", + "pistoia", + "pmn", + "pn", + "po", + "pordenone", + "potenza", + "pr", + "prato", + "pt", + "pu", + "pug", + "puglia", + "pv", + "pz", + "ra", + "ragusa", + "ravenna", + "rc", + "re", + "reggio-calabria", + "reggio-emilia", + "reggiocalabria", + "reggioemilia", + "rg", + "ri", + "rieti", + "rimini", + "rm", + "rn", + "ro", + "roma", + "rome", + "rovigo", + "sa", + "salerno", + "sar", + "sardegna", + "sardinia", + "sassari", + "savona", + "si", + "sic", + "sicilia", + "sicily", + "siena", + "siracusa", + "so", + "sondrio", + "sp", + "sr", + "ss", + "suedtirol", + "sv", + "ta", + "taa", + "taranto", + "te", + "tempio-olbia", + "tempioolbia", + "teramo", + "terni", + "tn", + "to", + "torino", + "tos", + "toscana", + "tp", + "tr", + "trani-andria-barletta", + "trani-barletta-andria", + "traniandriabarletta", + "tranibarlettaandria", + "trapani", + "trentino", + "trentino-a-adige", + "trentino-aadige", + "trentino-alto-adige", + "trentino-altoadige", + "trentino-s-tirol", + "trentino-stirol", + "trentino-sud-tirol", + "trentino-sudtirol", + "trentino-sued-tirol", + "trentino-suedtirol", + "trentinoa-adige", + "trentinoaadige", + "trentinoalto-adige", + "trentinoaltoadige", + "trentinos-tirol", + "trentinostirol", + "trentinosud-tirol", + "trentinosudtirol", + "trentinosued-tirol", + "trentinosuedtirol", + "trento", + "treviso", + "trieste", + "ts", + "turin", + "tuscany", + "tv", + "ud", + "udine", + "umb", + "umbria", + "urbino-pesaro", + "urbinopesaro", + "va", + "val-d-aosta", + "val-daosta", + "vald-aosta", + "valdaosta", + "valle-aosta", + "valle-d-aosta", + "valle-daosta", + "valleaosta", + "valled-aosta", + "valledaosta", + "vallee-aoste", + "valleeaoste", + "vao", + "varese", + "vb", + "vc", + "vda", + "ve", + "ven", + "veneto", + "venezia", + "venice", + "verbania", + "vercelli", + "verona", + "vi", + "vibo-valentia", + "vibovalentia", + "vicenza", + "viterbo", + "vr", + "vs", + "vt", + "vv", + "co", + "net", + "org", + "com", + "edu", + "gov", + "mil", + "name", + "net", + "org", + "sch", + "ac", + "ad", + "aichi", + "akita", + "aomori", + "blogspot", + "chiba", + "co", + "ed", + "ehime", + "fukui", + "fukuoka", + "fukushima", + "gifu", + "go", + "gr", + "gunma", + "hiroshima", + "hokkaido", + "hyogo", + "ibaraki", + "ishikawa", + "iwate", + "kagawa", + "kagoshima", + "kanagawa", + "kawasaki", + "kitakyushu", + "kobe", + "kochi", + "kumamoto", + "kyoto", + "lg", + "mie", + "miyagi", + "miyazaki", + "nagano", + "nagasaki", + "nagoya", + "nara", + "ne", + "niigata", + "oita", + "okayama", + "okinawa", + "or", + "osaka", + "saga", + "saitama", + "sapporo", + "sendai", + "shiga", + "shimane", + "shizuoka", + "tochigi", + "tokushima", + "tokyo", + "tottori", + "toyama", + "wakayama", + "xn--0trq7p7nn", + "xn--1ctwo", + "xn--1lqs03n", + "xn--1lqs71d", + "xn--2m4a15e", + "xn--32vp30h", + "xn--4it168d", + "xn--4it797k", + "xn--4pvxs", + "xn--5js045d", + "xn--5rtp49c", + "xn--5rtq34k", + "xn--6btw5a", + "xn--6orx2r", + "xn--7t0a264c", + "xn--8ltr62k", + "xn--8pvr4u", + "xn--c3s14m", + "xn--d5qv7z876c", + "xn--djrs72d6uy", + "xn--djty4k", + "xn--efvn9s", + "xn--ehqz56n", + "xn--elqq16h", + "xn--f6qx53a", + "xn--k7yn95e", + "xn--kbrq7o", + "xn--klt787d", + "xn--kltp7d", + "xn--kltx9a", + "xn--klty5x", + "xn--mkru45i", + "xn--nit225k", + "xn--ntso0iqx3a", + "xn--ntsq17g", + "xn--pssu33l", + "xn--qqqt11m", + "xn--rht27z", + "xn--rht3d", + "xn--rht61e", + "xn--rny31h", + "xn--tor131o", + "xn--uist22h", + "xn--uisz3g", + "xn--uuwu58a", + "xn--vgu402c", + "xn--zbx025d", + "yamagata", + "yamaguchi", + "yamanashi", + "yokohama", + "aisai", + "ama", + "anjo", + "asuke", + "chiryu", + "chita", + "fuso", + "gamagori", + "handa", + "hazu", + "hekinan", + "higashiura", + "ichinomiya", + "inazawa", + "inuyama", + "isshiki", + "iwakura", + "kanie", + "kariya", + "kasugai", + "kira", + "kiyosu", + "komaki", + "konan", + "kota", + "mihama", + "miyoshi", + "nishio", + "nisshin", + "obu", + "oguchi", + "oharu", + "okazaki", + "owariasahi", + "seto", + "shikatsu", + "shinshiro", + "shitara", + "tahara", + "takahama", + "tobishima", + "toei", + "togo", + "tokai", + "tokoname", + "toyoake", + "toyohashi", + "toyokawa", + "toyone", + "toyota", + "tsushima", + "yatomi", + "akita", + "daisen", + "fujisato", + "gojome", + "hachirogata", + "happou", + "higashinaruse", + "honjo", + "honjyo", + "ikawa", + "kamikoani", + "kamioka", + "katagami", + "kazuno", + "kitaakita", + "kosaka", + "kyowa", + "misato", + "mitane", + "moriyoshi", + "nikaho", + "noshiro", + "odate", + "oga", + "ogata", + "semboku", + "yokote", + "yurihonjo", + "aomori", + "gonohe", + "hachinohe", + "hashikami", + "hiranai", + "hirosaki", + "itayanagi", + "kuroishi", + "misawa", + "mutsu", + "nakadomari", + "noheji", + "oirase", + "owani", + "rokunohe", + "sannohe", + "shichinohe", + "shingo", + "takko", + "towada", + "tsugaru", + "tsuruta", + "abiko", + "asahi", + "chonan", + "chosei", + "choshi", + "chuo", + "funabashi", + "futtsu", + "hanamigawa", + "ichihara", + "ichikawa", + "ichinomiya", + "inzai", + "isumi", + "kamagaya", + "kamogawa", + "kashiwa", + "katori", + "katsuura", + "kimitsu", + "kisarazu", + "kozaki", + "kujukuri", + "kyonan", + "matsudo", + "midori", + "mihama", + "minamiboso", + "mobara", + "mutsuzawa", + "nagara", + "nagareyama", + "narashino", + "narita", + "noda", + "oamishirasato", + "omigawa", + "onjuku", + "otaki", + "sakae", + "sakura", + "shimofusa", + "shirako", + "shiroi", + "shisui", + "sodegaura", + "sosa", + "tako", + "tateyama", + "togane", + "tohnosho", + "tomisato", + "urayasu", + "yachimata", + "yachiyo", + "yokaichiba", + "yokoshibahikari", + "yotsukaido", + "ainan", + "honai", + "ikata", + "imabari", + "iyo", + "kamijima", + "kihoku", + "kumakogen", + "masaki", + "matsuno", + "matsuyama", + "namikata", + "niihama", + "ozu", + "saijo", + "seiyo", + "shikokuchuo", + "tobe", + "toon", + "uchiko", + "uwajima", + "yawatahama", + "echizen", + "eiheiji", + "fukui", + "ikeda", + "katsuyama", + "mihama", + "minamiechizen", + "obama", + "ohi", + "ono", + "sabae", + "sakai", + "takahama", + "tsuruga", + "wakasa", + "ashiya", + "buzen", + "chikugo", + "chikuho", + "chikujo", + "chikushino", + "chikuzen", + "chuo", + "dazaifu", + "fukuchi", + "hakata", + "higashi", + "hirokawa", + "hisayama", + "iizuka", + "inatsuki", + "kaho", + "kasuga", + "kasuya", + "kawara", + "keisen", + "koga", + "kurate", + "kurogi", + "kurume", + "minami", + "miyako", + "miyama", + "miyawaka", + "mizumaki", + "munakata", + "nakagawa", + "nakama", + "nishi", + "nogata", + "ogori", + "okagaki", + "okawa", + "oki", + "omuta", + "onga", + "onojo", + "oto", + "saigawa", + "sasaguri", + "shingu", + "shinyoshitomi", + "shonai", + "soeda", + "sue", + "tachiarai", + "tagawa", + "takata", + "toho", + "toyotsu", + "tsuiki", + "ukiha", + "umi", + "usui", + "yamada", + "yame", + "yanagawa", + "yukuhashi", + "aizubange", + "aizumisato", + "aizuwakamatsu", + "asakawa", + "bandai", + "date", + "fukushima", + "furudono", + "futaba", + "hanawa", + "higashi", + "hirata", + "hirono", + "iitate", + "inawashiro", + "ishikawa", + "iwaki", + "izumizaki", + "kagamiishi", + "kaneyama", + "kawamata", + "kitakata", + "kitashiobara", + "koori", + "koriyama", + "kunimi", + "miharu", + "mishima", + "namie", + "nango", + "nishiaizu", + "nishigo", + "okuma", + "omotego", + "ono", + "otama", + "samegawa", + "shimogo", + "shirakawa", + "showa", + "soma", + "sukagawa", + "taishin", + "tamakawa", + "tanagura", + "tenei", + "yabuki", + "yamato", + "yamatsuri", + "yanaizu", + "yugawa", + "anpachi", + "ena", + "gifu", + "ginan", + "godo", + "gujo", + "hashima", + "hichiso", + "hida", + "higashishirakawa", + "ibigawa", + "ikeda", + "kakamigahara", + "kani", + "kasahara", + "kasamatsu", + "kawaue", + "kitagata", + "mino", + "minokamo", + "mitake", + "mizunami", + "motosu", + "nakatsugawa", + "ogaki", + "sakahogi", + "seki", + "sekigahara", + "shirakawa", + "tajimi", + "takayama", + "tarui", + "toki", + "tomika", + "wanouchi", + "yamagata", + "yaotsu", + "yoro", + "annaka", + "chiyoda", + "fujioka", + "higashiagatsuma", + "isesaki", + "itakura", + "kanna", + "kanra", + "katashina", + "kawaba", + "kiryu", + "kusatsu", + "maebashi", + "meiwa", + "midori", + "minakami", + "naganohara", + "nakanojo", + "nanmoku", + "numata", + "oizumi", + "ora", + "ota", + "shibukawa", + "shimonita", + "shinto", + "showa", + "takasaki", + "takayama", + "tamamura", + "tatebayashi", + "tomioka", + "tsukiyono", + "tsumagoi", + "ueno", + "yoshioka", + "asaminami", + "daiwa", + "etajima", + "fuchu", + "fukuyama", + "hatsukaichi", + "higashihiroshima", + "hongo", + "jinsekikogen", + "kaita", + "kui", + "kumano", + "kure", + "mihara", + "miyoshi", + "naka", + "onomichi", + "osakikamijima", + "otake", + "saka", + "sera", + "seranishi", + "shinichi", + "shobara", + "takehara", + "abashiri", + "abira", + "aibetsu", + "akabira", + "akkeshi", + "asahikawa", + "ashibetsu", + "ashoro", + "assabu", + "atsuma", + "bibai", + "biei", + "bifuka", + "bihoro", + "biratori", + "chippubetsu", + "chitose", + "date", + "ebetsu", + "embetsu", + "eniwa", + "erimo", + "esan", + "esashi", + "fukagawa", + "fukushima", + "furano", + "furubira", + "haboro", + "hakodate", + "hamatonbetsu", + "hidaka", + "higashikagura", + "higashikawa", + "hiroo", + "hokuryu", + "hokuto", + "honbetsu", + "horokanai", + "horonobe", + "ikeda", + "imakane", + "ishikari", + "iwamizawa", + "iwanai", + "kamifurano", + "kamikawa", + "kamishihoro", + "kamisunagawa", + "kamoenai", + "kayabe", + "kembuchi", + "kikonai", + "kimobetsu", + "kitahiroshima", + "kitami", + "kiyosato", + "koshimizu", + "kunneppu", + "kuriyama", + "kuromatsunai", + "kushiro", + "kutchan", + "kyowa", + "mashike", + "matsumae", + "mikasa", + "minamifurano", + "mombetsu", + "moseushi", + "mukawa", + "muroran", + "naie", + "nakagawa", + "nakasatsunai", + "nakatombetsu", + "nanae", + "nanporo", + "nayoro", + "nemuro", + "niikappu", + "niki", + "nishiokoppe", + "noboribetsu", + "numata", + "obihiro", + "obira", + "oketo", + "okoppe", + "otaru", + "otobe", + "otofuke", + "otoineppu", + "oumu", + "ozora", + "pippu", + "rankoshi", + "rebun", + "rikubetsu", + "rishiri", + "rishirifuji", + "saroma", + "sarufutsu", + "shakotan", + "shari", + "shibecha", + "shibetsu", + "shikabe", + "shikaoi", + "shimamaki", + "shimizu", + "shimokawa", + "shinshinotsu", + "shintoku", + "shiranuka", + "shiraoi", + "shiriuchi", + "sobetsu", + "sunagawa", + "taiki", + "takasu", + "takikawa", + "takinoue", + "teshikaga", + "tobetsu", + "tohma", + "tomakomai", + "tomari", + "toya", + "toyako", + "toyotomi", + "toyoura", + "tsubetsu", + "tsukigata", + "urakawa", + "urausu", + "uryu", + "utashinai", + "wakkanai", + "wassamu", + "yakumo", + "yoichi", + "aioi", + "akashi", + "ako", + "amagasaki", + "aogaki", + "asago", + "ashiya", + "awaji", + "fukusaki", + "goshiki", + "harima", + "himeji", + "ichikawa", + "inagawa", + "itami", + "kakogawa", + "kamigori", + "kamikawa", + "kasai", + "kasuga", + "kawanishi", + "miki", + "minamiawaji", + "nishinomiya", + "nishiwaki", + "ono", + "sanda", + "sannan", + "sasayama", + "sayo", + "shingu", + "shinonsen", + "shiso", + "sumoto", + "taishi", + "taka", + "takarazuka", + "takasago", + "takino", + "tamba", + "tatsuno", + "toyooka", + "yabu", + "yashiro", + "yoka", + "yokawa", + "ami", + "asahi", + "bando", + "chikusei", + "daigo", + "fujishiro", + "hitachi", + "hitachinaka", + "hitachiomiya", + "hitachiota", + "ibaraki", + "ina", + "inashiki", + "itako", + "iwama", + "joso", + "kamisu", + "kasama", + "kashima", + "kasumigaura", + "koga", + "miho", + "mito", + "moriya", + "naka", + "namegata", + "oarai", + "ogawa", + "omitama", + "ryugasaki", + "sakai", + "sakuragawa", + "shimodate", + "shimotsuma", + "shirosato", + "sowa", + "suifu", + "takahagi", + "tamatsukuri", + "tokai", + "tomobe", + "tone", + "toride", + "tsuchiura", + "tsukuba", + "uchihara", + "ushiku", + "yachiyo", + "yamagata", + "yawara", + "yuki", + "anamizu", + "hakui", + "hakusan", + "kaga", + "kahoku", + "kanazawa", + "kawakita", + "komatsu", + "nakanoto", + "nanao", + "nomi", + "nonoichi", + "noto", + "shika", + "suzu", + "tsubata", + "tsurugi", + "uchinada", + "wajima", + "fudai", + "fujisawa", + "hanamaki", + "hiraizumi", + "hirono", + "ichinohe", + "ichinoseki", + "iwaizumi", + "iwate", + "joboji", + "kamaishi", + "kanegasaki", + "karumai", + "kawai", + "kitakami", + "kuji", + "kunohe", + "kuzumaki", + "miyako", + "mizusawa", + "morioka", + "ninohe", + "noda", + "ofunato", + "oshu", + "otsuchi", + "rikuzentakata", + "shiwa", + "shizukuishi", + "sumita", + "tanohata", + "tono", + "yahaba", + "yamada", + "ayagawa", + "higashikagawa", + "kanonji", + "kotohira", + "manno", + "marugame", + "mitoyo", + "naoshima", + "sanuki", + "tadotsu", + "takamatsu", + "tonosho", + "uchinomi", + "utazu", + "zentsuji", + "akune", + "amami", + "hioki", + "isa", + "isen", + "izumi", + "kagoshima", + "kanoya", + "kawanabe", + "kinko", + "kouyama", + "makurazaki", + "matsumoto", + "minamitane", + "nakatane", + "nishinoomote", + "satsumasendai", + "soo", + "tarumizu", + "yusui", + "aikawa", + "atsugi", + "ayase", + "chigasaki", + "ebina", + "fujisawa", + "hadano", + "hakone", + "hiratsuka", + "isehara", + "kaisei", + "kamakura", + "kiyokawa", + "matsuda", + "minamiashigara", + "miura", + "nakai", + "ninomiya", + "odawara", + "oi", + "oiso", + "sagamihara", + "samukawa", + "tsukui", + "yamakita", + "yamato", + "yokosuka", + "yugawara", + "zama", + "zushi", + "city", + "city", + "city", + "aki", + "geisei", + "hidaka", + "higashitsuno", + "ino", + "kagami", + "kami", + "kitagawa", + "kochi", + "mihara", + "motoyama", + "muroto", + "nahari", + "nakamura", + "nankoku", + "nishitosa", + "niyodogawa", + "ochi", + "okawa", + "otoyo", + "otsuki", + "sakawa", + "sukumo", + "susaki", + "tosa", + "tosashimizu", + "toyo", + "tsuno", + "umaji", + "yasuda", + "yusuhara", + "amakusa", + "arao", + "aso", + "choyo", + "gyokuto", + "hitoyoshi", + "kamiamakusa", + "kashima", + "kikuchi", + "kosa", + "kumamoto", + "mashiki", + "mifune", + "minamata", + "minamioguni", + "nagasu", + "nishihara", + "oguni", + "ozu", + "sumoto", + "takamori", + "uki", + "uto", + "yamaga", + "yamato", + "yatsushiro", + "ayabe", + "fukuchiyama", + "higashiyama", + "ide", + "ine", + "joyo", + "kameoka", + "kamo", + "kita", + "kizu", + "kumiyama", + "kyotamba", + "kyotanabe", + "kyotango", + "maizuru", + "minami", + "minamiyamashiro", + "miyazu", + "muko", + "nagaokakyo", + "nakagyo", + "nantan", + "oyamazaki", + "sakyo", + "seika", + "tanabe", + "uji", + "ujitawara", + "wazuka", + "yamashina", + "yawata", + "asahi", + "inabe", + "ise", + "kameyama", + "kawagoe", + "kiho", + "kisosaki", + "kiwa", + "komono", + "kumano", + "kuwana", + "matsusaka", + "meiwa", + "mihama", + "minamiise", + "misugi", + "miyama", + "nabari", + "shima", + "suzuka", + "tado", + "taiki", + "taki", + "tamaki", + "toba", + "tsu", + "udono", + "ureshino", + "watarai", + "yokkaichi", + "furukawa", + "higashimatsushima", + "ishinomaki", + "iwanuma", + "kakuda", + "kami", + "kawasaki", + "kesennuma", + "marumori", + "matsushima", + "minamisanriku", + "misato", + "murata", + "natori", + "ogawara", + "ohira", + "onagawa", + "osaki", + "rifu", + "semine", + "shibata", + "shichikashuku", + "shikama", + "shiogama", + "shiroishi", + "tagajo", + "taiwa", + "tome", + "tomiya", + "wakuya", + "watari", + "yamamoto", + "zao", + "aya", + "ebino", + "gokase", + "hyuga", + "kadogawa", + "kawaminami", + "kijo", + "kitagawa", + "kitakata", + "kitaura", + "kobayashi", + "kunitomi", + "kushima", + "mimata", + "miyakonojo", + "miyazaki", + "morotsuka", + "nichinan", + "nishimera", + "nobeoka", + "saito", + "shiiba", + "shintomi", + "takaharu", + "takanabe", + "takazaki", + "tsuno", + "achi", + "agematsu", + "anan", + "aoki", + "asahi", + "azumino", + "chikuhoku", + "chikuma", + "chino", + "fujimi", + "hakuba", + "hara", + "hiraya", + "iida", + "iijima", + "iiyama", + "iizuna", + "ikeda", + "ikusaka", + "ina", + "karuizawa", + "kawakami", + "kiso", + "kisofukushima", + "kitaaiki", + "komagane", + "komoro", + "matsukawa", + "matsumoto", + "miasa", + "minamiaiki", + "minamimaki", + "minamiminowa", + "minowa", + "miyada", + "miyota", + "mochizuki", + "nagano", + "nagawa", + "nagiso", + "nakagawa", + "nakano", + "nozawaonsen", + "obuse", + "ogawa", + "okaya", + "omachi", + "omi", + "ookuwa", + "ooshika", + "otaki", + "otari", + "sakae", + "sakaki", + "saku", + "sakuho", + "shimosuwa", + "shinanomachi", + "shiojiri", + "suwa", + "suzaka", + "takagi", + "takamori", + "takayama", + "tateshina", + "tatsuno", + "togakushi", + "togura", + "tomi", + "ueda", + "wada", + "yamagata", + "yamanouchi", + "yasaka", + "yasuoka", + "chijiwa", + "futsu", + "goto", + "hasami", + "hirado", + "iki", + "isahaya", + "kawatana", + "kuchinotsu", + "matsuura", + "nagasaki", + "obama", + "omura", + "oseto", + "saikai", + "sasebo", + "seihi", + "shimabara", + "shinkamigoto", + "togitsu", + "tsushima", + "unzen", + "city", + "ando", + "gose", + "heguri", + "higashiyoshino", + "ikaruga", + "ikoma", + "kamikitayama", + "kanmaki", + "kashiba", + "kashihara", + "katsuragi", + "kawai", + "kawakami", + "kawanishi", + "koryo", + "kurotaki", + "mitsue", + "miyake", + "nara", + "nosegawa", + "oji", + "ouda", + "oyodo", + "sakurai", + "sango", + "shimoichi", + "shimokitayama", + "shinjo", + "soni", + "takatori", + "tawaramoto", + "tenkawa", + "tenri", + "uda", + "yamatokoriyama", + "yamatotakada", + "yamazoe", + "yoshino", + "aga", + "agano", + "gosen", + "itoigawa", + "izumozaki", + "joetsu", + "kamo", + "kariwa", + "kashiwazaki", + "minamiuonuma", + "mitsuke", + "muika", + "murakami", + "myoko", + "nagaoka", + "niigata", + "ojiya", + "omi", + "sado", + "sanjo", + "seiro", + "seirou", + "sekikawa", + "shibata", + "tagami", + "tainai", + "tochio", + "tokamachi", + "tsubame", + "tsunan", + "uonuma", + "yahiko", + "yoita", + "yuzawa", + "beppu", + "bungoono", + "bungotakada", + "hasama", + "hiji", + "himeshima", + "hita", + "kamitsue", + "kokonoe", + "kuju", + "kunisaki", + "kusu", + "oita", + "saiki", + "taketa", + "tsukumi", + "usa", + "usuki", + "yufu", + "akaiwa", + "asakuchi", + "bizen", + "hayashima", + "ibara", + "kagamino", + "kasaoka", + "kibichuo", + "kumenan", + "kurashiki", + "maniwa", + "misaki", + "nagi", + "niimi", + "nishiawakura", + "okayama", + "satosho", + "setouchi", + "shinjo", + "shoo", + "soja", + "takahashi", + "tamano", + "tsuyama", + "wake", + "yakage", + "aguni", + "ginowan", + "ginoza", + "gushikami", + "haebaru", + "higashi", + "hirara", + "iheya", + "ishigaki", + "ishikawa", + "itoman", + "izena", + "kadena", + "kin", + "kitadaito", + "kitanakagusuku", + "kumejima", + "kunigami", + "minamidaito", + "motobu", + "nago", + "naha", + "nakagusuku", + "nakijin", + "nanjo", + "nishihara", + "ogimi", + "okinawa", + "onna", + "shimoji", + "taketomi", + "tarama", + "tokashiki", + "tomigusuku", + "tonaki", + "urasoe", + "uruma", + "yaese", + "yomitan", + "yonabaru", + "yonaguni", + "zamami", + "abeno", + "chihayaakasaka", + "chuo", + "daito", + "fujiidera", + "habikino", + "hannan", + "higashiosaka", + "higashisumiyoshi", + "higashiyodogawa", + "hirakata", + "ibaraki", + "ikeda", + "izumi", + "izumiotsu", + "izumisano", + "kadoma", + "kaizuka", + "kanan", + "kashiwara", + "katano", + "kawachinagano", + "kishiwada", + "kita", + "kumatori", + "matsubara", + "minato", + "minoh", + "misaki", + "moriguchi", + "neyagawa", + "nishi", + "nose", + "osakasayama", + "sakai", + "sayama", + "sennan", + "settsu", + "shijonawate", + "shimamoto", + "suita", + "tadaoka", + "taishi", + "tajiri", + "takaishi", + "takatsuki", + "tondabayashi", + "toyonaka", + "toyono", + "yao", + "ariake", + "arita", + "fukudomi", + "genkai", + "hamatama", + "hizen", + "imari", + "kamimine", + "kanzaki", + "karatsu", + "kashima", + "kitagata", + "kitahata", + "kiyama", + "kouhoku", + "kyuragi", + "nishiarita", + "ogi", + "omachi", + "ouchi", + "saga", + "shiroishi", + "taku", + "tara", + "tosu", + "yoshinogari", + "arakawa", + "asaka", + "chichibu", + "fujimi", + "fujimino", + "fukaya", + "hanno", + "hanyu", + "hasuda", + "hatogaya", + "hatoyama", + "hidaka", + "higashichichibu", + "higashimatsuyama", + "honjo", + "ina", + "iruma", + "iwatsuki", + "kamiizumi", + "kamikawa", + "kamisato", + "kasukabe", + "kawagoe", + "kawaguchi", + "kawajima", + "kazo", + "kitamoto", + "koshigaya", + "kounosu", + "kuki", + "kumagaya", + "matsubushi", + "minano", + "misato", + "miyashiro", + "miyoshi", + "moroyama", + "nagatoro", + "namegawa", + "niiza", + "ogano", + "ogawa", + "ogose", + "okegawa", + "omiya", + "otaki", + "ranzan", + "ryokami", + "saitama", + "sakado", + "satte", + "sayama", + "shiki", + "shiraoka", + "soka", + "sugito", + "toda", + "tokigawa", + "tokorozawa", + "tsurugashima", + "urawa", + "warabi", + "yashio", + "yokoze", + "yono", + "yorii", + "yoshida", + "yoshikawa", + "yoshimi", + "city", + "city", + "aisho", + "gamo", + "higashiomi", + "hikone", + "koka", + "konan", + "kosei", + "koto", + "kusatsu", + "maibara", + "moriyama", + "nagahama", + "nishiazai", + "notogawa", + "omihachiman", + "otsu", + "ritto", + "ryuoh", + "takashima", + "takatsuki", + "torahime", + "toyosato", + "yasu", + "akagi", + "ama", + "gotsu", + "hamada", + "higashiizumo", + "hikawa", + "hikimi", + "izumo", + "kakinoki", + "masuda", + "matsue", + "misato", + "nishinoshima", + "ohda", + "okinoshima", + "okuizumo", + "shimane", + "tamayu", + "tsuwano", + "unnan", + "yakumo", + "yasugi", + "yatsuka", + "arai", + "atami", + "fuji", + "fujieda", + "fujikawa", + "fujinomiya", + "fukuroi", + "gotemba", + "haibara", + "hamamatsu", + "higashiizu", + "ito", + "iwata", + "izu", + "izunokuni", + "kakegawa", + "kannami", + "kawanehon", + "kawazu", + "kikugawa", + "kosai", + "makinohara", + "matsuzaki", + "minamiizu", + "mishima", + "morimachi", + "nishiizu", + "numazu", + "omaezaki", + "shimada", + "shimizu", + "shimoda", + "shizuoka", + "susono", + "yaizu", + "yoshida", + "ashikaga", + "bato", + "haga", + "ichikai", + "iwafune", + "kaminokawa", + "kanuma", + "karasuyama", + "kuroiso", + "mashiko", + "mibu", + "moka", + "motegi", + "nasu", + "nasushiobara", + "nikko", + "nishikata", + "nogi", + "ohira", + "ohtawara", + "oyama", + "sakura", + "sano", + "shimotsuke", + "shioya", + "takanezawa", + "tochigi", + "tsuga", + "ujiie", + "utsunomiya", + "yaita", + "aizumi", + "anan", + "ichiba", + "itano", + "kainan", + "komatsushima", + "matsushige", + "mima", + "minami", + "miyoshi", + "mugi", + "nakagawa", + "naruto", + "sanagochi", + "shishikui", + "tokushima", + "wajiki", + "adachi", + "akiruno", + "akishima", + "aogashima", + "arakawa", + "bunkyo", + "chiyoda", + "chofu", + "chuo", + "edogawa", + "fuchu", + "fussa", + "hachijo", + "hachioji", + "hamura", + "higashikurume", + "higashimurayama", + "higashiyamato", + "hino", + "hinode", + "hinohara", + "inagi", + "itabashi", + "katsushika", + "kita", + "kiyose", + "kodaira", + "koganei", + "kokubunji", + "komae", + "koto", + "kouzushima", + "kunitachi", + "machida", + "meguro", + "minato", + "mitaka", + "mizuho", + "musashimurayama", + "musashino", + "nakano", + "nerima", + "ogasawara", + "okutama", + "ome", + "oshima", + "ota", + "setagaya", + "shibuya", + "shinagawa", + "shinjuku", + "suginami", + "sumida", + "tachikawa", + "taito", + "tama", + "toshima", + "chizu", + "hino", + "kawahara", + "koge", + "kotoura", + "misasa", + "nanbu", + "nichinan", + "sakaiminato", + "tottori", + "wakasa", + "yazu", + "yonago", + "asahi", + "fuchu", + "fukumitsu", + "funahashi", + "himi", + "imizu", + "inami", + "johana", + "kamiichi", + "kurobe", + "nakaniikawa", + "namerikawa", + "nanto", + "nyuzen", + "oyabe", + "taira", + "takaoka", + "tateyama", + "toga", + "tonami", + "toyama", + "unazuki", + "uozu", + "yamada", + "arida", + "aridagawa", + "gobo", + "hashimoto", + "hidaka", + "hirogawa", + "inami", + "iwade", + "kainan", + "kamitonda", + "katsuragi", + "kimino", + "kinokawa", + "kitayama", + "koya", + "koza", + "kozagawa", + "kudoyama", + "kushimoto", + "mihama", + "misato", + "nachikatsuura", + "shingu", + "shirahama", + "taiji", + "tanabe", + "wakayama", + "yuasa", + "yura", + "asahi", + "funagata", + "higashine", + "iide", + "kahoku", + "kaminoyama", + "kaneyama", + "kawanishi", + "mamurogawa", + "mikawa", + "murayama", + "nagai", + "nakayama", + "nanyo", + "nishikawa", + "obanazawa", + "oe", + "oguni", + "ohkura", + "oishida", + "sagae", + "sakata", + "sakegawa", + "shinjo", + "shirataka", + "shonai", + "takahata", + "tendo", + "tozawa", + "tsuruoka", + "yamagata", + "yamanobe", + "yonezawa", + "yuza", + "abu", + "hagi", + "hikari", + "hofu", + "iwakuni", + "kudamatsu", + "mitou", + "nagato", + "oshima", + "shimonoseki", + "shunan", + "tabuse", + "tokuyama", + "toyota", + "ube", + "yuu", + "chuo", + "doshi", + "fuefuki", + "fujikawa", + "fujikawaguchiko", + "fujiyoshida", + "hayakawa", + "hokuto", + "ichikawamisato", + "kai", + "kofu", + "koshu", + "kosuge", + "minami-alps", + "minobu", + "nakamichi", + "nanbu", + "narusawa", + "nirasaki", + "nishikatsura", + "oshino", + "otsuki", + "showa", + "tabayama", + "tsuru", + "uenohara", + "yamanakako", + "yamanashi", + "city", + "co", + "blogspot", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "biz", + "com", + "edu", + "gov", + "info", + "net", + "org", + "ass", + "asso", + "com", + "coop", + "edu", + "gouv", + "gov", + "medecin", + "mil", + "nom", + "notaires", + "org", + "pharmaciens", + "prd", + "presse", + "tm", + "veterinaire", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "gov", + "org", + "rep", + "tra", + "ac", + "blogspot", + "busan", + "chungbuk", + "chungnam", + "co", + "daegu", + "daejeon", + "es", + "gangwon", + "go", + "gwangju", + "gyeongbuk", + "gyeonggi", + "gyeongnam", + "hs", + "incheon", + "jeju", + "jeonbuk", + "jeonnam", + "kg", + "mil", + "ms", + "ne", + "or", + "pe", + "re", + "sc", + "seoul", + "ulsan", + "com", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "c", + "com", + "edu", + "gov", + "info", + "int", + "net", + "org", + "per", + "com", + "edu", + "gov", + "net", + "org", + "co", + "com", + "edu", + "gov", + "net", + "org", + "blogspot", + "ac", + "assn", + "com", + "edu", + "gov", + "grp", + "hotel", + "int", + "ltd", + "net", + "ngo", + "org", + "sch", + "soc", + "web", + "com", + "edu", + "gov", + "net", + "org", + "co", + "org", + "blogspot", + "gov", + "blogspot", + "asn", + "com", + "conf", + "edu", + "gov", + "id", + "mil", + "net", + "org", + "com", + "edu", + "gov", + "id", + "med", + "net", + "org", + "plc", + "sch", + "ac", + "co", + "gov", + "net", + "org", + "press", + "asso", + "tm", + "blogspot", + "ac", + "co", + "diskstation", + "dscloud", + "edu", + "gov", + "i234", + "its", + "myds", + "net", + "org", + "priv", + "synology", + "co", + "com", + "edu", + "gov", + "mil", + "nom", + "org", + "prd", + "tm", + "blogspot", + "com", + "edu", + "gov", + "inf", + "name", + "net", + "org", + "com", + "edu", + "gouv", + "gov", + "net", + "org", + "presse", + "edu", + "gov", + "nyc", + "org", + "com", + "edu", + "gov", + "net", + "org", + "dscloud", + "blogspot", + "gov", + "com", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "net", + "org", + "blogspot", + "ac", + "co", + "com", + "gov", + "net", + "or", + "org", + "academy", + "agriculture", + "air", + "airguard", + "alabama", + "alaska", + "amber", + "ambulance", + "american", + "americana", + "americanantiques", + "americanart", + "amsterdam", + "and", + "annefrank", + "anthro", + "anthropology", + "antiques", + "aquarium", + "arboretum", + "archaeological", + "archaeology", + "architecture", + "art", + "artanddesign", + "artcenter", + "artdeco", + "arteducation", + "artgallery", + "arts", + "artsandcrafts", + "asmatart", + "assassination", + "assisi", + "association", + "astronomy", + "atlanta", + "austin", + "australia", + "automotive", + "aviation", + "axis", + "badajoz", + "baghdad", + "bahn", + "bale", + "baltimore", + "barcelona", + "baseball", + "basel", + "baths", + "bauern", + "beauxarts", + "beeldengeluid", + "bellevue", + "bergbau", + "berkeley", + "berlin", + "bern", + "bible", + "bilbao", + "bill", + "birdart", + "birthplace", + "bonn", + "boston", + "botanical", + "botanicalgarden", + "botanicgarden", + "botany", + "brandywinevalley", + "brasil", + "bristol", + "british", + "britishcolumbia", + "broadcast", + "brunel", + "brussel", + "brussels", + "bruxelles", + "building", + "burghof", + "bus", + "bushey", + "cadaques", + "california", + "cambridge", + "can", + "canada", + "capebreton", + "carrier", + "cartoonart", + "casadelamoneda", + "castle", + "castres", + "celtic", + "center", + "chattanooga", + "cheltenham", + "chesapeakebay", + "chicago", + "children", + "childrens", + "childrensgarden", + "chiropractic", + "chocolate", + "christiansburg", + "cincinnati", + "cinema", + "circus", + "civilisation", + "civilization", + "civilwar", + "clinton", + "clock", + "coal", + "coastaldefence", + "cody", + "coldwar", + "collection", + "colonialwilliamsburg", + "coloradoplateau", + "columbia", + "columbus", + "communication", + "communications", + "community", + "computer", + "computerhistory", + "contemporary", + "contemporaryart", + "convent", + "copenhagen", + "corporation", + "corvette", + "costume", + "countryestate", + "county", + "crafts", + "cranbrook", + "creation", + "cultural", + "culturalcenter", + "culture", + "cyber", + "cymru", + "dali", + "dallas", + "database", + "ddr", + "decorativearts", + "delaware", + "delmenhorst", + "denmark", + "depot", + "design", + "detroit", + "dinosaur", + "discovery", + "dolls", + "donostia", + "durham", + "eastafrica", + "eastcoast", + "education", + "educational", + "egyptian", + "eisenbahn", + "elburg", + "elvendrell", + "embroidery", + "encyclopedic", + "england", + "entomology", + "environment", + "environmentalconservation", + "epilepsy", + "essex", + "estate", + "ethnology", + "exeter", + "exhibition", + "family", + "farm", + "farmequipment", + "farmers", + "farmstead", + "field", + "figueres", + "filatelia", + "film", + "fineart", + "finearts", + "finland", + "flanders", + "florida", + "force", + "fortmissoula", + "fortworth", + "foundation", + "francaise", + "frankfurt", + "franziskaner", + "freemasonry", + "freiburg", + "fribourg", + "frog", + "fundacio", + "furniture", + "gallery", + "garden", + "gateway", + "geelvinck", + "gemological", + "geology", + "georgia", + "giessen", + "glas", + "glass", + "gorge", + "grandrapids", + "graz", + "guernsey", + "halloffame", + "hamburg", + "handson", + "harvestcelebration", + "hawaii", + "health", + "heimatunduhren", + "hellas", + "helsinki", + "hembygdsforbund", + "heritage", + "histoire", + "historical", + "historicalsociety", + "historichouses", + "historisch", + "historisches", + "history", + "historyofscience", + "horology", + "house", + "humanities", + "illustration", + "imageandsound", + "indian", + "indiana", + "indianapolis", + "indianmarket", + "intelligence", + "interactive", + "iraq", + "iron", + "isleofman", + "jamison", + "jefferson", + "jerusalem", + "jewelry", + "jewish", + "jewishart", + "jfk", + "journalism", + "judaica", + "judygarland", + "juedisches", + "juif", + "karate", + "karikatur", + "kids", + "koebenhavn", + "koeln", + "kunst", + "kunstsammlung", + "kunstunddesign", + "labor", + "labour", + "lajolla", + "lancashire", + "landes", + "lans", + "larsson", + "lewismiller", + "lincoln", + "linz", + "living", + "livinghistory", + "localhistory", + "london", + "losangeles", + "louvre", + "loyalist", + "lucerne", + "luxembourg", + "luzern", + "mad", + "madrid", + "mallorca", + "manchester", + "mansion", + "mansions", + "manx", + "marburg", + "maritime", + "maritimo", + "maryland", + "marylhurst", + "media", + "medical", + "medizinhistorisches", + "meeres", + "memorial", + "mesaverde", + "michigan", + "midatlantic", + "military", + "mill", + "miners", + "mining", + "minnesota", + "missile", + "missoula", + "modern", + "moma", + "money", + "monmouth", + "monticello", + "montreal", + "moscow", + "motorcycle", + "muenchen", + "muenster", + "mulhouse", + "muncie", + "museet", + "museumcenter", + "museumvereniging", + "music", + "national", + "nationalfirearms", + "nationalheritage", + "nativeamerican", + "naturalhistory", + "naturalhistorymuseum", + "naturalsciences", + "nature", + "naturhistorisches", + "natuurwetenschappen", + "naumburg", + "naval", + "nebraska", + "neues", + "newhampshire", + "newjersey", + "newmexico", + "newport", + "newspaper", + "newyork", + "niepce", + "norfolk", + "north", + "nrw", + "nuernberg", + "nuremberg", + "nyc", + "nyny", + "oceanographic", + "oceanographique", + "omaha", + "online", + "ontario", + "openair", + "oregon", + "oregontrail", + "otago", + "oxford", + "pacific", + "paderborn", + "palace", + "paleo", + "palmsprings", + "panama", + "paris", + "pasadena", + "pharmacy", + "philadelphia", + "philadelphiaarea", + "philately", + "phoenix", + "photography", + "pilots", + "pittsburgh", + "planetarium", + "plantation", + "plants", + "plaza", + "portal", + "portland", + "portlligat", + "posts-and-telecommunications", + "preservation", + "presidio", + "press", + "project", + "public", + "pubol", + "quebec", + "railroad", + "railway", + "research", + "resistance", + "riodejaneiro", + "rochester", + "rockart", + "roma", + "russia", + "saintlouis", + "salem", + "salvadordali", + "salzburg", + "sandiego", + "sanfrancisco", + "santabarbara", + "santacruz", + "santafe", + "saskatchewan", + "satx", + "savannahga", + "schlesisches", + "schoenbrunn", + "schokoladen", + "school", + "schweiz", + "science", + "science-fiction", + "scienceandhistory", + "scienceandindustry", + "sciencecenter", + "sciencecenters", + "sciencehistory", + "sciences", + "sciencesnaturelles", + "scotland", + "seaport", + "settlement", + "settlers", + "shell", + "sherbrooke", + "sibenik", + "silk", + "ski", + "skole", + "society", + "sologne", + "soundandvision", + "southcarolina", + "southwest", + "space", + "spy", + "square", + "stadt", + "stalbans", + "starnberg", + "state", + "stateofdelaware", + "station", + "steam", + "steiermark", + "stjohn", + "stockholm", + "stpetersburg", + "stuttgart", + "suisse", + "surgeonshall", + "surrey", + "svizzera", + "sweden", + "sydney", + "tank", + "tcm", + "technology", + "telekommunikation", + "television", + "texas", + "textile", + "theater", + "time", + "timekeeping", + "topology", + "torino", + "touch", + "town", + "transport", + "tree", + "trolley", + "trust", + "trustee", + "uhren", + "ulm", + "undersea", + "university", + "usa", + "usantiques", + "usarts", + "uscountryestate", + "usculture", + "usdecorativearts", + "usgarden", + "ushistory", + "ushuaia", + "uslivinghistory", + "utah", + "uvic", + "valley", + "vantaa", + "versailles", + "viking", + "village", + "virginia", + "virtual", + "virtuel", + "vlaanderen", + "volkenkunde", + "wales", + "wallonie", + "war", + "washingtondc", + "watch-and-clock", + "watchandclock", + "western", + "westfalen", + "whaling", + "wildlife", + "williamsburg", + "windmill", + "workshop", + "xn--9dbhblg6di", + "xn--comunicaes-v6a2o", + "xn--correios-e-telecomunicaes-ghc29a", + "xn--h1aegh", + "xn--lns-qla", + "york", + "yorkshire", + "yosemite", + "youth", + "zoological", + "zoology", + "aero", + "biz", + "com", + "coop", + "edu", + "gov", + "info", + "int", + "mil", + "museum", + "name", + "net", + "org", + "pro", + "ac", + "biz", + "co", + "com", + "coop", + "edu", + "gov", + "int", + "museum", + "net", + "org", + "blogspot", + "com", + "edu", + "gob", + "net", + "org", + "blogspot", + "com", + "edu", + "gov", + "mil", + "name", + "net", + "org", + "teledata", + "ca", + "cc", + "co", + "com", + "dr", + "in", + "info", + "mobi", + "mx", + "name", + "or", + "org", + "pro", + "school", + "tv", + "us", + "ws", + "her", + "his", + "forgot", + "forgot", + "asso", + "at-band-camp", + "azure-mobile", + "azurewebsites", + "blogdns", + "broke-it", + "buyshouses", + "cdn77", + "cdn77-ssl", + "cloudapp", + "cloudfront", + "cloudfunctions", + "dnsalias", + "dnsdojo", + "does-it", + "dontexist", + "dsmynas", + "dynalias", + "dynathome", + "endofinternet", + "familyds", + "fastly", + "from-az", + "from-co", + "from-la", + "from-ny", + "gb", + "gets-it", + "ham-radio-op", + "homeftp", + "homeip", + "homelinux", + "homeunix", + "hu", + "in", + "in-the-band", + "is-a-chef", + "is-a-geek", + "isa-geek", + "jp", + "kicks-ass", + "office-on-the", + "podzone", + "rackmaze", + "scrapper-site", + "se", + "selfip", + "sells-it", + "servebbs", + "serveftp", + "thruhere", + "uk", + "webhop", + "za", + "r", + "prod", + "ssl", + "a", + "global", + "a", + "b", + "global", + "arts", + "com", + "firm", + "info", + "net", + "other", + "per", + "rec", + "store", + "web", + "com", + "edu", + "gov", + "i", + "mil", + "mobi", + "name", + "net", + "org", + "sch", + "blogspot", + "ac", + "biz", + "co", + "com", + "edu", + "gob", + "in", + "info", + "int", + "mil", + "net", + "nom", + "org", + "web", + "blogspot", + "bv", + "co", + "aa", + "aarborte", + "aejrie", + "afjord", + "agdenes", + "ah", + "akershus", + "aknoluokta", + "akrehamn", + "al", + "alaheadju", + "alesund", + "algard", + "alstahaug", + "alta", + "alvdal", + "amli", + "amot", + "andasuolo", + "andebu", + "andoy", + "ardal", + "aremark", + "arendal", + "arna", + "aseral", + "asker", + "askim", + "askoy", + "askvoll", + "asnes", + "audnedaln", + "aukra", + "aure", + "aurland", + "aurskog-holand", + "austevoll", + "austrheim", + "averoy", + "badaddja", + "bahcavuotna", + "bahccavuotna", + "baidar", + "bajddar", + "balat", + "balestrand", + "ballangen", + "balsfjord", + "bamble", + "bardu", + "barum", + "batsfjord", + "bearalvahki", + "beardu", + "beiarn", + "berg", + "bergen", + "berlevag", + "bievat", + "bindal", + "birkenes", + "bjarkoy", + "bjerkreim", + "bjugn", + "blogspot", + "bodo", + "bokn", + "bomlo", + "bremanger", + "bronnoy", + "bronnoysund", + "brumunddal", + "bryne", + "bu", + "budejju", + "buskerud", + "bygland", + "bykle", + "cahcesuolo", + "co", + "davvenjarga", + "davvesiida", + "deatnu", + "dep", + "dielddanuorri", + "divtasvuodna", + "divttasvuotna", + "donna", + "dovre", + "drammen", + "drangedal", + "drobak", + "dyroy", + "egersund", + "eid", + "eidfjord", + "eidsberg", + "eidskog", + "eidsvoll", + "eigersund", + "elverum", + "enebakk", + "engerdal", + "etne", + "etnedal", + "evenassi", + "evenes", + "evje-og-hornnes", + "farsund", + "fauske", + "fedje", + "fet", + "fetsund", + "fhs", + "finnoy", + "fitjar", + "fjaler", + "fjell", + "fla", + "flakstad", + "flatanger", + "flekkefjord", + "flesberg", + "flora", + "floro", + "fm", + "folkebibl", + "folldal", + "forde", + "forsand", + "fosnes", + "frana", + "fredrikstad", + "frei", + "frogn", + "froland", + "frosta", + "froya", + "fuoisku", + "fuossko", + "fusa", + "fylkesbibl", + "fyresdal", + "gaivuotna", + "galsa", + "gamvik", + "gangaviika", + "gaular", + "gausdal", + "giehtavuoatna", + "gildeskal", + "giske", + "gjemnes", + "gjerdrum", + "gjerstad", + "gjesdal", + "gjovik", + "gloppen", + "gol", + "gran", + "grane", + "granvin", + "gratangen", + "grimstad", + "grong", + "grue", + "gulen", + "guovdageaidnu", + "ha", + "habmer", + "hadsel", + "hagebostad", + "halden", + "halsa", + "hamar", + "hamaroy", + "hammarfeasta", + "hammerfest", + "hapmir", + "haram", + "hareid", + "harstad", + "hasvik", + "hattfjelldal", + "haugesund", + "hedmark", + "hemne", + "hemnes", + "hemsedal", + "herad", + "hitra", + "hjartdal", + "hjelmeland", + "hl", + "hm", + "hobol", + "hof", + "hokksund", + "hol", + "hole", + "holmestrand", + "holtalen", + "honefoss", + "hordaland", + "hornindal", + "horten", + "hoyanger", + "hoylandet", + "hurdal", + "hurum", + "hvaler", + "hyllestad", + "ibestad", + "idrett", + "inderoy", + "iveland", + "ivgu", + "jan-mayen", + "jessheim", + "jevnaker", + "jolster", + "jondal", + "jorpeland", + "kafjord", + "karasjohka", + "karasjok", + "karlsoy", + "karmoy", + "kautokeino", + "kirkenes", + "klabu", + "klepp", + "kommune", + "kongsberg", + "kongsvinger", + "kopervik", + "kraanghke", + "kragero", + "kristiansand", + "kristiansund", + "krodsherad", + "krokstadelva", + "kvafjord", + "kvalsund", + "kvam", + "kvanangen", + "kvinesdal", + "kvinnherad", + "kviteseid", + "kvitsoy", + "laakesvuemie", + "lahppi", + "langevag", + "lardal", + "larvik", + "lavagis", + "lavangen", + "leangaviika", + "lebesby", + "leikanger", + "leirfjord", + "leirvik", + "leka", + "leksvik", + "lenvik", + "lerdal", + "lesja", + "levanger", + "lier", + "lierne", + "lillehammer", + "lillesand", + "lindas", + "lindesnes", + "loabat", + "lodingen", + "lom", + "loppa", + "lorenskog", + "loten", + "lund", + "lunner", + "luroy", + "luster", + "lyngdal", + "lyngen", + "malatvuopmi", + "malselv", + "malvik", + "mandal", + "marker", + "marnardal", + "masfjorden", + "masoy", + "matta-varjjat", + "meland", + "meldal", + "melhus", + "meloy", + "meraker", + "midsund", + "midtre-gauldal", + "mil", + "mjondalen", + "mo-i-rana", + "moareke", + "modalen", + "modum", + "molde", + "more-og-romsdal", + "mosjoen", + "moskenes", + "moss", + "mosvik", + "mr", + "muosat", + "museum", + "naamesjevuemie", + "namdalseid", + "namsos", + "namsskogan", + "nannestad", + "naroy", + "narviika", + "narvik", + "naustdal", + "navuotna", + "nedre-eiker", + "nesna", + "nesodden", + "nesoddtangen", + "nesseby", + "nesset", + "nissedal", + "nittedal", + "nl", + "nord-aurdal", + "nord-fron", + "nord-odal", + "norddal", + "nordkapp", + "nordland", + "nordre-land", + "nordreisa", + "nore-og-uvdal", + "notodden", + "notteroy", + "nt", + "odda", + "of", + "oksnes", + "ol", + "omasvuotna", + "oppdal", + "oppegard", + "orkanger", + "orkdal", + "orland", + "orskog", + "orsta", + "osen", + "oslo", + "osoyro", + "osteroy", + "ostfold", + "ostre-toten", + "overhalla", + "ovre-eiker", + "oyer", + "oygarden", + "oystre-slidre", + "porsanger", + "porsangu", + "porsgrunn", + "priv", + "rade", + "radoy", + "rahkkeravju", + "raholt", + "raisa", + "rakkestad", + "ralingen", + "rana", + "randaberg", + "rauma", + "rendalen", + "rennebu", + "rennesoy", + "rindal", + "ringebu", + "ringerike", + "ringsaker", + "risor", + "rissa", + "rl", + "roan", + "rodoy", + "rollag", + "romsa", + "romskog", + "roros", + "rost", + "royken", + "royrvik", + "ruovat", + "rygge", + "salangen", + "salat", + "saltdal", + "samnanger", + "sandefjord", + "sandnes", + "sandnessjoen", + "sandoy", + "sarpsborg", + "sauda", + "sauherad", + "sel", + "selbu", + "selje", + "seljord", + "sf", + "siellak", + "sigdal", + "siljan", + "sirdal", + "skanit", + "skanland", + "skaun", + "skedsmo", + "skedsmokorset", + "ski", + "skien", + "skierva", + "skiptvet", + "skjak", + "skjervoy", + "skodje", + "slattum", + "smola", + "snaase", + "snasa", + "snillfjord", + "snoasa", + "sogndal", + "sogne", + "sokndal", + "sola", + "solund", + "somna", + "sondre-land", + "songdalen", + "sor-aurdal", + "sor-fron", + "sor-odal", + "sor-varanger", + "sorfold", + "sorreisa", + "sortland", + "sorum", + "spjelkavik", + "spydeberg", + "st", + "stange", + "stat", + "stathelle", + "stavanger", + "stavern", + "steigen", + "steinkjer", + "stjordal", + "stjordalshalsen", + "stokke", + "stor-elvdal", + "stord", + "stordal", + "storfjord", + "strand", + "stranda", + "stryn", + "sula", + "suldal", + "sund", + "sunndal", + "surnadal", + "svalbard", + "sveio", + "svelvik", + "sykkylven", + "tana", + "tananger", + "telemark", + "time", + "tingvoll", + "tinn", + "tjeldsund", + "tjome", + "tm", + "tokke", + "tolga", + "tonsberg", + "torsken", + "tr", + "trana", + "tranby", + "tranoy", + "troandin", + "trogstad", + "tromsa", + "tromso", + "trondheim", + "trysil", + "tvedestrand", + "tydal", + "tynset", + "tysfjord", + "tysnes", + "tysvar", + "ullensaker", + "ullensvang", + "ulvik", + "unjarga", + "utsira", + "va", + "vaapste", + "vadso", + "vaga", + "vagan", + "vagsoy", + "vaksdal", + "valle", + "vang", + "vanylven", + "vardo", + "varggat", + "varoy", + "vefsn", + "vega", + "vegarshei", + "vennesla", + "verdal", + "verran", + "vestby", + "vestfold", + "vestnes", + "vestre-slidre", + "vestre-toten", + "vestvagoy", + "vevelstad", + "vf", + "vgs", + "vik", + "vikna", + "vindafjord", + "voagat", + "volda", + "voss", + "vossevangen", + "xn--andy-ira", + "xn--asky-ira", + "xn--aurskog-hland-jnb", + "xn--avery-yua", + "xn--bdddj-mrabd", + "xn--bearalvhki-y4a", + "xn--berlevg-jxa", + "xn--bhcavuotna-s4a", + "xn--bhccavuotna-k7a", + "xn--bidr-5nac", + "xn--bievt-0qa", + "xn--bjarky-fya", + "xn--bjddar-pta", + "xn--blt-elab", + "xn--bmlo-gra", + "xn--bod-2na", + "xn--brnny-wuac", + "xn--brnnysund-m8ac", + "xn--brum-voa", + "xn--btsfjord-9za", + "xn--davvenjrga-y4a", + "xn--dnna-gra", + "xn--drbak-wua", + "xn--dyry-ira", + "xn--eveni-0qa01ga", + "xn--finny-yua", + "xn--fjord-lra", + "xn--fl-zia", + "xn--flor-jra", + "xn--frde-gra", + "xn--frna-woa", + "xn--frya-hra", + "xn--ggaviika-8ya47h", + "xn--gildeskl-g0a", + "xn--givuotna-8ya", + "xn--gjvik-wua", + "xn--gls-elac", + "xn--h-2fa", + "xn--hbmer-xqa", + "xn--hcesuolo-7ya35b", + "xn--hgebostad-g3a", + "xn--hmmrfeasta-s4ac", + "xn--hnefoss-q1a", + "xn--hobl-ira", + "xn--holtlen-hxa", + "xn--hpmir-xqa", + "xn--hyanger-q1a", + "xn--hylandet-54a", + "xn--indery-fya", + "xn--jlster-bya", + "xn--jrpeland-54a", + "xn--karmy-yua", + "xn--kfjord-iua", + "xn--klbu-woa", + "xn--koluokta-7ya57h", + "xn--krager-gya", + "xn--kranghke-b0a", + "xn--krdsherad-m8a", + "xn--krehamn-dxa", + "xn--krjohka-hwab49j", + "xn--ksnes-uua", + "xn--kvfjord-nxa", + "xn--kvitsy-fya", + "xn--kvnangen-k0a", + "xn--l-1fa", + "xn--laheadju-7ya", + "xn--langevg-jxa", + "xn--ldingen-q1a", + "xn--leagaviika-52b", + "xn--lesund-hua", + "xn--lgrd-poac", + "xn--lhppi-xqa", + "xn--linds-pra", + "xn--loabt-0qa", + "xn--lrdal-sra", + "xn--lrenskog-54a", + "xn--lt-liac", + "xn--lten-gra", + "xn--lury-ira", + "xn--mely-ira", + "xn--merker-kua", + "xn--mjndalen-64a", + "xn--mlatvuopmi-s4a", + "xn--mli-tla", + "xn--mlselv-iua", + "xn--moreke-jua", + "xn--mosjen-eya", + "xn--mot-tla", + "xn--mre-og-romsdal-qqb", + "xn--msy-ula0h", + "xn--mtta-vrjjat-k7af", + "xn--muost-0qa", + "xn--nmesjevuemie-tcba", + "xn--nry-yla5g", + "xn--nttery-byae", + "xn--nvuotna-hwa", + "xn--oppegrd-ixa", + "xn--ostery-fya", + "xn--osyro-wua", + "xn--porsgu-sta26f", + "xn--rady-ira", + "xn--rdal-poa", + "xn--rde-ula", + "xn--rdy-0nab", + "xn--rennesy-v1a", + "xn--rhkkervju-01af", + "xn--rholt-mra", + "xn--risa-5na", + "xn--risr-ira", + "xn--rland-uua", + "xn--rlingen-mxa", + "xn--rmskog-bya", + "xn--rros-gra", + "xn--rskog-uua", + "xn--rst-0na", + "xn--rsta-fra", + "xn--ryken-vua", + "xn--ryrvik-bya", + "xn--s-1fa", + "xn--sandnessjen-ogb", + "xn--sandy-yua", + "xn--seral-lra", + "xn--sgne-gra", + "xn--skierv-uta", + "xn--skjervy-v1a", + "xn--skjk-soa", + "xn--sknit-yqa", + "xn--sknland-fxa", + "xn--slat-5na", + "xn--slt-elab", + "xn--smla-hra", + "xn--smna-gra", + "xn--snase-nra", + "xn--sndre-land-0cb", + "xn--snes-poa", + "xn--snsa-roa", + "xn--sr-aurdal-l8a", + "xn--sr-fron-q1a", + "xn--sr-odal-q1a", + "xn--sr-varanger-ggb", + "xn--srfold-bya", + "xn--srreisa-q1a", + "xn--srum-gra", + "xn--stfold-9xa", + "xn--stjrdal-s1a", + "xn--stjrdalshalsen-sqb", + "xn--stre-toten-zcb", + "xn--tjme-hra", + "xn--tnsberg-q1a", + "xn--trany-yua", + "xn--trgstad-r1a", + "xn--trna-woa", + "xn--troms-zua", + "xn--tysvr-vra", + "xn--unjrga-rta", + "xn--vads-jra", + "xn--vard-jra", + "xn--vegrshei-c0a", + "xn--vestvgy-ixa6o", + "xn--vg-yiab", + "xn--vgan-qoa", + "xn--vgsy-qoa0j", + "xn--vre-eiker-k8a", + "xn--vrggt-xqad", + "xn--vry-yla5g", + "xn--yer-zna", + "xn--ygarden-p1a", + "xn--ystre-slidre-ujb", + "gs", + "gs", + "nes", + "gs", + "nes", + "gs", + "os", + "valer", + "xn--vler-qoa", + "gs", + "gs", + "os", + "gs", + "heroy", + "sande", + "gs", + "gs", + "bo", + "heroy", + "xn--b-5ga", + "xn--hery-ira", + "gs", + "gs", + "gs", + "gs", + "valer", + "gs", + "gs", + "gs", + "gs", + "bo", + "xn--b-5ga", + "gs", + "gs", + "gs", + "sande", + "gs", + "sande", + "xn--hery-ira", + "xn--vler-qoa", + "biz", + "com", + "edu", + "gov", + "info", + "net", + "org", + "merseine", + "mine", + "shacknet", + "ac", + "co", + "cri", + "geek", + "gen", + "govt", + "health", + "iwi", + "kiwi", + "maori", + "mil", + "net", + "org", + "parliament", + "school", + "xn--mori-qsa", + "blogspot", + "co", + "com", + "edu", + "gov", + "med", + "museum", + "net", + "org", + "pro", + "ae", + "blogdns", + "blogsite", + "bmoattachments", + "boldlygoingnowhere", + "cdn77", + "cdn77-secure", + "dnsalias", + "dnsdojo", + "doesntexist", + "dontexist", + "doomdns", + "dsmynas", + "duckdns", + "dvrdns", + "dynalias", + "dyndns", + "endofinternet", + "endoftheinternet", + "eu", + "familyds", + "from-me", + "game-host", + "gotdns", + "hk", + "hobby-site", + "homedns", + "homeftp", + "homelinux", + "homeunix", + "is-a-bruinsfan", + "is-a-candidate", + "is-a-celticsfan", + "is-a-chef", + "is-a-geek", + "is-a-knight", + "is-a-linux-user", + "is-a-patsfan", + "is-a-soxfan", + "is-found", + "is-lost", + "is-saved", + "is-very-bad", + "is-very-evil", + "is-very-good", + "is-very-nice", + "is-very-sweet", + "isa-geek", + "kicks-ass", + "misconfused", + "podzone", + "readmyblog", + "selfip", + "sellsyourhome", + "servebbs", + "serveftp", + "servegame", + "stuff-4-sale", + "us", + "webhop", + "za", + "c", + "rsc", + "origin", + "ssl", + "go", + "home", + "al", + "asso", + "at", + "au", + "be", + "bg", + "ca", + "cd", + "ch", + "cn", + "cy", + "cz", + "de", + "dk", + "edu", + "ee", + "es", + "fi", + "fr", + "gr", + "hr", + "hu", + "ie", + "il", + "in", + "int", + "is", + "it", + "jp", + "kr", + "lt", + "lu", + "lv", + "mc", + "me", + "mk", + "mt", + "my", + "net", + "ng", + "nl", + "no", + "nz", + "paris", + "pl", + "pt", + "q-a", + "ro", + "ru", + "se", + "si", + "sk", + "tr", + "uk", + "us", + "abo", + "ac", + "com", + "edu", + "gob", + "ing", + "med", + "net", + "nom", + "org", + "sld", + "blogspot", + "com", + "edu", + "gob", + "mil", + "net", + "nom", + "org", + "com", + "edu", + "org", + "com", + "edu", + "gov", + "i", + "mil", + "net", + "ngo", + "org", + "biz", + "com", + "edu", + "fam", + "gob", + "gok", + "gon", + "gop", + "gos", + "gov", + "info", + "net", + "org", + "web", + "agro", + "aid", + "art", + "atm", + "augustow", + "auto", + "babia-gora", + "bedzin", + "beskidy", + "bialowieza", + "bialystok", + "bielawa", + "bieszczady", + "biz", + "boleslawiec", + "bydgoszcz", + "bytom", + "cieszyn", + "co", + "com", + "czeladz", + "czest", + "dlugoleka", + "edu", + "elblag", + "elk", + "gda", + "gdansk", + "gdynia", + "gliwice", + "glogow", + "gmina", + "gniezno", + "gorlice", + "gov", + "grajewo", + "gsm", + "ilawa", + "info", + "jaworzno", + "jelenia-gora", + "jgora", + "kalisz", + "karpacz", + "kartuzy", + "kaszuby", + "katowice", + "kazimierz-dolny", + "kepno", + "ketrzyn", + "klodzko", + "kobierzyce", + "kolobrzeg", + "konin", + "konskowola", + "krakow", + "kutno", + "lapy", + "lebork", + "legnica", + "lezajsk", + "limanowa", + "lomza", + "lowicz", + "lubin", + "lukow", + "mail", + "malbork", + "malopolska", + "mazowsze", + "mazury", + "med", + "media", + "miasta", + "mielec", + "mielno", + "mil", + "mragowo", + "naklo", + "net", + "nieruchomosci", + "nom", + "nowaruda", + "nysa", + "olawa", + "olecko", + "olkusz", + "olsztyn", + "opoczno", + "opole", + "org", + "ostroda", + "ostroleka", + "ostrowiec", + "ostrowwlkp", + "pc", + "pila", + "pisz", + "podhale", + "podlasie", + "polkowice", + "pomorskie", + "pomorze", + "powiat", + "poznan", + "priv", + "prochowice", + "pruszkow", + "przeworsk", + "pulawy", + "radom", + "rawa-maz", + "realestate", + "rel", + "rybnik", + "rzeszow", + "sanok", + "sejny", + "sex", + "shop", + "sklep", + "skoczow", + "slask", + "slupsk", + "sopot", + "sos", + "sosnowiec", + "stalowa-wola", + "starachowice", + "stargard", + "suwalki", + "swidnica", + "swiebodzin", + "swinoujscie", + "szczecin", + "szczytno", + "szkola", + "targi", + "tarnobrzeg", + "tgory", + "tm", + "tourism", + "travel", + "turek", + "turystyka", + "tychy", + "ustka", + "walbrzych", + "warmia", + "warszawa", + "waw", + "wegrow", + "wielun", + "wlocl", + "wloclawek", + "wodzislaw", + "wolomin", + "wroc", + "wroclaw", + "zachpomor", + "zagan", + "zakopane", + "zarow", + "zgora", + "zgorzelec", + "ap", + "griw", + "ic", + "is", + "kmpsp", + "konsulat", + "kppsp", + "kwp", + "kwpsp", + "mup", + "mw", + "oirm", + "oum", + "pa", + "pinb", + "piw", + "po", + "psp", + "psse", + "pup", + "rzgw", + "sa", + "sdn", + "sko", + "so", + "sr", + "starostwo", + "ug", + "ugim", + "um", + "umig", + "upow", + "uppo", + "us", + "uw", + "uzs", + "wif", + "wiih", + "winb", + "wios", + "witd", + "wiw", + "wsa", + "wskr", + "wuoz", + "wzmiuw", + "zp", + "co", + "edu", + "gov", + "net", + "org", + "ac", + "biz", + "com", + "edu", + "est", + "gov", + "info", + "isla", + "name", + "net", + "org", + "pro", + "prof", + "aca", + "bar", + "cpa", + "eng", + "jur", + "law", + "med", + "com", + "edu", + "gov", + "net", + "org", + "plo", + "sec", + "blogspot", + "com", + "edu", + "gov", + "int", + "net", + "nome", + "org", + "publ", + "belau", + "co", + "ed", + "go", + "ne", + "or", + "com", + "coop", + "edu", + "gov", + "mil", + "net", + "org", + "blogspot", + "com", + "edu", + "gov", + "mil", + "name", + "net", + "org", + "sch", + "asso", + "blogspot", + "com", + "nom", + "arts", + "blogspot", + "com", + "firm", + "info", + "nom", + "nt", + "org", + "rec", + "store", + "tm", + "www", + "ac", + "blogspot", + "co", + "edu", + "gov", + "in", + "org", + "ac", + "adygeya", + "altai", + "amur", + "amursk", + "arkhangelsk", + "astrakhan", + "baikal", + "bashkiria", + "belgorod", + "bir", + "blogspot", + "bryansk", + "buryatia", + "cbg", + "chel", + "chelyabinsk", + "chita", + "chukotka", + "chuvashia", + "cmw", + "com", + "dagestan", + "dudinka", + "e-burg", + "edu", + "fareast", + "gov", + "grozny", + "int", + "irkutsk", + "ivanovo", + "izhevsk", + "jamal", + "jar", + "joshkar-ola", + "k-uralsk", + "kalmykia", + "kaluga", + "kamchatka", + "karelia", + "kazan", + "kchr", + "kemerovo", + "khabarovsk", + "khakassia", + "khv", + "kirov", + "kms", + "koenig", + "komi", + "kostroma", + "krasnoyarsk", + "kuban", + "kurgan", + "kursk", + "kustanai", + "kuzbass", + "lipetsk", + "magadan", + "mari", + "mari-el", + "marine", + "mil", + "mordovia", + "msk", + "murmansk", + "mytis", + "nakhodka", + "nalchik", + "net", + "nkz", + "nnov", + "norilsk", + "nov", + "novosibirsk", + "nsk", + "omsk", + "orenburg", + "org", + "oryol", + "oskol", + "palana", + "penza", + "perm", + "pp", + "ptz", + "pyatigorsk", + "rnd", + "rubtsovsk", + "ryazan", + "sakhalin", + "samara", + "saratov", + "simbirsk", + "smolensk", + "snz", + "spb", + "stavropol", + "stv", + "surgut", + "syzran", + "tambov", + "tatarstan", + "test", + "tom", + "tomsk", + "tsaritsyn", + "tsk", + "tula", + "tuva", + "tver", + "tyumen", + "udm", + "udmurtia", + "ulan-ude", + "vdonsk", + "vladikavkaz", + "vladimir", + "vladivostok", + "volgograd", + "vologda", + "voronezh", + "vrn", + "vyatka", + "yakutia", + "yamal", + "yaroslavl", + "yekaterinburg", + "yuzhno-sakhalinsk", + "zgrad", + "ac", + "co", + "com", + "edu", + "gouv", + "gov", + "int", + "mil", + "net", + "com", + "edu", + "gov", + "med", + "net", + "org", + "pub", + "sch", + "com", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "gov", + "net", + "org", + "com", + "edu", + "gov", + "info", + "med", + "net", + "org", + "tv", + "a", + "ac", + "b", + "bd", + "blogspot", + "brand", + "c", + "com", + "d", + "e", + "f", + "fh", + "fhsk", + "fhv", + "g", + "h", + "i", + "k", + "komforb", + "kommunalforbund", + "komvux", + "l", + "lanbib", + "m", + "n", + "naturbruksgymn", + "o", + "org", + "p", + "parti", + "pp", + "press", + "r", + "s", + "t", + "tm", + "u", + "w", + "x", + "y", + "z", + "blogspot", + "com", + "edu", + "gov", + "net", + "org", + "per", + "com", + "gov", + "hashbang", + "mil", + "net", + "org", + "platform", + "blogspot", + "blogspot", + "com", + "edu", + "gov", + "net", + "org", + "art", + "blogspot", + "com", + "edu", + "gouv", + "org", + "perso", + "univ", + "com", + "net", + "org", + "co", + "com", + "consulado", + "edu", + "embaixada", + "gov", + "mil", + "net", + "org", + "principe", + "saotome", + "store", + "adygeya", + "arkhangelsk", + "balashov", + "bashkiria", + "bryansk", + "dagestan", + "grozny", + "ivanovo", + "kalmykia", + "kaluga", + "karelia", + "khakassia", + "krasnodar", + "kurgan", + "lenug", + "mordovia", + "msk", + "murmansk", + "nalchik", + "nov", + "obninsk", + "penza", + "pokrovsk", + "sochi", + "spb", + "togliatti", + "troitsk", + "tula", + "tuva", + "vladikavkaz", + "vladimir", + "vologda", + "com", + "edu", + "gob", + "org", + "red", + "gov", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "ac", + "co", + "org", + "blogspot", + "ac", + "co", + "go", + "in", + "mi", + "net", + "or", + "ac", + "biz", + "co", + "com", + "edu", + "go", + "gov", + "int", + "mil", + "name", + "net", + "nic", + "org", + "test", + "web", + "gov", + "co", + "com", + "edu", + "gov", + "mil", + "net", + "nom", + "org", + "agrinet", + "com", + "defense", + "edunet", + "ens", + "fin", + "gov", + "ind", + "info", + "intl", + "mincom", + "nat", + "net", + "org", + "perso", + "rnrt", + "rns", + "rnu", + "tourism", + "turen", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "av", + "bbs", + "bel", + "biz", + "com", + "dr", + "edu", + "gen", + "gov", + "info", + "k12", + "kep", + "mil", + "name", + "nc", + "net", + "org", + "pol", + "tel", + "tv", + "web", + "blogspot", + "gov", + "aero", + "biz", + "co", + "com", + "coop", + "edu", + "gov", + "info", + "int", + "jobs", + "mobi", + "museum", + "name", + "net", + "org", + "pro", + "travel", + "better-than", + "dyndns", + "on-the-web", + "worse-than", + "blogspot", + "club", + "com", + "ebiz", + "edu", + "game", + "gov", + "idv", + "mil", + "net", + "org", + "xn--czrw28b", + "xn--uc0atv", + "xn--zf0ao64a", + "ac", + "co", + "go", + "hotel", + "info", + "me", + "mil", + "mobi", + "ne", + "or", + "sc", + "tv", + "biz", + "cherkassy", + "cherkasy", + "chernigov", + "chernihiv", + "chernivtsi", + "chernovtsy", + "ck", + "cn", + "co", + "com", + "cr", + "crimea", + "cv", + "dn", + "dnepropetrovsk", + "dnipropetrovsk", + "dominic", + "donetsk", + "dp", + "edu", + "gov", + "if", + "in", + "ivano-frankivsk", + "kh", + "kharkiv", + "kharkov", + "kherson", + "khmelnitskiy", + "khmelnytskyi", + "kiev", + "kirovograd", + "km", + "kr", + "krym", + "ks", + "kv", + "kyiv", + "lg", + "lt", + "lugansk", + "lutsk", + "lv", + "lviv", + "mk", + "mykolaiv", + "net", + "nikolaev", + "od", + "odesa", + "odessa", + "org", + "pl", + "poltava", + "pp", + "rivne", + "rovno", + "rv", + "sb", + "sebastopol", + "sevastopol", + "sm", + "sumy", + "te", + "ternopil", + "uz", + "uzhgorod", + "vinnica", + "vinnytsia", + "vn", + "volyn", + "yalta", + "zaporizhzhe", + "zaporizhzhia", + "zhitomir", + "zhytomyr", + "zp", + "zt", + "ac", + "blogspot", + "co", + "com", + "go", + "ne", + "or", + "org", + "sc", + "ac", + "co", + "gov", + "ltd", + "me", + "net", + "nhs", + "org", + "plc", + "police", + "sch", + "blogspot", + "service", + "ak", + "al", + "ar", + "as", + "az", + "ca", + "co", + "ct", + "dc", + "de", + "dni", + "fed", + "fl", + "ga", + "gu", + "hi", + "ia", + "id", + "il", + "in", + "is-by", + "isa", + "kids", + "ks", + "ky", + "la", + "land-4-sale", + "ma", + "md", + "me", + "mi", + "mn", + "mo", + "ms", + "mt", + "nc", + "nd", + "ne", + "nh", + "nj", + "nm", + "nsn", + "nv", + "ny", + "oh", + "ok", + "or", + "pa", + "pr", + "ri", + "sc", + "sd", + "stuff-4-sale", + "tn", + "tx", + "ut", + "va", + "vi", + "vt", + "wa", + "wi", + "wv", + "wy", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "chtr", + "paroch", + "pvt", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "k12", + "lib", + "cc", + "cc", + "k12", + "lib", + "com", + "edu", + "gub", + "mil", + "net", + "org", + "blogspot", + "co", + "com", + "net", + "org", + "com", + "edu", + "gov", + "mil", + "net", + "org", + "arts", + "co", + "com", + "e12", + "edu", + "firm", + "gob", + "gov", + "info", + "int", + "mil", + "net", + "org", + "rec", + "store", + "tec", + "web", + "co", + "com", + "k12", + "net", + "org", + "ac", + "biz", + "blogspot", + "com", + "edu", + "gov", + "health", + "info", + "int", + "name", + "net", + "org", + "pro", + "com", + "edu", + "net", + "org", + "com", + "dyndns", + "edu", + "gov", + "mypets", + "net", + "org", + "xn--80au", + "xn--90azh", + "xn--c1avg", + "xn--d1at", + "xn--o1ac", + "xn--o1ach", + "ac", + "agric", + "alt", + "co", + "edu", + "gov", + "grondar", + "law", + "mil", + "net", + "ngo", + "nis", + "nom", + "org", + "school", + "tm", + "web", + "blogspot", +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/events.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/events.go new file mode 100644 index 00000000..e66c7e32 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/events.go @@ -0,0 +1,524 @@ +// 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 trace + +import ( + "bytes" + "fmt" + "html/template" + "io" + "log" + "net/http" + "runtime" + "sort" + "strconv" + "strings" + "sync" + "sync/atomic" + "text/tabwriter" + "time" +) + +var eventsTmpl = template.Must(template.New("events").Funcs(template.FuncMap{ + "elapsed": elapsed, + "trimSpace": strings.TrimSpace, +}).Parse(eventsHTML)) + +const maxEventsPerLog = 100 + +type bucket struct { + MaxErrAge time.Duration + String string +} + +var buckets = []bucket{ + {0, "total"}, + {10 * time.Second, "errs<10s"}, + {1 * time.Minute, "errs<1m"}, + {10 * time.Minute, "errs<10m"}, + {1 * time.Hour, "errs<1h"}, + {10 * time.Hour, "errs<10h"}, + {24000 * time.Hour, "errors"}, +} + +// RenderEvents renders the HTML page typically served at /debug/events. +// It does not do any auth checking; see AuthRequest for the default auth check +// used by the handler registered on http.DefaultServeMux. +// req may be nil. +func RenderEvents(w http.ResponseWriter, req *http.Request, sensitive bool) { + now := time.Now() + data := &struct { + Families []string // family names + Buckets []bucket + Counts [][]int // eventLog count per family/bucket + + // Set when a bucket has been selected. + Family string + Bucket int + EventLogs eventLogs + Expanded bool + }{ + Buckets: buckets, + } + + data.Families = make([]string, 0, len(families)) + famMu.RLock() + for name := range families { + data.Families = append(data.Families, name) + } + famMu.RUnlock() + sort.Strings(data.Families) + + // Count the number of eventLogs in each family for each error age. + data.Counts = make([][]int, len(data.Families)) + for i, name := range data.Families { + // TODO(sameer): move this loop under the family lock. + f := getEventFamily(name) + data.Counts[i] = make([]int, len(data.Buckets)) + for j, b := range data.Buckets { + data.Counts[i][j] = f.Count(now, b.MaxErrAge) + } + } + + if req != nil { + var ok bool + data.Family, data.Bucket, ok = parseEventsArgs(req) + if !ok { + // No-op + } else { + data.EventLogs = getEventFamily(data.Family).Copy(now, buckets[data.Bucket].MaxErrAge) + } + if data.EventLogs != nil { + defer data.EventLogs.Free() + sort.Sort(data.EventLogs) + } + if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil { + data.Expanded = exp + } + } + + famMu.RLock() + defer famMu.RUnlock() + if err := eventsTmpl.Execute(w, data); err != nil { + log.Printf("net/trace: Failed executing template: %v", err) + } +} + +func parseEventsArgs(req *http.Request) (fam string, b int, ok bool) { + fam, bStr := req.FormValue("fam"), req.FormValue("b") + if fam == "" || bStr == "" { + return "", 0, false + } + b, err := strconv.Atoi(bStr) + if err != nil || b < 0 || b >= len(buckets) { + return "", 0, false + } + return fam, b, true +} + +// An EventLog provides a log of events associated with a specific object. +type EventLog interface { + // Printf formats its arguments with fmt.Sprintf and adds the + // result to the event log. + Printf(format string, a ...interface{}) + + // Errorf is like Printf, but it marks this event as an error. + Errorf(format string, a ...interface{}) + + // Finish declares that this event log is complete. + // The event log should not be used after calling this method. + Finish() +} + +// NewEventLog returns a new EventLog with the specified family name +// and title. +func NewEventLog(family, title string) EventLog { + el := newEventLog() + el.ref() + el.Family, el.Title = family, title + el.Start = time.Now() + el.events = make([]logEntry, 0, maxEventsPerLog) + el.stack = make([]uintptr, 32) + n := runtime.Callers(2, el.stack) + el.stack = el.stack[:n] + + getEventFamily(family).add(el) + return el +} + +func (el *eventLog) Finish() { + getEventFamily(el.Family).remove(el) + el.unref() // matches ref in New +} + +var ( + famMu sync.RWMutex + families = make(map[string]*eventFamily) // family name => family +) + +func getEventFamily(fam string) *eventFamily { + famMu.Lock() + defer famMu.Unlock() + f := families[fam] + if f == nil { + f = &eventFamily{} + families[fam] = f + } + return f +} + +type eventFamily struct { + mu sync.RWMutex + eventLogs eventLogs +} + +func (f *eventFamily) add(el *eventLog) { + f.mu.Lock() + f.eventLogs = append(f.eventLogs, el) + f.mu.Unlock() +} + +func (f *eventFamily) remove(el *eventLog) { + f.mu.Lock() + defer f.mu.Unlock() + for i, el0 := range f.eventLogs { + if el == el0 { + copy(f.eventLogs[i:], f.eventLogs[i+1:]) + f.eventLogs = f.eventLogs[:len(f.eventLogs)-1] + return + } + } +} + +func (f *eventFamily) Count(now time.Time, maxErrAge time.Duration) (n int) { + f.mu.RLock() + defer f.mu.RUnlock() + for _, el := range f.eventLogs { + if el.hasRecentError(now, maxErrAge) { + n++ + } + } + return +} + +func (f *eventFamily) Copy(now time.Time, maxErrAge time.Duration) (els eventLogs) { + f.mu.RLock() + defer f.mu.RUnlock() + els = make(eventLogs, 0, len(f.eventLogs)) + for _, el := range f.eventLogs { + if el.hasRecentError(now, maxErrAge) { + el.ref() + els = append(els, el) + } + } + return +} + +type eventLogs []*eventLog + +// Free calls unref on each element of the list. +func (els eventLogs) Free() { + for _, el := range els { + el.unref() + } +} + +// eventLogs may be sorted in reverse chronological order. +func (els eventLogs) Len() int { return len(els) } +func (els eventLogs) Less(i, j int) bool { return els[i].Start.After(els[j].Start) } +func (els eventLogs) Swap(i, j int) { els[i], els[j] = els[j], els[i] } + +// A logEntry is a timestamped log entry in an event log. +type logEntry struct { + When time.Time + Elapsed time.Duration // since previous event in log + NewDay bool // whether this event is on a different day to the previous event + What string + IsErr bool +} + +// WhenString returns a string representation of the elapsed time of the event. +// It will include the date if midnight was crossed. +func (e logEntry) WhenString() string { + if e.NewDay { + return e.When.Format("2006/01/02 15:04:05.000000") + } + return e.When.Format("15:04:05.000000") +} + +// An eventLog represents an active event log. +type eventLog struct { + // Family is the top-level grouping of event logs to which this belongs. + Family string + + // Title is the title of this event log. + Title string + + // Timing information. + Start time.Time + + // Call stack where this event log was created. + stack []uintptr + + // Append-only sequence of events. + // + // TODO(sameer): change this to a ring buffer to avoid the array copy + // when we hit maxEventsPerLog. + mu sync.RWMutex + events []logEntry + LastErrorTime time.Time + discarded int + + refs int32 // how many buckets this is in +} + +func (el *eventLog) reset() { + // Clear all but the mutex. Mutexes may not be copied, even when unlocked. + el.Family = "" + el.Title = "" + el.Start = time.Time{} + el.stack = nil + el.events = nil + el.LastErrorTime = time.Time{} + el.discarded = 0 + el.refs = 0 +} + +func (el *eventLog) hasRecentError(now time.Time, maxErrAge time.Duration) bool { + if maxErrAge == 0 { + return true + } + el.mu.RLock() + defer el.mu.RUnlock() + return now.Sub(el.LastErrorTime) < maxErrAge +} + +// delta returns the elapsed time since the last event or the log start, +// and whether it spans midnight. +// L >= el.mu +func (el *eventLog) delta(t time.Time) (time.Duration, bool) { + if len(el.events) == 0 { + return t.Sub(el.Start), false + } + prev := el.events[len(el.events)-1].When + return t.Sub(prev), prev.Day() != t.Day() + +} + +func (el *eventLog) Printf(format string, a ...interface{}) { + el.printf(false, format, a...) +} + +func (el *eventLog) Errorf(format string, a ...interface{}) { + el.printf(true, format, a...) +} + +func (el *eventLog) printf(isErr bool, format string, a ...interface{}) { + e := logEntry{When: time.Now(), IsErr: isErr, What: fmt.Sprintf(format, a...)} + el.mu.Lock() + e.Elapsed, e.NewDay = el.delta(e.When) + if len(el.events) < maxEventsPerLog { + el.events = append(el.events, e) + } else { + // Discard the oldest event. + if el.discarded == 0 { + // el.discarded starts at two to count for the event it + // is replacing, plus the next one that we are about to + // drop. + el.discarded = 2 + } else { + el.discarded++ + } + // TODO(sameer): if this causes allocations on a critical path, + // change eventLog.What to be a fmt.Stringer, as in trace.go. + el.events[0].What = fmt.Sprintf("(%d events discarded)", el.discarded) + // The timestamp of the discarded meta-event should be + // the time of the last event it is representing. + el.events[0].When = el.events[1].When + copy(el.events[1:], el.events[2:]) + el.events[maxEventsPerLog-1] = e + } + if e.IsErr { + el.LastErrorTime = e.When + } + el.mu.Unlock() +} + +func (el *eventLog) ref() { + atomic.AddInt32(&el.refs, 1) +} + +func (el *eventLog) unref() { + if atomic.AddInt32(&el.refs, -1) == 0 { + freeEventLog(el) + } +} + +func (el *eventLog) When() string { + return el.Start.Format("2006/01/02 15:04:05.000000") +} + +func (el *eventLog) ElapsedTime() string { + elapsed := time.Since(el.Start) + return fmt.Sprintf("%.6f", elapsed.Seconds()) +} + +func (el *eventLog) Stack() string { + buf := new(bytes.Buffer) + tw := tabwriter.NewWriter(buf, 1, 8, 1, '\t', 0) + printStackRecord(tw, el.stack) + tw.Flush() + return buf.String() +} + +// printStackRecord prints the function + source line information +// for a single stack trace. +// Adapted from runtime/pprof/pprof.go. +func printStackRecord(w io.Writer, stk []uintptr) { + for _, pc := range stk { + f := runtime.FuncForPC(pc) + if f == nil { + continue + } + file, line := f.FileLine(pc) + name := f.Name() + // Hide runtime.goexit and any runtime functions at the beginning. + if strings.HasPrefix(name, "runtime.") { + continue + } + fmt.Fprintf(w, "# %s\t%s:%d\n", name, file, line) + } +} + +func (el *eventLog) Events() []logEntry { + el.mu.RLock() + defer el.mu.RUnlock() + return el.events +} + +// freeEventLogs is a freelist of *eventLog +var freeEventLogs = make(chan *eventLog, 1000) + +// newEventLog returns a event log ready to use. +func newEventLog() *eventLog { + select { + case el := <-freeEventLogs: + return el + default: + return new(eventLog) + } +} + +// freeEventLog adds el to freeEventLogs if there's room. +// This is non-blocking. +func freeEventLog(el *eventLog) { + el.reset() + select { + case freeEventLogs <- el: + default: + } +} + +const eventsHTML = ` + + + events + + + + +

    /debug/events

    + +
  • + {{range $i, $fam := .Families}} + + + + {{range $j, $bucket := $.Buckets}} + {{$n := index $.Counts $i $j}} + + {{end}} + + {{end}} +
    {{$fam}} + {{if $n}}{{end}} + [{{$n}} {{$bucket.String}}] + {{if $n}}{{end}} +
    + +{{if $.EventLogs}} +


    +

    Family: {{$.Family}}

    + +{{if $.Expanded}}{{end}} +[Summary]{{if $.Expanded}}{{end}} + +{{if not $.Expanded}}{{end}} +[Expanded]{{if not $.Expanded}}{{end}} + + + + {{range $el := $.EventLogs}} + + + + + {{if $.Expanded}} + + + + + + {{range $el.Events}} + + + + + + {{end}} + {{end}} + {{end}} +
    WhenElapsed
    {{$el.When}}{{$el.ElapsedTime}}{{$el.Title}} +
    {{$el.Stack|trimSpace}}
    {{.WhenString}}{{elapsed .Elapsed}}.{{if .IsErr}}E{{else}}.{{end}}. {{.What}}
    +{{end}} + + +` diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/histogram.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/histogram.go new file mode 100644 index 00000000..bb42aa53 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/histogram.go @@ -0,0 +1,356 @@ +// 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 trace + +// This file implements histogramming for RPC statistics collection. + +import ( + "bytes" + "fmt" + "html/template" + "log" + "math" + + "golang.org/x/net/internal/timeseries" +) + +const ( + bucketCount = 38 +) + +// histogram keeps counts of values in buckets that are spaced +// out in powers of 2: 0-1, 2-3, 4-7... +// histogram implements timeseries.Observable +type histogram struct { + sum int64 // running total of measurements + sumOfSquares float64 // square of running total + buckets []int64 // bucketed values for histogram + value int // holds a single value as an optimization + valueCount int64 // number of values recorded for single value +} + +// AddMeasurement records a value measurement observation to the histogram. +func (h *histogram) addMeasurement(value int64) { + // TODO: assert invariant + h.sum += value + h.sumOfSquares += float64(value) * float64(value) + + bucketIndex := getBucket(value) + + if h.valueCount == 0 || (h.valueCount > 0 && h.value == bucketIndex) { + h.value = bucketIndex + h.valueCount++ + } else { + h.allocateBuckets() + h.buckets[bucketIndex]++ + } +} + +func (h *histogram) allocateBuckets() { + if h.buckets == nil { + h.buckets = make([]int64, bucketCount) + h.buckets[h.value] = h.valueCount + h.value = 0 + h.valueCount = -1 + } +} + +func log2(i int64) int { + n := 0 + for ; i >= 0x100; i >>= 8 { + n += 8 + } + for ; i > 0; i >>= 1 { + n += 1 + } + return n +} + +func getBucket(i int64) (index int) { + index = log2(i) - 1 + if index < 0 { + index = 0 + } + if index >= bucketCount { + index = bucketCount - 1 + } + return +} + +// Total returns the number of recorded observations. +func (h *histogram) total() (total int64) { + if h.valueCount >= 0 { + total = h.valueCount + } + for _, val := range h.buckets { + total += int64(val) + } + return +} + +// Average returns the average value of recorded observations. +func (h *histogram) average() float64 { + t := h.total() + if t == 0 { + return 0 + } + return float64(h.sum) / float64(t) +} + +// Variance returns the variance of recorded observations. +func (h *histogram) variance() float64 { + t := float64(h.total()) + if t == 0 { + return 0 + } + s := float64(h.sum) / t + return h.sumOfSquares/t - s*s +} + +// StandardDeviation returns the standard deviation of recorded observations. +func (h *histogram) standardDeviation() float64 { + return math.Sqrt(h.variance()) +} + +// PercentileBoundary estimates the value that the given fraction of recorded +// observations are less than. +func (h *histogram) percentileBoundary(percentile float64) int64 { + total := h.total() + + // Corner cases (make sure result is strictly less than Total()) + if total == 0 { + return 0 + } else if total == 1 { + return int64(h.average()) + } + + percentOfTotal := round(float64(total) * percentile) + var runningTotal int64 + + for i := range h.buckets { + value := h.buckets[i] + runningTotal += value + if runningTotal == percentOfTotal { + // We hit an exact bucket boundary. If the next bucket has data, it is a + // good estimate of the value. If the bucket is empty, we interpolate the + // midpoint between the next bucket's boundary and the next non-zero + // bucket. If the remaining buckets are all empty, then we use the + // boundary for the next bucket as the estimate. + j := uint8(i + 1) + min := bucketBoundary(j) + if runningTotal < total { + for h.buckets[j] == 0 { + j++ + } + } + max := bucketBoundary(j) + return min + round(float64(max-min)/2) + } else if runningTotal > percentOfTotal { + // The value is in this bucket. Interpolate the value. + delta := runningTotal - percentOfTotal + percentBucket := float64(value-delta) / float64(value) + bucketMin := bucketBoundary(uint8(i)) + nextBucketMin := bucketBoundary(uint8(i + 1)) + bucketSize := nextBucketMin - bucketMin + return bucketMin + round(percentBucket*float64(bucketSize)) + } + } + return bucketBoundary(bucketCount - 1) +} + +// Median returns the estimated median of the observed values. +func (h *histogram) median() int64 { + return h.percentileBoundary(0.5) +} + +// Add adds other to h. +func (h *histogram) Add(other timeseries.Observable) { + o := other.(*histogram) + if o.valueCount == 0 { + // Other histogram is empty + } else if h.valueCount >= 0 && o.valueCount > 0 && h.value == o.value { + // Both have a single bucketed value, aggregate them + h.valueCount += o.valueCount + } else { + // Two different values necessitate buckets in this histogram + h.allocateBuckets() + if o.valueCount >= 0 { + h.buckets[o.value] += o.valueCount + } else { + for i := range h.buckets { + h.buckets[i] += o.buckets[i] + } + } + } + h.sumOfSquares += o.sumOfSquares + h.sum += o.sum +} + +// Clear resets the histogram to an empty state, removing all observed values. +func (h *histogram) Clear() { + h.buckets = nil + h.value = 0 + h.valueCount = 0 + h.sum = 0 + h.sumOfSquares = 0 +} + +// CopyFrom copies from other, which must be a *histogram, into h. +func (h *histogram) CopyFrom(other timeseries.Observable) { + o := other.(*histogram) + if o.valueCount == -1 { + h.allocateBuckets() + copy(h.buckets, o.buckets) + } + h.sum = o.sum + h.sumOfSquares = o.sumOfSquares + h.value = o.value + h.valueCount = o.valueCount +} + +// Multiply scales the histogram by the specified ratio. +func (h *histogram) Multiply(ratio float64) { + if h.valueCount == -1 { + for i := range h.buckets { + h.buckets[i] = int64(float64(h.buckets[i]) * ratio) + } + } else { + h.valueCount = int64(float64(h.valueCount) * ratio) + } + h.sum = int64(float64(h.sum) * ratio) + h.sumOfSquares = h.sumOfSquares * ratio +} + +// New creates a new histogram. +func (h *histogram) New() timeseries.Observable { + r := new(histogram) + r.Clear() + return r +} + +func (h *histogram) String() string { + return fmt.Sprintf("%d, %f, %d, %d, %v", + h.sum, h.sumOfSquares, h.value, h.valueCount, h.buckets) +} + +// round returns the closest int64 to the argument +func round(in float64) int64 { + return int64(math.Floor(in + 0.5)) +} + +// bucketBoundary returns the first value in the bucket. +func bucketBoundary(bucket uint8) int64 { + if bucket == 0 { + return 0 + } + return 1 << bucket +} + +// bucketData holds data about a specific bucket for use in distTmpl. +type bucketData struct { + Lower, Upper int64 + N int64 + Pct, CumulativePct float64 + GraphWidth int +} + +// data holds data about a Distribution for use in distTmpl. +type data struct { + Buckets []*bucketData + Count, Median int64 + Mean, StandardDeviation float64 +} + +// maxHTMLBarWidth is the maximum width of the HTML bar for visualizing buckets. +const maxHTMLBarWidth = 350.0 + +// newData returns data representing h for use in distTmpl. +func (h *histogram) newData() *data { + // Force the allocation of buckets to simplify the rendering implementation + h.allocateBuckets() + // We scale the bars on the right so that the largest bar is + // maxHTMLBarWidth pixels in width. + maxBucket := int64(0) + for _, n := range h.buckets { + if n > maxBucket { + maxBucket = n + } + } + total := h.total() + barsizeMult := maxHTMLBarWidth / float64(maxBucket) + var pctMult float64 + if total == 0 { + pctMult = 1.0 + } else { + pctMult = 100.0 / float64(total) + } + + buckets := make([]*bucketData, len(h.buckets)) + runningTotal := int64(0) + for i, n := range h.buckets { + if n == 0 { + continue + } + runningTotal += n + var upperBound int64 + if i < bucketCount-1 { + upperBound = bucketBoundary(uint8(i + 1)) + } else { + upperBound = math.MaxInt64 + } + buckets[i] = &bucketData{ + Lower: bucketBoundary(uint8(i)), + Upper: upperBound, + N: n, + Pct: float64(n) * pctMult, + CumulativePct: float64(runningTotal) * pctMult, + GraphWidth: int(float64(n) * barsizeMult), + } + } + return &data{ + Buckets: buckets, + Count: total, + Median: h.median(), + Mean: h.average(), + StandardDeviation: h.standardDeviation(), + } +} + +func (h *histogram) html() template.HTML { + buf := new(bytes.Buffer) + if err := distTmpl.Execute(buf, h.newData()); err != nil { + buf.Reset() + log.Printf("net/trace: couldn't execute template: %v", err) + } + return template.HTML(buf.String()) +} + +// Input: data +var distTmpl = template.Must(template.New("distTmpl").Parse(` + + + + + + + +
    Count: {{.Count}}Mean: {{printf "%.0f" .Mean}}StdDev: {{printf "%.0f" .StandardDeviation}}Median: {{.Median}}
    +
    + +{{range $b := .Buckets}} +{{if $b}} + + + + + + + + + +{{end}} +{{end}} +
    [{{.Lower}},{{.Upper}}){{.N}}{{printf "%#.3f" .Pct}}%{{printf "%#.3f" .CumulativePct}}%
    +`)) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/histogram_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/histogram_test.go new file mode 100644 index 00000000..d384b933 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/histogram_test.go @@ -0,0 +1,325 @@ +// 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 trace + +import ( + "math" + "testing" +) + +type sumTest struct { + value int64 + sum int64 + sumOfSquares float64 + total int64 +} + +var sumTests = []sumTest{ + {100, 100, 10000, 1}, + {50, 150, 12500, 2}, + {50, 200, 15000, 3}, + {50, 250, 17500, 4}, +} + +type bucketingTest struct { + in int64 + log int + bucket int +} + +var bucketingTests = []bucketingTest{ + {0, 0, 0}, + {1, 1, 0}, + {2, 2, 1}, + {3, 2, 1}, + {4, 3, 2}, + {1000, 10, 9}, + {1023, 10, 9}, + {1024, 11, 10}, + {1000000, 20, 19}, +} + +type multiplyTest struct { + in int64 + ratio float64 + expectedSum int64 + expectedTotal int64 + expectedSumOfSquares float64 +} + +var multiplyTests = []multiplyTest{ + {15, 2.5, 37, 2, 562.5}, + {128, 4.6, 758, 13, 77953.9}, +} + +type percentileTest struct { + fraction float64 + expected int64 +} + +var percentileTests = []percentileTest{ + {0.25, 48}, + {0.5, 96}, + {0.6, 109}, + {0.75, 128}, + {0.90, 205}, + {0.95, 230}, + {0.99, 256}, +} + +func TestSum(t *testing.T) { + var h histogram + + for _, test := range sumTests { + h.addMeasurement(test.value) + sum := h.sum + if sum != test.sum { + t.Errorf("h.Sum = %v WANT: %v", sum, test.sum) + } + + sumOfSquares := h.sumOfSquares + if sumOfSquares != test.sumOfSquares { + t.Errorf("h.SumOfSquares = %v WANT: %v", sumOfSquares, test.sumOfSquares) + } + + total := h.total() + if total != test.total { + t.Errorf("h.Total = %v WANT: %v", total, test.total) + } + } +} + +func TestMultiply(t *testing.T) { + var h histogram + for i, test := range multiplyTests { + h.addMeasurement(test.in) + h.Multiply(test.ratio) + if h.sum != test.expectedSum { + t.Errorf("#%v: h.sum = %v WANT: %v", i, h.sum, test.expectedSum) + } + if h.total() != test.expectedTotal { + t.Errorf("#%v: h.total = %v WANT: %v", i, h.total(), test.expectedTotal) + } + if h.sumOfSquares != test.expectedSumOfSquares { + t.Errorf("#%v: h.SumOfSquares = %v WANT: %v", i, test.expectedSumOfSquares, h.sumOfSquares) + } + } +} + +func TestBucketingFunctions(t *testing.T) { + for _, test := range bucketingTests { + log := log2(test.in) + if log != test.log { + t.Errorf("log2 = %v WANT: %v", log, test.log) + } + + bucket := getBucket(test.in) + if bucket != test.bucket { + t.Errorf("getBucket = %v WANT: %v", bucket, test.bucket) + } + } +} + +func TestAverage(t *testing.T) { + a := new(histogram) + average := a.average() + if average != 0 { + t.Errorf("Average of empty histogram was %v WANT: 0", average) + } + + a.addMeasurement(1) + a.addMeasurement(1) + a.addMeasurement(3) + const expected = float64(5) / float64(3) + average = a.average() + + if !isApproximate(average, expected) { + t.Errorf("Average = %g WANT: %v", average, expected) + } +} + +func TestStandardDeviation(t *testing.T) { + a := new(histogram) + add(a, 10, 1<<4) + add(a, 10, 1<<5) + add(a, 10, 1<<6) + stdDev := a.standardDeviation() + const expected = 19.95 + + if !isApproximate(stdDev, expected) { + t.Errorf("StandardDeviation = %v WANT: %v", stdDev, expected) + } + + // No values + a = new(histogram) + stdDev = a.standardDeviation() + + if !isApproximate(stdDev, 0) { + t.Errorf("StandardDeviation = %v WANT: 0", stdDev) + } + + add(a, 1, 1<<4) + if !isApproximate(stdDev, 0) { + t.Errorf("StandardDeviation = %v WANT: 0", stdDev) + } + + add(a, 10, 1<<4) + if !isApproximate(stdDev, 0) { + t.Errorf("StandardDeviation = %v WANT: 0", stdDev) + } +} + +func TestPercentileBoundary(t *testing.T) { + a := new(histogram) + add(a, 5, 1<<4) + add(a, 10, 1<<6) + add(a, 5, 1<<7) + + for _, test := range percentileTests { + percentile := a.percentileBoundary(test.fraction) + if percentile != test.expected { + t.Errorf("h.PercentileBoundary (fraction=%v) = %v WANT: %v", test.fraction, percentile, test.expected) + } + } +} + +func TestCopyFrom(t *testing.T) { + a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1} + b := histogram{6, 36, []int64{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39}, 5, -1} + + a.CopyFrom(&b) + + if a.String() != b.String() { + t.Errorf("a.String = %s WANT: %s", a.String(), b.String()) + } +} + +func TestClear(t *testing.T) { + a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1} + + a.Clear() + + expected := "0, 0.000000, 0, 0, []" + if a.String() != expected { + t.Errorf("a.String = %s WANT %s", a.String(), expected) + } +} + +func TestNew(t *testing.T) { + a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1} + b := a.New() + + expected := "0, 0.000000, 0, 0, []" + if b.(*histogram).String() != expected { + t.Errorf("b.(*histogram).String = %s WANT: %s", b.(*histogram).String(), expected) + } +} + +func TestAdd(t *testing.T) { + // The tests here depend on the associativity of addMeasurement and Add. + // Add empty observation + a := histogram{5, 25, []int64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38}, 4, -1} + b := a.New() + + expected := a.String() + a.Add(b) + if a.String() != expected { + t.Errorf("a.String = %s WANT: %s", a.String(), expected) + } + + // Add same bucketed value, no new buckets + c := new(histogram) + d := new(histogram) + e := new(histogram) + c.addMeasurement(12) + d.addMeasurement(11) + e.addMeasurement(12) + e.addMeasurement(11) + c.Add(d) + if c.String() != e.String() { + t.Errorf("c.String = %s WANT: %s", c.String(), e.String()) + } + + // Add bucketed values + f := new(histogram) + g := new(histogram) + h := new(histogram) + f.addMeasurement(4) + f.addMeasurement(12) + f.addMeasurement(100) + g.addMeasurement(18) + g.addMeasurement(36) + g.addMeasurement(255) + h.addMeasurement(4) + h.addMeasurement(12) + h.addMeasurement(100) + h.addMeasurement(18) + h.addMeasurement(36) + h.addMeasurement(255) + f.Add(g) + if f.String() != h.String() { + t.Errorf("f.String = %q WANT: %q", f.String(), h.String()) + } + + // add buckets to no buckets + i := new(histogram) + j := new(histogram) + k := new(histogram) + j.addMeasurement(18) + j.addMeasurement(36) + j.addMeasurement(255) + k.addMeasurement(18) + k.addMeasurement(36) + k.addMeasurement(255) + i.Add(j) + if i.String() != k.String() { + t.Errorf("i.String = %q WANT: %q", i.String(), k.String()) + } + + // add buckets to single value (no overlap) + l := new(histogram) + m := new(histogram) + n := new(histogram) + l.addMeasurement(0) + m.addMeasurement(18) + m.addMeasurement(36) + m.addMeasurement(255) + n.addMeasurement(0) + n.addMeasurement(18) + n.addMeasurement(36) + n.addMeasurement(255) + l.Add(m) + if l.String() != n.String() { + t.Errorf("l.String = %q WANT: %q", l.String(), n.String()) + } + + // mixed order + o := new(histogram) + p := new(histogram) + o.addMeasurement(0) + o.addMeasurement(2) + o.addMeasurement(0) + p.addMeasurement(0) + p.addMeasurement(0) + p.addMeasurement(2) + if o.String() != p.String() { + t.Errorf("o.String = %q WANT: %q", o.String(), p.String()) + } +} + +func add(h *histogram, times int, val int64) { + for i := 0; i < times; i++ { + h.addMeasurement(val) + } +} + +func isApproximate(x, y float64) bool { + return math.Abs(x-y) < 1e-2 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/trace.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/trace.go new file mode 100644 index 00000000..0767c8c6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/trace.go @@ -0,0 +1,1059 @@ +// 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 trace implements tracing of requests and long-lived objects. +It exports HTTP interfaces on /debug/requests and /debug/events. + +A trace.Trace provides tracing for short-lived objects, usually requests. +A request handler might be implemented like this: + + func fooHandler(w http.ResponseWriter, req *http.Request) { + tr := trace.New("mypkg.Foo", req.URL.Path) + defer tr.Finish() + ... + tr.LazyPrintf("some event %q happened", str) + ... + if err := somethingImportant(); err != nil { + tr.LazyPrintf("somethingImportant failed: %v", err) + tr.SetError() + } + } + +The /debug/requests HTTP endpoint organizes the traces by family, +errors, and duration. It also provides histogram of request duration +for each family. + +A trace.EventLog provides tracing for long-lived objects, such as RPC +connections. + + // A Fetcher fetches URL paths for a single domain. + type Fetcher struct { + domain string + events trace.EventLog + } + + func NewFetcher(domain string) *Fetcher { + return &Fetcher{ + domain, + trace.NewEventLog("mypkg.Fetcher", domain), + } + } + + func (f *Fetcher) Fetch(path string) (string, error) { + resp, err := http.Get("http://" + f.domain + "/" + path) + if err != nil { + f.events.Errorf("Get(%q) = %v", path, err) + return "", err + } + f.events.Printf("Get(%q) = %s", path, resp.Status) + ... + } + + func (f *Fetcher) Close() error { + f.events.Finish() + return nil + } + +The /debug/events HTTP endpoint organizes the event logs by family and +by time since the last error. The expanded view displays recent log +entries and the log's call stack. +*/ +package trace // import "golang.org/x/net/trace" + +import ( + "bytes" + "fmt" + "html/template" + "io" + "log" + "net" + "net/http" + "runtime" + "sort" + "strconv" + "sync" + "sync/atomic" + "time" + + "golang.org/x/net/context" + "golang.org/x/net/internal/timeseries" +) + +// DebugUseAfterFinish controls whether to debug uses of Trace values after finishing. +// FOR DEBUGGING ONLY. This will slow down the program. +var DebugUseAfterFinish = false + +// AuthRequest determines whether a specific request is permitted to load the +// /debug/requests or /debug/events pages. +// +// It returns two bools; the first indicates whether the page may be viewed at all, +// and the second indicates whether sensitive events will be shown. +// +// AuthRequest may be replaced by a program to customise its authorisation requirements. +// +// The default AuthRequest function returns (true, true) iff the request comes from localhost/127.0.0.1/[::1]. +var AuthRequest = func(req *http.Request) (any, sensitive bool) { + host, _, err := net.SplitHostPort(req.RemoteAddr) + switch { + case err != nil: // Badly formed address; fail closed. + return false, false + case host == "localhost" || host == "127.0.0.1" || host == "::1": + return true, true + default: + return false, false + } +} + +func init() { + http.HandleFunc("/debug/requests", func(w http.ResponseWriter, req *http.Request) { + any, sensitive := AuthRequest(req) + if !any { + http.Error(w, "not allowed", http.StatusUnauthorized) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + Render(w, req, sensitive) + }) + http.HandleFunc("/debug/events", func(w http.ResponseWriter, req *http.Request) { + any, sensitive := AuthRequest(req) + if !any { + http.Error(w, "not allowed", http.StatusUnauthorized) + return + } + w.Header().Set("Content-Type", "text/html; charset=utf-8") + RenderEvents(w, req, sensitive) + }) +} + +// Render renders the HTML page typically served at /debug/requests. +// It does not do any auth checking; see AuthRequest for the default auth check +// used by the handler registered on http.DefaultServeMux. +// req may be nil. +func Render(w io.Writer, req *http.Request, sensitive bool) { + data := &struct { + Families []string + ActiveTraceCount map[string]int + CompletedTraces map[string]*family + + // Set when a bucket has been selected. + Traces traceList + Family string + Bucket int + Expanded bool + Traced bool + Active bool + ShowSensitive bool // whether to show sensitive events + + Histogram template.HTML + HistogramWindow string // e.g. "last minute", "last hour", "all time" + + // If non-zero, the set of traces is a partial set, + // and this is the total number. + Total int + }{ + CompletedTraces: completedTraces, + } + + data.ShowSensitive = sensitive + if req != nil { + // Allow show_sensitive=0 to force hiding of sensitive data for testing. + // This only goes one way; you can't use show_sensitive=1 to see things. + if req.FormValue("show_sensitive") == "0" { + data.ShowSensitive = false + } + + if exp, err := strconv.ParseBool(req.FormValue("exp")); err == nil { + data.Expanded = exp + } + if exp, err := strconv.ParseBool(req.FormValue("rtraced")); err == nil { + data.Traced = exp + } + } + + completedMu.RLock() + data.Families = make([]string, 0, len(completedTraces)) + for fam := range completedTraces { + data.Families = append(data.Families, fam) + } + completedMu.RUnlock() + sort.Strings(data.Families) + + // We are careful here to minimize the time spent locking activeMu, + // since that lock is required every time an RPC starts and finishes. + data.ActiveTraceCount = make(map[string]int, len(data.Families)) + activeMu.RLock() + for fam, s := range activeTraces { + data.ActiveTraceCount[fam] = s.Len() + } + activeMu.RUnlock() + + var ok bool + data.Family, data.Bucket, ok = parseArgs(req) + switch { + case !ok: + // No-op + case data.Bucket == -1: + data.Active = true + n := data.ActiveTraceCount[data.Family] + data.Traces = getActiveTraces(data.Family) + if len(data.Traces) < n { + data.Total = n + } + case data.Bucket < bucketsPerFamily: + if b := lookupBucket(data.Family, data.Bucket); b != nil { + data.Traces = b.Copy(data.Traced) + } + default: + if f := getFamily(data.Family, false); f != nil { + var obs timeseries.Observable + f.LatencyMu.RLock() + switch o := data.Bucket - bucketsPerFamily; o { + case 0: + obs = f.Latency.Minute() + data.HistogramWindow = "last minute" + case 1: + obs = f.Latency.Hour() + data.HistogramWindow = "last hour" + case 2: + obs = f.Latency.Total() + data.HistogramWindow = "all time" + } + f.LatencyMu.RUnlock() + if obs != nil { + data.Histogram = obs.(*histogram).html() + } + } + } + + if data.Traces != nil { + defer data.Traces.Free() + sort.Sort(data.Traces) + } + + completedMu.RLock() + defer completedMu.RUnlock() + if err := pageTmpl.ExecuteTemplate(w, "Page", data); err != nil { + log.Printf("net/trace: Failed executing template: %v", err) + } +} + +func parseArgs(req *http.Request) (fam string, b int, ok bool) { + if req == nil { + return "", 0, false + } + fam, bStr := req.FormValue("fam"), req.FormValue("b") + if fam == "" || bStr == "" { + return "", 0, false + } + b, err := strconv.Atoi(bStr) + if err != nil || b < -1 { + return "", 0, false + } + + return fam, b, true +} + +func lookupBucket(fam string, b int) *traceBucket { + f := getFamily(fam, false) + if f == nil || b < 0 || b >= len(f.Buckets) { + return nil + } + return f.Buckets[b] +} + +type contextKeyT string + +var contextKey = contextKeyT("golang.org/x/net/trace.Trace") + +// NewContext returns a copy of the parent context +// and associates it with a Trace. +func NewContext(ctx context.Context, tr Trace) context.Context { + return context.WithValue(ctx, contextKey, tr) +} + +// FromContext returns the Trace bound to the context, if any. +func FromContext(ctx context.Context) (tr Trace, ok bool) { + tr, ok = ctx.Value(contextKey).(Trace) + return +} + +// Trace represents an active request. +type Trace interface { + // LazyLog adds x to the event log. It will be evaluated each time the + // /debug/requests page is rendered. Any memory referenced by x will be + // pinned until the trace is finished and later discarded. + LazyLog(x fmt.Stringer, sensitive bool) + + // LazyPrintf evaluates its arguments with fmt.Sprintf each time the + // /debug/requests page is rendered. Any memory referenced by a will be + // pinned until the trace is finished and later discarded. + LazyPrintf(format string, a ...interface{}) + + // SetError declares that this trace resulted in an error. + SetError() + + // SetRecycler sets a recycler for the trace. + // f will be called for each event passed to LazyLog at a time when + // it is no longer required, whether while the trace is still active + // and the event is discarded, or when a completed trace is discarded. + SetRecycler(f func(interface{})) + + // SetTraceInfo sets the trace info for the trace. + // This is currently unused. + SetTraceInfo(traceID, spanID uint64) + + // SetMaxEvents sets the maximum number of events that will be stored + // in the trace. This has no effect if any events have already been + // added to the trace. + SetMaxEvents(m int) + + // Finish declares that this trace is complete. + // The trace should not be used after calling this method. + Finish() +} + +type lazySprintf struct { + format string + a []interface{} +} + +func (l *lazySprintf) String() string { + return fmt.Sprintf(l.format, l.a...) +} + +// New returns a new Trace with the specified family and title. +func New(family, title string) Trace { + tr := newTrace() + tr.ref() + tr.Family, tr.Title = family, title + tr.Start = time.Now() + tr.events = make([]event, 0, maxEventsPerTrace) + + activeMu.RLock() + s := activeTraces[tr.Family] + activeMu.RUnlock() + if s == nil { + activeMu.Lock() + s = activeTraces[tr.Family] // check again + if s == nil { + s = new(traceSet) + activeTraces[tr.Family] = s + } + activeMu.Unlock() + } + s.Add(tr) + + // Trigger allocation of the completed trace structure for this family. + // This will cause the family to be present in the request page during + // the first trace of this family. We don't care about the return value, + // nor is there any need for this to run inline, so we execute it in its + // own goroutine, but only if the family isn't allocated yet. + completedMu.RLock() + if _, ok := completedTraces[tr.Family]; !ok { + go allocFamily(tr.Family) + } + completedMu.RUnlock() + + return tr +} + +func (tr *trace) Finish() { + tr.Elapsed = time.Now().Sub(tr.Start) + if DebugUseAfterFinish { + buf := make([]byte, 4<<10) // 4 KB should be enough + n := runtime.Stack(buf, false) + tr.finishStack = buf[:n] + } + + activeMu.RLock() + m := activeTraces[tr.Family] + activeMu.RUnlock() + m.Remove(tr) + + f := getFamily(tr.Family, true) + for _, b := range f.Buckets { + if b.Cond.match(tr) { + b.Add(tr) + } + } + // Add a sample of elapsed time as microseconds to the family's timeseries + h := new(histogram) + h.addMeasurement(tr.Elapsed.Nanoseconds() / 1e3) + f.LatencyMu.Lock() + f.Latency.Add(h) + f.LatencyMu.Unlock() + + tr.unref() // matches ref in New +} + +const ( + bucketsPerFamily = 9 + tracesPerBucket = 10 + maxActiveTraces = 20 // Maximum number of active traces to show. + maxEventsPerTrace = 10 + numHistogramBuckets = 38 +) + +var ( + // The active traces. + activeMu sync.RWMutex + activeTraces = make(map[string]*traceSet) // family -> traces + + // Families of completed traces. + completedMu sync.RWMutex + completedTraces = make(map[string]*family) // family -> traces +) + +type traceSet struct { + mu sync.RWMutex + m map[*trace]bool + + // We could avoid the entire map scan in FirstN by having a slice of all the traces + // ordered by start time, and an index into that from the trace struct, with a periodic + // repack of the slice after enough traces finish; we could also use a skip list or similar. + // However, that would shift some of the expense from /debug/requests time to RPC time, + // which is probably the wrong trade-off. +} + +func (ts *traceSet) Len() int { + ts.mu.RLock() + defer ts.mu.RUnlock() + return len(ts.m) +} + +func (ts *traceSet) Add(tr *trace) { + ts.mu.Lock() + if ts.m == nil { + ts.m = make(map[*trace]bool) + } + ts.m[tr] = true + ts.mu.Unlock() +} + +func (ts *traceSet) Remove(tr *trace) { + ts.mu.Lock() + delete(ts.m, tr) + ts.mu.Unlock() +} + +// FirstN returns the first n traces ordered by time. +func (ts *traceSet) FirstN(n int) traceList { + ts.mu.RLock() + defer ts.mu.RUnlock() + + if n > len(ts.m) { + n = len(ts.m) + } + trl := make(traceList, 0, n) + + // Fast path for when no selectivity is needed. + if n == len(ts.m) { + for tr := range ts.m { + tr.ref() + trl = append(trl, tr) + } + sort.Sort(trl) + return trl + } + + // Pick the oldest n traces. + // This is inefficient. See the comment in the traceSet struct. + for tr := range ts.m { + // Put the first n traces into trl in the order they occur. + // When we have n, sort trl, and thereafter maintain its order. + if len(trl) < n { + tr.ref() + trl = append(trl, tr) + if len(trl) == n { + // This is guaranteed to happen exactly once during this loop. + sort.Sort(trl) + } + continue + } + if tr.Start.After(trl[n-1].Start) { + continue + } + + // Find where to insert this one. + tr.ref() + i := sort.Search(n, func(i int) bool { return trl[i].Start.After(tr.Start) }) + trl[n-1].unref() + copy(trl[i+1:], trl[i:]) + trl[i] = tr + } + + return trl +} + +func getActiveTraces(fam string) traceList { + activeMu.RLock() + s := activeTraces[fam] + activeMu.RUnlock() + if s == nil { + return nil + } + return s.FirstN(maxActiveTraces) +} + +func getFamily(fam string, allocNew bool) *family { + completedMu.RLock() + f := completedTraces[fam] + completedMu.RUnlock() + if f == nil && allocNew { + f = allocFamily(fam) + } + return f +} + +func allocFamily(fam string) *family { + completedMu.Lock() + defer completedMu.Unlock() + f := completedTraces[fam] + if f == nil { + f = newFamily() + completedTraces[fam] = f + } + return f +} + +// family represents a set of trace buckets and associated latency information. +type family struct { + // traces may occur in multiple buckets. + Buckets [bucketsPerFamily]*traceBucket + + // latency time series + LatencyMu sync.RWMutex + Latency *timeseries.MinuteHourSeries +} + +func newFamily() *family { + return &family{ + Buckets: [bucketsPerFamily]*traceBucket{ + {Cond: minCond(0)}, + {Cond: minCond(50 * time.Millisecond)}, + {Cond: minCond(100 * time.Millisecond)}, + {Cond: minCond(200 * time.Millisecond)}, + {Cond: minCond(500 * time.Millisecond)}, + {Cond: minCond(1 * time.Second)}, + {Cond: minCond(10 * time.Second)}, + {Cond: minCond(100 * time.Second)}, + {Cond: errorCond{}}, + }, + Latency: timeseries.NewMinuteHourSeries(func() timeseries.Observable { return new(histogram) }), + } +} + +// traceBucket represents a size-capped bucket of historic traces, +// along with a condition for a trace to belong to the bucket. +type traceBucket struct { + Cond cond + + // Ring buffer implementation of a fixed-size FIFO queue. + mu sync.RWMutex + buf [tracesPerBucket]*trace + start int // < tracesPerBucket + length int // <= tracesPerBucket +} + +func (b *traceBucket) Add(tr *trace) { + b.mu.Lock() + defer b.mu.Unlock() + + i := b.start + b.length + if i >= tracesPerBucket { + i -= tracesPerBucket + } + if b.length == tracesPerBucket { + // "Remove" an element from the bucket. + b.buf[i].unref() + b.start++ + if b.start == tracesPerBucket { + b.start = 0 + } + } + b.buf[i] = tr + if b.length < tracesPerBucket { + b.length++ + } + tr.ref() +} + +// Copy returns a copy of the traces in the bucket. +// If tracedOnly is true, only the traces with trace information will be returned. +// The logs will be ref'd before returning; the caller should call +// the Free method when it is done with them. +// TODO(dsymonds): keep track of traced requests in separate buckets. +func (b *traceBucket) Copy(tracedOnly bool) traceList { + b.mu.RLock() + defer b.mu.RUnlock() + + trl := make(traceList, 0, b.length) + for i, x := 0, b.start; i < b.length; i++ { + tr := b.buf[x] + if !tracedOnly || tr.spanID != 0 { + tr.ref() + trl = append(trl, tr) + } + x++ + if x == b.length { + x = 0 + } + } + return trl +} + +func (b *traceBucket) Empty() bool { + b.mu.RLock() + defer b.mu.RUnlock() + return b.length == 0 +} + +// cond represents a condition on a trace. +type cond interface { + match(t *trace) bool + String() string +} + +type minCond time.Duration + +func (m minCond) match(t *trace) bool { return t.Elapsed >= time.Duration(m) } +func (m minCond) String() string { return fmt.Sprintf("≥%gs", time.Duration(m).Seconds()) } + +type errorCond struct{} + +func (e errorCond) match(t *trace) bool { return t.IsError } +func (e errorCond) String() string { return "errors" } + +type traceList []*trace + +// Free calls unref on each element of the list. +func (trl traceList) Free() { + for _, t := range trl { + t.unref() + } +} + +// traceList may be sorted in reverse chronological order. +func (trl traceList) Len() int { return len(trl) } +func (trl traceList) Less(i, j int) bool { return trl[i].Start.After(trl[j].Start) } +func (trl traceList) Swap(i, j int) { trl[i], trl[j] = trl[j], trl[i] } + +// An event is a timestamped log entry in a trace. +type event struct { + When time.Time + Elapsed time.Duration // since previous event in trace + NewDay bool // whether this event is on a different day to the previous event + Recyclable bool // whether this event was passed via LazyLog + What interface{} // string or fmt.Stringer + Sensitive bool // whether this event contains sensitive information +} + +// WhenString returns a string representation of the elapsed time of the event. +// It will include the date if midnight was crossed. +func (e event) WhenString() string { + if e.NewDay { + return e.When.Format("2006/01/02 15:04:05.000000") + } + return e.When.Format("15:04:05.000000") +} + +// discarded represents a number of discarded events. +// It is stored as *discarded to make it easier to update in-place. +type discarded int + +func (d *discarded) String() string { + return fmt.Sprintf("(%d events discarded)", int(*d)) +} + +// trace represents an active or complete request, +// either sent or received by this program. +type trace struct { + // Family is the top-level grouping of traces to which this belongs. + Family string + + // Title is the title of this trace. + Title string + + // Timing information. + Start time.Time + Elapsed time.Duration // zero while active + + // Trace information if non-zero. + traceID uint64 + spanID uint64 + + // Whether this trace resulted in an error. + IsError bool + + // Append-only sequence of events (modulo discards). + mu sync.RWMutex + events []event + + refs int32 // how many buckets this is in + recycler func(interface{}) + disc discarded // scratch space to avoid allocation + + finishStack []byte // where finish was called, if DebugUseAfterFinish is set +} + +func (tr *trace) reset() { + // Clear all but the mutex. Mutexes may not be copied, even when unlocked. + tr.Family = "" + tr.Title = "" + tr.Start = time.Time{} + tr.Elapsed = 0 + tr.traceID = 0 + tr.spanID = 0 + tr.IsError = false + tr.events = nil + tr.refs = 0 + tr.recycler = nil + tr.disc = 0 + tr.finishStack = nil +} + +// delta returns the elapsed time since the last event or the trace start, +// and whether it spans midnight. +// L >= tr.mu +func (tr *trace) delta(t time.Time) (time.Duration, bool) { + if len(tr.events) == 0 { + return t.Sub(tr.Start), false + } + prev := tr.events[len(tr.events)-1].When + return t.Sub(prev), prev.Day() != t.Day() +} + +func (tr *trace) addEvent(x interface{}, recyclable, sensitive bool) { + if DebugUseAfterFinish && tr.finishStack != nil { + buf := make([]byte, 4<<10) // 4 KB should be enough + n := runtime.Stack(buf, false) + log.Printf("net/trace: trace used after finish:\nFinished at:\n%s\nUsed at:\n%s", tr.finishStack, buf[:n]) + } + + /* + NOTE TO DEBUGGERS + + If you are here because your program panicked in this code, + it is almost definitely the fault of code using this package, + and very unlikely to be the fault of this code. + + The most likely scenario is that some code elsewhere is using + a requestz.Trace after its Finish method is called. + You can temporarily set the DebugUseAfterFinish var + to help discover where that is; do not leave that var set, + since it makes this package much less efficient. + */ + + e := event{When: time.Now(), What: x, Recyclable: recyclable, Sensitive: sensitive} + tr.mu.Lock() + e.Elapsed, e.NewDay = tr.delta(e.When) + if len(tr.events) < cap(tr.events) { + tr.events = append(tr.events, e) + } else { + // Discard the middle events. + di := int((cap(tr.events) - 1) / 2) + if d, ok := tr.events[di].What.(*discarded); ok { + (*d)++ + } else { + // disc starts at two to count for the event it is replacing, + // plus the next one that we are about to drop. + tr.disc = 2 + if tr.recycler != nil && tr.events[di].Recyclable { + go tr.recycler(tr.events[di].What) + } + tr.events[di].What = &tr.disc + } + // The timestamp of the discarded meta-event should be + // the time of the last event it is representing. + tr.events[di].When = tr.events[di+1].When + + if tr.recycler != nil && tr.events[di+1].Recyclable { + go tr.recycler(tr.events[di+1].What) + } + copy(tr.events[di+1:], tr.events[di+2:]) + tr.events[cap(tr.events)-1] = e + } + tr.mu.Unlock() +} + +func (tr *trace) LazyLog(x fmt.Stringer, sensitive bool) { + tr.addEvent(x, true, sensitive) +} + +func (tr *trace) LazyPrintf(format string, a ...interface{}) { + tr.addEvent(&lazySprintf{format, a}, false, false) +} + +func (tr *trace) SetError() { tr.IsError = true } + +func (tr *trace) SetRecycler(f func(interface{})) { + tr.recycler = f +} + +func (tr *trace) SetTraceInfo(traceID, spanID uint64) { + tr.traceID, tr.spanID = traceID, spanID +} + +func (tr *trace) SetMaxEvents(m int) { + // Always keep at least three events: first, discarded count, last. + if len(tr.events) == 0 && m > 3 { + tr.events = make([]event, 0, m) + } +} + +func (tr *trace) ref() { + atomic.AddInt32(&tr.refs, 1) +} + +func (tr *trace) unref() { + if atomic.AddInt32(&tr.refs, -1) == 0 { + if tr.recycler != nil { + // freeTrace clears tr, so we hold tr.recycler and tr.events here. + go func(f func(interface{}), es []event) { + for _, e := range es { + if e.Recyclable { + f(e.What) + } + } + }(tr.recycler, tr.events) + } + + freeTrace(tr) + } +} + +func (tr *trace) When() string { + return tr.Start.Format("2006/01/02 15:04:05.000000") +} + +func (tr *trace) ElapsedTime() string { + t := tr.Elapsed + if t == 0 { + // Active trace. + t = time.Since(tr.Start) + } + return fmt.Sprintf("%.6f", t.Seconds()) +} + +func (tr *trace) Events() []event { + tr.mu.RLock() + defer tr.mu.RUnlock() + return tr.events +} + +var traceFreeList = make(chan *trace, 1000) // TODO(dsymonds): Use sync.Pool? + +// newTrace returns a trace ready to use. +func newTrace() *trace { + select { + case tr := <-traceFreeList: + return tr + default: + return new(trace) + } +} + +// freeTrace adds tr to traceFreeList if there's room. +// This is non-blocking. +func freeTrace(tr *trace) { + if DebugUseAfterFinish { + return // never reuse + } + tr.reset() + select { + case traceFreeList <- tr: + default: + } +} + +func elapsed(d time.Duration) string { + b := []byte(fmt.Sprintf("%.6f", d.Seconds())) + + // For subsecond durations, blank all zeros before decimal point, + // and all zeros between the decimal point and the first non-zero digit. + if d < time.Second { + dot := bytes.IndexByte(b, '.') + for i := 0; i < dot; i++ { + b[i] = ' ' + } + for i := dot + 1; i < len(b); i++ { + if b[i] == '0' { + b[i] = ' ' + } else { + break + } + } + } + + return string(b) +} + +var pageTmpl = template.Must(template.New("Page").Funcs(template.FuncMap{ + "elapsed": elapsed, + "add": func(a, b int) int { return a + b }, +}).Parse(pageHTML)) + +const pageHTML = ` +{{template "Prolog" .}} +{{template "StatusTable" .}} +{{template "Epilog" .}} + +{{define "Prolog"}} + + + /debug/requests + + + + +

    /debug/requests

    +{{end}} {{/* end of Prolog */}} + +{{define "StatusTable"}} + + {{range $fam := .Families}} + + + + {{$n := index $.ActiveTraceCount $fam}} + + + {{$f := index $.CompletedTraces $fam}} + {{range $i, $b := $f.Buckets}} + {{$empty := $b.Empty}} + + {{end}} + + {{$nb := len $f.Buckets}} + + + + + + {{end}} +
    {{$fam}} + {{if $n}}{{end}} + [{{$n}} active] + {{if $n}}{{end}} + + {{if not $empty}}{{end}} + [{{.Cond}}] + {{if not $empty}}{{end}} + + [minute] + + [hour] + + [total] +
    +{{end}} {{/* end of StatusTable */}} + +{{define "Epilog"}} +{{if $.Traces}} +
    +

    Family: {{$.Family}}

    + +{{if or $.Expanded $.Traced}} + [Normal/Summary] +{{else}} + [Normal/Summary] +{{end}} + +{{if or (not $.Expanded) $.Traced}} + [Normal/Expanded] +{{else}} + [Normal/Expanded] +{{end}} + +{{if not $.Active}} + {{if or $.Expanded (not $.Traced)}} + [Traced/Summary] + {{else}} + [Traced/Summary] + {{end}} + {{if or (not $.Expanded) (not $.Traced)}} + [Traced/Expanded] + {{else}} + [Traced/Expanded] + {{end}} +{{end}} + +{{if $.Total}} +

    Showing {{len $.Traces}} of {{$.Total}} traces.

    +{{end}} + + + + + {{range $tr := $.Traces}} + + + + + {{/* TODO: include traceID/spanID */}} + + {{if $.Expanded}} + {{range $tr.Events}} + + + + + + {{end}} + {{end}} + {{end}} +
    + {{if $.Active}}Active{{else}}Completed{{end}} Requests +
    WhenElapsed (s)
    {{$tr.When}}{{$tr.ElapsedTime}}{{$tr.Title}}
    {{.WhenString}}{{elapsed .Elapsed}}{{if or $.ShowSensitive (not .Sensitive)}}... {{.What}}{{else}}[redacted]{{end}}
    +{{end}} {{/* if $.Traces */}} + +{{if $.Histogram}} +

    Latency (µs) of {{$.Family}} over {{$.HistogramWindow}}

    +{{$.Histogram}} +{{end}} {{/* if $.Histogram */}} + + + +{{end}} {{/* end of Epilog */}} +` diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/trace_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/trace_test.go new file mode 100644 index 00000000..c2f5fcba --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/trace/trace_test.go @@ -0,0 +1,46 @@ +// 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 trace + +import ( + "reflect" + "testing" +) + +type s struct{} + +func (s) String() string { return "lazy string" } + +// TestReset checks whether all the fields are zeroed after reset. +func TestReset(t *testing.T) { + tr := New("foo", "bar") + tr.LazyLog(s{}, false) + tr.LazyPrintf("%d", 1) + tr.SetRecycler(func(_ interface{}) {}) + tr.SetTraceInfo(3, 4) + tr.SetMaxEvents(100) + tr.SetError() + tr.Finish() + + tr.(*trace).reset() + + if !reflect.DeepEqual(tr, new(trace)) { + t.Errorf("reset didn't clear all fields: %+v", tr) + } +} + +// TestResetLog checks whether all the fields are zeroed after reset. +func TestResetLog(t *testing.T) { + el := NewEventLog("foo", "bar") + el.Printf("message") + el.Errorf("error") + el.Finish() + + el.(*eventLog).reset() + + if !reflect.DeepEqual(el, new(eventLog)) { + t.Errorf("reset didn't clear all fields: %+v", el) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/file.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/file.go new file mode 100644 index 00000000..9ba1ca16 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/file.go @@ -0,0 +1,795 @@ +// 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. + +package webdav + +import ( + "io" + "net/http" + "os" + "path" + "path/filepath" + "strings" + "sync" + "time" + + "golang.org/x/net/webdav/internal/xml" +) + +// slashClean is equivalent to but slightly more efficient than +// path.Clean("/" + name). +func slashClean(name string) string { + if name == "" || name[0] != '/' { + name = "/" + name + } + return path.Clean(name) +} + +// A FileSystem implements access to a collection of named files. The elements +// in a file path are separated by slash ('/', U+002F) characters, regardless +// of host operating system convention. +// +// Each method has the same semantics as the os package's function of the same +// name. +// +// Note that the os.Rename documentation says that "OS-specific restrictions +// might apply". In particular, whether or not renaming a file or directory +// overwriting another existing file or directory is an error is OS-dependent. +type FileSystem interface { + Mkdir(name string, perm os.FileMode) error + OpenFile(name string, flag int, perm os.FileMode) (File, error) + RemoveAll(name string) error + Rename(oldName, newName string) error + Stat(name string) (os.FileInfo, error) +} + +// A File is returned by a FileSystem's OpenFile method and can be served by a +// Handler. +// +// A File may optionally implement the DeadPropsHolder interface, if it can +// load and save dead properties. +type File interface { + http.File + io.Writer +} + +// A Dir implements FileSystem using the native file system restricted to a +// specific directory tree. +// +// While the FileSystem.OpenFile method takes '/'-separated paths, a Dir's +// string value is a filename on the native file system, not a URL, so it is +// separated by filepath.Separator, which isn't necessarily '/'. +// +// An empty Dir is treated as ".". +type Dir string + +func (d Dir) resolve(name string) string { + // This implementation is based on Dir.Open's code in the standard net/http package. + if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 || + strings.Contains(name, "\x00") { + return "" + } + dir := string(d) + if dir == "" { + dir = "." + } + return filepath.Join(dir, filepath.FromSlash(slashClean(name))) +} + +func (d Dir) Mkdir(name string, perm os.FileMode) error { + if name = d.resolve(name); name == "" { + return os.ErrNotExist + } + return os.Mkdir(name, perm) +} + +func (d Dir) OpenFile(name string, flag int, perm os.FileMode) (File, error) { + if name = d.resolve(name); name == "" { + return nil, os.ErrNotExist + } + f, err := os.OpenFile(name, flag, perm) + if err != nil { + return nil, err + } + return f, nil +} + +func (d Dir) RemoveAll(name string) error { + if name = d.resolve(name); name == "" { + return os.ErrNotExist + } + if name == filepath.Clean(string(d)) { + // Prohibit removing the virtual root directory. + return os.ErrInvalid + } + return os.RemoveAll(name) +} + +func (d Dir) Rename(oldName, newName string) error { + if oldName = d.resolve(oldName); oldName == "" { + return os.ErrNotExist + } + if newName = d.resolve(newName); newName == "" { + return os.ErrNotExist + } + if root := filepath.Clean(string(d)); root == oldName || root == newName { + // Prohibit renaming from or to the virtual root directory. + return os.ErrInvalid + } + return os.Rename(oldName, newName) +} + +func (d Dir) Stat(name string) (os.FileInfo, error) { + if name = d.resolve(name); name == "" { + return nil, os.ErrNotExist + } + return os.Stat(name) +} + +// NewMemFS returns a new in-memory FileSystem implementation. +func NewMemFS() FileSystem { + return &memFS{ + root: memFSNode{ + children: make(map[string]*memFSNode), + mode: 0660 | os.ModeDir, + modTime: time.Now(), + }, + } +} + +// A memFS implements FileSystem, storing all metadata and actual file data +// in-memory. No limits on filesystem size are used, so it is not recommended +// this be used where the clients are untrusted. +// +// Concurrent access is permitted. The tree structure is protected by a mutex, +// and each node's contents and metadata are protected by a per-node mutex. +// +// TODO: Enforce file permissions. +type memFS struct { + mu sync.Mutex + root memFSNode +} + +// TODO: clean up and rationalize the walk/find code. + +// walk walks the directory tree for the fullname, calling f at each step. If f +// returns an error, the walk will be aborted and return that same error. +// +// dir is the directory at that step, frag is the name fragment, and final is +// whether it is the final step. For example, walking "/foo/bar/x" will result +// in 3 calls to f: +// - "/", "foo", false +// - "/foo/", "bar", false +// - "/foo/bar/", "x", true +// The frag argument will be empty only if dir is the root node and the walk +// ends at that root node. +func (fs *memFS) walk(op, fullname string, f func(dir *memFSNode, frag string, final bool) error) error { + original := fullname + fullname = slashClean(fullname) + + // Strip any leading "/"s to make fullname a relative path, as the walk + // starts at fs.root. + if fullname[0] == '/' { + fullname = fullname[1:] + } + dir := &fs.root + + for { + frag, remaining := fullname, "" + i := strings.IndexRune(fullname, '/') + final := i < 0 + if !final { + frag, remaining = fullname[:i], fullname[i+1:] + } + if frag == "" && dir != &fs.root { + panic("webdav: empty path fragment for a clean path") + } + if err := f(dir, frag, final); err != nil { + return &os.PathError{ + Op: op, + Path: original, + Err: err, + } + } + if final { + break + } + child := dir.children[frag] + if child == nil { + return &os.PathError{ + Op: op, + Path: original, + Err: os.ErrNotExist, + } + } + if !child.mode.IsDir() { + return &os.PathError{ + Op: op, + Path: original, + Err: os.ErrInvalid, + } + } + dir, fullname = child, remaining + } + return nil +} + +// find returns the parent of the named node and the relative name fragment +// from the parent to the child. For example, if finding "/foo/bar/baz" then +// parent will be the node for "/foo/bar" and frag will be "baz". +// +// If the fullname names the root node, then parent, frag and err will be zero. +// +// find returns an error if the parent does not already exist or the parent +// isn't a directory, but it will not return an error per se if the child does +// not already exist. The error returned is either nil or an *os.PathError +// whose Op is op. +func (fs *memFS) find(op, fullname string) (parent *memFSNode, frag string, err error) { + err = fs.walk(op, fullname, func(parent0 *memFSNode, frag0 string, final bool) error { + if !final { + return nil + } + if frag0 != "" { + parent, frag = parent0, frag0 + } + return nil + }) + return parent, frag, err +} + +func (fs *memFS) Mkdir(name string, perm os.FileMode) error { + fs.mu.Lock() + defer fs.mu.Unlock() + + dir, frag, err := fs.find("mkdir", name) + if err != nil { + return err + } + if dir == nil { + // We can't create the root. + return os.ErrInvalid + } + if _, ok := dir.children[frag]; ok { + return os.ErrExist + } + dir.children[frag] = &memFSNode{ + children: make(map[string]*memFSNode), + mode: perm.Perm() | os.ModeDir, + modTime: time.Now(), + } + return nil +} + +func (fs *memFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) { + fs.mu.Lock() + defer fs.mu.Unlock() + + dir, frag, err := fs.find("open", name) + if err != nil { + return nil, err + } + var n *memFSNode + if dir == nil { + // We're opening the root. + if flag&(os.O_WRONLY|os.O_RDWR) != 0 { + return nil, os.ErrPermission + } + n, frag = &fs.root, "/" + + } else { + n = dir.children[frag] + if flag&(os.O_SYNC|os.O_APPEND) != 0 { + // memFile doesn't support these flags yet. + return nil, os.ErrInvalid + } + if flag&os.O_CREATE != 0 { + if flag&os.O_EXCL != 0 && n != nil { + return nil, os.ErrExist + } + if n == nil { + n = &memFSNode{ + mode: perm.Perm(), + } + dir.children[frag] = n + } + } + if n == nil { + return nil, os.ErrNotExist + } + if flag&(os.O_WRONLY|os.O_RDWR) != 0 && flag&os.O_TRUNC != 0 { + n.mu.Lock() + n.data = nil + n.mu.Unlock() + } + } + + children := make([]os.FileInfo, 0, len(n.children)) + for cName, c := range n.children { + children = append(children, c.stat(cName)) + } + return &memFile{ + n: n, + nameSnapshot: frag, + childrenSnapshot: children, + }, nil +} + +func (fs *memFS) RemoveAll(name string) error { + fs.mu.Lock() + defer fs.mu.Unlock() + + dir, frag, err := fs.find("remove", name) + if err != nil { + return err + } + if dir == nil { + // We can't remove the root. + return os.ErrInvalid + } + delete(dir.children, frag) + return nil +} + +func (fs *memFS) Rename(oldName, newName string) error { + fs.mu.Lock() + defer fs.mu.Unlock() + + oldName = slashClean(oldName) + newName = slashClean(newName) + if oldName == newName { + return nil + } + if strings.HasPrefix(newName, oldName+"/") { + // We can't rename oldName to be a sub-directory of itself. + return os.ErrInvalid + } + + oDir, oFrag, err := fs.find("rename", oldName) + if err != nil { + return err + } + if oDir == nil { + // We can't rename from the root. + return os.ErrInvalid + } + + nDir, nFrag, err := fs.find("rename", newName) + if err != nil { + return err + } + if nDir == nil { + // We can't rename to the root. + return os.ErrInvalid + } + + oNode, ok := oDir.children[oFrag] + if !ok { + return os.ErrNotExist + } + if oNode.children != nil { + if nNode, ok := nDir.children[nFrag]; ok { + if nNode.children == nil { + return errNotADirectory + } + if len(nNode.children) != 0 { + return errDirectoryNotEmpty + } + } + } + delete(oDir.children, oFrag) + nDir.children[nFrag] = oNode + return nil +} + +func (fs *memFS) Stat(name string) (os.FileInfo, error) { + fs.mu.Lock() + defer fs.mu.Unlock() + + dir, frag, err := fs.find("stat", name) + if err != nil { + return nil, err + } + if dir == nil { + // We're stat'ting the root. + return fs.root.stat("/"), nil + } + if n, ok := dir.children[frag]; ok { + return n.stat(path.Base(name)), nil + } + return nil, os.ErrNotExist +} + +// A memFSNode represents a single entry in the in-memory filesystem and also +// implements os.FileInfo. +type memFSNode struct { + // children is protected by memFS.mu. + children map[string]*memFSNode + + mu sync.Mutex + data []byte + mode os.FileMode + modTime time.Time + deadProps map[xml.Name]Property +} + +func (n *memFSNode) stat(name string) *memFileInfo { + n.mu.Lock() + defer n.mu.Unlock() + return &memFileInfo{ + name: name, + size: int64(len(n.data)), + mode: n.mode, + modTime: n.modTime, + } +} + +func (n *memFSNode) DeadProps() (map[xml.Name]Property, error) { + n.mu.Lock() + defer n.mu.Unlock() + if len(n.deadProps) == 0 { + return nil, nil + } + ret := make(map[xml.Name]Property, len(n.deadProps)) + for k, v := range n.deadProps { + ret[k] = v + } + return ret, nil +} + +func (n *memFSNode) Patch(patches []Proppatch) ([]Propstat, error) { + n.mu.Lock() + defer n.mu.Unlock() + pstat := Propstat{Status: http.StatusOK} + for _, patch := range patches { + for _, p := range patch.Props { + pstat.Props = append(pstat.Props, Property{XMLName: p.XMLName}) + if patch.Remove { + delete(n.deadProps, p.XMLName) + continue + } + if n.deadProps == nil { + n.deadProps = map[xml.Name]Property{} + } + n.deadProps[p.XMLName] = p + } + } + return []Propstat{pstat}, nil +} + +type memFileInfo struct { + name string + size int64 + mode os.FileMode + modTime time.Time +} + +func (f *memFileInfo) Name() string { return f.name } +func (f *memFileInfo) Size() int64 { return f.size } +func (f *memFileInfo) Mode() os.FileMode { return f.mode } +func (f *memFileInfo) ModTime() time.Time { return f.modTime } +func (f *memFileInfo) IsDir() bool { return f.mode.IsDir() } +func (f *memFileInfo) Sys() interface{} { return nil } + +// A memFile is a File implementation for a memFSNode. It is a per-file (not +// per-node) read/write position, and a snapshot of the memFS' tree structure +// (a node's name and children) for that node. +type memFile struct { + n *memFSNode + nameSnapshot string + childrenSnapshot []os.FileInfo + // pos is protected by n.mu. + pos int +} + +// A *memFile implements the optional DeadPropsHolder interface. +var _ DeadPropsHolder = (*memFile)(nil) + +func (f *memFile) DeadProps() (map[xml.Name]Property, error) { return f.n.DeadProps() } +func (f *memFile) Patch(patches []Proppatch) ([]Propstat, error) { return f.n.Patch(patches) } + +func (f *memFile) Close() error { + return nil +} + +func (f *memFile) Read(p []byte) (int, error) { + f.n.mu.Lock() + defer f.n.mu.Unlock() + if f.n.mode.IsDir() { + return 0, os.ErrInvalid + } + if f.pos >= len(f.n.data) { + return 0, io.EOF + } + n := copy(p, f.n.data[f.pos:]) + f.pos += n + return n, nil +} + +func (f *memFile) Readdir(count int) ([]os.FileInfo, error) { + f.n.mu.Lock() + defer f.n.mu.Unlock() + if !f.n.mode.IsDir() { + return nil, os.ErrInvalid + } + old := f.pos + if old >= len(f.childrenSnapshot) { + // The os.File Readdir docs say that at the end of a directory, + // the error is io.EOF if count > 0 and nil if count <= 0. + if count > 0 { + return nil, io.EOF + } + return nil, nil + } + if count > 0 { + f.pos += count + if f.pos > len(f.childrenSnapshot) { + f.pos = len(f.childrenSnapshot) + } + } else { + f.pos = len(f.childrenSnapshot) + old = 0 + } + return f.childrenSnapshot[old:f.pos], nil +} + +func (f *memFile) Seek(offset int64, whence int) (int64, error) { + f.n.mu.Lock() + defer f.n.mu.Unlock() + npos := f.pos + // TODO: How to handle offsets greater than the size of system int? + switch whence { + case os.SEEK_SET: + npos = int(offset) + case os.SEEK_CUR: + npos += int(offset) + case os.SEEK_END: + npos = len(f.n.data) + int(offset) + default: + npos = -1 + } + if npos < 0 { + return 0, os.ErrInvalid + } + f.pos = npos + return int64(f.pos), nil +} + +func (f *memFile) Stat() (os.FileInfo, error) { + return f.n.stat(f.nameSnapshot), nil +} + +func (f *memFile) Write(p []byte) (int, error) { + lenp := len(p) + f.n.mu.Lock() + defer f.n.mu.Unlock() + + if f.n.mode.IsDir() { + return 0, os.ErrInvalid + } + if f.pos < len(f.n.data) { + n := copy(f.n.data[f.pos:], p) + f.pos += n + p = p[n:] + } else if f.pos > len(f.n.data) { + // Write permits the creation of holes, if we've seek'ed past the + // existing end of file. + if f.pos <= cap(f.n.data) { + oldLen := len(f.n.data) + f.n.data = f.n.data[:f.pos] + hole := f.n.data[oldLen:] + for i := range hole { + hole[i] = 0 + } + } else { + d := make([]byte, f.pos, f.pos+len(p)) + copy(d, f.n.data) + f.n.data = d + } + } + + if len(p) > 0 { + // We should only get here if f.pos == len(f.n.data). + f.n.data = append(f.n.data, p...) + f.pos = len(f.n.data) + } + f.n.modTime = time.Now() + return lenp, nil +} + +// moveFiles moves files and/or directories from src to dst. +// +// See section 9.9.4 for when various HTTP status codes apply. +func moveFiles(fs FileSystem, src, dst string, overwrite bool) (status int, err error) { + created := false + if _, err := fs.Stat(dst); err != nil { + if !os.IsNotExist(err) { + return http.StatusForbidden, err + } + created = true + } else if overwrite { + // Section 9.9.3 says that "If a resource exists at the destination + // and the Overwrite header is "T", then prior to performing the move, + // the server must perform a DELETE with "Depth: infinity" on the + // destination resource. + if err := fs.RemoveAll(dst); err != nil { + return http.StatusForbidden, err + } + } else { + return http.StatusPreconditionFailed, os.ErrExist + } + if err := fs.Rename(src, dst); err != nil { + return http.StatusForbidden, err + } + if created { + return http.StatusCreated, nil + } + return http.StatusNoContent, nil +} + +func copyProps(dst, src File) error { + d, ok := dst.(DeadPropsHolder) + if !ok { + return nil + } + s, ok := src.(DeadPropsHolder) + if !ok { + return nil + } + m, err := s.DeadProps() + if err != nil { + return err + } + props := make([]Property, 0, len(m)) + for _, prop := range m { + props = append(props, prop) + } + _, err = d.Patch([]Proppatch{{Props: props}}) + return err +} + +// copyFiles copies files and/or directories from src to dst. +// +// See section 9.8.5 for when various HTTP status codes apply. +func copyFiles(fs FileSystem, src, dst string, overwrite bool, depth int, recursion int) (status int, err error) { + if recursion == 1000 { + return http.StatusInternalServerError, errRecursionTooDeep + } + recursion++ + + // TODO: section 9.8.3 says that "Note that an infinite-depth COPY of /A/ + // into /A/B/ could lead to infinite recursion if not handled correctly." + + srcFile, err := fs.OpenFile(src, os.O_RDONLY, 0) + if err != nil { + if os.IsNotExist(err) { + return http.StatusNotFound, err + } + return http.StatusInternalServerError, err + } + defer srcFile.Close() + srcStat, err := srcFile.Stat() + if err != nil { + if os.IsNotExist(err) { + return http.StatusNotFound, err + } + return http.StatusInternalServerError, err + } + srcPerm := srcStat.Mode() & os.ModePerm + + created := false + if _, err := fs.Stat(dst); err != nil { + if os.IsNotExist(err) { + created = true + } else { + return http.StatusForbidden, err + } + } else { + if !overwrite { + return http.StatusPreconditionFailed, os.ErrExist + } + if err := fs.RemoveAll(dst); err != nil && !os.IsNotExist(err) { + return http.StatusForbidden, err + } + } + + if srcStat.IsDir() { + if err := fs.Mkdir(dst, srcPerm); err != nil { + return http.StatusForbidden, err + } + if depth == infiniteDepth { + children, err := srcFile.Readdir(-1) + if err != nil { + return http.StatusForbidden, err + } + for _, c := range children { + name := c.Name() + s := path.Join(src, name) + d := path.Join(dst, name) + cStatus, cErr := copyFiles(fs, s, d, overwrite, depth, recursion) + if cErr != nil { + // TODO: MultiStatus. + return cStatus, cErr + } + } + } + + } else { + dstFile, err := fs.OpenFile(dst, os.O_RDWR|os.O_CREATE|os.O_TRUNC, srcPerm) + if err != nil { + if os.IsNotExist(err) { + return http.StatusConflict, err + } + return http.StatusForbidden, err + + } + _, copyErr := io.Copy(dstFile, srcFile) + propsErr := copyProps(dstFile, srcFile) + closeErr := dstFile.Close() + if copyErr != nil { + return http.StatusInternalServerError, copyErr + } + if propsErr != nil { + return http.StatusInternalServerError, propsErr + } + if closeErr != nil { + return http.StatusInternalServerError, closeErr + } + } + + if created { + return http.StatusCreated, nil + } + return http.StatusNoContent, nil +} + +// walkFS traverses filesystem fs starting at name up to depth levels. +// +// Allowed values for depth are 0, 1 or infiniteDepth. For each visited node, +// walkFS calls walkFn. If a visited file system node is a directory and +// walkFn returns filepath.SkipDir, walkFS will skip traversal of this node. +func walkFS(fs FileSystem, depth int, name string, info os.FileInfo, walkFn filepath.WalkFunc) error { + // This implementation is based on Walk's code in the standard path/filepath package. + err := walkFn(name, info, nil) + if err != nil { + if info.IsDir() && err == filepath.SkipDir { + return nil + } + return err + } + if !info.IsDir() || depth == 0 { + return nil + } + if depth == 1 { + depth = 0 + } + + // Read directory names. + f, err := fs.OpenFile(name, os.O_RDONLY, 0) + if err != nil { + return walkFn(name, info, err) + } + fileInfos, err := f.Readdir(0) + f.Close() + if err != nil { + return walkFn(name, info, err) + } + + for _, fileInfo := range fileInfos { + filename := path.Join(name, fileInfo.Name()) + fileInfo, err := fs.Stat(filename) + if err != nil { + if err := walkFn(filename, fileInfo, err); err != nil && err != filepath.SkipDir { + return err + } + } else { + err = walkFS(fs, depth, filename, fileInfo, walkFn) + if err != nil { + if !fileInfo.IsDir() || err != filepath.SkipDir { + return err + } + } + } + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/file_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/file_test.go new file mode 100644 index 00000000..99547e16 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/file_test.go @@ -0,0 +1,1167 @@ +// 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. + +package webdav + +import ( + "fmt" + "io" + "io/ioutil" + "os" + "path" + "path/filepath" + "reflect" + "runtime" + "sort" + "strconv" + "strings" + "testing" + + "golang.org/x/net/webdav/internal/xml" +) + +func TestSlashClean(t *testing.T) { + testCases := []string{ + "", + ".", + "/", + "/./", + "//", + "//.", + "//a", + "/a", + "/a/b/c", + "/a//b/./../c/d/", + "a", + "a/b/c", + } + for _, tc := range testCases { + got := slashClean(tc) + want := path.Clean("/" + tc) + if got != want { + t.Errorf("tc=%q: got %q, want %q", tc, got, want) + } + } +} + +func TestDirResolve(t *testing.T) { + testCases := []struct { + dir, name, want string + }{ + {"/", "", "/"}, + {"/", "/", "/"}, + {"/", ".", "/"}, + {"/", "./a", "/a"}, + {"/", "..", "/"}, + {"/", "..", "/"}, + {"/", "../", "/"}, + {"/", "../.", "/"}, + {"/", "../a", "/a"}, + {"/", "../..", "/"}, + {"/", "../bar/a", "/bar/a"}, + {"/", "../baz/a", "/baz/a"}, + {"/", "...", "/..."}, + {"/", ".../a", "/.../a"}, + {"/", ".../..", "/"}, + {"/", "a", "/a"}, + {"/", "a/./b", "/a/b"}, + {"/", "a/../../b", "/b"}, + {"/", "a/../b", "/b"}, + {"/", "a/b", "/a/b"}, + {"/", "a/b/c/../../d", "/a/d"}, + {"/", "a/b/c/../../../d", "/d"}, + {"/", "a/b/c/../../../../d", "/d"}, + {"/", "a/b/c/d", "/a/b/c/d"}, + + {"/foo/bar", "", "/foo/bar"}, + {"/foo/bar", "/", "/foo/bar"}, + {"/foo/bar", ".", "/foo/bar"}, + {"/foo/bar", "./a", "/foo/bar/a"}, + {"/foo/bar", "..", "/foo/bar"}, + {"/foo/bar", "../", "/foo/bar"}, + {"/foo/bar", "../.", "/foo/bar"}, + {"/foo/bar", "../a", "/foo/bar/a"}, + {"/foo/bar", "../..", "/foo/bar"}, + {"/foo/bar", "../bar/a", "/foo/bar/bar/a"}, + {"/foo/bar", "../baz/a", "/foo/bar/baz/a"}, + {"/foo/bar", "...", "/foo/bar/..."}, + {"/foo/bar", ".../a", "/foo/bar/.../a"}, + {"/foo/bar", ".../..", "/foo/bar"}, + {"/foo/bar", "a", "/foo/bar/a"}, + {"/foo/bar", "a/./b", "/foo/bar/a/b"}, + {"/foo/bar", "a/../../b", "/foo/bar/b"}, + {"/foo/bar", "a/../b", "/foo/bar/b"}, + {"/foo/bar", "a/b", "/foo/bar/a/b"}, + {"/foo/bar", "a/b/c/../../d", "/foo/bar/a/d"}, + {"/foo/bar", "a/b/c/../../../d", "/foo/bar/d"}, + {"/foo/bar", "a/b/c/../../../../d", "/foo/bar/d"}, + {"/foo/bar", "a/b/c/d", "/foo/bar/a/b/c/d"}, + + {"/foo/bar/", "", "/foo/bar"}, + {"/foo/bar/", "/", "/foo/bar"}, + {"/foo/bar/", ".", "/foo/bar"}, + {"/foo/bar/", "./a", "/foo/bar/a"}, + {"/foo/bar/", "..", "/foo/bar"}, + + {"/foo//bar///", "", "/foo/bar"}, + {"/foo//bar///", "/", "/foo/bar"}, + {"/foo//bar///", ".", "/foo/bar"}, + {"/foo//bar///", "./a", "/foo/bar/a"}, + {"/foo//bar///", "..", "/foo/bar"}, + + {"/x/y/z", "ab/c\x00d/ef", ""}, + + {".", "", "."}, + {".", "/", "."}, + {".", ".", "."}, + {".", "./a", "a"}, + {".", "..", "."}, + {".", "..", "."}, + {".", "../", "."}, + {".", "../.", "."}, + {".", "../a", "a"}, + {".", "../..", "."}, + {".", "../bar/a", "bar/a"}, + {".", "../baz/a", "baz/a"}, + {".", "...", "..."}, + {".", ".../a", ".../a"}, + {".", ".../..", "."}, + {".", "a", "a"}, + {".", "a/./b", "a/b"}, + {".", "a/../../b", "b"}, + {".", "a/../b", "b"}, + {".", "a/b", "a/b"}, + {".", "a/b/c/../../d", "a/d"}, + {".", "a/b/c/../../../d", "d"}, + {".", "a/b/c/../../../../d", "d"}, + {".", "a/b/c/d", "a/b/c/d"}, + + {"", "", "."}, + {"", "/", "."}, + {"", ".", "."}, + {"", "./a", "a"}, + {"", "..", "."}, + } + + for _, tc := range testCases { + d := Dir(filepath.FromSlash(tc.dir)) + if got := filepath.ToSlash(d.resolve(tc.name)); got != tc.want { + t.Errorf("dir=%q, name=%q: got %q, want %q", tc.dir, tc.name, got, tc.want) + } + } +} + +func TestWalk(t *testing.T) { + type walkStep struct { + name, frag string + final bool + } + + testCases := []struct { + dir string + want []walkStep + }{ + {"", []walkStep{ + {"", "", true}, + }}, + {"/", []walkStep{ + {"", "", true}, + }}, + {"/a", []walkStep{ + {"", "a", true}, + }}, + {"/a/", []walkStep{ + {"", "a", true}, + }}, + {"/a/b", []walkStep{ + {"", "a", false}, + {"a", "b", true}, + }}, + {"/a/b/", []walkStep{ + {"", "a", false}, + {"a", "b", true}, + }}, + {"/a/b/c", []walkStep{ + {"", "a", false}, + {"a", "b", false}, + {"b", "c", true}, + }}, + // The following test case is the one mentioned explicitly + // in the method description. + {"/foo/bar/x", []walkStep{ + {"", "foo", false}, + {"foo", "bar", false}, + {"bar", "x", true}, + }}, + } + + for _, tc := range testCases { + fs := NewMemFS().(*memFS) + + parts := strings.Split(tc.dir, "/") + for p := 2; p < len(parts); p++ { + d := strings.Join(parts[:p], "/") + if err := fs.Mkdir(d, 0666); err != nil { + t.Errorf("tc.dir=%q: mkdir: %q: %v", tc.dir, d, err) + } + } + + i, prevFrag := 0, "" + err := fs.walk("test", tc.dir, func(dir *memFSNode, frag string, final bool) error { + got := walkStep{ + name: prevFrag, + frag: frag, + final: final, + } + want := tc.want[i] + + if got != want { + return fmt.Errorf("got %+v, want %+v", got, want) + } + i, prevFrag = i+1, frag + return nil + }) + if err != nil { + t.Errorf("tc.dir=%q: %v", tc.dir, err) + } + } +} + +// find appends to ss the names of the named file and its children. It is +// analogous to the Unix find command. +// +// The returned strings are not guaranteed to be in any particular order. +func find(ss []string, fs FileSystem, name string) ([]string, error) { + stat, err := fs.Stat(name) + if err != nil { + return nil, err + } + ss = append(ss, name) + if stat.IsDir() { + f, err := fs.OpenFile(name, os.O_RDONLY, 0) + if err != nil { + return nil, err + } + defer f.Close() + children, err := f.Readdir(-1) + if err != nil { + return nil, err + } + for _, c := range children { + ss, err = find(ss, fs, path.Join(name, c.Name())) + if err != nil { + return nil, err + } + } + } + return ss, nil +} + +func testFS(t *testing.T, fs FileSystem) { + errStr := func(err error) string { + switch { + case os.IsExist(err): + return "errExist" + case os.IsNotExist(err): + return "errNotExist" + case err != nil: + return "err" + } + return "ok" + } + + // The non-"find" non-"stat" test cases should change the file system state. The + // indentation of the "find"s and "stat"s helps distinguish such test cases. + testCases := []string{ + " stat / want dir", + " stat /a want errNotExist", + " stat /d want errNotExist", + " stat /d/e want errNotExist", + "create /a A want ok", + " stat /a want 1", + "create /d/e EEE want errNotExist", + "mk-dir /a want errExist", + "mk-dir /d/m want errNotExist", + "mk-dir /d want ok", + " stat /d want dir", + "create /d/e EEE want ok", + " stat /d/e want 3", + " find / /a /d /d/e", + "create /d/f FFFF want ok", + "create /d/g GGGGGGG want ok", + "mk-dir /d/m want ok", + "mk-dir /d/m want errExist", + "create /d/m/p PPPPP want ok", + " stat /d/e want 3", + " stat /d/f want 4", + " stat /d/g want 7", + " stat /d/h want errNotExist", + " stat /d/m want dir", + " stat /d/m/p want 5", + " find / /a /d /d/e /d/f /d/g /d/m /d/m/p", + "rm-all /d want ok", + " stat /a want 1", + " stat /d want errNotExist", + " stat /d/e want errNotExist", + " stat /d/f want errNotExist", + " stat /d/g want errNotExist", + " stat /d/m want errNotExist", + " stat /d/m/p want errNotExist", + " find / /a", + "mk-dir /d/m want errNotExist", + "mk-dir /d want ok", + "create /d/f FFFF want ok", + "rm-all /d/f want ok", + "mk-dir /d/m want ok", + "rm-all /z want ok", + "rm-all / want err", + "create /b BB want ok", + " stat / want dir", + " stat /a want 1", + " stat /b want 2", + " stat /c want errNotExist", + " stat /d want dir", + " stat /d/m want dir", + " find / /a /b /d /d/m", + "move__ o=F /b /c want ok", + " stat /b want errNotExist", + " stat /c want 2", + " stat /d/m want dir", + " stat /d/n want errNotExist", + " find / /a /c /d /d/m", + "move__ o=F /d/m /d/n want ok", + "create /d/n/q QQQQ want ok", + " stat /d/m want errNotExist", + " stat /d/n want dir", + " stat /d/n/q want 4", + "move__ o=F /d /d/n/z want err", + "move__ o=T /c /d/n/q want ok", + " stat /c want errNotExist", + " stat /d/n/q want 2", + " find / /a /d /d/n /d/n/q", + "create /d/n/r RRRRR want ok", + "mk-dir /u want ok", + "mk-dir /u/v want ok", + "move__ o=F /d/n /u want errExist", + "create /t TTTTTT want ok", + "move__ o=F /d/n /t want errExist", + "rm-all /t want ok", + "move__ o=F /d/n /t want ok", + " stat /d want dir", + " stat /d/n want errNotExist", + " stat /d/n/r want errNotExist", + " stat /t want dir", + " stat /t/q want 2", + " stat /t/r want 5", + " find / /a /d /t /t/q /t/r /u /u/v", + "move__ o=F /t / want errExist", + "move__ o=T /t /u/v want ok", + " stat /u/v/r want 5", + "move__ o=F / /z want err", + " find / /a /d /u /u/v /u/v/q /u/v/r", + " stat /a want 1", + " stat /b want errNotExist", + " stat /c want errNotExist", + " stat /u/v/r want 5", + "copy__ o=F d=0 /a /b want ok", + "copy__ o=T d=0 /a /c want ok", + " stat /a want 1", + " stat /b want 1", + " stat /c want 1", + " stat /u/v/r want 5", + "copy__ o=F d=0 /u/v/r /b want errExist", + " stat /b want 1", + "copy__ o=T d=0 /u/v/r /b want ok", + " stat /a want 1", + " stat /b want 5", + " stat /u/v/r want 5", + "rm-all /a want ok", + "rm-all /b want ok", + "mk-dir /u/v/w want ok", + "create /u/v/w/s SSSSSSSS want ok", + " stat /d want dir", + " stat /d/x want errNotExist", + " stat /d/y want errNotExist", + " stat /u/v/r want 5", + " stat /u/v/w/s want 8", + " find / /c /d /u /u/v /u/v/q /u/v/r /u/v/w /u/v/w/s", + "copy__ o=T d=0 /u/v /d/x want ok", + "copy__ o=T d=∞ /u/v /d/y want ok", + "rm-all /u want ok", + " stat /d/x want dir", + " stat /d/x/q want errNotExist", + " stat /d/x/r want errNotExist", + " stat /d/x/w want errNotExist", + " stat /d/x/w/s want errNotExist", + " stat /d/y want dir", + " stat /d/y/q want 2", + " stat /d/y/r want 5", + " stat /d/y/w want dir", + " stat /d/y/w/s want 8", + " stat /u want errNotExist", + " find / /c /d /d/x /d/y /d/y/q /d/y/r /d/y/w /d/y/w/s", + "copy__ o=F d=∞ /d/y /d/x want errExist", + } + + for i, tc := range testCases { + tc = strings.TrimSpace(tc) + j := strings.IndexByte(tc, ' ') + if j < 0 { + t.Fatalf("test case #%d %q: invalid command", i, tc) + } + op, arg := tc[:j], tc[j+1:] + + switch op { + default: + t.Fatalf("test case #%d %q: invalid operation %q", i, tc, op) + + case "create": + parts := strings.Split(arg, " ") + if len(parts) != 4 || parts[2] != "want" { + t.Fatalf("test case #%d %q: invalid write", i, tc) + } + f, opErr := fs.OpenFile(parts[0], os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if got := errStr(opErr); got != parts[3] { + t.Fatalf("test case #%d %q: OpenFile: got %q (%v), want %q", i, tc, got, opErr, parts[3]) + } + if f != nil { + if _, err := f.Write([]byte(parts[1])); err != nil { + t.Fatalf("test case #%d %q: Write: %v", i, tc, err) + } + if err := f.Close(); err != nil { + t.Fatalf("test case #%d %q: Close: %v", i, tc, err) + } + } + + case "find": + got, err := find(nil, fs, "/") + if err != nil { + t.Fatalf("test case #%d %q: find: %v", i, tc, err) + } + sort.Strings(got) + want := strings.Split(arg, " ") + if !reflect.DeepEqual(got, want) { + t.Fatalf("test case #%d %q:\ngot %s\nwant %s", i, tc, got, want) + } + + case "copy__", "mk-dir", "move__", "rm-all", "stat": + nParts := 3 + switch op { + case "copy__": + nParts = 6 + case "move__": + nParts = 5 + } + parts := strings.Split(arg, " ") + if len(parts) != nParts { + t.Fatalf("test case #%d %q: invalid %s", i, tc, op) + } + + got, opErr := "", error(nil) + switch op { + case "copy__": + depth := 0 + if parts[1] == "d=∞" { + depth = infiniteDepth + } + _, opErr = copyFiles(fs, parts[2], parts[3], parts[0] == "o=T", depth, 0) + case "mk-dir": + opErr = fs.Mkdir(parts[0], 0777) + case "move__": + _, opErr = moveFiles(fs, parts[1], parts[2], parts[0] == "o=T") + case "rm-all": + opErr = fs.RemoveAll(parts[0]) + case "stat": + var stat os.FileInfo + fileName := parts[0] + if stat, opErr = fs.Stat(fileName); opErr == nil { + if stat.IsDir() { + got = "dir" + } else { + got = strconv.Itoa(int(stat.Size())) + } + + if fileName == "/" { + // For a Dir FileSystem, the virtual file system root maps to a + // real file system name like "/tmp/webdav-test012345", which does + // not end with "/". We skip such cases. + } else if statName := stat.Name(); path.Base(fileName) != statName { + t.Fatalf("test case #%d %q: file name %q inconsistent with stat name %q", + i, tc, fileName, statName) + } + } + } + if got == "" { + got = errStr(opErr) + } + + if parts[len(parts)-2] != "want" { + t.Fatalf("test case #%d %q: invalid %s", i, tc, op) + } + if want := parts[len(parts)-1]; got != want { + t.Fatalf("test case #%d %q: got %q (%v), want %q", i, tc, got, opErr, want) + } + } + } +} + +func TestDir(t *testing.T) { + switch runtime.GOOS { + case "nacl": + t.Skip("see golang.org/issue/12004") + case "plan9": + t.Skip("see golang.org/issue/11453") + } + + td, err := ioutil.TempDir("", "webdav-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(td) + testFS(t, Dir(td)) +} + +func TestMemFS(t *testing.T) { + testFS(t, NewMemFS()) +} + +func TestMemFSRoot(t *testing.T) { + fs := NewMemFS() + for i := 0; i < 5; i++ { + stat, err := fs.Stat("/") + if err != nil { + t.Fatalf("i=%d: Stat: %v", i, err) + } + if !stat.IsDir() { + t.Fatalf("i=%d: Stat.IsDir is false, want true", i) + } + + f, err := fs.OpenFile("/", os.O_RDONLY, 0) + if err != nil { + t.Fatalf("i=%d: OpenFile: %v", i, err) + } + defer f.Close() + children, err := f.Readdir(-1) + if err != nil { + t.Fatalf("i=%d: Readdir: %v", i, err) + } + if len(children) != i { + t.Fatalf("i=%d: got %d children, want %d", i, len(children), i) + } + + if _, err := f.Write(make([]byte, 1)); err == nil { + t.Fatalf("i=%d: Write: got nil error, want non-nil", i) + } + + if err := fs.Mkdir(fmt.Sprintf("/dir%d", i), 0777); err != nil { + t.Fatalf("i=%d: Mkdir: %v", i, err) + } + } +} + +func TestMemFileReaddir(t *testing.T) { + fs := NewMemFS() + if err := fs.Mkdir("/foo", 0777); err != nil { + t.Fatalf("Mkdir: %v", err) + } + readdir := func(count int) ([]os.FileInfo, error) { + f, err := fs.OpenFile("/foo", os.O_RDONLY, 0) + if err != nil { + t.Fatalf("OpenFile: %v", err) + } + defer f.Close() + return f.Readdir(count) + } + if got, err := readdir(-1); len(got) != 0 || err != nil { + t.Fatalf("readdir(-1): got %d fileInfos with err=%v, want 0, ", len(got), err) + } + if got, err := readdir(+1); len(got) != 0 || err != io.EOF { + t.Fatalf("readdir(+1): got %d fileInfos with err=%v, want 0, EOF", len(got), err) + } +} + +func TestMemFile(t *testing.T) { + testCases := []string{ + "wantData ", + "wantSize 0", + "write abc", + "wantData abc", + "write de", + "wantData abcde", + "wantSize 5", + "write 5*x", + "write 4*y+2*z", + "write 3*st", + "wantData abcdexxxxxyyyyzzststst", + "wantSize 22", + "seek set 4 want 4", + "write EFG", + "wantData abcdEFGxxxyyyyzzststst", + "wantSize 22", + "seek set 2 want 2", + "read cdEF", + "read Gx", + "seek cur 0 want 8", + "seek cur 2 want 10", + "seek cur -1 want 9", + "write J", + "wantData abcdEFGxxJyyyyzzststst", + "wantSize 22", + "seek cur -4 want 6", + "write ghijk", + "wantData abcdEFghijkyyyzzststst", + "wantSize 22", + "read yyyz", + "seek cur 0 want 15", + "write ", + "seek cur 0 want 15", + "read ", + "seek cur 0 want 15", + "seek end -3 want 19", + "write ZZ", + "wantData abcdEFghijkyyyzzstsZZt", + "wantSize 22", + "write 4*A", + "wantData abcdEFghijkyyyzzstsZZAAAA", + "wantSize 25", + "seek end 0 want 25", + "seek end -5 want 20", + "read Z+4*A", + "write 5*B", + "wantData abcdEFghijkyyyzzstsZZAAAABBBBB", + "wantSize 30", + "seek end 10 want 40", + "write C", + "wantData abcdEFghijkyyyzzstsZZAAAABBBBB..........C", + "wantSize 41", + "write D", + "wantData abcdEFghijkyyyzzstsZZAAAABBBBB..........CD", + "wantSize 42", + "seek set 43 want 43", + "write E", + "wantData abcdEFghijkyyyzzstsZZAAAABBBBB..........CD.E", + "wantSize 44", + "seek set 0 want 0", + "write 5*123456789_", + "wantData 123456789_123456789_123456789_123456789_123456789_", + "wantSize 50", + "seek cur 0 want 50", + "seek cur -99 want err", + } + + const filename = "/foo" + fs := NewMemFS() + f, err := fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + t.Fatalf("OpenFile: %v", err) + } + defer f.Close() + + for i, tc := range testCases { + j := strings.IndexByte(tc, ' ') + if j < 0 { + t.Fatalf("test case #%d %q: invalid command", i, tc) + } + op, arg := tc[:j], tc[j+1:] + + // Expand an arg like "3*a+2*b" to "aaabb". + parts := strings.Split(arg, "+") + for j, part := range parts { + if k := strings.IndexByte(part, '*'); k >= 0 { + repeatCount, repeatStr := part[:k], part[k+1:] + n, err := strconv.Atoi(repeatCount) + if err != nil { + t.Fatalf("test case #%d %q: invalid repeat count %q", i, tc, repeatCount) + } + parts[j] = strings.Repeat(repeatStr, n) + } + } + arg = strings.Join(parts, "") + + switch op { + default: + t.Fatalf("test case #%d %q: invalid operation %q", i, tc, op) + + case "read": + buf := make([]byte, len(arg)) + if _, err := io.ReadFull(f, buf); err != nil { + t.Fatalf("test case #%d %q: ReadFull: %v", i, tc, err) + } + if got := string(buf); got != arg { + t.Fatalf("test case #%d %q:\ngot %q\nwant %q", i, tc, got, arg) + } + + case "seek": + parts := strings.Split(arg, " ") + if len(parts) != 4 { + t.Fatalf("test case #%d %q: invalid seek", i, tc) + } + + whence := 0 + switch parts[0] { + default: + t.Fatalf("test case #%d %q: invalid seek whence", i, tc) + case "set": + whence = os.SEEK_SET + case "cur": + whence = os.SEEK_CUR + case "end": + whence = os.SEEK_END + } + offset, err := strconv.Atoi(parts[1]) + if err != nil { + t.Fatalf("test case #%d %q: invalid offset %q", i, tc, parts[1]) + } + + if parts[2] != "want" { + t.Fatalf("test case #%d %q: invalid seek", i, tc) + } + if parts[3] == "err" { + _, err := f.Seek(int64(offset), whence) + if err == nil { + t.Fatalf("test case #%d %q: Seek returned nil error, want non-nil", i, tc) + } + } else { + got, err := f.Seek(int64(offset), whence) + if err != nil { + t.Fatalf("test case #%d %q: Seek: %v", i, tc, err) + } + want, err := strconv.Atoi(parts[3]) + if err != nil { + t.Fatalf("test case #%d %q: invalid want %q", i, tc, parts[3]) + } + if got != int64(want) { + t.Fatalf("test case #%d %q: got %d, want %d", i, tc, got, want) + } + } + + case "write": + n, err := f.Write([]byte(arg)) + if err != nil { + t.Fatalf("test case #%d %q: write: %v", i, tc, err) + } + if n != len(arg) { + t.Fatalf("test case #%d %q: write returned %d bytes, want %d", i, tc, n, len(arg)) + } + + case "wantData": + g, err := fs.OpenFile(filename, os.O_RDONLY, 0666) + if err != nil { + t.Fatalf("test case #%d %q: OpenFile: %v", i, tc, err) + } + gotBytes, err := ioutil.ReadAll(g) + if err != nil { + t.Fatalf("test case #%d %q: ReadAll: %v", i, tc, err) + } + for i, c := range gotBytes { + if c == '\x00' { + gotBytes[i] = '.' + } + } + got := string(gotBytes) + if got != arg { + t.Fatalf("test case #%d %q:\ngot %q\nwant %q", i, tc, got, arg) + } + if err := g.Close(); err != nil { + t.Fatalf("test case #%d %q: Close: %v", i, tc, err) + } + + case "wantSize": + n, err := strconv.Atoi(arg) + if err != nil { + t.Fatalf("test case #%d %q: invalid size %q", i, tc, arg) + } + fi, err := fs.Stat(filename) + if err != nil { + t.Fatalf("test case #%d %q: Stat: %v", i, tc, err) + } + if got, want := fi.Size(), int64(n); got != want { + t.Fatalf("test case #%d %q: got %d, want %d", i, tc, got, want) + } + } + } +} + +// TestMemFileWriteAllocs tests that writing N consecutive 1KiB chunks to a +// memFile doesn't allocate a new buffer for each of those N times. Otherwise, +// calling io.Copy(aMemFile, src) is likely to have quadratic complexity. +func TestMemFileWriteAllocs(t *testing.T) { + fs := NewMemFS() + f, err := fs.OpenFile("/xxx", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + t.Fatalf("OpenFile: %v", err) + } + defer f.Close() + + xxx := make([]byte, 1024) + for i := range xxx { + xxx[i] = 'x' + } + + a := testing.AllocsPerRun(100, func() { + f.Write(xxx) + }) + // AllocsPerRun returns an integral value, so we compare the rounded-down + // number to zero. + if a > 0 { + t.Fatalf("%v allocs per run, want 0", a) + } +} + +func BenchmarkMemFileWrite(b *testing.B) { + fs := NewMemFS() + xxx := make([]byte, 1024) + for i := range xxx { + xxx[i] = 'x' + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + f, err := fs.OpenFile("/xxx", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + b.Fatalf("OpenFile: %v", err) + } + for j := 0; j < 100; j++ { + f.Write(xxx) + } + if err := f.Close(); err != nil { + b.Fatalf("Close: %v", err) + } + if err := fs.RemoveAll("/xxx"); err != nil { + b.Fatalf("RemoveAll: %v", err) + } + } +} + +func TestCopyMoveProps(t *testing.T) { + fs := NewMemFS() + create := func(name string) error { + f, err := fs.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return err + } + _, wErr := f.Write([]byte("contents")) + cErr := f.Close() + if wErr != nil { + return wErr + } + return cErr + } + patch := func(name string, patches ...Proppatch) error { + f, err := fs.OpenFile(name, os.O_RDWR, 0666) + if err != nil { + return err + } + _, pErr := f.(DeadPropsHolder).Patch(patches) + cErr := f.Close() + if pErr != nil { + return pErr + } + return cErr + } + props := func(name string) (map[xml.Name]Property, error) { + f, err := fs.OpenFile(name, os.O_RDWR, 0666) + if err != nil { + return nil, err + } + m, pErr := f.(DeadPropsHolder).DeadProps() + cErr := f.Close() + if pErr != nil { + return nil, pErr + } + if cErr != nil { + return nil, cErr + } + return m, nil + } + + p0 := Property{ + XMLName: xml.Name{Space: "x:", Local: "boat"}, + InnerXML: []byte("pea-green"), + } + p1 := Property{ + XMLName: xml.Name{Space: "x:", Local: "ring"}, + InnerXML: []byte("1 shilling"), + } + p2 := Property{ + XMLName: xml.Name{Space: "x:", Local: "spoon"}, + InnerXML: []byte("runcible"), + } + p3 := Property{ + XMLName: xml.Name{Space: "x:", Local: "moon"}, + InnerXML: []byte("light"), + } + + if err := create("/src"); err != nil { + t.Fatalf("create /src: %v", err) + } + if err := patch("/src", Proppatch{Props: []Property{p0, p1}}); err != nil { + t.Fatalf("patch /src +p0 +p1: %v", err) + } + if _, err := copyFiles(fs, "/src", "/tmp", true, infiniteDepth, 0); err != nil { + t.Fatalf("copyFiles /src /tmp: %v", err) + } + if _, err := moveFiles(fs, "/tmp", "/dst", true); err != nil { + t.Fatalf("moveFiles /tmp /dst: %v", err) + } + if err := patch("/src", Proppatch{Props: []Property{p0}, Remove: true}); err != nil { + t.Fatalf("patch /src -p0: %v", err) + } + if err := patch("/src", Proppatch{Props: []Property{p2}}); err != nil { + t.Fatalf("patch /src +p2: %v", err) + } + if err := patch("/dst", Proppatch{Props: []Property{p1}, Remove: true}); err != nil { + t.Fatalf("patch /dst -p1: %v", err) + } + if err := patch("/dst", Proppatch{Props: []Property{p3}}); err != nil { + t.Fatalf("patch /dst +p3: %v", err) + } + + gotSrc, err := props("/src") + if err != nil { + t.Fatalf("props /src: %v", err) + } + wantSrc := map[xml.Name]Property{ + p1.XMLName: p1, + p2.XMLName: p2, + } + if !reflect.DeepEqual(gotSrc, wantSrc) { + t.Fatalf("props /src:\ngot %v\nwant %v", gotSrc, wantSrc) + } + + gotDst, err := props("/dst") + if err != nil { + t.Fatalf("props /dst: %v", err) + } + wantDst := map[xml.Name]Property{ + p0.XMLName: p0, + p3.XMLName: p3, + } + if !reflect.DeepEqual(gotDst, wantDst) { + t.Fatalf("props /dst:\ngot %v\nwant %v", gotDst, wantDst) + } +} + +func TestWalkFS(t *testing.T) { + testCases := []struct { + desc string + buildfs []string + startAt string + depth int + walkFn filepath.WalkFunc + want []string + }{{ + "just root", + []string{}, + "/", + infiniteDepth, + nil, + []string{ + "/", + }, + }, { + "infinite walk from root", + []string{ + "mkdir /a", + "mkdir /a/b", + "touch /a/b/c", + "mkdir /a/d", + "mkdir /e", + "touch /f", + }, + "/", + infiniteDepth, + nil, + []string{ + "/", + "/a", + "/a/b", + "/a/b/c", + "/a/d", + "/e", + "/f", + }, + }, { + "infinite walk from subdir", + []string{ + "mkdir /a", + "mkdir /a/b", + "touch /a/b/c", + "mkdir /a/d", + "mkdir /e", + "touch /f", + }, + "/a", + infiniteDepth, + nil, + []string{ + "/a", + "/a/b", + "/a/b/c", + "/a/d", + }, + }, { + "depth 1 walk from root", + []string{ + "mkdir /a", + "mkdir /a/b", + "touch /a/b/c", + "mkdir /a/d", + "mkdir /e", + "touch /f", + }, + "/", + 1, + nil, + []string{ + "/", + "/a", + "/e", + "/f", + }, + }, { + "depth 1 walk from subdir", + []string{ + "mkdir /a", + "mkdir /a/b", + "touch /a/b/c", + "mkdir /a/b/g", + "mkdir /a/b/g/h", + "touch /a/b/g/i", + "touch /a/b/g/h/j", + }, + "/a/b", + 1, + nil, + []string{ + "/a/b", + "/a/b/c", + "/a/b/g", + }, + }, { + "depth 0 walk from subdir", + []string{ + "mkdir /a", + "mkdir /a/b", + "touch /a/b/c", + "mkdir /a/b/g", + "mkdir /a/b/g/h", + "touch /a/b/g/i", + "touch /a/b/g/h/j", + }, + "/a/b", + 0, + nil, + []string{ + "/a/b", + }, + }, { + "infinite walk from file", + []string{ + "mkdir /a", + "touch /a/b", + "touch /a/c", + }, + "/a/b", + 0, + nil, + []string{ + "/a/b", + }, + }, { + "infinite walk with skipped subdir", + []string{ + "mkdir /a", + "mkdir /a/b", + "touch /a/b/c", + "mkdir /a/b/g", + "mkdir /a/b/g/h", + "touch /a/b/g/i", + "touch /a/b/g/h/j", + "touch /a/b/z", + }, + "/", + infiniteDepth, + func(path string, info os.FileInfo, err error) error { + if path == "/a/b/g" { + return filepath.SkipDir + } + return nil + }, + []string{ + "/", + "/a", + "/a/b", + "/a/b/c", + "/a/b/z", + }, + }} + for _, tc := range testCases { + fs, err := buildTestFS(tc.buildfs) + if err != nil { + t.Fatalf("%s: cannot create test filesystem: %v", tc.desc, err) + } + var got []string + traceFn := func(path string, info os.FileInfo, err error) error { + if tc.walkFn != nil { + err = tc.walkFn(path, info, err) + if err != nil { + return err + } + } + got = append(got, path) + return nil + } + fi, err := fs.Stat(tc.startAt) + if err != nil { + t.Fatalf("%s: cannot stat: %v", tc.desc, err) + } + err = walkFS(fs, tc.depth, tc.startAt, fi, traceFn) + if err != nil { + t.Errorf("%s:\ngot error %v, want nil", tc.desc, err) + continue + } + sort.Strings(got) + sort.Strings(tc.want) + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("%s:\ngot %q\nwant %q", tc.desc, got, tc.want) + continue + } + } +} + +func buildTestFS(buildfs []string) (FileSystem, error) { + // TODO: Could this be merged with the build logic in TestFS? + + fs := NewMemFS() + for _, b := range buildfs { + op := strings.Split(b, " ") + switch op[0] { + case "mkdir": + err := fs.Mkdir(op[1], os.ModeDir|0777) + if err != nil { + return nil, err + } + case "touch": + f, err := fs.OpenFile(op[1], os.O_RDWR|os.O_CREATE, 0666) + if err != nil { + return nil, err + } + f.Close() + case "write": + f, err := fs.OpenFile(op[1], os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return nil, err + } + _, err = f.Write([]byte(op[2])) + f.Close() + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unknown file operation %q", op[0]) + } + } + return fs, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/if.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/if.go new file mode 100644 index 00000000..416e81cd --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/if.go @@ -0,0 +1,173 @@ +// 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. + +package webdav + +// The If header is covered by Section 10.4. +// http://www.webdav.org/specs/rfc4918.html#HEADER_If + +import ( + "strings" +) + +// ifHeader is a disjunction (OR) of ifLists. +type ifHeader struct { + lists []ifList +} + +// ifList is a conjunction (AND) of Conditions, and an optional resource tag. +type ifList struct { + resourceTag string + conditions []Condition +} + +// parseIfHeader parses the "If: foo bar" HTTP header. The httpHeader string +// should omit the "If:" prefix and have any "\r\n"s collapsed to a " ", as is +// returned by req.Header.Get("If") for a http.Request req. +func parseIfHeader(httpHeader string) (h ifHeader, ok bool) { + s := strings.TrimSpace(httpHeader) + switch tokenType, _, _ := lex(s); tokenType { + case '(': + return parseNoTagLists(s) + case angleTokenType: + return parseTaggedLists(s) + default: + return ifHeader{}, false + } +} + +func parseNoTagLists(s string) (h ifHeader, ok bool) { + for { + l, remaining, ok := parseList(s) + if !ok { + return ifHeader{}, false + } + h.lists = append(h.lists, l) + if remaining == "" { + return h, true + } + s = remaining + } +} + +func parseTaggedLists(s string) (h ifHeader, ok bool) { + resourceTag, n := "", 0 + for first := true; ; first = false { + tokenType, tokenStr, remaining := lex(s) + switch tokenType { + case angleTokenType: + if !first && n == 0 { + return ifHeader{}, false + } + resourceTag, n = tokenStr, 0 + s = remaining + case '(': + n++ + l, remaining, ok := parseList(s) + if !ok { + return ifHeader{}, false + } + l.resourceTag = resourceTag + h.lists = append(h.lists, l) + if remaining == "" { + return h, true + } + s = remaining + default: + return ifHeader{}, false + } + } +} + +func parseList(s string) (l ifList, remaining string, ok bool) { + tokenType, _, s := lex(s) + if tokenType != '(' { + return ifList{}, "", false + } + for { + tokenType, _, remaining = lex(s) + if tokenType == ')' { + if len(l.conditions) == 0 { + return ifList{}, "", false + } + return l, remaining, true + } + c, remaining, ok := parseCondition(s) + if !ok { + return ifList{}, "", false + } + l.conditions = append(l.conditions, c) + s = remaining + } +} + +func parseCondition(s string) (c Condition, remaining string, ok bool) { + tokenType, tokenStr, s := lex(s) + if tokenType == notTokenType { + c.Not = true + tokenType, tokenStr, s = lex(s) + } + switch tokenType { + case strTokenType, angleTokenType: + c.Token = tokenStr + case squareTokenType: + c.ETag = tokenStr + default: + return Condition{}, "", false + } + return c, s, true +} + +// Single-rune tokens like '(' or ')' have a token type equal to their rune. +// All other tokens have a negative token type. +const ( + errTokenType = rune(-1) + eofTokenType = rune(-2) + strTokenType = rune(-3) + notTokenType = rune(-4) + angleTokenType = rune(-5) + squareTokenType = rune(-6) +) + +func lex(s string) (tokenType rune, tokenStr string, remaining string) { + // The net/textproto Reader that parses the HTTP header will collapse + // Linear White Space that spans multiple "\r\n" lines to a single " ", + // so we don't need to look for '\r' or '\n'. + for len(s) > 0 && (s[0] == '\t' || s[0] == ' ') { + s = s[1:] + } + if len(s) == 0 { + return eofTokenType, "", "" + } + i := 0 +loop: + for ; i < len(s); i++ { + switch s[i] { + case '\t', ' ', '(', ')', '<', '>', '[', ']': + break loop + } + } + + if i != 0 { + tokenStr, remaining = s[:i], s[i:] + if tokenStr == "Not" { + return notTokenType, "", remaining + } + return strTokenType, tokenStr, remaining + } + + j := 0 + switch s[0] { + case '<': + j, tokenType = strings.IndexByte(s, '>'), angleTokenType + case '[': + j, tokenType = strings.IndexByte(s, ']'), squareTokenType + default: + return rune(s[0]), "", s[1:] + } + if j < 0 { + return errTokenType, "", "" + } + return tokenType, s[1:j], s[j+1:] +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/if_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/if_test.go new file mode 100644 index 00000000..aad61a40 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/if_test.go @@ -0,0 +1,322 @@ +// 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. + +package webdav + +import ( + "reflect" + "strings" + "testing" +) + +func TestParseIfHeader(t *testing.T) { + // The "section x.y.z" test cases come from section x.y.z of the spec at + // http://www.webdav.org/specs/rfc4918.html + testCases := []struct { + desc string + input string + want ifHeader + }{{ + "bad: empty", + ``, + ifHeader{}, + }, { + "bad: no parens", + `foobar`, + ifHeader{}, + }, { + "bad: empty list #1", + `()`, + ifHeader{}, + }, { + "bad: empty list #2", + `(a) (b c) () (d)`, + ifHeader{}, + }, { + "bad: no list after resource #1", + ``, + ifHeader{}, + }, { + "bad: no list after resource #2", + ` (a)`, + ifHeader{}, + }, { + "bad: no list after resource #3", + ` (a) (b) `, + ifHeader{}, + }, { + "bad: no-tag-list followed by tagged-list", + `(a) (b) (c)`, + ifHeader{}, + }, { + "bad: unfinished list", + `(a`, + ifHeader{}, + }, { + "bad: unfinished ETag", + `([b`, + ifHeader{}, + }, { + "bad: unfinished Notted list", + `(Not a`, + ifHeader{}, + }, { + "bad: double Not", + `(Not Not a)`, + ifHeader{}, + }, { + "good: one list with a Token", + `(a)`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Token: `a`, + }}, + }}, + }, + }, { + "good: one list with an ETag", + `([a])`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + ETag: `a`, + }}, + }}, + }, + }, { + "good: one list with three Nots", + `(Not a Not b Not [d])`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Not: true, + Token: `a`, + }, { + Not: true, + Token: `b`, + }, { + Not: true, + ETag: `d`, + }}, + }}, + }, + }, { + "good: two lists", + `(a) (b)`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Token: `a`, + }}, + }, { + conditions: []Condition{{ + Token: `b`, + }}, + }}, + }, + }, { + "good: two Notted lists", + `(Not a) (Not b)`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Not: true, + Token: `a`, + }}, + }, { + conditions: []Condition{{ + Not: true, + Token: `b`, + }}, + }}, + }, + }, { + "section 7.5.1", + ` + ()`, + ifHeader{ + lists: []ifList{{ + resourceTag: `http://www.example.com/users/f/fielding/index.html`, + conditions: []Condition{{ + Token: `urn:uuid:f81d4fae-7dec-11d0-a765-00a0c91e6bf6`, + }}, + }}, + }, + }, { + "section 7.5.2 #1", + `()`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, + }}, + }}, + }, + }, { + "section 7.5.2 #2", + ` + ()`, + ifHeader{ + lists: []ifList{{ + resourceTag: `http://example.com/locked/`, + conditions: []Condition{{ + Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, + }}, + }}, + }, + }, { + "section 7.5.2 #3", + ` + ()`, + ifHeader{ + lists: []ifList{{ + resourceTag: `http://example.com/locked/member`, + conditions: []Condition{{ + Token: `urn:uuid:150852e2-3847-42d5-8cbe-0f4f296f26cf`, + }}, + }}, + }, + }, { + "section 9.9.6", + `() + ()`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Token: `urn:uuid:fe184f2e-6eec-41d0-c765-01adc56e6bb4`, + }}, + }, { + conditions: []Condition{{ + Token: `urn:uuid:e454f3f3-acdc-452a-56c7-00a5c91e4b77`, + }}, + }}, + }, + }, { + "section 9.10.8", + `()`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Token: `urn:uuid:e71d4fae-5dec-22d6-fea5-00a0c91e6be4`, + }}, + }}, + }, + }, { + "section 10.4.6", + `( + ["I am an ETag"]) + (["I am another ETag"])`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, + }, { + ETag: `"I am an ETag"`, + }}, + }, { + conditions: []Condition{{ + ETag: `"I am another ETag"`, + }}, + }}, + }, + }, { + "section 10.4.7", + `(Not + )`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Not: true, + Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, + }, { + Token: `urn:uuid:58f202ac-22cf-11d1-b12d-002035b29092`, + }}, + }}, + }, + }, { + "section 10.4.8", + `() + (Not )`, + ifHeader{ + lists: []ifList{{ + conditions: []Condition{{ + Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, + }}, + }, { + conditions: []Condition{{ + Not: true, + Token: `DAV:no-lock`, + }}, + }}, + }, + }, { + "section 10.4.9", + ` + ( + [W/"A weak ETag"]) (["strong ETag"])`, + ifHeader{ + lists: []ifList{{ + resourceTag: `/resource1`, + conditions: []Condition{{ + Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, + }, { + ETag: `W/"A weak ETag"`, + }}, + }, { + resourceTag: `/resource1`, + conditions: []Condition{{ + ETag: `"strong ETag"`, + }}, + }}, + }, + }, { + "section 10.4.10", + ` + ()`, + ifHeader{ + lists: []ifList{{ + resourceTag: `http://www.example.com/specs/`, + conditions: []Condition{{ + Token: `urn:uuid:181d4fae-7d8c-11d0-a765-00a0c91e6bf2`, + }}, + }}, + }, + }, { + "section 10.4.11 #1", + ` (["4217"])`, + ifHeader{ + lists: []ifList{{ + resourceTag: `/specs/rfc2518.doc`, + conditions: []Condition{{ + ETag: `"4217"`, + }}, + }}, + }, + }, { + "section 10.4.11 #2", + ` (Not ["4217"])`, + ifHeader{ + lists: []ifList{{ + resourceTag: `/specs/rfc2518.doc`, + conditions: []Condition{{ + Not: true, + ETag: `"4217"`, + }}, + }}, + }, + }} + + for _, tc := range testCases { + got, ok := parseIfHeader(strings.Replace(tc.input, "\n", "", -1)) + if gotEmpty := reflect.DeepEqual(got, ifHeader{}); gotEmpty == ok { + t.Errorf("%s: should be different: empty header == %t, ok == %t", tc.desc, gotEmpty, ok) + continue + } + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("%s:\ngot %v\nwant %v", tc.desc, got, tc.want) + continue + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/README b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/README new file mode 100644 index 00000000..89656f48 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/README @@ -0,0 +1,11 @@ +This is a fork of the encoding/xml package at ca1d6c4, the last commit before +https://go.googlesource.com/go/+/c0d6d33 "encoding/xml: restore Go 1.4 name +space behavior" made late in the lead-up to the Go 1.5 release. + +The list of encoding/xml changes is at +https://go.googlesource.com/go/+log/master/src/encoding/xml + +This fork is temporary, and I (nigeltao) expect to revert it after Go 1.6 is +released. + +See http://golang.org/issue/11841 diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/atom_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/atom_test.go new file mode 100644 index 00000000..a7128431 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/atom_test.go @@ -0,0 +1,56 @@ +// 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 xml + +import "time" + +var atomValue = &Feed{ + XMLName: Name{"http://www.w3.org/2005/Atom", "feed"}, + Title: "Example Feed", + Link: []Link{{Href: "http://example.org/"}}, + Updated: ParseTime("2003-12-13T18:30:02Z"), + Author: Person{Name: "John Doe"}, + Id: "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6", + + Entry: []Entry{ + { + Title: "Atom-Powered Robots Run Amok", + Link: []Link{{Href: "http://example.org/2003/12/13/atom03"}}, + Id: "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a", + Updated: ParseTime("2003-12-13T18:30:02Z"), + Summary: NewText("Some text."), + }, + }, +} + +var atomXml = `` + + `` + + `Example Feed` + + `urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6` + + `` + + `John Doe` + + `` + + `Atom-Powered Robots Run Amok` + + `urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a` + + `` + + `2003-12-13T18:30:02Z` + + `` + + `Some text.` + + `` + + `` + +func ParseTime(str string) time.Time { + t, err := time.Parse(time.RFC3339, str) + if err != nil { + panic(err) + } + return t +} + +func NewText(text string) Text { + return Text{ + Body: text, + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/example_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/example_test.go new file mode 100644 index 00000000..becedd58 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/example_test.go @@ -0,0 +1,151 @@ +// 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 xml_test + +import ( + "encoding/xml" + "fmt" + "os" +) + +func ExampleMarshalIndent() { + type Address struct { + City, State string + } + type Person struct { + XMLName xml.Name `xml:"person"` + Id int `xml:"id,attr"` + FirstName string `xml:"name>first"` + LastName string `xml:"name>last"` + Age int `xml:"age"` + Height float32 `xml:"height,omitempty"` + Married bool + Address + Comment string `xml:",comment"` + } + + v := &Person{Id: 13, FirstName: "John", LastName: "Doe", Age: 42} + v.Comment = " Need more details. " + v.Address = Address{"Hanga Roa", "Easter Island"} + + output, err := xml.MarshalIndent(v, " ", " ") + if err != nil { + fmt.Printf("error: %v\n", err) + } + + os.Stdout.Write(output) + // Output: + // + // + // John + // Doe + // + // 42 + // false + // Hanga Roa + // Easter Island + // + // +} + +func ExampleEncoder() { + type Address struct { + City, State string + } + type Person struct { + XMLName xml.Name `xml:"person"` + Id int `xml:"id,attr"` + FirstName string `xml:"name>first"` + LastName string `xml:"name>last"` + Age int `xml:"age"` + Height float32 `xml:"height,omitempty"` + Married bool + Address + Comment string `xml:",comment"` + } + + v := &Person{Id: 13, FirstName: "John", LastName: "Doe", Age: 42} + v.Comment = " Need more details. " + v.Address = Address{"Hanga Roa", "Easter Island"} + + enc := xml.NewEncoder(os.Stdout) + enc.Indent(" ", " ") + if err := enc.Encode(v); err != nil { + fmt.Printf("error: %v\n", err) + } + + // Output: + // + // + // John + // Doe + // + // 42 + // false + // Hanga Roa + // Easter Island + // + // +} + +// This example demonstrates unmarshaling an XML excerpt into a value with +// some preset fields. Note that the Phone field isn't modified and that +// the XML element is ignored. Also, the Groups field is assigned +// considering the element path provided in its tag. +func ExampleUnmarshal() { + type Email struct { + Where string `xml:"where,attr"` + Addr string + } + type Address struct { + City, State string + } + type Result struct { + XMLName xml.Name `xml:"Person"` + Name string `xml:"FullName"` + Phone string + Email []Email + Groups []string `xml:"Group>Value"` + Address + } + v := Result{Name: "none", Phone: "none"} + + data := ` + + Grace R. Emlin + Example Inc. + + gre@example.com + + + gre@work.com + + + Friends + Squash + + Hanga Roa + Easter Island + + ` + err := xml.Unmarshal([]byte(data), &v) + if err != nil { + fmt.Printf("error: %v", err) + return + } + fmt.Printf("XMLName: %#v\n", v.XMLName) + fmt.Printf("Name: %q\n", v.Name) + fmt.Printf("Phone: %q\n", v.Phone) + fmt.Printf("Email: %v\n", v.Email) + fmt.Printf("Groups: %v\n", v.Groups) + fmt.Printf("Address: %v\n", v.Address) + // Output: + // XMLName: xml.Name{Space:"", Local:"Person"} + // Name: "Grace R. Emlin" + // Phone: "none" + // Email: [{home gre@example.com} {work gre@work.com}] + // Groups: [Friends Squash] + // Address: {Hanga Roa Easter Island} +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/marshal.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/marshal.go new file mode 100644 index 00000000..3c3b6aca --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/marshal.go @@ -0,0 +1,1223 @@ +// 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 xml + +import ( + "bufio" + "bytes" + "encoding" + "fmt" + "io" + "reflect" + "strconv" + "strings" +) + +const ( + // A generic XML header suitable for use with the output of Marshal. + // This is not automatically added to any output of this package, + // it is provided as a convenience. + Header = `` + "\n" +) + +// Marshal returns the XML encoding of v. +// +// Marshal handles an array or slice by marshalling each of the elements. +// Marshal handles a pointer by marshalling the value it points at or, if the +// pointer is nil, by writing nothing. Marshal handles an interface value by +// marshalling the value it contains or, if the interface value is nil, by +// writing nothing. Marshal handles all other data by writing one or more XML +// elements containing the data. +// +// The name for the XML elements is taken from, in order of preference: +// - the tag on the XMLName field, if the data is a struct +// - the value of the XMLName field of type xml.Name +// - the tag of the struct field used to obtain the data +// - the name of the struct field used to obtain the data +// - the name of the marshalled type +// +// The XML element for a struct contains marshalled elements for each of the +// exported fields of the struct, with these exceptions: +// - the XMLName field, described above, is omitted. +// - a field with tag "-" is omitted. +// - a field with tag "name,attr" becomes an attribute with +// the given name in the XML element. +// - a field with tag ",attr" becomes an attribute with the +// field name in the XML element. +// - a field with tag ",chardata" is written as character data, +// not as an XML element. +// - a field with tag ",innerxml" is written verbatim, not subject +// to the usual marshalling procedure. +// - a field with tag ",comment" is written as an XML comment, not +// subject to the usual marshalling procedure. It must not contain +// the "--" string within it. +// - a field with a tag including the "omitempty" option is omitted +// if the field value is empty. The empty values are false, 0, any +// nil pointer or interface value, and any array, slice, map, or +// string of length zero. +// - an anonymous struct field is handled as if the fields of its +// value were part of the outer struct. +// +// If a field uses a tag "a>b>c", then the element c will be nested inside +// parent elements a and b. Fields that appear next to each other that name +// the same parent will be enclosed in one XML element. +// +// See MarshalIndent for an example. +// +// Marshal will return an error if asked to marshal a channel, function, or map. +func Marshal(v interface{}) ([]byte, error) { + var b bytes.Buffer + if err := NewEncoder(&b).Encode(v); err != nil { + return nil, err + } + return b.Bytes(), nil +} + +// Marshaler is the interface implemented by objects that can marshal +// themselves into valid XML elements. +// +// MarshalXML encodes the receiver as zero or more XML elements. +// By convention, arrays or slices are typically encoded as a sequence +// of elements, one per entry. +// Using start as the element tag is not required, but doing so +// will enable Unmarshal to match the XML elements to the correct +// struct field. +// One common implementation strategy is to construct a separate +// value with a layout corresponding to the desired XML and then +// to encode it using e.EncodeElement. +// Another common strategy is to use repeated calls to e.EncodeToken +// to generate the XML output one token at a time. +// The sequence of encoded tokens must make up zero or more valid +// XML elements. +type Marshaler interface { + MarshalXML(e *Encoder, start StartElement) error +} + +// MarshalerAttr is the interface implemented by objects that can marshal +// themselves into valid XML attributes. +// +// MarshalXMLAttr returns an XML attribute with the encoded value of the receiver. +// Using name as the attribute name is not required, but doing so +// will enable Unmarshal to match the attribute to the correct +// struct field. +// If MarshalXMLAttr returns the zero attribute Attr{}, no attribute +// will be generated in the output. +// MarshalXMLAttr is used only for struct fields with the +// "attr" option in the field tag. +type MarshalerAttr interface { + MarshalXMLAttr(name Name) (Attr, error) +} + +// MarshalIndent works like Marshal, but each XML element begins on a new +// indented line that starts with prefix and is followed by one or more +// copies of indent according to the nesting depth. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + var b bytes.Buffer + enc := NewEncoder(&b) + enc.Indent(prefix, indent) + if err := enc.Encode(v); err != nil { + return nil, err + } + return b.Bytes(), nil +} + +// An Encoder writes XML data to an output stream. +type Encoder struct { + p printer +} + +// NewEncoder returns a new encoder that writes to w. +func NewEncoder(w io.Writer) *Encoder { + e := &Encoder{printer{Writer: bufio.NewWriter(w)}} + e.p.encoder = e + return e +} + +// Indent sets the encoder to generate XML in which each element +// begins on a new indented line that starts with prefix and is followed by +// one or more copies of indent according to the nesting depth. +func (enc *Encoder) Indent(prefix, indent string) { + enc.p.prefix = prefix + enc.p.indent = indent +} + +// Encode writes the XML encoding of v to the stream. +// +// See the documentation for Marshal for details about the conversion +// of Go values to XML. +// +// Encode calls Flush before returning. +func (enc *Encoder) Encode(v interface{}) error { + err := enc.p.marshalValue(reflect.ValueOf(v), nil, nil) + if err != nil { + return err + } + return enc.p.Flush() +} + +// EncodeElement writes the XML encoding of v to the stream, +// using start as the outermost tag in the encoding. +// +// See the documentation for Marshal for details about the conversion +// of Go values to XML. +// +// EncodeElement calls Flush before returning. +func (enc *Encoder) EncodeElement(v interface{}, start StartElement) error { + err := enc.p.marshalValue(reflect.ValueOf(v), nil, &start) + if err != nil { + return err + } + return enc.p.Flush() +} + +var ( + begComment = []byte("") + endProcInst = []byte("?>") + endDirective = []byte(">") +) + +// EncodeToken writes the given XML token to the stream. +// It returns an error if StartElement and EndElement tokens are not +// properly matched. +// +// EncodeToken does not call Flush, because usually it is part of a +// larger operation such as Encode or EncodeElement (or a custom +// Marshaler's MarshalXML invoked during those), and those will call +// Flush when finished. Callers that create an Encoder and then invoke +// EncodeToken directly, without using Encode or EncodeElement, need to +// call Flush when finished to ensure that the XML is written to the +// underlying writer. +// +// EncodeToken allows writing a ProcInst with Target set to "xml" only +// as the first token in the stream. +// +// When encoding a StartElement holding an XML namespace prefix +// declaration for a prefix that is not already declared, contained +// elements (including the StartElement itself) will use the declared +// prefix when encoding names with matching namespace URIs. +func (enc *Encoder) EncodeToken(t Token) error { + + p := &enc.p + switch t := t.(type) { + case StartElement: + if err := p.writeStart(&t); err != nil { + return err + } + case EndElement: + if err := p.writeEnd(t.Name); err != nil { + return err + } + case CharData: + escapeText(p, t, false) + case Comment: + if bytes.Contains(t, endComment) { + return fmt.Errorf("xml: EncodeToken of Comment containing --> marker") + } + p.WriteString("") + return p.cachedWriteError() + case ProcInst: + // First token to be encoded which is also a ProcInst with target of xml + // is the xml declaration. The only ProcInst where target of xml is allowed. + if t.Target == "xml" && p.Buffered() != 0 { + return fmt.Errorf("xml: EncodeToken of ProcInst xml target only valid for xml declaration, first token encoded") + } + if !isNameString(t.Target) { + return fmt.Errorf("xml: EncodeToken of ProcInst with invalid Target") + } + if bytes.Contains(t.Inst, endProcInst) { + return fmt.Errorf("xml: EncodeToken of ProcInst containing ?> marker") + } + p.WriteString(" 0 { + p.WriteByte(' ') + p.Write(t.Inst) + } + p.WriteString("?>") + case Directive: + if !isValidDirective(t) { + return fmt.Errorf("xml: EncodeToken of Directive containing wrong < or > markers") + } + p.WriteString("") + default: + return fmt.Errorf("xml: EncodeToken of invalid token type") + + } + return p.cachedWriteError() +} + +// isValidDirective reports whether dir is a valid directive text, +// meaning angle brackets are matched, ignoring comments and strings. +func isValidDirective(dir Directive) bool { + var ( + depth int + inquote uint8 + incomment bool + ) + for i, c := range dir { + switch { + case incomment: + if c == '>' { + if n := 1 + i - len(endComment); n >= 0 && bytes.Equal(dir[n:i+1], endComment) { + incomment = false + } + } + // Just ignore anything in comment + case inquote != 0: + if c == inquote { + inquote = 0 + } + // Just ignore anything within quotes + case c == '\'' || c == '"': + inquote = c + case c == '<': + if i+len(begComment) < len(dir) && bytes.Equal(dir[i:i+len(begComment)], begComment) { + incomment = true + } else { + depth++ + } + case c == '>': + if depth == 0 { + return false + } + depth-- + } + } + return depth == 0 && inquote == 0 && !incomment +} + +// Flush flushes any buffered XML to the underlying writer. +// See the EncodeToken documentation for details about when it is necessary. +func (enc *Encoder) Flush() error { + return enc.p.Flush() +} + +type printer struct { + *bufio.Writer + encoder *Encoder + seq int + indent string + prefix string + depth int + indentedIn bool + putNewline bool + defaultNS string + attrNS map[string]string // map prefix -> name space + attrPrefix map[string]string // map name space -> prefix + prefixes []printerPrefix + tags []Name +} + +// printerPrefix holds a namespace undo record. +// When an element is popped, the prefix record +// is set back to the recorded URL. The empty +// prefix records the URL for the default name space. +// +// The start of an element is recorded with an element +// that has mark=true. +type printerPrefix struct { + prefix string + url string + mark bool +} + +func (p *printer) prefixForNS(url string, isAttr bool) string { + // The "http://www.w3.org/XML/1998/namespace" name space is predefined as "xml" + // and must be referred to that way. + // (The "http://www.w3.org/2000/xmlns/" name space is also predefined as "xmlns", + // but users should not be trying to use that one directly - that's our job.) + if url == xmlURL { + return "xml" + } + if !isAttr && url == p.defaultNS { + // We can use the default name space. + return "" + } + return p.attrPrefix[url] +} + +// defineNS pushes any namespace definition found in the given attribute. +// If ignoreNonEmptyDefault is true, an xmlns="nonempty" +// attribute will be ignored. +func (p *printer) defineNS(attr Attr, ignoreNonEmptyDefault bool) error { + var prefix string + if attr.Name.Local == "xmlns" { + if attr.Name.Space != "" && attr.Name.Space != "xml" && attr.Name.Space != xmlURL { + return fmt.Errorf("xml: cannot redefine xmlns attribute prefix") + } + } else if attr.Name.Space == "xmlns" && attr.Name.Local != "" { + prefix = attr.Name.Local + if attr.Value == "" { + // Technically, an empty XML namespace is allowed for an attribute. + // From http://www.w3.org/TR/xml-names11/#scoping-defaulting: + // + // The attribute value in a namespace declaration for a prefix may be + // empty. This has the effect, within the scope of the declaration, of removing + // any association of the prefix with a namespace name. + // + // However our namespace prefixes here are used only as hints. There's + // no need to respect the removal of a namespace prefix, so we ignore it. + return nil + } + } else { + // Ignore: it's not a namespace definition + return nil + } + if prefix == "" { + if attr.Value == p.defaultNS { + // No need for redefinition. + return nil + } + if attr.Value != "" && ignoreNonEmptyDefault { + // We have an xmlns="..." value but + // it can't define a name space in this context, + // probably because the element has an empty + // name space. In this case, we just ignore + // the name space declaration. + return nil + } + } else if _, ok := p.attrPrefix[attr.Value]; ok { + // There's already a prefix for the given name space, + // so use that. This prevents us from + // having two prefixes for the same name space + // so attrNS and attrPrefix can remain bijective. + return nil + } + p.pushPrefix(prefix, attr.Value) + return nil +} + +// createNSPrefix creates a name space prefix attribute +// to use for the given name space, defining a new prefix +// if necessary. +// If isAttr is true, the prefix is to be created for an attribute +// prefix, which means that the default name space cannot +// be used. +func (p *printer) createNSPrefix(url string, isAttr bool) { + if _, ok := p.attrPrefix[url]; ok { + // We already have a prefix for the given URL. + return + } + switch { + case !isAttr && url == p.defaultNS: + // We can use the default name space. + return + case url == "": + // The only way we can encode names in the empty + // name space is by using the default name space, + // so we must use that. + if p.defaultNS != "" { + // The default namespace is non-empty, so we + // need to set it to empty. + p.pushPrefix("", "") + } + return + case url == xmlURL: + return + } + // TODO If the URL is an existing prefix, we could + // use it as is. That would enable the + // marshaling of elements that had been unmarshaled + // and with a name space prefix that was not found. + // although technically it would be incorrect. + + // Pick a name. We try to use the final element of the path + // but fall back to _. + prefix := strings.TrimRight(url, "/") + if i := strings.LastIndex(prefix, "/"); i >= 0 { + prefix = prefix[i+1:] + } + if prefix == "" || !isName([]byte(prefix)) || strings.Contains(prefix, ":") { + prefix = "_" + } + if strings.HasPrefix(prefix, "xml") { + // xmlanything is reserved. + prefix = "_" + prefix + } + if p.attrNS[prefix] != "" { + // Name is taken. Find a better one. + for p.seq++; ; p.seq++ { + if id := prefix + "_" + strconv.Itoa(p.seq); p.attrNS[id] == "" { + prefix = id + break + } + } + } + + p.pushPrefix(prefix, url) +} + +// writeNamespaces writes xmlns attributes for all the +// namespace prefixes that have been defined in +// the current element. +func (p *printer) writeNamespaces() { + for i := len(p.prefixes) - 1; i >= 0; i-- { + prefix := p.prefixes[i] + if prefix.mark { + return + } + p.WriteString(" ") + if prefix.prefix == "" { + // Default name space. + p.WriteString(`xmlns="`) + } else { + p.WriteString("xmlns:") + p.WriteString(prefix.prefix) + p.WriteString(`="`) + } + EscapeText(p, []byte(p.nsForPrefix(prefix.prefix))) + p.WriteString(`"`) + } +} + +// pushPrefix pushes a new prefix on the prefix stack +// without checking to see if it is already defined. +func (p *printer) pushPrefix(prefix, url string) { + p.prefixes = append(p.prefixes, printerPrefix{ + prefix: prefix, + url: p.nsForPrefix(prefix), + }) + p.setAttrPrefix(prefix, url) +} + +// nsForPrefix returns the name space for the given +// prefix. Note that this is not valid for the +// empty attribute prefix, which always has an empty +// name space. +func (p *printer) nsForPrefix(prefix string) string { + if prefix == "" { + return p.defaultNS + } + return p.attrNS[prefix] +} + +// markPrefix marks the start of an element on the prefix +// stack. +func (p *printer) markPrefix() { + p.prefixes = append(p.prefixes, printerPrefix{ + mark: true, + }) +} + +// popPrefix pops all defined prefixes for the current +// element. +func (p *printer) popPrefix() { + for len(p.prefixes) > 0 { + prefix := p.prefixes[len(p.prefixes)-1] + p.prefixes = p.prefixes[:len(p.prefixes)-1] + if prefix.mark { + break + } + p.setAttrPrefix(prefix.prefix, prefix.url) + } +} + +// setAttrPrefix sets an attribute name space prefix. +// If url is empty, the attribute is removed. +// If prefix is empty, the default name space is set. +func (p *printer) setAttrPrefix(prefix, url string) { + if prefix == "" { + p.defaultNS = url + return + } + if url == "" { + delete(p.attrPrefix, p.attrNS[prefix]) + delete(p.attrNS, prefix) + return + } + if p.attrPrefix == nil { + // Need to define a new name space. + p.attrPrefix = make(map[string]string) + p.attrNS = make(map[string]string) + } + // Remove any old prefix value. This is OK because we maintain a + // strict one-to-one mapping between prefix and URL (see + // defineNS) + delete(p.attrPrefix, p.attrNS[prefix]) + p.attrPrefix[url] = prefix + p.attrNS[prefix] = url +} + +var ( + marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() + marshalerAttrType = reflect.TypeOf((*MarshalerAttr)(nil)).Elem() + textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() +) + +// marshalValue writes one or more XML elements representing val. +// If val was obtained from a struct field, finfo must have its details. +func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo, startTemplate *StartElement) error { + if startTemplate != nil && startTemplate.Name.Local == "" { + return fmt.Errorf("xml: EncodeElement of StartElement with missing name") + } + + if !val.IsValid() { + return nil + } + if finfo != nil && finfo.flags&fOmitEmpty != 0 && isEmptyValue(val) { + return nil + } + + // Drill into interfaces and pointers. + // This can turn into an infinite loop given a cyclic chain, + // but it matches the Go 1 behavior. + for val.Kind() == reflect.Interface || val.Kind() == reflect.Ptr { + if val.IsNil() { + return nil + } + val = val.Elem() + } + + kind := val.Kind() + typ := val.Type() + + // Check for marshaler. + if val.CanInterface() && typ.Implements(marshalerType) { + return p.marshalInterface(val.Interface().(Marshaler), p.defaultStart(typ, finfo, startTemplate)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(marshalerType) { + return p.marshalInterface(pv.Interface().(Marshaler), p.defaultStart(pv.Type(), finfo, startTemplate)) + } + } + + // Check for text marshaler. + if val.CanInterface() && typ.Implements(textMarshalerType) { + return p.marshalTextInterface(val.Interface().(encoding.TextMarshaler), p.defaultStart(typ, finfo, startTemplate)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + return p.marshalTextInterface(pv.Interface().(encoding.TextMarshaler), p.defaultStart(pv.Type(), finfo, startTemplate)) + } + } + + // Slices and arrays iterate over the elements. They do not have an enclosing tag. + if (kind == reflect.Slice || kind == reflect.Array) && typ.Elem().Kind() != reflect.Uint8 { + for i, n := 0, val.Len(); i < n; i++ { + if err := p.marshalValue(val.Index(i), finfo, startTemplate); err != nil { + return err + } + } + return nil + } + + tinfo, err := getTypeInfo(typ) + if err != nil { + return err + } + + // Create start element. + // Precedence for the XML element name is: + // 0. startTemplate + // 1. XMLName field in underlying struct; + // 2. field name/tag in the struct field; and + // 3. type name + var start StartElement + + // explicitNS records whether the element's name space has been + // explicitly set (for example an XMLName field). + explicitNS := false + + if startTemplate != nil { + start.Name = startTemplate.Name + explicitNS = true + start.Attr = append(start.Attr, startTemplate.Attr...) + } else if tinfo.xmlname != nil { + xmlname := tinfo.xmlname + if xmlname.name != "" { + start.Name.Space, start.Name.Local = xmlname.xmlns, xmlname.name + } else if v, ok := xmlname.value(val).Interface().(Name); ok && v.Local != "" { + start.Name = v + } + explicitNS = true + } + if start.Name.Local == "" && finfo != nil { + start.Name.Local = finfo.name + if finfo.xmlns != "" { + start.Name.Space = finfo.xmlns + explicitNS = true + } + } + if start.Name.Local == "" { + name := typ.Name() + if name == "" { + return &UnsupportedTypeError{typ} + } + start.Name.Local = name + } + + // defaultNS records the default name space as set by a xmlns="..." + // attribute. We don't set p.defaultNS because we want to let + // the attribute writing code (in p.defineNS) be solely responsible + // for maintaining that. + defaultNS := p.defaultNS + + // Attributes + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fAttr == 0 { + continue + } + attr, err := p.fieldAttr(finfo, val) + if err != nil { + return err + } + if attr.Name.Local == "" { + continue + } + start.Attr = append(start.Attr, attr) + if attr.Name.Space == "" && attr.Name.Local == "xmlns" { + defaultNS = attr.Value + } + } + if !explicitNS { + // Historic behavior: elements use the default name space + // they are contained in by default. + start.Name.Space = defaultNS + } + // Historic behaviour: an element that's in a namespace sets + // the default namespace for all elements contained within it. + start.setDefaultNamespace() + + if err := p.writeStart(&start); err != nil { + return err + } + + if val.Kind() == reflect.Struct { + err = p.marshalStruct(tinfo, val) + } else { + s, b, err1 := p.marshalSimple(typ, val) + if err1 != nil { + err = err1 + } else if b != nil { + EscapeText(p, b) + } else { + p.EscapeString(s) + } + } + if err != nil { + return err + } + + if err := p.writeEnd(start.Name); err != nil { + return err + } + + return p.cachedWriteError() +} + +// fieldAttr returns the attribute of the given field. +// If the returned attribute has an empty Name.Local, +// it should not be used. +// The given value holds the value containing the field. +func (p *printer) fieldAttr(finfo *fieldInfo, val reflect.Value) (Attr, error) { + fv := finfo.value(val) + name := Name{Space: finfo.xmlns, Local: finfo.name} + if finfo.flags&fOmitEmpty != 0 && isEmptyValue(fv) { + return Attr{}, nil + } + if fv.Kind() == reflect.Interface && fv.IsNil() { + return Attr{}, nil + } + if fv.CanInterface() && fv.Type().Implements(marshalerAttrType) { + attr, err := fv.Interface().(MarshalerAttr).MarshalXMLAttr(name) + return attr, err + } + if fv.CanAddr() { + pv := fv.Addr() + if pv.CanInterface() && pv.Type().Implements(marshalerAttrType) { + attr, err := pv.Interface().(MarshalerAttr).MarshalXMLAttr(name) + return attr, err + } + } + if fv.CanInterface() && fv.Type().Implements(textMarshalerType) { + text, err := fv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return Attr{}, err + } + return Attr{name, string(text)}, nil + } + if fv.CanAddr() { + pv := fv.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + text, err := pv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return Attr{}, err + } + return Attr{name, string(text)}, nil + } + } + // Dereference or skip nil pointer, interface values. + switch fv.Kind() { + case reflect.Ptr, reflect.Interface: + if fv.IsNil() { + return Attr{}, nil + } + fv = fv.Elem() + } + s, b, err := p.marshalSimple(fv.Type(), fv) + if err != nil { + return Attr{}, err + } + if b != nil { + s = string(b) + } + return Attr{name, s}, nil +} + +// defaultStart returns the default start element to use, +// given the reflect type, field info, and start template. +func (p *printer) defaultStart(typ reflect.Type, finfo *fieldInfo, startTemplate *StartElement) StartElement { + var start StartElement + // Precedence for the XML element name is as above, + // except that we do not look inside structs for the first field. + if startTemplate != nil { + start.Name = startTemplate.Name + start.Attr = append(start.Attr, startTemplate.Attr...) + } else if finfo != nil && finfo.name != "" { + start.Name.Local = finfo.name + start.Name.Space = finfo.xmlns + } else if typ.Name() != "" { + start.Name.Local = typ.Name() + } else { + // Must be a pointer to a named type, + // since it has the Marshaler methods. + start.Name.Local = typ.Elem().Name() + } + // Historic behaviour: elements use the name space of + // the element they are contained in by default. + if start.Name.Space == "" { + start.Name.Space = p.defaultNS + } + start.setDefaultNamespace() + return start +} + +// marshalInterface marshals a Marshaler interface value. +func (p *printer) marshalInterface(val Marshaler, start StartElement) error { + // Push a marker onto the tag stack so that MarshalXML + // cannot close the XML tags that it did not open. + p.tags = append(p.tags, Name{}) + n := len(p.tags) + + err := val.MarshalXML(p.encoder, start) + if err != nil { + return err + } + + // Make sure MarshalXML closed all its tags. p.tags[n-1] is the mark. + if len(p.tags) > n { + return fmt.Errorf("xml: %s.MarshalXML wrote invalid XML: <%s> not closed", receiverType(val), p.tags[len(p.tags)-1].Local) + } + p.tags = p.tags[:n-1] + return nil +} + +// marshalTextInterface marshals a TextMarshaler interface value. +func (p *printer) marshalTextInterface(val encoding.TextMarshaler, start StartElement) error { + if err := p.writeStart(&start); err != nil { + return err + } + text, err := val.MarshalText() + if err != nil { + return err + } + EscapeText(p, text) + return p.writeEnd(start.Name) +} + +// writeStart writes the given start element. +func (p *printer) writeStart(start *StartElement) error { + if start.Name.Local == "" { + return fmt.Errorf("xml: start tag with no name") + } + + p.tags = append(p.tags, start.Name) + p.markPrefix() + // Define any name spaces explicitly declared in the attributes. + // We do this as a separate pass so that explicitly declared prefixes + // will take precedence over implicitly declared prefixes + // regardless of the order of the attributes. + ignoreNonEmptyDefault := start.Name.Space == "" + for _, attr := range start.Attr { + if err := p.defineNS(attr, ignoreNonEmptyDefault); err != nil { + return err + } + } + // Define any new name spaces implied by the attributes. + for _, attr := range start.Attr { + name := attr.Name + // From http://www.w3.org/TR/xml-names11/#defaulting + // "Default namespace declarations do not apply directly + // to attribute names; the interpretation of unprefixed + // attributes is determined by the element on which they + // appear." + // This means we don't need to create a new namespace + // when an attribute name space is empty. + if name.Space != "" && !name.isNamespace() { + p.createNSPrefix(name.Space, true) + } + } + p.createNSPrefix(start.Name.Space, false) + + p.writeIndent(1) + p.WriteByte('<') + p.writeName(start.Name, false) + p.writeNamespaces() + for _, attr := range start.Attr { + name := attr.Name + if name.Local == "" || name.isNamespace() { + // Namespaces have already been written by writeNamespaces above. + continue + } + p.WriteByte(' ') + p.writeName(name, true) + p.WriteString(`="`) + p.EscapeString(attr.Value) + p.WriteByte('"') + } + p.WriteByte('>') + return nil +} + +// writeName writes the given name. It assumes +// that p.createNSPrefix(name) has already been called. +func (p *printer) writeName(name Name, isAttr bool) { + if prefix := p.prefixForNS(name.Space, isAttr); prefix != "" { + p.WriteString(prefix) + p.WriteByte(':') + } + p.WriteString(name.Local) +} + +func (p *printer) writeEnd(name Name) error { + if name.Local == "" { + return fmt.Errorf("xml: end tag with no name") + } + if len(p.tags) == 0 || p.tags[len(p.tags)-1].Local == "" { + return fmt.Errorf("xml: end tag without start tag", name.Local) + } + if top := p.tags[len(p.tags)-1]; top != name { + if top.Local != name.Local { + return fmt.Errorf("xml: end tag does not match start tag <%s>", name.Local, top.Local) + } + return fmt.Errorf("xml: end tag in namespace %s does not match start tag <%s> in namespace %s", name.Local, name.Space, top.Local, top.Space) + } + p.tags = p.tags[:len(p.tags)-1] + + p.writeIndent(-1) + p.WriteByte('<') + p.WriteByte('/') + p.writeName(name, false) + p.WriteByte('>') + p.popPrefix() + return nil +} + +func (p *printer) marshalSimple(typ reflect.Type, val reflect.Value) (string, []byte, error) { + switch val.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return strconv.FormatInt(val.Int(), 10), nil, nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return strconv.FormatUint(val.Uint(), 10), nil, nil + case reflect.Float32, reflect.Float64: + return strconv.FormatFloat(val.Float(), 'g', -1, val.Type().Bits()), nil, nil + case reflect.String: + return val.String(), nil, nil + case reflect.Bool: + return strconv.FormatBool(val.Bool()), nil, nil + case reflect.Array: + if typ.Elem().Kind() != reflect.Uint8 { + break + } + // [...]byte + var bytes []byte + if val.CanAddr() { + bytes = val.Slice(0, val.Len()).Bytes() + } else { + bytes = make([]byte, val.Len()) + reflect.Copy(reflect.ValueOf(bytes), val) + } + return "", bytes, nil + case reflect.Slice: + if typ.Elem().Kind() != reflect.Uint8 { + break + } + // []byte + return "", val.Bytes(), nil + } + return "", nil, &UnsupportedTypeError{typ} +} + +var ddBytes = []byte("--") + +func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { + s := parentStack{p: p} + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fAttr != 0 { + continue + } + vf := finfo.value(val) + + // Dereference or skip nil pointer, interface values. + switch vf.Kind() { + case reflect.Ptr, reflect.Interface: + if !vf.IsNil() { + vf = vf.Elem() + } + } + + switch finfo.flags & fMode { + case fCharData: + if err := s.setParents(&noField, reflect.Value{}); err != nil { + return err + } + if vf.CanInterface() && vf.Type().Implements(textMarshalerType) { + data, err := vf.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + Escape(p, data) + continue + } + if vf.CanAddr() { + pv := vf.Addr() + if pv.CanInterface() && pv.Type().Implements(textMarshalerType) { + data, err := pv.Interface().(encoding.TextMarshaler).MarshalText() + if err != nil { + return err + } + Escape(p, data) + continue + } + } + var scratch [64]byte + switch vf.Kind() { + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + Escape(p, strconv.AppendInt(scratch[:0], vf.Int(), 10)) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + Escape(p, strconv.AppendUint(scratch[:0], vf.Uint(), 10)) + case reflect.Float32, reflect.Float64: + Escape(p, strconv.AppendFloat(scratch[:0], vf.Float(), 'g', -1, vf.Type().Bits())) + case reflect.Bool: + Escape(p, strconv.AppendBool(scratch[:0], vf.Bool())) + case reflect.String: + if err := EscapeText(p, []byte(vf.String())); err != nil { + return err + } + case reflect.Slice: + if elem, ok := vf.Interface().([]byte); ok { + if err := EscapeText(p, elem); err != nil { + return err + } + } + } + continue + + case fComment: + if err := s.setParents(&noField, reflect.Value{}); err != nil { + return err + } + k := vf.Kind() + if !(k == reflect.String || k == reflect.Slice && vf.Type().Elem().Kind() == reflect.Uint8) { + return fmt.Errorf("xml: bad type for comment field of %s", val.Type()) + } + if vf.Len() == 0 { + continue + } + p.writeIndent(0) + p.WriteString("" is invalid grammar. Make it "- -->" + p.WriteByte(' ') + } + p.WriteString("-->") + continue + + case fInnerXml: + iface := vf.Interface() + switch raw := iface.(type) { + case []byte: + p.Write(raw) + continue + case string: + p.WriteString(raw) + continue + } + + case fElement, fElement | fAny: + if err := s.setParents(finfo, vf); err != nil { + return err + } + } + if err := p.marshalValue(vf, finfo, nil); err != nil { + return err + } + } + if err := s.setParents(&noField, reflect.Value{}); err != nil { + return err + } + return p.cachedWriteError() +} + +var noField fieldInfo + +// return the bufio Writer's cached write error +func (p *printer) cachedWriteError() error { + _, err := p.Write(nil) + return err +} + +func (p *printer) writeIndent(depthDelta int) { + if len(p.prefix) == 0 && len(p.indent) == 0 { + return + } + if depthDelta < 0 { + p.depth-- + if p.indentedIn { + p.indentedIn = false + return + } + p.indentedIn = false + } + if p.putNewline { + p.WriteByte('\n') + } else { + p.putNewline = true + } + if len(p.prefix) > 0 { + p.WriteString(p.prefix) + } + if len(p.indent) > 0 { + for i := 0; i < p.depth; i++ { + p.WriteString(p.indent) + } + } + if depthDelta > 0 { + p.depth++ + p.indentedIn = true + } +} + +type parentStack struct { + p *printer + xmlns string + parents []string +} + +// setParents sets the stack of current parents to those found in finfo. +// It only writes the start elements if vf holds a non-nil value. +// If finfo is &noField, it pops all elements. +func (s *parentStack) setParents(finfo *fieldInfo, vf reflect.Value) error { + xmlns := s.p.defaultNS + if finfo.xmlns != "" { + xmlns = finfo.xmlns + } + commonParents := 0 + if xmlns == s.xmlns { + for ; commonParents < len(finfo.parents) && commonParents < len(s.parents); commonParents++ { + if finfo.parents[commonParents] != s.parents[commonParents] { + break + } + } + } + // Pop off any parents that aren't in common with the previous field. + for i := len(s.parents) - 1; i >= commonParents; i-- { + if err := s.p.writeEnd(Name{ + Space: s.xmlns, + Local: s.parents[i], + }); err != nil { + return err + } + } + s.parents = finfo.parents + s.xmlns = xmlns + if commonParents >= len(s.parents) { + // No new elements to push. + return nil + } + if (vf.Kind() == reflect.Ptr || vf.Kind() == reflect.Interface) && vf.IsNil() { + // The element is nil, so no need for the start elements. + s.parents = s.parents[:commonParents] + return nil + } + // Push any new parents required. + for _, name := range s.parents[commonParents:] { + start := &StartElement{ + Name: Name{ + Space: s.xmlns, + Local: name, + }, + } + // Set the default name space for parent elements + // to match what we do with other elements. + if s.xmlns != s.p.defaultNS { + start.setDefaultNamespace() + } + if err := s.p.writeStart(start); err != nil { + return err + } + } + return nil +} + +// A MarshalXMLError is returned when Marshal encounters a type +// that cannot be converted into XML. +type UnsupportedTypeError struct { + Type reflect.Type +} + +func (e *UnsupportedTypeError) Error() string { + return "xml: unsupported type: " + e.Type.String() +} + +func isEmptyValue(v reflect.Value) bool { + switch v.Kind() { + case reflect.Array, reflect.Map, reflect.Slice, reflect.String: + return v.Len() == 0 + case reflect.Bool: + return !v.Bool() + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return v.Int() == 0 + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return v.Uint() == 0 + case reflect.Float32, reflect.Float64: + return v.Float() == 0 + case reflect.Interface, reflect.Ptr: + return v.IsNil() + } + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/marshal_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/marshal_test.go new file mode 100644 index 00000000..5dc78e74 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/marshal_test.go @@ -0,0 +1,1939 @@ +// 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 xml + +import ( + "bytes" + "errors" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "sync" + "testing" + "time" +) + +type DriveType int + +const ( + HyperDrive DriveType = iota + ImprobabilityDrive +) + +type Passenger struct { + Name []string `xml:"name"` + Weight float32 `xml:"weight"` +} + +type Ship struct { + XMLName struct{} `xml:"spaceship"` + + Name string `xml:"name,attr"` + Pilot string `xml:"pilot,attr"` + Drive DriveType `xml:"drive"` + Age uint `xml:"age"` + Passenger []*Passenger `xml:"passenger"` + secret string +} + +type NamedType string + +type Port struct { + XMLName struct{} `xml:"port"` + Type string `xml:"type,attr,omitempty"` + Comment string `xml:",comment"` + Number string `xml:",chardata"` +} + +type Domain struct { + XMLName struct{} `xml:"domain"` + Country string `xml:",attr,omitempty"` + Name []byte `xml:",chardata"` + Comment []byte `xml:",comment"` +} + +type Book struct { + XMLName struct{} `xml:"book"` + Title string `xml:",chardata"` +} + +type Event struct { + XMLName struct{} `xml:"event"` + Year int `xml:",chardata"` +} + +type Movie struct { + XMLName struct{} `xml:"movie"` + Length uint `xml:",chardata"` +} + +type Pi struct { + XMLName struct{} `xml:"pi"` + Approximation float32 `xml:",chardata"` +} + +type Universe struct { + XMLName struct{} `xml:"universe"` + Visible float64 `xml:",chardata"` +} + +type Particle struct { + XMLName struct{} `xml:"particle"` + HasMass bool `xml:",chardata"` +} + +type Departure struct { + XMLName struct{} `xml:"departure"` + When time.Time `xml:",chardata"` +} + +type SecretAgent struct { + XMLName struct{} `xml:"agent"` + Handle string `xml:"handle,attr"` + Identity string + Obfuscate string `xml:",innerxml"` +} + +type NestedItems struct { + XMLName struct{} `xml:"result"` + Items []string `xml:">item"` + Item1 []string `xml:"Items>item1"` +} + +type NestedOrder struct { + XMLName struct{} `xml:"result"` + Field1 string `xml:"parent>c"` + Field2 string `xml:"parent>b"` + Field3 string `xml:"parent>a"` +} + +type MixedNested struct { + XMLName struct{} `xml:"result"` + A string `xml:"parent1>a"` + B string `xml:"b"` + C string `xml:"parent1>parent2>c"` + D string `xml:"parent1>d"` +} + +type NilTest struct { + A interface{} `xml:"parent1>parent2>a"` + B interface{} `xml:"parent1>b"` + C interface{} `xml:"parent1>parent2>c"` +} + +type Service struct { + XMLName struct{} `xml:"service"` + Domain *Domain `xml:"host>domain"` + Port *Port `xml:"host>port"` + Extra1 interface{} + Extra2 interface{} `xml:"host>extra2"` +} + +var nilStruct *Ship + +type EmbedA struct { + EmbedC + EmbedB EmbedB + FieldA string +} + +type EmbedB struct { + FieldB string + *EmbedC +} + +type EmbedC struct { + FieldA1 string `xml:"FieldA>A1"` + FieldA2 string `xml:"FieldA>A2"` + FieldB string + FieldC string +} + +type NameCasing struct { + XMLName struct{} `xml:"casing"` + Xy string + XY string + XyA string `xml:"Xy,attr"` + XYA string `xml:"XY,attr"` +} + +type NamePrecedence struct { + XMLName Name `xml:"Parent"` + FromTag XMLNameWithoutTag `xml:"InTag"` + FromNameVal XMLNameWithoutTag + FromNameTag XMLNameWithTag + InFieldName string +} + +type XMLNameWithTag struct { + XMLName Name `xml:"InXMLNameTag"` + Value string `xml:",chardata"` +} + +type XMLNameWithNSTag struct { + XMLName Name `xml:"ns InXMLNameWithNSTag"` + Value string `xml:",chardata"` +} + +type XMLNameWithoutTag struct { + XMLName Name + Value string `xml:",chardata"` +} + +type NameInField struct { + Foo Name `xml:"ns foo"` +} + +type AttrTest struct { + Int int `xml:",attr"` + Named int `xml:"int,attr"` + Float float64 `xml:",attr"` + Uint8 uint8 `xml:",attr"` + Bool bool `xml:",attr"` + Str string `xml:",attr"` + Bytes []byte `xml:",attr"` +} + +type OmitAttrTest struct { + Int int `xml:",attr,omitempty"` + Named int `xml:"int,attr,omitempty"` + Float float64 `xml:",attr,omitempty"` + Uint8 uint8 `xml:",attr,omitempty"` + Bool bool `xml:",attr,omitempty"` + Str string `xml:",attr,omitempty"` + Bytes []byte `xml:",attr,omitempty"` +} + +type OmitFieldTest struct { + Int int `xml:",omitempty"` + Named int `xml:"int,omitempty"` + Float float64 `xml:",omitempty"` + Uint8 uint8 `xml:",omitempty"` + Bool bool `xml:",omitempty"` + Str string `xml:",omitempty"` + Bytes []byte `xml:",omitempty"` + Ptr *PresenceTest `xml:",omitempty"` +} + +type AnyTest struct { + XMLName struct{} `xml:"a"` + Nested string `xml:"nested>value"` + AnyField AnyHolder `xml:",any"` +} + +type AnyOmitTest struct { + XMLName struct{} `xml:"a"` + Nested string `xml:"nested>value"` + AnyField *AnyHolder `xml:",any,omitempty"` +} + +type AnySliceTest struct { + XMLName struct{} `xml:"a"` + Nested string `xml:"nested>value"` + AnyField []AnyHolder `xml:",any"` +} + +type AnyHolder struct { + XMLName Name + XML string `xml:",innerxml"` +} + +type RecurseA struct { + A string + B *RecurseB +} + +type RecurseB struct { + A *RecurseA + B string +} + +type PresenceTest struct { + Exists *struct{} +} + +type IgnoreTest struct { + PublicSecret string `xml:"-"` +} + +type MyBytes []byte + +type Data struct { + Bytes []byte + Attr []byte `xml:",attr"` + Custom MyBytes +} + +type Plain struct { + V interface{} +} + +type MyInt int + +type EmbedInt struct { + MyInt +} + +type Strings struct { + X []string `xml:"A>B,omitempty"` +} + +type PointerFieldsTest struct { + XMLName Name `xml:"dummy"` + Name *string `xml:"name,attr"` + Age *uint `xml:"age,attr"` + Empty *string `xml:"empty,attr"` + Contents *string `xml:",chardata"` +} + +type ChardataEmptyTest struct { + XMLName Name `xml:"test"` + Contents *string `xml:",chardata"` +} + +type MyMarshalerTest struct { +} + +var _ Marshaler = (*MyMarshalerTest)(nil) + +func (m *MyMarshalerTest) MarshalXML(e *Encoder, start StartElement) error { + e.EncodeToken(start) + e.EncodeToken(CharData([]byte("hello world"))) + e.EncodeToken(EndElement{start.Name}) + return nil +} + +type MyMarshalerAttrTest struct{} + +var _ MarshalerAttr = (*MyMarshalerAttrTest)(nil) + +func (m *MyMarshalerAttrTest) MarshalXMLAttr(name Name) (Attr, error) { + return Attr{name, "hello world"}, nil +} + +type MyMarshalerValueAttrTest struct{} + +var _ MarshalerAttr = MyMarshalerValueAttrTest{} + +func (m MyMarshalerValueAttrTest) MarshalXMLAttr(name Name) (Attr, error) { + return Attr{name, "hello world"}, nil +} + +type MarshalerStruct struct { + Foo MyMarshalerAttrTest `xml:",attr"` +} + +type MarshalerValueStruct struct { + Foo MyMarshalerValueAttrTest `xml:",attr"` +} + +type InnerStruct struct { + XMLName Name `xml:"testns outer"` +} + +type OuterStruct struct { + InnerStruct + IntAttr int `xml:"int,attr"` +} + +type OuterNamedStruct struct { + InnerStruct + XMLName Name `xml:"outerns test"` + IntAttr int `xml:"int,attr"` +} + +type OuterNamedOrderedStruct struct { + XMLName Name `xml:"outerns test"` + InnerStruct + IntAttr int `xml:"int,attr"` +} + +type OuterOuterStruct struct { + OuterStruct +} + +type NestedAndChardata struct { + AB []string `xml:"A>B"` + Chardata string `xml:",chardata"` +} + +type NestedAndComment struct { + AB []string `xml:"A>B"` + Comment string `xml:",comment"` +} + +type XMLNSFieldStruct struct { + Ns string `xml:"xmlns,attr"` + Body string +} + +type NamedXMLNSFieldStruct struct { + XMLName struct{} `xml:"testns test"` + Ns string `xml:"xmlns,attr"` + Body string +} + +type XMLNSFieldStructWithOmitEmpty struct { + Ns string `xml:"xmlns,attr,omitempty"` + Body string +} + +type NamedXMLNSFieldStructWithEmptyNamespace struct { + XMLName struct{} `xml:"test"` + Ns string `xml:"xmlns,attr"` + Body string +} + +type RecursiveXMLNSFieldStruct struct { + Ns string `xml:"xmlns,attr"` + Body *RecursiveXMLNSFieldStruct `xml:",omitempty"` + Text string `xml:",omitempty"` +} + +func ifaceptr(x interface{}) interface{} { + return &x +} + +var ( + nameAttr = "Sarah" + ageAttr = uint(12) + contentsAttr = "lorem ipsum" +) + +// Unless explicitly stated as such (or *Plain), all of the +// tests below are two-way tests. When introducing new tests, +// please try to make them two-way as well to ensure that +// marshalling and unmarshalling are as symmetrical as feasible. +var marshalTests = []struct { + Value interface{} + ExpectXML string + MarshalOnly bool + UnmarshalOnly bool +}{ + // Test nil marshals to nothing + {Value: nil, ExpectXML: ``, MarshalOnly: true}, + {Value: nilStruct, ExpectXML: ``, MarshalOnly: true}, + + // Test value types + {Value: &Plain{true}, ExpectXML: `true`}, + {Value: &Plain{false}, ExpectXML: `false`}, + {Value: &Plain{int(42)}, ExpectXML: `42`}, + {Value: &Plain{int8(42)}, ExpectXML: `42`}, + {Value: &Plain{int16(42)}, ExpectXML: `42`}, + {Value: &Plain{int32(42)}, ExpectXML: `42`}, + {Value: &Plain{uint(42)}, ExpectXML: `42`}, + {Value: &Plain{uint8(42)}, ExpectXML: `42`}, + {Value: &Plain{uint16(42)}, ExpectXML: `42`}, + {Value: &Plain{uint32(42)}, ExpectXML: `42`}, + {Value: &Plain{float32(1.25)}, ExpectXML: `1.25`}, + {Value: &Plain{float64(1.25)}, ExpectXML: `1.25`}, + {Value: &Plain{uintptr(0xFFDD)}, ExpectXML: `65501`}, + {Value: &Plain{"gopher"}, ExpectXML: `gopher`}, + {Value: &Plain{[]byte("gopher")}, ExpectXML: `gopher`}, + {Value: &Plain{""}, ExpectXML: `</>`}, + {Value: &Plain{[]byte("")}, ExpectXML: `</>`}, + {Value: &Plain{[3]byte{'<', '/', '>'}}, ExpectXML: `</>`}, + {Value: &Plain{NamedType("potato")}, ExpectXML: `potato`}, + {Value: &Plain{[]int{1, 2, 3}}, ExpectXML: `123`}, + {Value: &Plain{[3]int{1, 2, 3}}, ExpectXML: `123`}, + {Value: ifaceptr(true), MarshalOnly: true, ExpectXML: `true`}, + + // Test time. + { + Value: &Plain{time.Unix(1e9, 123456789).UTC()}, + ExpectXML: `2001-09-09T01:46:40.123456789Z`, + }, + + // A pointer to struct{} may be used to test for an element's presence. + { + Value: &PresenceTest{new(struct{})}, + ExpectXML: ``, + }, + { + Value: &PresenceTest{}, + ExpectXML: ``, + }, + + // A pointer to struct{} may be used to test for an element's presence. + { + Value: &PresenceTest{new(struct{})}, + ExpectXML: ``, + }, + { + Value: &PresenceTest{}, + ExpectXML: ``, + }, + + // A []byte field is only nil if the element was not found. + { + Value: &Data{}, + ExpectXML: ``, + UnmarshalOnly: true, + }, + { + Value: &Data{Bytes: []byte{}, Custom: MyBytes{}, Attr: []byte{}}, + ExpectXML: ``, + UnmarshalOnly: true, + }, + + // Check that []byte works, including named []byte types. + { + Value: &Data{Bytes: []byte("ab"), Custom: MyBytes("cd"), Attr: []byte{'v'}}, + ExpectXML: `abcd`, + }, + + // Test innerxml + { + Value: &SecretAgent{ + Handle: "007", + Identity: "James Bond", + Obfuscate: "", + }, + ExpectXML: `James Bond`, + MarshalOnly: true, + }, + { + Value: &SecretAgent{ + Handle: "007", + Identity: "James Bond", + Obfuscate: "James Bond", + }, + ExpectXML: `James Bond`, + UnmarshalOnly: true, + }, + + // Test structs + {Value: &Port{Type: "ssl", Number: "443"}, ExpectXML: `443`}, + {Value: &Port{Number: "443"}, ExpectXML: `443`}, + {Value: &Port{Type: ""}, ExpectXML: ``}, + {Value: &Port{Number: "443", Comment: "https"}, ExpectXML: `443`}, + {Value: &Port{Number: "443", Comment: "add space-"}, ExpectXML: `443`, MarshalOnly: true}, + {Value: &Domain{Name: []byte("google.com&friends")}, ExpectXML: `google.com&friends`}, + {Value: &Domain{Name: []byte("google.com"), Comment: []byte(" &friends ")}, ExpectXML: `google.com`}, + {Value: &Book{Title: "Pride & Prejudice"}, ExpectXML: `Pride & Prejudice`}, + {Value: &Event{Year: -3114}, ExpectXML: `-3114`}, + {Value: &Movie{Length: 13440}, ExpectXML: `13440`}, + {Value: &Pi{Approximation: 3.14159265}, ExpectXML: `3.1415927`}, + {Value: &Universe{Visible: 9.3e13}, ExpectXML: `9.3e+13`}, + {Value: &Particle{HasMass: true}, ExpectXML: `true`}, + {Value: &Departure{When: ParseTime("2013-01-09T00:15:00-09:00")}, ExpectXML: `2013-01-09T00:15:00-09:00`}, + {Value: atomValue, ExpectXML: atomXml}, + { + Value: &Ship{ + Name: "Heart of Gold", + Pilot: "Computer", + Age: 1, + Drive: ImprobabilityDrive, + Passenger: []*Passenger{ + { + Name: []string{"Zaphod", "Beeblebrox"}, + Weight: 7.25, + }, + { + Name: []string{"Trisha", "McMillen"}, + Weight: 5.5, + }, + { + Name: []string{"Ford", "Prefect"}, + Weight: 7, + }, + { + Name: []string{"Arthur", "Dent"}, + Weight: 6.75, + }, + }, + }, + ExpectXML: `` + + `` + strconv.Itoa(int(ImprobabilityDrive)) + `` + + `1` + + `` + + `Zaphod` + + `Beeblebrox` + + `7.25` + + `` + + `` + + `Trisha` + + `McMillen` + + `5.5` + + `` + + `` + + `Ford` + + `Prefect` + + `7` + + `` + + `` + + `Arthur` + + `Dent` + + `6.75` + + `` + + ``, + }, + + // Test a>b + { + Value: &NestedItems{Items: nil, Item1: nil}, + ExpectXML: `` + + `` + + `` + + ``, + }, + { + Value: &NestedItems{Items: []string{}, Item1: []string{}}, + ExpectXML: `` + + `` + + `` + + ``, + MarshalOnly: true, + }, + { + Value: &NestedItems{Items: nil, Item1: []string{"A"}}, + ExpectXML: `` + + `` + + `A` + + `` + + ``, + }, + { + Value: &NestedItems{Items: []string{"A", "B"}, Item1: nil}, + ExpectXML: `` + + `` + + `A` + + `B` + + `` + + ``, + }, + { + Value: &NestedItems{Items: []string{"A", "B"}, Item1: []string{"C"}}, + ExpectXML: `` + + `` + + `A` + + `B` + + `C` + + `` + + ``, + }, + { + Value: &NestedOrder{Field1: "C", Field2: "B", Field3: "A"}, + ExpectXML: `` + + `` + + `C` + + `B` + + `A` + + `` + + ``, + }, + { + Value: &NilTest{A: "A", B: nil, C: "C"}, + ExpectXML: `` + + `` + + `A` + + `C` + + `` + + ``, + MarshalOnly: true, // Uses interface{} + }, + { + Value: &MixedNested{A: "A", B: "B", C: "C", D: "D"}, + ExpectXML: `` + + `A` + + `B` + + `` + + `C` + + `D` + + `` + + ``, + }, + { + Value: &Service{Port: &Port{Number: "80"}}, + ExpectXML: `80`, + }, + { + Value: &Service{}, + ExpectXML: ``, + }, + { + Value: &Service{Port: &Port{Number: "80"}, Extra1: "A", Extra2: "B"}, + ExpectXML: `` + + `80` + + `A` + + `B` + + ``, + MarshalOnly: true, + }, + { + Value: &Service{Port: &Port{Number: "80"}, Extra2: "example"}, + ExpectXML: `` + + `80` + + `example` + + ``, + MarshalOnly: true, + }, + { + Value: &struct { + XMLName struct{} `xml:"space top"` + A string `xml:"x>a"` + B string `xml:"x>b"` + C string `xml:"space x>c"` + C1 string `xml:"space1 x>c"` + D1 string `xml:"space1 x>d"` + E1 string `xml:"x>e"` + }{ + A: "a", + B: "b", + C: "c", + C1: "c1", + D1: "d1", + E1: "e1", + }, + ExpectXML: `` + + `abc` + + `` + + `c1` + + `d1` + + `` + + `` + + `e1` + + `` + + ``, + }, + { + Value: &struct { + XMLName Name + A string `xml:"x>a"` + B string `xml:"x>b"` + C string `xml:"space x>c"` + C1 string `xml:"space1 x>c"` + D1 string `xml:"space1 x>d"` + }{ + XMLName: Name{ + Space: "space0", + Local: "top", + }, + A: "a", + B: "b", + C: "c", + C1: "c1", + D1: "d1", + }, + ExpectXML: `` + + `ab` + + `c` + + `` + + `c1` + + `d1` + + `` + + ``, + }, + { + Value: &struct { + XMLName struct{} `xml:"top"` + B string `xml:"space x>b"` + B1 string `xml:"space1 x>b"` + }{ + B: "b", + B1: "b1", + }, + ExpectXML: `` + + `b` + + `b1` + + ``, + }, + + // Test struct embedding + { + Value: &EmbedA{ + EmbedC: EmbedC{ + FieldA1: "", // Shadowed by A.A + FieldA2: "", // Shadowed by A.A + FieldB: "A.C.B", + FieldC: "A.C.C", + }, + EmbedB: EmbedB{ + FieldB: "A.B.B", + EmbedC: &EmbedC{ + FieldA1: "A.B.C.A1", + FieldA2: "A.B.C.A2", + FieldB: "", // Shadowed by A.B.B + FieldC: "A.B.C.C", + }, + }, + FieldA: "A.A", + }, + ExpectXML: `` + + `A.C.B` + + `A.C.C` + + `` + + `A.B.B` + + `` + + `A.B.C.A1` + + `A.B.C.A2` + + `` + + `A.B.C.C` + + `` + + `A.A` + + ``, + }, + + // Test that name casing matters + { + Value: &NameCasing{Xy: "mixed", XY: "upper", XyA: "mixedA", XYA: "upperA"}, + ExpectXML: `mixedupper`, + }, + + // Test the order in which the XML element name is chosen + { + Value: &NamePrecedence{ + FromTag: XMLNameWithoutTag{Value: "A"}, + FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "InXMLName"}, Value: "B"}, + FromNameTag: XMLNameWithTag{Value: "C"}, + InFieldName: "D", + }, + ExpectXML: `` + + `A` + + `B` + + `C` + + `D` + + ``, + MarshalOnly: true, + }, + { + Value: &NamePrecedence{ + XMLName: Name{Local: "Parent"}, + FromTag: XMLNameWithoutTag{XMLName: Name{Local: "InTag"}, Value: "A"}, + FromNameVal: XMLNameWithoutTag{XMLName: Name{Local: "FromNameVal"}, Value: "B"}, + FromNameTag: XMLNameWithTag{XMLName: Name{Local: "InXMLNameTag"}, Value: "C"}, + InFieldName: "D", + }, + ExpectXML: `` + + `A` + + `B` + + `C` + + `D` + + ``, + UnmarshalOnly: true, + }, + + // xml.Name works in a plain field as well. + { + Value: &NameInField{Name{Space: "ns", Local: "foo"}}, + ExpectXML: ``, + }, + { + Value: &NameInField{Name{Space: "ns", Local: "foo"}}, + ExpectXML: ``, + UnmarshalOnly: true, + }, + + // Marshaling zero xml.Name uses the tag or field name. + { + Value: &NameInField{}, + ExpectXML: ``, + MarshalOnly: true, + }, + + // Test attributes + { + Value: &AttrTest{ + Int: 8, + Named: 9, + Float: 23.5, + Uint8: 255, + Bool: true, + Str: "str", + Bytes: []byte("byt"), + }, + ExpectXML: ``, + }, + { + Value: &AttrTest{Bytes: []byte{}}, + ExpectXML: ``, + }, + { + Value: &OmitAttrTest{ + Int: 8, + Named: 9, + Float: 23.5, + Uint8: 255, + Bool: true, + Str: "str", + Bytes: []byte("byt"), + }, + ExpectXML: ``, + }, + { + Value: &OmitAttrTest{}, + ExpectXML: ``, + }, + + // pointer fields + { + Value: &PointerFieldsTest{Name: &nameAttr, Age: &ageAttr, Contents: &contentsAttr}, + ExpectXML: `lorem ipsum`, + MarshalOnly: true, + }, + + // empty chardata pointer field + { + Value: &ChardataEmptyTest{}, + ExpectXML: ``, + MarshalOnly: true, + }, + + // omitempty on fields + { + Value: &OmitFieldTest{ + Int: 8, + Named: 9, + Float: 23.5, + Uint8: 255, + Bool: true, + Str: "str", + Bytes: []byte("byt"), + Ptr: &PresenceTest{}, + }, + ExpectXML: `` + + `8` + + `9` + + `23.5` + + `255` + + `true` + + `str` + + `byt` + + `` + + ``, + }, + { + Value: &OmitFieldTest{}, + ExpectXML: ``, + }, + + // Test ",any" + { + ExpectXML: `knownunknown`, + Value: &AnyTest{ + Nested: "known", + AnyField: AnyHolder{ + XMLName: Name{Local: "other"}, + XML: "unknown", + }, + }, + }, + { + Value: &AnyTest{Nested: "known", + AnyField: AnyHolder{ + XML: "", + XMLName: Name{Local: "AnyField"}, + }, + }, + ExpectXML: `known`, + }, + { + ExpectXML: `b`, + Value: &AnyOmitTest{ + Nested: "b", + }, + }, + { + ExpectXML: `bei`, + Value: &AnySliceTest{ + Nested: "b", + AnyField: []AnyHolder{ + { + XMLName: Name{Local: "c"}, + XML: "e", + }, + { + XMLName: Name{Space: "f", Local: "g"}, + XML: "i", + }, + }, + }, + }, + { + ExpectXML: `b`, + Value: &AnySliceTest{ + Nested: "b", + }, + }, + + // Test recursive types. + { + Value: &RecurseA{ + A: "a1", + B: &RecurseB{ + A: &RecurseA{"a2", nil}, + B: "b1", + }, + }, + ExpectXML: `a1a2b1`, + }, + + // Test ignoring fields via "-" tag + { + ExpectXML: ``, + Value: &IgnoreTest{}, + }, + { + ExpectXML: ``, + Value: &IgnoreTest{PublicSecret: "can't tell"}, + MarshalOnly: true, + }, + { + ExpectXML: `ignore me`, + Value: &IgnoreTest{}, + UnmarshalOnly: true, + }, + + // Test escaping. + { + ExpectXML: `dquote: "; squote: '; ampersand: &; less: <; greater: >;`, + Value: &AnyTest{ + Nested: `dquote: "; squote: '; ampersand: &; less: <; greater: >;`, + AnyField: AnyHolder{XMLName: Name{Local: "empty"}}, + }, + }, + { + ExpectXML: `newline: ; cr: ; tab: ;`, + Value: &AnyTest{ + Nested: "newline: \n; cr: \r; tab: \t;", + AnyField: AnyHolder{XMLName: Name{Local: "AnyField"}}, + }, + }, + { + ExpectXML: "1\r2\r\n3\n\r4\n5", + Value: &AnyTest{ + Nested: "1\n2\n3\n\n4\n5", + }, + UnmarshalOnly: true, + }, + { + ExpectXML: `42`, + Value: &EmbedInt{ + MyInt: 42, + }, + }, + // Test omitempty with parent chain; see golang.org/issue/4168. + { + ExpectXML: ``, + Value: &Strings{}, + }, + // Custom marshalers. + { + ExpectXML: `hello world`, + Value: &MyMarshalerTest{}, + }, + { + ExpectXML: ``, + Value: &MarshalerStruct{}, + }, + { + ExpectXML: ``, + Value: &MarshalerValueStruct{}, + }, + { + ExpectXML: ``, + Value: &OuterStruct{IntAttr: 10}, + }, + { + ExpectXML: ``, + Value: &OuterNamedStruct{XMLName: Name{Space: "outerns", Local: "test"}, IntAttr: 10}, + }, + { + ExpectXML: ``, + Value: &OuterNamedOrderedStruct{XMLName: Name{Space: "outerns", Local: "test"}, IntAttr: 10}, + }, + { + ExpectXML: ``, + Value: &OuterOuterStruct{OuterStruct{IntAttr: 10}}, + }, + { + ExpectXML: `test`, + Value: &NestedAndChardata{AB: make([]string, 2), Chardata: "test"}, + }, + { + ExpectXML: ``, + Value: &NestedAndComment{AB: make([]string, 2), Comment: "test"}, + }, + { + ExpectXML: `hello world`, + Value: &XMLNSFieldStruct{Ns: "http://example.com/ns", Body: "hello world"}, + }, + { + ExpectXML: `hello world`, + Value: &NamedXMLNSFieldStruct{Ns: "http://example.com/ns", Body: "hello world"}, + }, + { + ExpectXML: `hello world`, + Value: &NamedXMLNSFieldStruct{Ns: "", Body: "hello world"}, + }, + { + ExpectXML: `hello world`, + Value: &XMLNSFieldStructWithOmitEmpty{Body: "hello world"}, + }, + { + // The xmlns attribute must be ignored because the + // element is in the empty namespace, so it's not possible + // to set the default namespace to something non-empty. + ExpectXML: `hello world`, + Value: &NamedXMLNSFieldStructWithEmptyNamespace{Ns: "foo", Body: "hello world"}, + MarshalOnly: true, + }, + { + ExpectXML: `hello world`, + Value: &RecursiveXMLNSFieldStruct{ + Ns: "foo", + Body: &RecursiveXMLNSFieldStruct{ + Text: "hello world", + }, + }, + }, +} + +func TestMarshal(t *testing.T) { + for idx, test := range marshalTests { + if test.UnmarshalOnly { + continue + } + data, err := Marshal(test.Value) + if err != nil { + t.Errorf("#%d: marshal(%#v): %s", idx, test.Value, err) + continue + } + if got, want := string(data), test.ExpectXML; got != want { + if strings.Contains(want, "\n") { + t.Errorf("#%d: marshal(%#v):\nHAVE:\n%s\nWANT:\n%s", idx, test.Value, got, want) + } else { + t.Errorf("#%d: marshal(%#v):\nhave %#q\nwant %#q", idx, test.Value, got, want) + } + } + } +} + +type AttrParent struct { + X string `xml:"X>Y,attr"` +} + +type BadAttr struct { + Name []string `xml:"name,attr"` +} + +var marshalErrorTests = []struct { + Value interface{} + Err string + Kind reflect.Kind +}{ + { + Value: make(chan bool), + Err: "xml: unsupported type: chan bool", + Kind: reflect.Chan, + }, + { + Value: map[string]string{ + "question": "What do you get when you multiply six by nine?", + "answer": "42", + }, + Err: "xml: unsupported type: map[string]string", + Kind: reflect.Map, + }, + { + Value: map[*Ship]bool{nil: false}, + Err: "xml: unsupported type: map[*xml.Ship]bool", + Kind: reflect.Map, + }, + { + Value: &Domain{Comment: []byte("f--bar")}, + Err: `xml: comments must not contain "--"`, + }, + // Reject parent chain with attr, never worked; see golang.org/issue/5033. + { + Value: &AttrParent{}, + Err: `xml: X>Y chain not valid with attr flag`, + }, + { + Value: BadAttr{[]string{"X", "Y"}}, + Err: `xml: unsupported type: []string`, + }, +} + +var marshalIndentTests = []struct { + Value interface{} + Prefix string + Indent string + ExpectXML string +}{ + { + Value: &SecretAgent{ + Handle: "007", + Identity: "James Bond", + Obfuscate: "", + }, + Prefix: "", + Indent: "\t", + ExpectXML: fmt.Sprintf("\n\tJames Bond\n"), + }, +} + +func TestMarshalErrors(t *testing.T) { + for idx, test := range marshalErrorTests { + data, err := Marshal(test.Value) + if err == nil { + t.Errorf("#%d: marshal(%#v) = [success] %q, want error %v", idx, test.Value, data, test.Err) + continue + } + if err.Error() != test.Err { + t.Errorf("#%d: marshal(%#v) = [error] %v, want %v", idx, test.Value, err, test.Err) + } + if test.Kind != reflect.Invalid { + if kind := err.(*UnsupportedTypeError).Type.Kind(); kind != test.Kind { + t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, kind, test.Kind) + } + } + } +} + +// Do invertibility testing on the various structures that we test +func TestUnmarshal(t *testing.T) { + for i, test := range marshalTests { + if test.MarshalOnly { + continue + } + if _, ok := test.Value.(*Plain); ok { + continue + } + vt := reflect.TypeOf(test.Value) + dest := reflect.New(vt.Elem()).Interface() + err := Unmarshal([]byte(test.ExpectXML), dest) + + switch fix := dest.(type) { + case *Feed: + fix.Author.InnerXML = "" + for i := range fix.Entry { + fix.Entry[i].Author.InnerXML = "" + } + } + + if err != nil { + t.Errorf("#%d: unexpected error: %#v", i, err) + } else if got, want := dest, test.Value; !reflect.DeepEqual(got, want) { + t.Errorf("#%d: unmarshal(%q):\nhave %#v\nwant %#v", i, test.ExpectXML, got, want) + } + } +} + +func TestMarshalIndent(t *testing.T) { + for i, test := range marshalIndentTests { + data, err := MarshalIndent(test.Value, test.Prefix, test.Indent) + if err != nil { + t.Errorf("#%d: Error: %s", i, err) + continue + } + if got, want := string(data), test.ExpectXML; got != want { + t.Errorf("#%d: MarshalIndent:\nGot:%s\nWant:\n%s", i, got, want) + } + } +} + +type limitedBytesWriter struct { + w io.Writer + remain int // until writes fail +} + +func (lw *limitedBytesWriter) Write(p []byte) (n int, err error) { + if lw.remain <= 0 { + println("error") + return 0, errors.New("write limit hit") + } + if len(p) > lw.remain { + p = p[:lw.remain] + n, _ = lw.w.Write(p) + lw.remain = 0 + return n, errors.New("write limit hit") + } + n, err = lw.w.Write(p) + lw.remain -= n + return n, err +} + +func TestMarshalWriteErrors(t *testing.T) { + var buf bytes.Buffer + const writeCap = 1024 + w := &limitedBytesWriter{&buf, writeCap} + enc := NewEncoder(w) + var err error + var i int + const n = 4000 + for i = 1; i <= n; i++ { + err = enc.Encode(&Passenger{ + Name: []string{"Alice", "Bob"}, + Weight: 5, + }) + if err != nil { + break + } + } + if err == nil { + t.Error("expected an error") + } + if i == n { + t.Errorf("expected to fail before the end") + } + if buf.Len() != writeCap { + t.Errorf("buf.Len() = %d; want %d", buf.Len(), writeCap) + } +} + +func TestMarshalWriteIOErrors(t *testing.T) { + enc := NewEncoder(errWriter{}) + + expectErr := "unwritable" + err := enc.Encode(&Passenger{}) + if err == nil || err.Error() != expectErr { + t.Errorf("EscapeTest = [error] %v, want %v", err, expectErr) + } +} + +func TestMarshalFlush(t *testing.T) { + var buf bytes.Buffer + enc := NewEncoder(&buf) + if err := enc.EncodeToken(CharData("hello world")); err != nil { + t.Fatalf("enc.EncodeToken: %v", err) + } + if buf.Len() > 0 { + t.Fatalf("enc.EncodeToken caused actual write: %q", buf.Bytes()) + } + if err := enc.Flush(); err != nil { + t.Fatalf("enc.Flush: %v", err) + } + if buf.String() != "hello world" { + t.Fatalf("after enc.Flush, buf.String() = %q, want %q", buf.String(), "hello world") + } +} + +var encodeElementTests = []struct { + desc string + value interface{} + start StartElement + expectXML string +}{{ + desc: "simple string", + value: "hello", + start: StartElement{ + Name: Name{Local: "a"}, + }, + expectXML: `hello`, +}, { + desc: "string with added attributes", + value: "hello", + start: StartElement{ + Name: Name{Local: "a"}, + Attr: []Attr{{ + Name: Name{Local: "x"}, + Value: "y", + }, { + Name: Name{Local: "foo"}, + Value: "bar", + }}, + }, + expectXML: `hello`, +}, { + desc: "start element with default name space", + value: struct { + Foo XMLNameWithNSTag + }{ + Foo: XMLNameWithNSTag{ + Value: "hello", + }, + }, + start: StartElement{ + Name: Name{Space: "ns", Local: "a"}, + Attr: []Attr{{ + Name: Name{Local: "xmlns"}, + // "ns" is the name space defined in XMLNameWithNSTag + Value: "ns", + }}, + }, + expectXML: `hello`, +}, { + desc: "start element in name space with different default name space", + value: struct { + Foo XMLNameWithNSTag + }{ + Foo: XMLNameWithNSTag{ + Value: "hello", + }, + }, + start: StartElement{ + Name: Name{Space: "ns2", Local: "a"}, + Attr: []Attr{{ + Name: Name{Local: "xmlns"}, + // "ns" is the name space defined in XMLNameWithNSTag + Value: "ns", + }}, + }, + expectXML: `hello`, +}, { + desc: "XMLMarshaler with start element with default name space", + value: &MyMarshalerTest{}, + start: StartElement{ + Name: Name{Space: "ns2", Local: "a"}, + Attr: []Attr{{ + Name: Name{Local: "xmlns"}, + // "ns" is the name space defined in XMLNameWithNSTag + Value: "ns", + }}, + }, + expectXML: `hello world`, +}} + +func TestEncodeElement(t *testing.T) { + for idx, test := range encodeElementTests { + var buf bytes.Buffer + enc := NewEncoder(&buf) + err := enc.EncodeElement(test.value, test.start) + if err != nil { + t.Fatalf("enc.EncodeElement: %v", err) + } + err = enc.Flush() + if err != nil { + t.Fatalf("enc.Flush: %v", err) + } + if got, want := buf.String(), test.expectXML; got != want { + t.Errorf("#%d(%s): EncodeElement(%#v, %#v):\nhave %#q\nwant %#q", idx, test.desc, test.value, test.start, got, want) + } + } +} + +func BenchmarkMarshal(b *testing.B) { + b.ReportAllocs() + for i := 0; i < b.N; i++ { + Marshal(atomValue) + } +} + +func BenchmarkUnmarshal(b *testing.B) { + b.ReportAllocs() + xml := []byte(atomXml) + for i := 0; i < b.N; i++ { + Unmarshal(xml, &Feed{}) + } +} + +// golang.org/issue/6556 +func TestStructPointerMarshal(t *testing.T) { + type A struct { + XMLName string `xml:"a"` + B []interface{} + } + type C struct { + XMLName Name + Value string `xml:"value"` + } + + a := new(A) + a.B = append(a.B, &C{ + XMLName: Name{Local: "c"}, + Value: "x", + }) + + b, err := Marshal(a) + if err != nil { + t.Fatal(err) + } + if x := string(b); x != "x" { + t.Fatal(x) + } + var v A + err = Unmarshal(b, &v) + if err != nil { + t.Fatal(err) + } +} + +var encodeTokenTests = []struct { + desc string + toks []Token + want string + err string +}{{ + desc: "start element with name space", + toks: []Token{ + StartElement{Name{"space", "local"}, nil}, + }, + want: ``, +}, { + desc: "start element with no name", + toks: []Token{ + StartElement{Name{"space", ""}, nil}, + }, + err: "xml: start tag with no name", +}, { + desc: "end element with no name", + toks: []Token{ + EndElement{Name{"space", ""}}, + }, + err: "xml: end tag with no name", +}, { + desc: "char data", + toks: []Token{ + CharData("foo"), + }, + want: `foo`, +}, { + desc: "char data with escaped chars", + toks: []Token{ + CharData(" \t\n"), + }, + want: " \n", +}, { + desc: "comment", + toks: []Token{ + Comment("foo"), + }, + want: ``, +}, { + desc: "comment with invalid content", + toks: []Token{ + Comment("foo-->"), + }, + err: "xml: EncodeToken of Comment containing --> marker", +}, { + desc: "proc instruction", + toks: []Token{ + ProcInst{"Target", []byte("Instruction")}, + }, + want: ``, +}, { + desc: "proc instruction with empty target", + toks: []Token{ + ProcInst{"", []byte("Instruction")}, + }, + err: "xml: EncodeToken of ProcInst with invalid Target", +}, { + desc: "proc instruction with bad content", + toks: []Token{ + ProcInst{"", []byte("Instruction?>")}, + }, + err: "xml: EncodeToken of ProcInst with invalid Target", +}, { + desc: "directive", + toks: []Token{ + Directive("foo"), + }, + want: ``, +}, { + desc: "more complex directive", + toks: []Token{ + Directive("DOCTYPE doc [ '> ]"), + }, + want: `'> ]>`, +}, { + desc: "directive instruction with bad name", + toks: []Token{ + Directive("foo>"), + }, + err: "xml: EncodeToken of Directive containing wrong < or > markers", +}, { + desc: "end tag without start tag", + toks: []Token{ + EndElement{Name{"foo", "bar"}}, + }, + err: "xml: end tag without start tag", +}, { + desc: "mismatching end tag local name", + toks: []Token{ + StartElement{Name{"", "foo"}, nil}, + EndElement{Name{"", "bar"}}, + }, + err: "xml: end tag does not match start tag ", + want: ``, +}, { + desc: "mismatching end tag namespace", + toks: []Token{ + StartElement{Name{"space", "foo"}, nil}, + EndElement{Name{"another", "foo"}}, + }, + err: "xml: end tag in namespace another does not match start tag in namespace space", + want: ``, +}, { + desc: "start element with explicit namespace", + toks: []Token{ + StartElement{Name{"space", "local"}, []Attr{ + {Name{"xmlns", "x"}, "space"}, + {Name{"space", "foo"}, "value"}, + }}, + }, + want: ``, +}, { + desc: "start element with explicit namespace and colliding prefix", + toks: []Token{ + StartElement{Name{"space", "local"}, []Attr{ + {Name{"xmlns", "x"}, "space"}, + {Name{"space", "foo"}, "value"}, + {Name{"x", "bar"}, "other"}, + }}, + }, + want: ``, +}, { + desc: "start element using previously defined namespace", + toks: []Token{ + StartElement{Name{"", "local"}, []Attr{ + {Name{"xmlns", "x"}, "space"}, + }}, + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"space", "x"}, "y"}, + }}, + }, + want: ``, +}, { + desc: "nested name space with same prefix", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"xmlns", "x"}, "space1"}, + }}, + StartElement{Name{"", "foo"}, []Attr{ + {Name{"xmlns", "x"}, "space2"}, + }}, + StartElement{Name{"", "foo"}, []Attr{ + {Name{"space1", "a"}, "space1 value"}, + {Name{"space2", "b"}, "space2 value"}, + }}, + EndElement{Name{"", "foo"}}, + EndElement{Name{"", "foo"}}, + StartElement{Name{"", "foo"}, []Attr{ + {Name{"space1", "a"}, "space1 value"}, + {Name{"space2", "b"}, "space2 value"}, + }}, + }, + want: ``, +}, { + desc: "start element defining several prefixes for the same name space", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"xmlns", "a"}, "space"}, + {Name{"xmlns", "b"}, "space"}, + {Name{"space", "x"}, "value"}, + }}, + }, + want: ``, +}, { + desc: "nested element redefines name space", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"xmlns", "x"}, "space"}, + }}, + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"xmlns", "y"}, "space"}, + {Name{"space", "a"}, "value"}, + }}, + }, + want: ``, +}, { + desc: "nested element creates alias for default name space", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + }}, + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"xmlns", "y"}, "space"}, + {Name{"space", "a"}, "value"}, + }}, + }, + want: ``, +}, { + desc: "nested element defines default name space with existing prefix", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"xmlns", "x"}, "space"}, + }}, + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + {Name{"space", "a"}, "value"}, + }}, + }, + want: ``, +}, { + desc: "nested element uses empty attribute name space when default ns defined", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + }}, + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "attr"}, "value"}, + }}, + }, + want: ``, +}, { + desc: "redefine xmlns", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"foo", "xmlns"}, "space"}, + }}, + }, + err: `xml: cannot redefine xmlns attribute prefix`, +}, { + desc: "xmlns with explicit name space #1", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"xml", "xmlns"}, "space"}, + }}, + }, + want: ``, +}, { + desc: "xmlns with explicit name space #2", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{xmlURL, "xmlns"}, "space"}, + }}, + }, + want: ``, +}, { + desc: "empty name space declaration is ignored", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"xmlns", "foo"}, ""}, + }}, + }, + want: ``, +}, { + desc: "attribute with no name is ignored", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"", ""}, "value"}, + }}, + }, + want: ``, +}, { + desc: "namespace URL with non-valid name", + toks: []Token{ + StartElement{Name{"/34", "foo"}, []Attr{ + {Name{"/34", "x"}, "value"}, + }}, + }, + want: `<_:foo xmlns:_="/34" _:x="value">`, +}, { + desc: "nested element resets default namespace to empty", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + }}, + StartElement{Name{"", "foo"}, []Attr{ + {Name{"", "xmlns"}, ""}, + {Name{"", "x"}, "value"}, + {Name{"space", "x"}, "value"}, + }}, + }, + want: ``, +}, { + desc: "nested element requires empty default name space", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + }}, + StartElement{Name{"", "foo"}, nil}, + }, + want: ``, +}, { + desc: "attribute uses name space from xmlns", + toks: []Token{ + StartElement{Name{"some/space", "foo"}, []Attr{ + {Name{"", "attr"}, "value"}, + {Name{"some/space", "other"}, "other value"}, + }}, + }, + want: ``, +}, { + desc: "default name space should not be used by attributes", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + {Name{"xmlns", "bar"}, "space"}, + {Name{"space", "baz"}, "foo"}, + }}, + StartElement{Name{"space", "baz"}, nil}, + EndElement{Name{"space", "baz"}}, + EndElement{Name{"space", "foo"}}, + }, + want: ``, +}, { + desc: "default name space not used by attributes, not explicitly defined", + toks: []Token{ + StartElement{Name{"space", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + {Name{"space", "baz"}, "foo"}, + }}, + StartElement{Name{"space", "baz"}, nil}, + EndElement{Name{"space", "baz"}}, + EndElement{Name{"space", "foo"}}, + }, + want: ``, +}, { + desc: "impossible xmlns declaration", + toks: []Token{ + StartElement{Name{"", "foo"}, []Attr{ + {Name{"", "xmlns"}, "space"}, + }}, + StartElement{Name{"space", "bar"}, []Attr{ + {Name{"space", "attr"}, "value"}, + }}, + }, + want: ``, +}} + +func TestEncodeToken(t *testing.T) { +loop: + for i, tt := range encodeTokenTests { + var buf bytes.Buffer + enc := NewEncoder(&buf) + var err error + for j, tok := range tt.toks { + err = enc.EncodeToken(tok) + if err != nil && j < len(tt.toks)-1 { + t.Errorf("#%d %s token #%d: %v", i, tt.desc, j, err) + continue loop + } + } + errorf := func(f string, a ...interface{}) { + t.Errorf("#%d %s token #%d:%s", i, tt.desc, len(tt.toks)-1, fmt.Sprintf(f, a...)) + } + switch { + case tt.err != "" && err == nil: + errorf(" expected error; got none") + continue + case tt.err == "" && err != nil: + errorf(" got error: %v", err) + continue + case tt.err != "" && err != nil && tt.err != err.Error(): + errorf(" error mismatch; got %v, want %v", err, tt.err) + continue + } + if err := enc.Flush(); err != nil { + errorf(" %v", err) + continue + } + if got := buf.String(); got != tt.want { + errorf("\ngot %v\nwant %v", got, tt.want) + continue + } + } +} + +func TestProcInstEncodeToken(t *testing.T) { + var buf bytes.Buffer + enc := NewEncoder(&buf) + + if err := enc.EncodeToken(ProcInst{"xml", []byte("Instruction")}); err != nil { + t.Fatalf("enc.EncodeToken: expected to be able to encode xml target ProcInst as first token, %s", err) + } + + if err := enc.EncodeToken(ProcInst{"Target", []byte("Instruction")}); err != nil { + t.Fatalf("enc.EncodeToken: expected to be able to add non-xml target ProcInst") + } + + if err := enc.EncodeToken(ProcInst{"xml", []byte("Instruction")}); err == nil { + t.Fatalf("enc.EncodeToken: expected to not be allowed to encode xml target ProcInst when not first token") + } +} + +func TestDecodeEncode(t *testing.T) { + var in, out bytes.Buffer + in.WriteString(` + + + +`) + dec := NewDecoder(&in) + enc := NewEncoder(&out) + for tok, err := dec.Token(); err == nil; tok, err = dec.Token() { + err = enc.EncodeToken(tok) + if err != nil { + t.Fatalf("enc.EncodeToken: Unable to encode token (%#v), %v", tok, err) + } + } +} + +// Issue 9796. Used to fail with GORACE="halt_on_error=1" -race. +func TestRace9796(t *testing.T) { + type A struct{} + type B struct { + C []A `xml:"X>Y"` + } + var wg sync.WaitGroup + for i := 0; i < 2; i++ { + wg.Add(1) + go func() { + Marshal(B{[]A{A{}}}) + wg.Done() + }() + } + wg.Wait() +} + +func TestIsValidDirective(t *testing.T) { + testOK := []string{ + "<>", + "< < > >", + "' '>' >", + " ]>", + " '<' ' doc ANY> ]>", + ">>> a < comment --> [ ] >", + } + testKO := []string{ + "<", + ">", + "", + "< > > < < >", + " -->", + "", + "'", + "", + } + for _, s := range testOK { + if !isValidDirective(Directive(s)) { + t.Errorf("Directive %q is expected to be valid", s) + } + } + for _, s := range testKO { + if isValidDirective(Directive(s)) { + t.Errorf("Directive %q is expected to be invalid", s) + } + } +} + +// Issue 11719. EncodeToken used to silently eat tokens with an invalid type. +func TestSimpleUseOfEncodeToken(t *testing.T) { + var buf bytes.Buffer + enc := NewEncoder(&buf) + if err := enc.EncodeToken(&StartElement{Name: Name{"", "object1"}}); err == nil { + t.Errorf("enc.EncodeToken: pointer type should be rejected") + } + if err := enc.EncodeToken(&EndElement{Name: Name{"", "object1"}}); err == nil { + t.Errorf("enc.EncodeToken: pointer type should be rejected") + } + if err := enc.EncodeToken(StartElement{Name: Name{"", "object2"}}); err != nil { + t.Errorf("enc.EncodeToken: StartElement %s", err) + } + if err := enc.EncodeToken(EndElement{Name: Name{"", "object2"}}); err != nil { + t.Errorf("enc.EncodeToken: EndElement %s", err) + } + if err := enc.EncodeToken(Universe{}); err == nil { + t.Errorf("enc.EncodeToken: invalid type not caught") + } + if err := enc.Flush(); err != nil { + t.Errorf("enc.Flush: %s", err) + } + if buf.Len() == 0 { + t.Errorf("enc.EncodeToken: empty buffer") + } + want := "" + if buf.String() != want { + t.Errorf("enc.EncodeToken: expected %q; got %q", want, buf.String()) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/read.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/read.go new file mode 100644 index 00000000..75b9f2ba --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/read.go @@ -0,0 +1,692 @@ +// Copyright 2009 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 xml + +import ( + "bytes" + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" +) + +// BUG(rsc): Mapping between XML elements and data structures is inherently flawed: +// an XML element is an order-dependent collection of anonymous +// values, while a data structure is an order-independent collection +// of named values. +// See package json for a textual representation more suitable +// to data structures. + +// Unmarshal parses the XML-encoded data and stores the result in +// the value pointed to by v, which must be an arbitrary struct, +// slice, or string. Well-formed data that does not fit into v is +// discarded. +// +// Because Unmarshal uses the reflect package, it can only assign +// to exported (upper case) fields. Unmarshal uses a case-sensitive +// comparison to match XML element names to tag values and struct +// field names. +// +// Unmarshal maps an XML element to a struct using the following rules. +// In the rules, the tag of a field refers to the value associated with the +// key 'xml' in the struct field's tag (see the example above). +// +// * If the struct has a field of type []byte or string with tag +// ",innerxml", Unmarshal accumulates the raw XML nested inside the +// element in that field. The rest of the rules still apply. +// +// * If the struct has a field named XMLName of type xml.Name, +// Unmarshal records the element name in that field. +// +// * If the XMLName field has an associated tag of the form +// "name" or "namespace-URL name", the XML element must have +// the given name (and, optionally, name space) or else Unmarshal +// returns an error. +// +// * If the XML element has an attribute whose name matches a +// struct field name with an associated tag containing ",attr" or +// the explicit name in a struct field tag of the form "name,attr", +// Unmarshal records the attribute value in that field. +// +// * If the XML element contains character data, that data is +// accumulated in the first struct field that has tag ",chardata". +// The struct field may have type []byte or string. +// If there is no such field, the character data is discarded. +// +// * If the XML element contains comments, they are accumulated in +// the first struct field that has tag ",comment". The struct +// field may have type []byte or string. If there is no such +// field, the comments are discarded. +// +// * If the XML element contains a sub-element whose name matches +// the prefix of a tag formatted as "a" or "a>b>c", unmarshal +// will descend into the XML structure looking for elements with the +// given names, and will map the innermost elements to that struct +// field. A tag starting with ">" is equivalent to one starting +// with the field name followed by ">". +// +// * If the XML element contains a sub-element whose name matches +// a struct field's XMLName tag and the struct field has no +// explicit name tag as per the previous rule, unmarshal maps +// the sub-element to that struct field. +// +// * If the XML element contains a sub-element whose name matches a +// field without any mode flags (",attr", ",chardata", etc), Unmarshal +// maps the sub-element to that struct field. +// +// * If the XML element contains a sub-element that hasn't matched any +// of the above rules and the struct has a field with tag ",any", +// unmarshal maps the sub-element to that struct field. +// +// * An anonymous struct field is handled as if the fields of its +// value were part of the outer struct. +// +// * A struct field with tag "-" is never unmarshalled into. +// +// Unmarshal maps an XML element to a string or []byte by saving the +// concatenation of that element's character data in the string or +// []byte. The saved []byte is never nil. +// +// Unmarshal maps an attribute value to a string or []byte by saving +// the value in the string or slice. +// +// Unmarshal maps an XML element to a slice by extending the length of +// the slice and mapping the element to the newly created value. +// +// Unmarshal maps an XML element or attribute value to a bool by +// setting it to the boolean value represented by the string. +// +// Unmarshal maps an XML element or attribute value to an integer or +// floating-point field by setting the field to the result of +// interpreting the string value in decimal. There is no check for +// overflow. +// +// Unmarshal maps an XML element to an xml.Name by recording the +// element name. +// +// Unmarshal maps an XML element to a pointer by setting the pointer +// to a freshly allocated value and then mapping the element to that value. +// +func Unmarshal(data []byte, v interface{}) error { + return NewDecoder(bytes.NewReader(data)).Decode(v) +} + +// Decode works like xml.Unmarshal, except it reads the decoder +// stream to find the start element. +func (d *Decoder) Decode(v interface{}) error { + return d.DecodeElement(v, nil) +} + +// DecodeElement works like xml.Unmarshal except that it takes +// a pointer to the start XML element to decode into v. +// It is useful when a client reads some raw XML tokens itself +// but also wants to defer to Unmarshal for some elements. +func (d *Decoder) DecodeElement(v interface{}, start *StartElement) error { + val := reflect.ValueOf(v) + if val.Kind() != reflect.Ptr { + return errors.New("non-pointer passed to Unmarshal") + } + return d.unmarshal(val.Elem(), start) +} + +// An UnmarshalError represents an error in the unmarshalling process. +type UnmarshalError string + +func (e UnmarshalError) Error() string { return string(e) } + +// Unmarshaler is the interface implemented by objects that can unmarshal +// an XML element description of themselves. +// +// UnmarshalXML decodes a single XML element +// beginning with the given start element. +// If it returns an error, the outer call to Unmarshal stops and +// returns that error. +// UnmarshalXML must consume exactly one XML element. +// One common implementation strategy is to unmarshal into +// a separate value with a layout matching the expected XML +// using d.DecodeElement, and then to copy the data from +// that value into the receiver. +// Another common strategy is to use d.Token to process the +// XML object one token at a time. +// UnmarshalXML may not use d.RawToken. +type Unmarshaler interface { + UnmarshalXML(d *Decoder, start StartElement) error +} + +// UnmarshalerAttr is the interface implemented by objects that can unmarshal +// an XML attribute description of themselves. +// +// UnmarshalXMLAttr decodes a single XML attribute. +// If it returns an error, the outer call to Unmarshal stops and +// returns that error. +// UnmarshalXMLAttr is used only for struct fields with the +// "attr" option in the field tag. +type UnmarshalerAttr interface { + UnmarshalXMLAttr(attr Attr) error +} + +// receiverType returns the receiver type to use in an expression like "%s.MethodName". +func receiverType(val interface{}) string { + t := reflect.TypeOf(val) + if t.Name() != "" { + return t.String() + } + return "(" + t.String() + ")" +} + +// unmarshalInterface unmarshals a single XML element into val. +// start is the opening tag of the element. +func (p *Decoder) unmarshalInterface(val Unmarshaler, start *StartElement) error { + // Record that decoder must stop at end tag corresponding to start. + p.pushEOF() + + p.unmarshalDepth++ + err := val.UnmarshalXML(p, *start) + p.unmarshalDepth-- + if err != nil { + p.popEOF() + return err + } + + if !p.popEOF() { + return fmt.Errorf("xml: %s.UnmarshalXML did not consume entire <%s> element", receiverType(val), start.Name.Local) + } + + return nil +} + +// unmarshalTextInterface unmarshals a single XML element into val. +// The chardata contained in the element (but not its children) +// is passed to the text unmarshaler. +func (p *Decoder) unmarshalTextInterface(val encoding.TextUnmarshaler, start *StartElement) error { + var buf []byte + depth := 1 + for depth > 0 { + t, err := p.Token() + if err != nil { + return err + } + switch t := t.(type) { + case CharData: + if depth == 1 { + buf = append(buf, t...) + } + case StartElement: + depth++ + case EndElement: + depth-- + } + } + return val.UnmarshalText(buf) +} + +// unmarshalAttr unmarshals a single XML attribute into val. +func (p *Decoder) unmarshalAttr(val reflect.Value, attr Attr) error { + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + + if val.CanInterface() && val.Type().Implements(unmarshalerAttrType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return val.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(unmarshalerAttrType) { + return pv.Interface().(UnmarshalerAttr).UnmarshalXMLAttr(attr) + } + } + + // Not an UnmarshalerAttr; try encoding.TextUnmarshaler. + if val.CanInterface() && val.Type().Implements(textUnmarshalerType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return val.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) + } + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + return pv.Interface().(encoding.TextUnmarshaler).UnmarshalText([]byte(attr.Value)) + } + } + + copyValue(val, []byte(attr.Value)) + return nil +} + +var ( + unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem() + unmarshalerAttrType = reflect.TypeOf((*UnmarshalerAttr)(nil)).Elem() + textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() +) + +// Unmarshal a single XML element into val. +func (p *Decoder) unmarshal(val reflect.Value, start *StartElement) error { + // Find start element if we need it. + if start == nil { + for { + tok, err := p.Token() + if err != nil { + return err + } + if t, ok := tok.(StartElement); ok { + start = &t + break + } + } + } + + // Load value from interface, but only if the result will be + // usefully addressable. + if val.Kind() == reflect.Interface && !val.IsNil() { + e := val.Elem() + if e.Kind() == reflect.Ptr && !e.IsNil() { + val = e + } + } + + if val.Kind() == reflect.Ptr { + if val.IsNil() { + val.Set(reflect.New(val.Type().Elem())) + } + val = val.Elem() + } + + if val.CanInterface() && val.Type().Implements(unmarshalerType) { + // This is an unmarshaler with a non-pointer receiver, + // so it's likely to be incorrect, but we do what we're told. + return p.unmarshalInterface(val.Interface().(Unmarshaler), start) + } + + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(unmarshalerType) { + return p.unmarshalInterface(pv.Interface().(Unmarshaler), start) + } + } + + if val.CanInterface() && val.Type().Implements(textUnmarshalerType) { + return p.unmarshalTextInterface(val.Interface().(encoding.TextUnmarshaler), start) + } + + if val.CanAddr() { + pv := val.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + return p.unmarshalTextInterface(pv.Interface().(encoding.TextUnmarshaler), start) + } + } + + var ( + data []byte + saveData reflect.Value + comment []byte + saveComment reflect.Value + saveXML reflect.Value + saveXMLIndex int + saveXMLData []byte + saveAny reflect.Value + sv reflect.Value + tinfo *typeInfo + err error + ) + + switch v := val; v.Kind() { + default: + return errors.New("unknown type " + v.Type().String()) + + case reflect.Interface: + // TODO: For now, simply ignore the field. In the near + // future we may choose to unmarshal the start + // element on it, if not nil. + return p.Skip() + + case reflect.Slice: + typ := v.Type() + if typ.Elem().Kind() == reflect.Uint8 { + // []byte + saveData = v + break + } + + // Slice of element values. + // Grow slice. + n := v.Len() + if n >= v.Cap() { + ncap := 2 * n + if ncap < 4 { + ncap = 4 + } + new := reflect.MakeSlice(typ, n, ncap) + reflect.Copy(new, v) + v.Set(new) + } + v.SetLen(n + 1) + + // Recur to read element into slice. + if err := p.unmarshal(v.Index(n), start); err != nil { + v.SetLen(n) + return err + } + return nil + + case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr, reflect.String: + saveData = v + + case reflect.Struct: + typ := v.Type() + if typ == nameType { + v.Set(reflect.ValueOf(start.Name)) + break + } + + sv = v + tinfo, err = getTypeInfo(typ) + if err != nil { + return err + } + + // Validate and assign element name. + if tinfo.xmlname != nil { + finfo := tinfo.xmlname + if finfo.name != "" && finfo.name != start.Name.Local { + return UnmarshalError("expected element type <" + finfo.name + "> but have <" + start.Name.Local + ">") + } + if finfo.xmlns != "" && finfo.xmlns != start.Name.Space { + e := "expected element <" + finfo.name + "> in name space " + finfo.xmlns + " but have " + if start.Name.Space == "" { + e += "no name space" + } else { + e += start.Name.Space + } + return UnmarshalError(e) + } + fv := finfo.value(sv) + if _, ok := fv.Interface().(Name); ok { + fv.Set(reflect.ValueOf(start.Name)) + } + } + + // Assign attributes. + // Also, determine whether we need to save character data or comments. + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + switch finfo.flags & fMode { + case fAttr: + strv := finfo.value(sv) + // Look for attribute. + for _, a := range start.Attr { + if a.Name.Local == finfo.name && (finfo.xmlns == "" || finfo.xmlns == a.Name.Space) { + if err := p.unmarshalAttr(strv, a); err != nil { + return err + } + break + } + } + + case fCharData: + if !saveData.IsValid() { + saveData = finfo.value(sv) + } + + case fComment: + if !saveComment.IsValid() { + saveComment = finfo.value(sv) + } + + case fAny, fAny | fElement: + if !saveAny.IsValid() { + saveAny = finfo.value(sv) + } + + case fInnerXml: + if !saveXML.IsValid() { + saveXML = finfo.value(sv) + if p.saved == nil { + saveXMLIndex = 0 + p.saved = new(bytes.Buffer) + } else { + saveXMLIndex = p.savedOffset() + } + } + } + } + } + + // Find end element. + // Process sub-elements along the way. +Loop: + for { + var savedOffset int + if saveXML.IsValid() { + savedOffset = p.savedOffset() + } + tok, err := p.Token() + if err != nil { + return err + } + switch t := tok.(type) { + case StartElement: + consumed := false + if sv.IsValid() { + consumed, err = p.unmarshalPath(tinfo, sv, nil, &t) + if err != nil { + return err + } + if !consumed && saveAny.IsValid() { + consumed = true + if err := p.unmarshal(saveAny, &t); err != nil { + return err + } + } + } + if !consumed { + if err := p.Skip(); err != nil { + return err + } + } + + case EndElement: + if saveXML.IsValid() { + saveXMLData = p.saved.Bytes()[saveXMLIndex:savedOffset] + if saveXMLIndex == 0 { + p.saved = nil + } + } + break Loop + + case CharData: + if saveData.IsValid() { + data = append(data, t...) + } + + case Comment: + if saveComment.IsValid() { + comment = append(comment, t...) + } + } + } + + if saveData.IsValid() && saveData.CanInterface() && saveData.Type().Implements(textUnmarshalerType) { + if err := saveData.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return err + } + saveData = reflect.Value{} + } + + if saveData.IsValid() && saveData.CanAddr() { + pv := saveData.Addr() + if pv.CanInterface() && pv.Type().Implements(textUnmarshalerType) { + if err := pv.Interface().(encoding.TextUnmarshaler).UnmarshalText(data); err != nil { + return err + } + saveData = reflect.Value{} + } + } + + if err := copyValue(saveData, data); err != nil { + return err + } + + switch t := saveComment; t.Kind() { + case reflect.String: + t.SetString(string(comment)) + case reflect.Slice: + t.Set(reflect.ValueOf(comment)) + } + + switch t := saveXML; t.Kind() { + case reflect.String: + t.SetString(string(saveXMLData)) + case reflect.Slice: + t.Set(reflect.ValueOf(saveXMLData)) + } + + return nil +} + +func copyValue(dst reflect.Value, src []byte) (err error) { + dst0 := dst + + if dst.Kind() == reflect.Ptr { + if dst.IsNil() { + dst.Set(reflect.New(dst.Type().Elem())) + } + dst = dst.Elem() + } + + // Save accumulated data. + switch dst.Kind() { + case reflect.Invalid: + // Probably a comment. + default: + return errors.New("cannot unmarshal into " + dst0.Type().String()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + itmp, err := strconv.ParseInt(string(src), 10, dst.Type().Bits()) + if err != nil { + return err + } + dst.SetInt(itmp) + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + utmp, err := strconv.ParseUint(string(src), 10, dst.Type().Bits()) + if err != nil { + return err + } + dst.SetUint(utmp) + case reflect.Float32, reflect.Float64: + ftmp, err := strconv.ParseFloat(string(src), dst.Type().Bits()) + if err != nil { + return err + } + dst.SetFloat(ftmp) + case reflect.Bool: + value, err := strconv.ParseBool(strings.TrimSpace(string(src))) + if err != nil { + return err + } + dst.SetBool(value) + case reflect.String: + dst.SetString(string(src)) + case reflect.Slice: + if len(src) == 0 { + // non-nil to flag presence + src = []byte{} + } + dst.SetBytes(src) + } + return nil +} + +// unmarshalPath walks down an XML structure looking for wanted +// paths, and calls unmarshal on them. +// The consumed result tells whether XML elements have been consumed +// from the Decoder until start's matching end element, or if it's +// still untouched because start is uninteresting for sv's fields. +func (p *Decoder) unmarshalPath(tinfo *typeInfo, sv reflect.Value, parents []string, start *StartElement) (consumed bool, err error) { + recurse := false +Loop: + for i := range tinfo.fields { + finfo := &tinfo.fields[i] + if finfo.flags&fElement == 0 || len(finfo.parents) < len(parents) || finfo.xmlns != "" && finfo.xmlns != start.Name.Space { + continue + } + for j := range parents { + if parents[j] != finfo.parents[j] { + continue Loop + } + } + if len(finfo.parents) == len(parents) && finfo.name == start.Name.Local { + // It's a perfect match, unmarshal the field. + return true, p.unmarshal(finfo.value(sv), start) + } + if len(finfo.parents) > len(parents) && finfo.parents[len(parents)] == start.Name.Local { + // It's a prefix for the field. Break and recurse + // since it's not ok for one field path to be itself + // the prefix for another field path. + recurse = true + + // We can reuse the same slice as long as we + // don't try to append to it. + parents = finfo.parents[:len(parents)+1] + break + } + } + if !recurse { + // We have no business with this element. + return false, nil + } + // The element is not a perfect match for any field, but one + // or more fields have the path to this element as a parent + // prefix. Recurse and attempt to match these. + for { + var tok Token + tok, err = p.Token() + if err != nil { + return true, err + } + switch t := tok.(type) { + case StartElement: + consumed2, err := p.unmarshalPath(tinfo, sv, parents, &t) + if err != nil { + return true, err + } + if !consumed2 { + if err := p.Skip(); err != nil { + return true, err + } + } + case EndElement: + return true, nil + } + } +} + +// Skip reads tokens until it has consumed the end element +// matching the most recent start element already consumed. +// It recurs if it encounters a start element, so it can be used to +// skip nested structures. +// It returns nil if it finds an end element matching the start +// element; otherwise it returns an error describing the problem. +func (d *Decoder) Skip() error { + for { + tok, err := d.Token() + if err != nil { + return err + } + switch tok.(type) { + case StartElement: + if err := d.Skip(); err != nil { + return err + } + case EndElement: + return nil + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/read_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/read_test.go new file mode 100644 index 00000000..02f1e10c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/read_test.go @@ -0,0 +1,744 @@ +// Copyright 2009 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 xml + +import ( + "bytes" + "fmt" + "io" + "reflect" + "strings" + "testing" + "time" +) + +// Stripped down Atom feed data structures. + +func TestUnmarshalFeed(t *testing.T) { + var f Feed + if err := Unmarshal([]byte(atomFeedString), &f); err != nil { + t.Fatalf("Unmarshal: %s", err) + } + if !reflect.DeepEqual(f, atomFeed) { + t.Fatalf("have %#v\nwant %#v", f, atomFeed) + } +} + +// hget http://codereview.appspot.com/rss/mine/rsc +const atomFeedString = ` + +Code Review - My issueshttp://codereview.appspot.com/rietveld<>rietveld: an attempt at pubsubhubbub +2009-10-04T01:35:58+00:00email-address-removedurn:md5:134d9179c41f806be79b3a5f7877d19a + An attempt at adding pubsubhubbub support to Rietveld. +http://code.google.com/p/pubsubhubbub +http://code.google.com/p/rietveld/issues/detail?id=155 + +The server side of the protocol is trivial: + 1. add a &lt;link rel=&quot;hub&quot; href=&quot;hub-server&quot;&gt; tag to all + feeds that will be pubsubhubbubbed. + 2. every time one of those feeds changes, tell the hub + with a simple POST request. + +I have tested this by adding debug prints to a local hub +server and checking that the server got the right publish +requests. + +I can&#39;t quite get the server to work, but I think the bug +is not in my code. I think that the server expects to be +able to grab the feed and see the feed&#39;s actual URL in +the link rel=&quot;self&quot;, but the default value for that drops +the :port from the URL, and I cannot for the life of me +figure out how to get the Atom generator deep inside +django not to do that, or even where it is doing that, +or even what code is running to generate the Atom feed. +(I thought I knew but I added some assert False statements +and it kept running!) + +Ignoring that particular problem, I would appreciate +feedback on the right way to get the two values at +the top of feeds.py marked NOTE(rsc). + + +rietveld: correct tab handling +2009-10-03T23:02:17+00:00email-address-removedurn:md5:0a2a4f19bb815101f0ba2904aed7c35a + This fixes the buggy tab rendering that can be seen at +http://codereview.appspot.com/116075/diff/1/2 + +The fundamental problem was that the tab code was +not being told what column the text began in, so it +didn&#39;t know where to put the tab stops. Another problem +was that some of the code assumed that string byte +offsets were the same as column offsets, which is only +true if there are no tabs. + +In the process of fixing this, I cleaned up the arguments +to Fold and ExpandTabs and renamed them Break and +_ExpandTabs so that I could be sure that I found all the +call sites. I also wanted to verify that ExpandTabs was +not being used from outside intra_region_diff.py. + + + ` + +type Feed struct { + XMLName Name `xml:"http://www.w3.org/2005/Atom feed"` + Title string `xml:"title"` + Id string `xml:"id"` + Link []Link `xml:"link"` + Updated time.Time `xml:"updated,attr"` + Author Person `xml:"author"` + Entry []Entry `xml:"entry"` +} + +type Entry struct { + Title string `xml:"title"` + Id string `xml:"id"` + Link []Link `xml:"link"` + Updated time.Time `xml:"updated"` + Author Person `xml:"author"` + Summary Text `xml:"summary"` +} + +type Link struct { + Rel string `xml:"rel,attr,omitempty"` + Href string `xml:"href,attr"` +} + +type Person struct { + Name string `xml:"name"` + URI string `xml:"uri"` + Email string `xml:"email"` + InnerXML string `xml:",innerxml"` +} + +type Text struct { + Type string `xml:"type,attr,omitempty"` + Body string `xml:",chardata"` +} + +var atomFeed = Feed{ + XMLName: Name{"http://www.w3.org/2005/Atom", "feed"}, + Title: "Code Review - My issues", + Link: []Link{ + {Rel: "alternate", Href: "http://codereview.appspot.com/"}, + {Rel: "self", Href: "http://codereview.appspot.com/rss/mine/rsc"}, + }, + Id: "http://codereview.appspot.com/", + Updated: ParseTime("2009-10-04T01:35:58+00:00"), + Author: Person{ + Name: "rietveld<>", + InnerXML: "rietveld<>", + }, + Entry: []Entry{ + { + Title: "rietveld: an attempt at pubsubhubbub\n", + Link: []Link{ + {Rel: "alternate", Href: "http://codereview.appspot.com/126085"}, + }, + Updated: ParseTime("2009-10-04T01:35:58+00:00"), + Author: Person{ + Name: "email-address-removed", + InnerXML: "email-address-removed", + }, + Id: "urn:md5:134d9179c41f806be79b3a5f7877d19a", + Summary: Text{ + Type: "html", + Body: ` + An attempt at adding pubsubhubbub support to Rietveld. +http://code.google.com/p/pubsubhubbub +http://code.google.com/p/rietveld/issues/detail?id=155 + +The server side of the protocol is trivial: + 1. add a <link rel="hub" href="hub-server"> tag to all + feeds that will be pubsubhubbubbed. + 2. every time one of those feeds changes, tell the hub + with a simple POST request. + +I have tested this by adding debug prints to a local hub +server and checking that the server got the right publish +requests. + +I can't quite get the server to work, but I think the bug +is not in my code. I think that the server expects to be +able to grab the feed and see the feed's actual URL in +the link rel="self", but the default value for that drops +the :port from the URL, and I cannot for the life of me +figure out how to get the Atom generator deep inside +django not to do that, or even where it is doing that, +or even what code is running to generate the Atom feed. +(I thought I knew but I added some assert False statements +and it kept running!) + +Ignoring that particular problem, I would appreciate +feedback on the right way to get the two values at +the top of feeds.py marked NOTE(rsc). + + +`, + }, + }, + { + Title: "rietveld: correct tab handling\n", + Link: []Link{ + {Rel: "alternate", Href: "http://codereview.appspot.com/124106"}, + }, + Updated: ParseTime("2009-10-03T23:02:17+00:00"), + Author: Person{ + Name: "email-address-removed", + InnerXML: "email-address-removed", + }, + Id: "urn:md5:0a2a4f19bb815101f0ba2904aed7c35a", + Summary: Text{ + Type: "html", + Body: ` + This fixes the buggy tab rendering that can be seen at +http://codereview.appspot.com/116075/diff/1/2 + +The fundamental problem was that the tab code was +not being told what column the text began in, so it +didn't know where to put the tab stops. Another problem +was that some of the code assumed that string byte +offsets were the same as column offsets, which is only +true if there are no tabs. + +In the process of fixing this, I cleaned up the arguments +to Fold and ExpandTabs and renamed them Break and +_ExpandTabs so that I could be sure that I found all the +call sites. I also wanted to verify that ExpandTabs was +not being used from outside intra_region_diff.py. + + +`, + }, + }, + }, +} + +const pathTestString = ` + + 1 + + + A + + + B + + + C + D + + <_> + E + + + 2 + +` + +type PathTestItem struct { + Value string +} + +type PathTestA struct { + Items []PathTestItem `xml:">Item1"` + Before, After string +} + +type PathTestB struct { + Other []PathTestItem `xml:"Items>Item1"` + Before, After string +} + +type PathTestC struct { + Values1 []string `xml:"Items>Item1>Value"` + Values2 []string `xml:"Items>Item2>Value"` + Before, After string +} + +type PathTestSet struct { + Item1 []PathTestItem +} + +type PathTestD struct { + Other PathTestSet `xml:"Items"` + Before, After string +} + +type PathTestE struct { + Underline string `xml:"Items>_>Value"` + Before, After string +} + +var pathTests = []interface{}{ + &PathTestA{Items: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"}, + &PathTestB{Other: []PathTestItem{{"A"}, {"D"}}, Before: "1", After: "2"}, + &PathTestC{Values1: []string{"A", "C", "D"}, Values2: []string{"B"}, Before: "1", After: "2"}, + &PathTestD{Other: PathTestSet{Item1: []PathTestItem{{"A"}, {"D"}}}, Before: "1", After: "2"}, + &PathTestE{Underline: "E", Before: "1", After: "2"}, +} + +func TestUnmarshalPaths(t *testing.T) { + for _, pt := range pathTests { + v := reflect.New(reflect.TypeOf(pt).Elem()).Interface() + if err := Unmarshal([]byte(pathTestString), v); err != nil { + t.Fatalf("Unmarshal: %s", err) + } + if !reflect.DeepEqual(v, pt) { + t.Fatalf("have %#v\nwant %#v", v, pt) + } + } +} + +type BadPathTestA struct { + First string `xml:"items>item1"` + Other string `xml:"items>item2"` + Second string `xml:"items"` +} + +type BadPathTestB struct { + Other string `xml:"items>item2>value"` + First string `xml:"items>item1"` + Second string `xml:"items>item1>value"` +} + +type BadPathTestC struct { + First string + Second string `xml:"First"` +} + +type BadPathTestD struct { + BadPathEmbeddedA + BadPathEmbeddedB +} + +type BadPathEmbeddedA struct { + First string +} + +type BadPathEmbeddedB struct { + Second string `xml:"First"` +} + +var badPathTests = []struct { + v, e interface{} +}{ + {&BadPathTestA{}, &TagPathError{reflect.TypeOf(BadPathTestA{}), "First", "items>item1", "Second", "items"}}, + {&BadPathTestB{}, &TagPathError{reflect.TypeOf(BadPathTestB{}), "First", "items>item1", "Second", "items>item1>value"}}, + {&BadPathTestC{}, &TagPathError{reflect.TypeOf(BadPathTestC{}), "First", "", "Second", "First"}}, + {&BadPathTestD{}, &TagPathError{reflect.TypeOf(BadPathTestD{}), "First", "", "Second", "First"}}, +} + +func TestUnmarshalBadPaths(t *testing.T) { + for _, tt := range badPathTests { + err := Unmarshal([]byte(pathTestString), tt.v) + if !reflect.DeepEqual(err, tt.e) { + t.Fatalf("Unmarshal with %#v didn't fail properly:\nhave %#v,\nwant %#v", tt.v, err, tt.e) + } + } +} + +const OK = "OK" +const withoutNameTypeData = ` + +` + +type TestThree struct { + XMLName Name `xml:"Test3"` + Attr string `xml:",attr"` +} + +func TestUnmarshalWithoutNameType(t *testing.T) { + var x TestThree + if err := Unmarshal([]byte(withoutNameTypeData), &x); err != nil { + t.Fatalf("Unmarshal: %s", err) + } + if x.Attr != OK { + t.Fatalf("have %v\nwant %v", x.Attr, OK) + } +} + +func TestUnmarshalAttr(t *testing.T) { + type ParamVal struct { + Int int `xml:"int,attr"` + } + + type ParamPtr struct { + Int *int `xml:"int,attr"` + } + + type ParamStringPtr struct { + Int *string `xml:"int,attr"` + } + + x := []byte(``) + + p1 := &ParamPtr{} + if err := Unmarshal(x, p1); err != nil { + t.Fatalf("Unmarshal: %s", err) + } + if p1.Int == nil { + t.Fatalf("Unmarshal failed in to *int field") + } else if *p1.Int != 1 { + t.Fatalf("Unmarshal with %s failed:\nhave %#v,\n want %#v", x, p1.Int, 1) + } + + p2 := &ParamVal{} + if err := Unmarshal(x, p2); err != nil { + t.Fatalf("Unmarshal: %s", err) + } + if p2.Int != 1 { + t.Fatalf("Unmarshal with %s failed:\nhave %#v,\n want %#v", x, p2.Int, 1) + } + + p3 := &ParamStringPtr{} + if err := Unmarshal(x, p3); err != nil { + t.Fatalf("Unmarshal: %s", err) + } + if p3.Int == nil { + t.Fatalf("Unmarshal failed in to *string field") + } else if *p3.Int != "1" { + t.Fatalf("Unmarshal with %s failed:\nhave %#v,\n want %#v", x, p3.Int, 1) + } +} + +type Tables struct { + HTable string `xml:"http://www.w3.org/TR/html4/ table"` + FTable string `xml:"http://www.w3schools.com/furniture table"` +} + +var tables = []struct { + xml string + tab Tables + ns string +}{ + { + xml: `` + + `hello
    ` + + `world
    ` + + `
    `, + tab: Tables{"hello", "world"}, + }, + { + xml: `` + + `world
    ` + + `hello
    ` + + `
    `, + tab: Tables{"hello", "world"}, + }, + { + xml: `` + + `world` + + `hello` + + ``, + tab: Tables{"hello", "world"}, + }, + { + xml: `` + + `bogus
    ` + + `
    `, + tab: Tables{}, + }, + { + xml: `` + + `only
    ` + + `
    `, + tab: Tables{HTable: "only"}, + ns: "http://www.w3.org/TR/html4/", + }, + { + xml: `` + + `only
    ` + + `
    `, + tab: Tables{FTable: "only"}, + ns: "http://www.w3schools.com/furniture", + }, + { + xml: `` + + `only
    ` + + `
    `, + tab: Tables{}, + ns: "something else entirely", + }, +} + +func TestUnmarshalNS(t *testing.T) { + for i, tt := range tables { + var dst Tables + var err error + if tt.ns != "" { + d := NewDecoder(strings.NewReader(tt.xml)) + d.DefaultSpace = tt.ns + err = d.Decode(&dst) + } else { + err = Unmarshal([]byte(tt.xml), &dst) + } + if err != nil { + t.Errorf("#%d: Unmarshal: %v", i, err) + continue + } + want := tt.tab + if dst != want { + t.Errorf("#%d: dst=%+v, want %+v", i, dst, want) + } + } +} + +func TestRoundTrip(t *testing.T) { + // From issue 7535 + const s = `` + in := bytes.NewBufferString(s) + for i := 0; i < 10; i++ { + out := &bytes.Buffer{} + d := NewDecoder(in) + e := NewEncoder(out) + + for { + t, err := d.Token() + if err == io.EOF { + break + } + if err != nil { + fmt.Println("failed:", err) + return + } + e.EncodeToken(t) + } + e.Flush() + in = out + } + if got := in.String(); got != s { + t.Errorf("have: %q\nwant: %q\n", got, s) + } +} + +func TestMarshalNS(t *testing.T) { + dst := Tables{"hello", "world"} + data, err := Marshal(&dst) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + want := `hello
    world
    ` + str := string(data) + if str != want { + t.Errorf("have: %q\nwant: %q\n", str, want) + } +} + +type TableAttrs struct { + TAttr TAttr +} + +type TAttr struct { + HTable string `xml:"http://www.w3.org/TR/html4/ table,attr"` + FTable string `xml:"http://www.w3schools.com/furniture table,attr"` + Lang string `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"` + Other1 string `xml:"http://golang.org/xml/ other,attr,omitempty"` + Other2 string `xml:"http://golang.org/xmlfoo/ other,attr,omitempty"` + Other3 string `xml:"http://golang.org/json/ other,attr,omitempty"` + Other4 string `xml:"http://golang.org/2/json/ other,attr,omitempty"` +} + +var tableAttrs = []struct { + xml string + tab TableAttrs + ns string +}{ + { + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: "world"}}, + }, + { + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: "world"}}, + }, + { + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: "world"}}, + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: ""}}, + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "", FTable: "world"}}, + }, + { + xml: ``, + tab: TableAttrs{}, + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "hello", FTable: ""}}, + ns: "http://www.w3schools.com/furniture", + }, + { + // Default space does not apply to attribute names. + xml: ``, + tab: TableAttrs{TAttr{HTable: "", FTable: "world"}}, + ns: "http://www.w3.org/TR/html4/", + }, + { + xml: ``, + tab: TableAttrs{}, + ns: "something else entirely", + }, +} + +func TestUnmarshalNSAttr(t *testing.T) { + for i, tt := range tableAttrs { + var dst TableAttrs + var err error + if tt.ns != "" { + d := NewDecoder(strings.NewReader(tt.xml)) + d.DefaultSpace = tt.ns + err = d.Decode(&dst) + } else { + err = Unmarshal([]byte(tt.xml), &dst) + } + if err != nil { + t.Errorf("#%d: Unmarshal: %v", i, err) + continue + } + want := tt.tab + if dst != want { + t.Errorf("#%d: dst=%+v, want %+v", i, dst, want) + } + } +} + +func TestMarshalNSAttr(t *testing.T) { + src := TableAttrs{TAttr{"hello", "world", "en_US", "other1", "other2", "other3", "other4"}} + data, err := Marshal(&src) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + want := `` + str := string(data) + if str != want { + t.Errorf("Marshal:\nhave: %#q\nwant: %#q\n", str, want) + } + + var dst TableAttrs + if err := Unmarshal(data, &dst); err != nil { + t.Errorf("Unmarshal: %v", err) + } + + if dst != src { + t.Errorf("Unmarshal = %q, want %q", dst, src) + } +} + +type MyCharData struct { + body string +} + +func (m *MyCharData) UnmarshalXML(d *Decoder, start StartElement) error { + for { + t, err := d.Token() + if err == io.EOF { // found end of element + break + } + if err != nil { + return err + } + if char, ok := t.(CharData); ok { + m.body += string(char) + } + } + return nil +} + +var _ Unmarshaler = (*MyCharData)(nil) + +func (m *MyCharData) UnmarshalXMLAttr(attr Attr) error { + panic("must not call") +} + +type MyAttr struct { + attr string +} + +func (m *MyAttr) UnmarshalXMLAttr(attr Attr) error { + m.attr = attr.Value + return nil +} + +var _ UnmarshalerAttr = (*MyAttr)(nil) + +type MyStruct struct { + Data *MyCharData + Attr *MyAttr `xml:",attr"` + + Data2 MyCharData + Attr2 MyAttr `xml:",attr"` +} + +func TestUnmarshaler(t *testing.T) { + xml := ` + + hello world + howdy world + + ` + + var m MyStruct + if err := Unmarshal([]byte(xml), &m); err != nil { + t.Fatal(err) + } + + if m.Data == nil || m.Attr == nil || m.Data.body != "hello world" || m.Attr.attr != "attr1" || m.Data2.body != "howdy world" || m.Attr2.attr != "attr2" { + t.Errorf("m=%#+v\n", m) + } +} + +type Pea struct { + Cotelydon string +} + +type Pod struct { + Pea interface{} `xml:"Pea"` +} + +// https://golang.org/issue/6836 +func TestUnmarshalIntoInterface(t *testing.T) { + pod := new(Pod) + pod.Pea = new(Pea) + xml := `Green stuff` + err := Unmarshal([]byte(xml), pod) + if err != nil { + t.Fatalf("failed to unmarshal %q: %v", xml, err) + } + pea, ok := pod.Pea.(*Pea) + if !ok { + t.Fatalf("unmarshalled into wrong type: have %T want *Pea", pod.Pea) + } + have, want := pea.Cotelydon, "Green stuff" + if have != want { + t.Errorf("failed to unmarshal into interface, have %q want %q", have, want) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/typeinfo.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/typeinfo.go new file mode 100644 index 00000000..c9a6421f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/typeinfo.go @@ -0,0 +1,371 @@ +// 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 xml + +import ( + "fmt" + "reflect" + "strings" + "sync" +) + +// typeInfo holds details for the xml representation of a type. +type typeInfo struct { + xmlname *fieldInfo + fields []fieldInfo +} + +// fieldInfo holds details for the xml representation of a single field. +type fieldInfo struct { + idx []int + name string + xmlns string + flags fieldFlags + parents []string +} + +type fieldFlags int + +const ( + fElement fieldFlags = 1 << iota + fAttr + fCharData + fInnerXml + fComment + fAny + + fOmitEmpty + + fMode = fElement | fAttr | fCharData | fInnerXml | fComment | fAny +) + +var tinfoMap = make(map[reflect.Type]*typeInfo) +var tinfoLock sync.RWMutex + +var nameType = reflect.TypeOf(Name{}) + +// getTypeInfo returns the typeInfo structure with details necessary +// for marshalling and unmarshalling typ. +func getTypeInfo(typ reflect.Type) (*typeInfo, error) { + tinfoLock.RLock() + tinfo, ok := tinfoMap[typ] + tinfoLock.RUnlock() + if ok { + return tinfo, nil + } + tinfo = &typeInfo{} + if typ.Kind() == reflect.Struct && typ != nameType { + n := typ.NumField() + for i := 0; i < n; i++ { + f := typ.Field(i) + if f.PkgPath != "" || f.Tag.Get("xml") == "-" { + continue // Private field + } + + // For embedded structs, embed its fields. + if f.Anonymous { + t := f.Type + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + if t.Kind() == reflect.Struct { + inner, err := getTypeInfo(t) + if err != nil { + return nil, err + } + if tinfo.xmlname == nil { + tinfo.xmlname = inner.xmlname + } + for _, finfo := range inner.fields { + finfo.idx = append([]int{i}, finfo.idx...) + if err := addFieldInfo(typ, tinfo, &finfo); err != nil { + return nil, err + } + } + continue + } + } + + finfo, err := structFieldInfo(typ, &f) + if err != nil { + return nil, err + } + + if f.Name == "XMLName" { + tinfo.xmlname = finfo + continue + } + + // Add the field if it doesn't conflict with other fields. + if err := addFieldInfo(typ, tinfo, finfo); err != nil { + return nil, err + } + } + } + tinfoLock.Lock() + tinfoMap[typ] = tinfo + tinfoLock.Unlock() + return tinfo, nil +} + +// structFieldInfo builds and returns a fieldInfo for f. +func structFieldInfo(typ reflect.Type, f *reflect.StructField) (*fieldInfo, error) { + finfo := &fieldInfo{idx: f.Index} + + // Split the tag from the xml namespace if necessary. + tag := f.Tag.Get("xml") + if i := strings.Index(tag, " "); i >= 0 { + finfo.xmlns, tag = tag[:i], tag[i+1:] + } + + // Parse flags. + tokens := strings.Split(tag, ",") + if len(tokens) == 1 { + finfo.flags = fElement + } else { + tag = tokens[0] + for _, flag := range tokens[1:] { + switch flag { + case "attr": + finfo.flags |= fAttr + case "chardata": + finfo.flags |= fCharData + case "innerxml": + finfo.flags |= fInnerXml + case "comment": + finfo.flags |= fComment + case "any": + finfo.flags |= fAny + case "omitempty": + finfo.flags |= fOmitEmpty + } + } + + // Validate the flags used. + valid := true + switch mode := finfo.flags & fMode; mode { + case 0: + finfo.flags |= fElement + case fAttr, fCharData, fInnerXml, fComment, fAny: + if f.Name == "XMLName" || tag != "" && mode != fAttr { + valid = false + } + default: + // This will also catch multiple modes in a single field. + valid = false + } + if finfo.flags&fMode == fAny { + finfo.flags |= fElement + } + if finfo.flags&fOmitEmpty != 0 && finfo.flags&(fElement|fAttr) == 0 { + valid = false + } + if !valid { + return nil, fmt.Errorf("xml: invalid tag in field %s of type %s: %q", + f.Name, typ, f.Tag.Get("xml")) + } + } + + // Use of xmlns without a name is not allowed. + if finfo.xmlns != "" && tag == "" { + return nil, fmt.Errorf("xml: namespace without name in field %s of type %s: %q", + f.Name, typ, f.Tag.Get("xml")) + } + + if f.Name == "XMLName" { + // The XMLName field records the XML element name. Don't + // process it as usual because its name should default to + // empty rather than to the field name. + finfo.name = tag + return finfo, nil + } + + if tag == "" { + // If the name part of the tag is completely empty, get + // default from XMLName of underlying struct if feasible, + // or field name otherwise. + if xmlname := lookupXMLName(f.Type); xmlname != nil { + finfo.xmlns, finfo.name = xmlname.xmlns, xmlname.name + } else { + finfo.name = f.Name + } + return finfo, nil + } + + if finfo.xmlns == "" && finfo.flags&fAttr == 0 { + // If it's an element no namespace specified, get the default + // from the XMLName of enclosing struct if possible. + if xmlname := lookupXMLName(typ); xmlname != nil { + finfo.xmlns = xmlname.xmlns + } + } + + // Prepare field name and parents. + parents := strings.Split(tag, ">") + if parents[0] == "" { + parents[0] = f.Name + } + if parents[len(parents)-1] == "" { + return nil, fmt.Errorf("xml: trailing '>' in field %s of type %s", f.Name, typ) + } + finfo.name = parents[len(parents)-1] + if len(parents) > 1 { + if (finfo.flags & fElement) == 0 { + return nil, fmt.Errorf("xml: %s chain not valid with %s flag", tag, strings.Join(tokens[1:], ",")) + } + finfo.parents = parents[:len(parents)-1] + } + + // If the field type has an XMLName field, the names must match + // so that the behavior of both marshalling and unmarshalling + // is straightforward and unambiguous. + if finfo.flags&fElement != 0 { + ftyp := f.Type + xmlname := lookupXMLName(ftyp) + if xmlname != nil && xmlname.name != finfo.name { + return nil, fmt.Errorf("xml: name %q in tag of %s.%s conflicts with name %q in %s.XMLName", + finfo.name, typ, f.Name, xmlname.name, ftyp) + } + } + return finfo, nil +} + +// lookupXMLName returns the fieldInfo for typ's XMLName field +// in case it exists and has a valid xml field tag, otherwise +// it returns nil. +func lookupXMLName(typ reflect.Type) (xmlname *fieldInfo) { + for typ.Kind() == reflect.Ptr { + typ = typ.Elem() + } + if typ.Kind() != reflect.Struct { + return nil + } + for i, n := 0, typ.NumField(); i < n; i++ { + f := typ.Field(i) + if f.Name != "XMLName" { + continue + } + finfo, err := structFieldInfo(typ, &f) + if finfo.name != "" && err == nil { + return finfo + } + // Also consider errors as a non-existent field tag + // and let getTypeInfo itself report the error. + break + } + return nil +} + +func min(a, b int) int { + if a <= b { + return a + } + return b +} + +// addFieldInfo adds finfo to tinfo.fields if there are no +// conflicts, or if conflicts arise from previous fields that were +// obtained from deeper embedded structures than finfo. In the latter +// case, the conflicting entries are dropped. +// A conflict occurs when the path (parent + name) to a field is +// itself a prefix of another path, or when two paths match exactly. +// It is okay for field paths to share a common, shorter prefix. +func addFieldInfo(typ reflect.Type, tinfo *typeInfo, newf *fieldInfo) error { + var conflicts []int +Loop: + // First, figure all conflicts. Most working code will have none. + for i := range tinfo.fields { + oldf := &tinfo.fields[i] + if oldf.flags&fMode != newf.flags&fMode { + continue + } + if oldf.xmlns != "" && newf.xmlns != "" && oldf.xmlns != newf.xmlns { + continue + } + minl := min(len(newf.parents), len(oldf.parents)) + for p := 0; p < minl; p++ { + if oldf.parents[p] != newf.parents[p] { + continue Loop + } + } + if len(oldf.parents) > len(newf.parents) { + if oldf.parents[len(newf.parents)] == newf.name { + conflicts = append(conflicts, i) + } + } else if len(oldf.parents) < len(newf.parents) { + if newf.parents[len(oldf.parents)] == oldf.name { + conflicts = append(conflicts, i) + } + } else { + if newf.name == oldf.name { + conflicts = append(conflicts, i) + } + } + } + // Without conflicts, add the new field and return. + if conflicts == nil { + tinfo.fields = append(tinfo.fields, *newf) + return nil + } + + // If any conflict is shallower, ignore the new field. + // This matches the Go field resolution on embedding. + for _, i := range conflicts { + if len(tinfo.fields[i].idx) < len(newf.idx) { + return nil + } + } + + // Otherwise, if any of them is at the same depth level, it's an error. + for _, i := range conflicts { + oldf := &tinfo.fields[i] + if len(oldf.idx) == len(newf.idx) { + f1 := typ.FieldByIndex(oldf.idx) + f2 := typ.FieldByIndex(newf.idx) + return &TagPathError{typ, f1.Name, f1.Tag.Get("xml"), f2.Name, f2.Tag.Get("xml")} + } + } + + // Otherwise, the new field is shallower, and thus takes precedence, + // so drop the conflicting fields from tinfo and append the new one. + for c := len(conflicts) - 1; c >= 0; c-- { + i := conflicts[c] + copy(tinfo.fields[i:], tinfo.fields[i+1:]) + tinfo.fields = tinfo.fields[:len(tinfo.fields)-1] + } + tinfo.fields = append(tinfo.fields, *newf) + return nil +} + +// A TagPathError represents an error in the unmarshalling process +// caused by the use of field tags with conflicting paths. +type TagPathError struct { + Struct reflect.Type + Field1, Tag1 string + Field2, Tag2 string +} + +func (e *TagPathError) Error() string { + return fmt.Sprintf("%s field %q with tag %q conflicts with field %q with tag %q", e.Struct, e.Field1, e.Tag1, e.Field2, e.Tag2) +} + +// value returns v's field value corresponding to finfo. +// It's equivalent to v.FieldByIndex(finfo.idx), but initializes +// and dereferences pointers as necessary. +func (finfo *fieldInfo) value(v reflect.Value) reflect.Value { + for i, x := range finfo.idx { + if i > 0 { + t := v.Type() + if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct { + if v.IsNil() { + v.Set(reflect.New(v.Type().Elem())) + } + v = v.Elem() + } + } + v = v.Field(x) + } + return v +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/xml.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/xml.go new file mode 100644 index 00000000..ffab4a70 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/internal/xml/xml.go @@ -0,0 +1,1998 @@ +// Copyright 2009 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 xml implements a simple XML 1.0 parser that +// understands XML name spaces. +package xml + +// References: +// Annotated XML spec: http://www.xml.com/axml/testaxml.htm +// XML name spaces: http://www.w3.org/TR/REC-xml-names/ + +// TODO(rsc): +// Test error handling. + +import ( + "bufio" + "bytes" + "errors" + "fmt" + "io" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// A SyntaxError represents a syntax error in the XML input stream. +type SyntaxError struct { + Msg string + Line int +} + +func (e *SyntaxError) Error() string { + return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg +} + +// A Name represents an XML name (Local) annotated with a name space +// identifier (Space). In tokens returned by Decoder.Token, the Space +// identifier is given as a canonical URL, not the short prefix used in +// the document being parsed. +// +// As a special case, XML namespace declarations will use the literal +// string "xmlns" for the Space field instead of the fully resolved URL. +// See Encoder.EncodeToken for more information on namespace encoding +// behaviour. +type Name struct { + Space, Local string +} + +// isNamespace reports whether the name is a namespace-defining name. +func (name Name) isNamespace() bool { + return name.Local == "xmlns" || name.Space == "xmlns" +} + +// An Attr represents an attribute in an XML element (Name=Value). +type Attr struct { + Name Name + Value string +} + +// A Token is an interface holding one of the token types: +// StartElement, EndElement, CharData, Comment, ProcInst, or Directive. +type Token interface{} + +// A StartElement represents an XML start element. +type StartElement struct { + Name Name + Attr []Attr +} + +func (e StartElement) Copy() StartElement { + attrs := make([]Attr, len(e.Attr)) + copy(attrs, e.Attr) + e.Attr = attrs + return e +} + +// End returns the corresponding XML end element. +func (e StartElement) End() EndElement { + return EndElement{e.Name} +} + +// setDefaultNamespace sets the namespace of the element +// as the default for all elements contained within it. +func (e *StartElement) setDefaultNamespace() { + if e.Name.Space == "" { + // If there's no namespace on the element, don't + // set the default. Strictly speaking this might be wrong, as + // we can't tell if the element had no namespace set + // or was just using the default namespace. + return + } + // Don't add a default name space if there's already one set. + for _, attr := range e.Attr { + if attr.Name.Space == "" && attr.Name.Local == "xmlns" { + return + } + } + e.Attr = append(e.Attr, Attr{ + Name: Name{ + Local: "xmlns", + }, + Value: e.Name.Space, + }) +} + +// An EndElement represents an XML end element. +type EndElement struct { + Name Name +} + +// A CharData represents XML character data (raw text), +// in which XML escape sequences have been replaced by +// the characters they represent. +type CharData []byte + +func makeCopy(b []byte) []byte { + b1 := make([]byte, len(b)) + copy(b1, b) + return b1 +} + +func (c CharData) Copy() CharData { return CharData(makeCopy(c)) } + +// A Comment represents an XML comment of the form . +// The bytes do not include the comment markers. +type Comment []byte + +func (c Comment) Copy() Comment { return Comment(makeCopy(c)) } + +// A ProcInst represents an XML processing instruction of the form +type ProcInst struct { + Target string + Inst []byte +} + +func (p ProcInst) Copy() ProcInst { + p.Inst = makeCopy(p.Inst) + return p +} + +// A Directive represents an XML directive of the form . +// The bytes do not include the markers. +type Directive []byte + +func (d Directive) Copy() Directive { return Directive(makeCopy(d)) } + +// CopyToken returns a copy of a Token. +func CopyToken(t Token) Token { + switch v := t.(type) { + case CharData: + return v.Copy() + case Comment: + return v.Copy() + case Directive: + return v.Copy() + case ProcInst: + return v.Copy() + case StartElement: + return v.Copy() + } + return t +} + +// A Decoder represents an XML parser reading a particular input stream. +// The parser assumes that its input is encoded in UTF-8. +type Decoder struct { + // Strict defaults to true, enforcing the requirements + // of the XML specification. + // If set to false, the parser allows input containing common + // mistakes: + // * If an element is missing an end tag, the parser invents + // end tags as necessary to keep the return values from Token + // properly balanced. + // * In attribute values and character data, unknown or malformed + // character entities (sequences beginning with &) are left alone. + // + // Setting: + // + // d.Strict = false; + // d.AutoClose = HTMLAutoClose; + // d.Entity = HTMLEntity + // + // creates a parser that can handle typical HTML. + // + // Strict mode does not enforce the requirements of the XML name spaces TR. + // In particular it does not reject name space tags using undefined prefixes. + // Such tags are recorded with the unknown prefix as the name space URL. + Strict bool + + // When Strict == false, AutoClose indicates a set of elements to + // consider closed immediately after they are opened, regardless + // of whether an end element is present. + AutoClose []string + + // Entity can be used to map non-standard entity names to string replacements. + // The parser behaves as if these standard mappings are present in the map, + // regardless of the actual map content: + // + // "lt": "<", + // "gt": ">", + // "amp": "&", + // "apos": "'", + // "quot": `"`, + Entity map[string]string + + // CharsetReader, if non-nil, defines a function to generate + // charset-conversion readers, converting from the provided + // non-UTF-8 charset into UTF-8. If CharsetReader is nil or + // returns an error, parsing stops with an error. One of the + // the CharsetReader's result values must be non-nil. + CharsetReader func(charset string, input io.Reader) (io.Reader, error) + + // DefaultSpace sets the default name space used for unadorned tags, + // as if the entire XML stream were wrapped in an element containing + // the attribute xmlns="DefaultSpace". + DefaultSpace string + + r io.ByteReader + buf bytes.Buffer + saved *bytes.Buffer + stk *stack + free *stack + needClose bool + toClose Name + nextToken Token + nextByte int + ns map[string]string + err error + line int + offset int64 + unmarshalDepth int +} + +// NewDecoder creates a new XML parser reading from r. +// If r does not implement io.ByteReader, NewDecoder will +// do its own buffering. +func NewDecoder(r io.Reader) *Decoder { + d := &Decoder{ + ns: make(map[string]string), + nextByte: -1, + line: 1, + Strict: true, + } + d.switchToReader(r) + return d +} + +// Token returns the next XML token in the input stream. +// At the end of the input stream, Token returns nil, io.EOF. +// +// Slices of bytes in the returned token data refer to the +// parser's internal buffer and remain valid only until the next +// call to Token. To acquire a copy of the bytes, call CopyToken +// or the token's Copy method. +// +// Token expands self-closing elements such as
    +// into separate start and end elements returned by successive calls. +// +// Token guarantees that the StartElement and EndElement +// tokens it returns are properly nested and matched: +// if Token encounters an unexpected end element, +// it will return an error. +// +// Token implements XML name spaces as described by +// http://www.w3.org/TR/REC-xml-names/. Each of the +// Name structures contained in the Token has the Space +// set to the URL identifying its name space when known. +// If Token encounters an unrecognized name space prefix, +// it uses the prefix as the Space rather than report an error. +func (d *Decoder) Token() (t Token, err error) { + if d.stk != nil && d.stk.kind == stkEOF { + err = io.EOF + return + } + if d.nextToken != nil { + t = d.nextToken + d.nextToken = nil + } else if t, err = d.rawToken(); err != nil { + return + } + + if !d.Strict { + if t1, ok := d.autoClose(t); ok { + d.nextToken = t + t = t1 + } + } + switch t1 := t.(type) { + case StartElement: + // In XML name spaces, the translations listed in the + // attributes apply to the element name and + // to the other attribute names, so process + // the translations first. + for _, a := range t1.Attr { + if a.Name.Space == "xmlns" { + v, ok := d.ns[a.Name.Local] + d.pushNs(a.Name.Local, v, ok) + d.ns[a.Name.Local] = a.Value + } + if a.Name.Space == "" && a.Name.Local == "xmlns" { + // Default space for untagged names + v, ok := d.ns[""] + d.pushNs("", v, ok) + d.ns[""] = a.Value + } + } + + d.translate(&t1.Name, true) + for i := range t1.Attr { + d.translate(&t1.Attr[i].Name, false) + } + d.pushElement(t1.Name) + t = t1 + + case EndElement: + d.translate(&t1.Name, true) + if !d.popElement(&t1) { + return nil, d.err + } + t = t1 + } + return +} + +const xmlURL = "http://www.w3.org/XML/1998/namespace" + +// Apply name space translation to name n. +// The default name space (for Space=="") +// applies only to element names, not to attribute names. +func (d *Decoder) translate(n *Name, isElementName bool) { + switch { + case n.Space == "xmlns": + return + case n.Space == "" && !isElementName: + return + case n.Space == "xml": + n.Space = xmlURL + case n.Space == "" && n.Local == "xmlns": + return + } + if v, ok := d.ns[n.Space]; ok { + n.Space = v + } else if n.Space == "" { + n.Space = d.DefaultSpace + } +} + +func (d *Decoder) switchToReader(r io.Reader) { + // Get efficient byte at a time reader. + // Assume that if reader has its own + // ReadByte, it's efficient enough. + // Otherwise, use bufio. + if rb, ok := r.(io.ByteReader); ok { + d.r = rb + } else { + d.r = bufio.NewReader(r) + } +} + +// Parsing state - stack holds old name space translations +// and the current set of open elements. The translations to pop when +// ending a given tag are *below* it on the stack, which is +// more work but forced on us by XML. +type stack struct { + next *stack + kind int + name Name + ok bool +} + +const ( + stkStart = iota + stkNs + stkEOF +) + +func (d *Decoder) push(kind int) *stack { + s := d.free + if s != nil { + d.free = s.next + } else { + s = new(stack) + } + s.next = d.stk + s.kind = kind + d.stk = s + return s +} + +func (d *Decoder) pop() *stack { + s := d.stk + if s != nil { + d.stk = s.next + s.next = d.free + d.free = s + } + return s +} + +// Record that after the current element is finished +// (that element is already pushed on the stack) +// Token should return EOF until popEOF is called. +func (d *Decoder) pushEOF() { + // Walk down stack to find Start. + // It might not be the top, because there might be stkNs + // entries above it. + start := d.stk + for start.kind != stkStart { + start = start.next + } + // The stkNs entries below a start are associated with that + // element too; skip over them. + for start.next != nil && start.next.kind == stkNs { + start = start.next + } + s := d.free + if s != nil { + d.free = s.next + } else { + s = new(stack) + } + s.kind = stkEOF + s.next = start.next + start.next = s +} + +// Undo a pushEOF. +// The element must have been finished, so the EOF should be at the top of the stack. +func (d *Decoder) popEOF() bool { + if d.stk == nil || d.stk.kind != stkEOF { + return false + } + d.pop() + return true +} + +// Record that we are starting an element with the given name. +func (d *Decoder) pushElement(name Name) { + s := d.push(stkStart) + s.name = name +} + +// Record that we are changing the value of ns[local]. +// The old value is url, ok. +func (d *Decoder) pushNs(local string, url string, ok bool) { + s := d.push(stkNs) + s.name.Local = local + s.name.Space = url + s.ok = ok +} + +// Creates a SyntaxError with the current line number. +func (d *Decoder) syntaxError(msg string) error { + return &SyntaxError{Msg: msg, Line: d.line} +} + +// Record that we are ending an element with the given name. +// The name must match the record at the top of the stack, +// which must be a pushElement record. +// After popping the element, apply any undo records from +// the stack to restore the name translations that existed +// before we saw this element. +func (d *Decoder) popElement(t *EndElement) bool { + s := d.pop() + name := t.Name + switch { + case s == nil || s.kind != stkStart: + d.err = d.syntaxError("unexpected end element ") + return false + case s.name.Local != name.Local: + if !d.Strict { + d.needClose = true + d.toClose = t.Name + t.Name = s.name + return true + } + d.err = d.syntaxError("element <" + s.name.Local + "> closed by ") + return false + case s.name.Space != name.Space: + d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space + + "closed by in space " + name.Space) + return false + } + + // Pop stack until a Start or EOF is on the top, undoing the + // translations that were associated with the element we just closed. + for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF { + s := d.pop() + if s.ok { + d.ns[s.name.Local] = s.name.Space + } else { + delete(d.ns, s.name.Local) + } + } + + return true +} + +// If the top element on the stack is autoclosing and +// t is not the end tag, invent the end tag. +func (d *Decoder) autoClose(t Token) (Token, bool) { + if d.stk == nil || d.stk.kind != stkStart { + return nil, false + } + name := strings.ToLower(d.stk.name.Local) + for _, s := range d.AutoClose { + if strings.ToLower(s) == name { + // This one should be auto closed if t doesn't close it. + et, ok := t.(EndElement) + if !ok || et.Name.Local != name { + return EndElement{d.stk.name}, true + } + break + } + } + return nil, false +} + +var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method") + +// RawToken is like Token but does not verify that +// start and end elements match and does not translate +// name space prefixes to their corresponding URLs. +func (d *Decoder) RawToken() (Token, error) { + if d.unmarshalDepth > 0 { + return nil, errRawToken + } + return d.rawToken() +} + +func (d *Decoder) rawToken() (Token, error) { + if d.err != nil { + return nil, d.err + } + if d.needClose { + // The last element we read was self-closing and + // we returned just the StartElement half. + // Return the EndElement half now. + d.needClose = false + return EndElement{d.toClose}, nil + } + + b, ok := d.getc() + if !ok { + return nil, d.err + } + + if b != '<' { + // Text section. + d.ungetc(b) + data := d.text(-1, false) + if data == nil { + return nil, d.err + } + return CharData(data), nil + } + + if b, ok = d.mustgetc(); !ok { + return nil, d.err + } + switch b { + case '/': + // ' { + d.err = d.syntaxError("invalid characters between ") + return nil, d.err + } + return EndElement{name}, nil + + case '?': + // ' { + break + } + b0 = b + } + data := d.buf.Bytes() + data = data[0 : len(data)-2] // chop ?> + + if target == "xml" { + content := string(data) + ver := procInst("version", content) + if ver != "" && ver != "1.0" { + d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver) + return nil, d.err + } + enc := procInst("encoding", content) + if enc != "" && enc != "utf-8" && enc != "UTF-8" { + if d.CharsetReader == nil { + d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc) + return nil, d.err + } + newr, err := d.CharsetReader(enc, d.r.(io.Reader)) + if err != nil { + d.err = fmt.Errorf("xml: opening charset %q: %v", enc, err) + return nil, d.err + } + if newr == nil { + panic("CharsetReader returned a nil Reader for charset " + enc) + } + d.switchToReader(newr) + } + } + return ProcInst{target, data}, nil + + case '!': + // ' { + break + } + b0, b1 = b1, b + } + data := d.buf.Bytes() + data = data[0 : len(data)-3] // chop --> + return Comment(data), nil + + case '[': // . + data := d.text(-1, true) + if data == nil { + return nil, d.err + } + return CharData(data), nil + } + + // Probably a directive: , , etc. + // We don't care, but accumulate for caller. Quoted angle + // brackets do not count for nesting. + d.buf.Reset() + d.buf.WriteByte(b) + inquote := uint8(0) + depth := 0 + for { + if b, ok = d.mustgetc(); !ok { + return nil, d.err + } + if inquote == 0 && b == '>' && depth == 0 { + break + } + HandleB: + d.buf.WriteByte(b) + switch { + case b == inquote: + inquote = 0 + + case inquote != 0: + // in quotes, no special action + + case b == '\'' || b == '"': + inquote = b + + case b == '>' && inquote == 0: + depth-- + + case b == '<' && inquote == 0: + // Look for ` + +var testEntity = map[string]string{"何": "What", "is-it": "is it?"} + +var rawTokens = []Token{ + CharData("\n"), + ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)}, + CharData("\n"), + Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`), + CharData("\n"), + StartElement{Name{"", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}}, + CharData("\n "), + StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}}, + CharData("World <>'\" 白鵬翔"), + EndElement{Name{"", "hello"}}, + CharData("\n "), + StartElement{Name{"", "query"}, []Attr{}}, + CharData("What is it?"), + EndElement{Name{"", "query"}}, + CharData("\n "), + StartElement{Name{"", "goodbye"}, []Attr{}}, + EndElement{Name{"", "goodbye"}}, + CharData("\n "), + StartElement{Name{"", "outer"}, []Attr{{Name{"foo", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}}, + CharData("\n "), + StartElement{Name{"", "inner"}, []Attr{}}, + EndElement{Name{"", "inner"}}, + CharData("\n "), + EndElement{Name{"", "outer"}}, + CharData("\n "), + StartElement{Name{"tag", "name"}, []Attr{}}, + CharData("\n "), + CharData("Some text here."), + CharData("\n "), + EndElement{Name{"tag", "name"}}, + CharData("\n"), + EndElement{Name{"", "body"}}, + Comment(" missing final newline "), +} + +var cookedTokens = []Token{ + CharData("\n"), + ProcInst{"xml", []byte(`version="1.0" encoding="UTF-8"`)}, + CharData("\n"), + Directive(`DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"`), + CharData("\n"), + StartElement{Name{"ns2", "body"}, []Attr{{Name{"xmlns", "foo"}, "ns1"}, {Name{"", "xmlns"}, "ns2"}, {Name{"xmlns", "tag"}, "ns3"}}}, + CharData("\n "), + StartElement{Name{"ns2", "hello"}, []Attr{{Name{"", "lang"}, "en"}}}, + CharData("World <>'\" 白鵬翔"), + EndElement{Name{"ns2", "hello"}}, + CharData("\n "), + StartElement{Name{"ns2", "query"}, []Attr{}}, + CharData("What is it?"), + EndElement{Name{"ns2", "query"}}, + CharData("\n "), + StartElement{Name{"ns2", "goodbye"}, []Attr{}}, + EndElement{Name{"ns2", "goodbye"}}, + CharData("\n "), + StartElement{Name{"ns2", "outer"}, []Attr{{Name{"ns1", "attr"}, "value"}, {Name{"xmlns", "tag"}, "ns4"}}}, + CharData("\n "), + StartElement{Name{"ns2", "inner"}, []Attr{}}, + EndElement{Name{"ns2", "inner"}}, + CharData("\n "), + EndElement{Name{"ns2", "outer"}}, + CharData("\n "), + StartElement{Name{"ns3", "name"}, []Attr{}}, + CharData("\n "), + CharData("Some text here."), + CharData("\n "), + EndElement{Name{"ns3", "name"}}, + CharData("\n"), + EndElement{Name{"ns2", "body"}}, + Comment(" missing final newline "), +} + +const testInputAltEncoding = ` + +VALUE` + +var rawTokensAltEncoding = []Token{ + CharData("\n"), + ProcInst{"xml", []byte(`version="1.0" encoding="x-testing-uppercase"`)}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("value"), + EndElement{Name{"", "tag"}}, +} + +var xmlInput = []string{ + // unexpected EOF cases + "<", + "", + "", + "", + // "", // let the Token() caller handle + "", + "", + "", + "", + " c;", + "", + "", + "", + // "", // let the Token() caller handle + "", + "", + "cdata]]>", +} + +func TestRawToken(t *testing.T) { + d := NewDecoder(strings.NewReader(testInput)) + d.Entity = testEntity + testRawToken(t, d, testInput, rawTokens) +} + +const nonStrictInput = ` +non&entity +&unknown;entity +{ +&#zzz; +&なまえ3; +<-gt; +&; +&0a; +` + +var nonStringEntity = map[string]string{"": "oops!", "0a": "oops!"} + +var nonStrictTokens = []Token{ + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("non&entity"), + EndElement{Name{"", "tag"}}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("&unknown;entity"), + EndElement{Name{"", "tag"}}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("{"), + EndElement{Name{"", "tag"}}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("&#zzz;"), + EndElement{Name{"", "tag"}}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("&なまえ3;"), + EndElement{Name{"", "tag"}}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("<-gt;"), + EndElement{Name{"", "tag"}}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("&;"), + EndElement{Name{"", "tag"}}, + CharData("\n"), + StartElement{Name{"", "tag"}, []Attr{}}, + CharData("&0a;"), + EndElement{Name{"", "tag"}}, + CharData("\n"), +} + +func TestNonStrictRawToken(t *testing.T) { + d := NewDecoder(strings.NewReader(nonStrictInput)) + d.Strict = false + testRawToken(t, d, nonStrictInput, nonStrictTokens) +} + +type downCaser struct { + t *testing.T + r io.ByteReader +} + +func (d *downCaser) ReadByte() (c byte, err error) { + c, err = d.r.ReadByte() + if c >= 'A' && c <= 'Z' { + c += 'a' - 'A' + } + return +} + +func (d *downCaser) Read(p []byte) (int, error) { + d.t.Fatalf("unexpected Read call on downCaser reader") + panic("unreachable") +} + +func TestRawTokenAltEncoding(t *testing.T) { + d := NewDecoder(strings.NewReader(testInputAltEncoding)) + d.CharsetReader = func(charset string, input io.Reader) (io.Reader, error) { + if charset != "x-testing-uppercase" { + t.Fatalf("unexpected charset %q", charset) + } + return &downCaser{t, input.(io.ByteReader)}, nil + } + testRawToken(t, d, testInputAltEncoding, rawTokensAltEncoding) +} + +func TestRawTokenAltEncodingNoConverter(t *testing.T) { + d := NewDecoder(strings.NewReader(testInputAltEncoding)) + token, err := d.RawToken() + if token == nil { + t.Fatalf("expected a token on first RawToken call") + } + if err != nil { + t.Fatal(err) + } + token, err = d.RawToken() + if token != nil { + t.Errorf("expected a nil token; got %#v", token) + } + if err == nil { + t.Fatalf("expected an error on second RawToken call") + } + const encoding = "x-testing-uppercase" + if !strings.Contains(err.Error(), encoding) { + t.Errorf("expected error to contain %q; got error: %v", + encoding, err) + } +} + +func testRawToken(t *testing.T, d *Decoder, raw string, rawTokens []Token) { + lastEnd := int64(0) + for i, want := range rawTokens { + start := d.InputOffset() + have, err := d.RawToken() + end := d.InputOffset() + if err != nil { + t.Fatalf("token %d: unexpected error: %s", i, err) + } + if !reflect.DeepEqual(have, want) { + var shave, swant string + if _, ok := have.(CharData); ok { + shave = fmt.Sprintf("CharData(%q)", have) + } else { + shave = fmt.Sprintf("%#v", have) + } + if _, ok := want.(CharData); ok { + swant = fmt.Sprintf("CharData(%q)", want) + } else { + swant = fmt.Sprintf("%#v", want) + } + t.Errorf("token %d = %s, want %s", i, shave, swant) + } + + // Check that InputOffset returned actual token. + switch { + case start < lastEnd: + t.Errorf("token %d: position [%d,%d) for %T is before previous token", i, start, end, have) + case start >= end: + // Special case: EndElement can be synthesized. + if start == end && end == lastEnd { + break + } + t.Errorf("token %d: position [%d,%d) for %T is empty", i, start, end, have) + case end > int64(len(raw)): + t.Errorf("token %d: position [%d,%d) for %T extends beyond input", i, start, end, have) + default: + text := raw[start:end] + if strings.ContainsAny(text, "<>") && (!strings.HasPrefix(text, "<") || !strings.HasSuffix(text, ">")) { + t.Errorf("token %d: misaligned raw token %#q for %T", i, text, have) + } + } + lastEnd = end + } +} + +// Ensure that directives (specifically !DOCTYPE) include the complete +// text of any nested directives, noting that < and > do not change +// nesting depth if they are in single or double quotes. + +var nestedDirectivesInput = ` +]> +">]> +]> +'>]> +]> +'>]> +]> +` + +var nestedDirectivesTokens = []Token{ + CharData("\n"), + Directive(`DOCTYPE []`), + CharData("\n"), + Directive(`DOCTYPE [">]`), + CharData("\n"), + Directive(`DOCTYPE []`), + CharData("\n"), + Directive(`DOCTYPE ['>]`), + CharData("\n"), + Directive(`DOCTYPE []`), + CharData("\n"), + Directive(`DOCTYPE ['>]`), + CharData("\n"), + Directive(`DOCTYPE []`), + CharData("\n"), +} + +func TestNestedDirectives(t *testing.T) { + d := NewDecoder(strings.NewReader(nestedDirectivesInput)) + + for i, want := range nestedDirectivesTokens { + have, err := d.Token() + if err != nil { + t.Fatalf("token %d: unexpected error: %s", i, err) + } + if !reflect.DeepEqual(have, want) { + t.Errorf("token %d = %#v want %#v", i, have, want) + } + } +} + +func TestToken(t *testing.T) { + d := NewDecoder(strings.NewReader(testInput)) + d.Entity = testEntity + + for i, want := range cookedTokens { + have, err := d.Token() + if err != nil { + t.Fatalf("token %d: unexpected error: %s", i, err) + } + if !reflect.DeepEqual(have, want) { + t.Errorf("token %d = %#v want %#v", i, have, want) + } + } +} + +func TestSyntax(t *testing.T) { + for i := range xmlInput { + d := NewDecoder(strings.NewReader(xmlInput[i])) + var err error + for _, err = d.Token(); err == nil; _, err = d.Token() { + } + if _, ok := err.(*SyntaxError); !ok { + t.Fatalf(`xmlInput "%s": expected SyntaxError not received`, xmlInput[i]) + } + } +} + +type allScalars struct { + True1 bool + True2 bool + False1 bool + False2 bool + Int int + Int8 int8 + Int16 int16 + Int32 int32 + Int64 int64 + Uint int + Uint8 uint8 + Uint16 uint16 + Uint32 uint32 + Uint64 uint64 + Uintptr uintptr + Float32 float32 + Float64 float64 + String string + PtrString *string +} + +var all = allScalars{ + True1: true, + True2: true, + False1: false, + False2: false, + Int: 1, + Int8: -2, + Int16: 3, + Int32: -4, + Int64: 5, + Uint: 6, + Uint8: 7, + Uint16: 8, + Uint32: 9, + Uint64: 10, + Uintptr: 11, + Float32: 13.0, + Float64: 14.0, + String: "15", + PtrString: &sixteen, +} + +var sixteen = "16" + +const testScalarsInput = ` + true + 1 + false + 0 + 1 + -2 + 3 + -4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12.0 + 13.0 + 14.0 + 15 + 16 +` + +func TestAllScalars(t *testing.T) { + var a allScalars + err := Unmarshal([]byte(testScalarsInput), &a) + + if err != nil { + t.Fatal(err) + } + if !reflect.DeepEqual(a, all) { + t.Errorf("have %+v want %+v", a, all) + } +} + +type item struct { + Field_a string +} + +func TestIssue569(t *testing.T) { + data := `abcd` + var i item + err := Unmarshal([]byte(data), &i) + + if err != nil || i.Field_a != "abcd" { + t.Fatal("Expecting abcd") + } +} + +func TestUnquotedAttrs(t *testing.T) { + data := "" + d := NewDecoder(strings.NewReader(data)) + d.Strict = false + token, err := d.Token() + if _, ok := err.(*SyntaxError); ok { + t.Errorf("Unexpected error: %v", err) + } + if token.(StartElement).Name.Local != "tag" { + t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local) + } + attr := token.(StartElement).Attr[0] + if attr.Value != "azAZ09:-_" { + t.Errorf("Unexpected attribute value: %v", attr.Value) + } + if attr.Name.Local != "attr" { + t.Errorf("Unexpected attribute name: %v", attr.Name.Local) + } +} + +func TestValuelessAttrs(t *testing.T) { + tests := [][3]string{ + {"

    ", "p", "nowrap"}, + {"

    ", "p", "nowrap"}, + {"", "input", "checked"}, + {"", "input", "checked"}, + } + for _, test := range tests { + d := NewDecoder(strings.NewReader(test[0])) + d.Strict = false + token, err := d.Token() + if _, ok := err.(*SyntaxError); ok { + t.Errorf("Unexpected error: %v", err) + } + if token.(StartElement).Name.Local != test[1] { + t.Errorf("Unexpected tag name: %v", token.(StartElement).Name.Local) + } + attr := token.(StartElement).Attr[0] + if attr.Value != test[2] { + t.Errorf("Unexpected attribute value: %v", attr.Value) + } + if attr.Name.Local != test[2] { + t.Errorf("Unexpected attribute name: %v", attr.Name.Local) + } + } +} + +func TestCopyTokenCharData(t *testing.T) { + data := []byte("same data") + var tok1 Token = CharData(data) + tok2 := CopyToken(tok1) + if !reflect.DeepEqual(tok1, tok2) { + t.Error("CopyToken(CharData) != CharData") + } + data[1] = 'o' + if reflect.DeepEqual(tok1, tok2) { + t.Error("CopyToken(CharData) uses same buffer.") + } +} + +func TestCopyTokenStartElement(t *testing.T) { + elt := StartElement{Name{"", "hello"}, []Attr{{Name{"", "lang"}, "en"}}} + var tok1 Token = elt + tok2 := CopyToken(tok1) + if tok1.(StartElement).Attr[0].Value != "en" { + t.Error("CopyToken overwrote Attr[0]") + } + if !reflect.DeepEqual(tok1, tok2) { + t.Error("CopyToken(StartElement) != StartElement") + } + tok1.(StartElement).Attr[0] = Attr{Name{"", "lang"}, "de"} + if reflect.DeepEqual(tok1, tok2) { + t.Error("CopyToken(CharData) uses same buffer.") + } +} + +func TestSyntaxErrorLineNum(t *testing.T) { + testInput := "

    Foo

    \n\n

    Bar\n" + d := NewDecoder(strings.NewReader(testInput)) + var err error + for _, err = d.Token(); err == nil; _, err = d.Token() { + } + synerr, ok := err.(*SyntaxError) + if !ok { + t.Error("Expected SyntaxError.") + } + if synerr.Line != 3 { + t.Error("SyntaxError didn't have correct line number.") + } +} + +func TestTrailingRawToken(t *testing.T) { + input := ` ` + d := NewDecoder(strings.NewReader(input)) + var err error + for _, err = d.RawToken(); err == nil; _, err = d.RawToken() { + } + if err != io.EOF { + t.Fatalf("d.RawToken() = _, %v, want _, io.EOF", err) + } +} + +func TestTrailingToken(t *testing.T) { + input := ` ` + d := NewDecoder(strings.NewReader(input)) + var err error + for _, err = d.Token(); err == nil; _, err = d.Token() { + } + if err != io.EOF { + t.Fatalf("d.Token() = _, %v, want _, io.EOF", err) + } +} + +func TestEntityInsideCDATA(t *testing.T) { + input := `` + d := NewDecoder(strings.NewReader(input)) + var err error + for _, err = d.Token(); err == nil; _, err = d.Token() { + } + if err != io.EOF { + t.Fatalf("d.Token() = _, %v, want _, io.EOF", err) + } +} + +var characterTests = []struct { + in string + err string +}{ + {"\x12", "illegal character code U+0012"}, + {"\x0b", "illegal character code U+000B"}, + {"\xef\xbf\xbe", "illegal character code U+FFFE"}, + {"\r\n\x07", "illegal character code U+0007"}, + {"what's up", "expected attribute name in element"}, + {"&abc\x01;", "invalid character entity &abc (no semicolon)"}, + {"&\x01;", "invalid character entity & (no semicolon)"}, + {"&\xef\xbf\xbe;", "invalid character entity &\uFFFE;"}, + {"&hello;", "invalid character entity &hello;"}, +} + +func TestDisallowedCharacters(t *testing.T) { + + for i, tt := range characterTests { + d := NewDecoder(strings.NewReader(tt.in)) + var err error + + for err == nil { + _, err = d.Token() + } + synerr, ok := err.(*SyntaxError) + if !ok { + t.Fatalf("input %d d.Token() = _, %v, want _, *SyntaxError", i, err) + } + if synerr.Msg != tt.err { + t.Fatalf("input %d synerr.Msg wrong: want %q, got %q", i, tt.err, synerr.Msg) + } + } +} + +type procInstEncodingTest struct { + expect, got string +} + +var procInstTests = []struct { + input string + expect [2]string +}{ + {`version="1.0" encoding="utf-8"`, [2]string{"1.0", "utf-8"}}, + {`version="1.0" encoding='utf-8'`, [2]string{"1.0", "utf-8"}}, + {`version="1.0" encoding='utf-8' `, [2]string{"1.0", "utf-8"}}, + {`version="1.0" encoding=utf-8`, [2]string{"1.0", ""}}, + {`encoding="FOO" `, [2]string{"", "FOO"}}, +} + +func TestProcInstEncoding(t *testing.T) { + for _, test := range procInstTests { + if got := procInst("version", test.input); got != test.expect[0] { + t.Errorf("procInst(version, %q) = %q; want %q", test.input, got, test.expect[0]) + } + if got := procInst("encoding", test.input); got != test.expect[1] { + t.Errorf("procInst(encoding, %q) = %q; want %q", test.input, got, test.expect[1]) + } + } +} + +// Ensure that directives with comments include the complete +// text of any nested directives. + +var directivesWithCommentsInput = ` +]> +]> + --> --> []> +` + +var directivesWithCommentsTokens = []Token{ + CharData("\n"), + Directive(`DOCTYPE []`), + CharData("\n"), + Directive(`DOCTYPE []`), + CharData("\n"), + Directive(`DOCTYPE []`), + CharData("\n"), +} + +func TestDirectivesWithComments(t *testing.T) { + d := NewDecoder(strings.NewReader(directivesWithCommentsInput)) + + for i, want := range directivesWithCommentsTokens { + have, err := d.Token() + if err != nil { + t.Fatalf("token %d: unexpected error: %s", i, err) + } + if !reflect.DeepEqual(have, want) { + t.Errorf("token %d = %#v want %#v", i, have, want) + } + } +} + +// Writer whose Write method always returns an error. +type errWriter struct{} + +func (errWriter) Write(p []byte) (n int, err error) { return 0, fmt.Errorf("unwritable") } + +func TestEscapeTextIOErrors(t *testing.T) { + expectErr := "unwritable" + err := EscapeText(errWriter{}, []byte{'A'}) + + if err == nil || err.Error() != expectErr { + t.Errorf("have %v, want %v", err, expectErr) + } +} + +func TestEscapeTextInvalidChar(t *testing.T) { + input := []byte("A \x00 terminated string.") + expected := "A \uFFFD terminated string." + + buff := new(bytes.Buffer) + if err := EscapeText(buff, input); err != nil { + t.Fatalf("have %v, want nil", err) + } + text := buff.String() + + if text != expected { + t.Errorf("have %v, want %v", text, expected) + } +} + +func TestIssue5880(t *testing.T) { + type T []byte + data, err := Marshal(T{192, 168, 0, 1}) + if err != nil { + t.Errorf("Marshal error: %v", err) + } + if !utf8.Valid(data) { + t.Errorf("Marshal generated invalid UTF-8: %x", data) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/litmus_test_server.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/litmus_test_server.go new file mode 100644 index 00000000..514db5dd --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/litmus_test_server.go @@ -0,0 +1,94 @@ +// 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 is a server for the WebDAV 'litmus' compliance test at +http://www.webdav.org/neon/litmus/ +To run the test: + +go run litmus_test_server.go + +and separately, from the downloaded litmus-xxx directory: + +make URL=http://localhost:9999/ check +*/ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "net/url" + + "golang.org/x/net/webdav" +) + +var port = flag.Int("port", 9999, "server port") + +func main() { + flag.Parse() + log.SetFlags(0) + h := &webdav.Handler{ + FileSystem: webdav.NewMemFS(), + LockSystem: webdav.NewMemLS(), + Logger: func(r *http.Request, err error) { + litmus := r.Header.Get("X-Litmus") + if len(litmus) > 19 { + litmus = litmus[:16] + "..." + } + + switch r.Method { + case "COPY", "MOVE": + dst := "" + if u, err := url.Parse(r.Header.Get("Destination")); err == nil { + dst = u.Path + } + o := r.Header.Get("Overwrite") + log.Printf("%-20s%-10s%-30s%-30so=%-2s%v", litmus, r.Method, r.URL.Path, dst, o, err) + default: + log.Printf("%-20s%-10s%-30s%v", litmus, r.Method, r.URL.Path, err) + } + }, + } + + // The next line would normally be: + // http.Handle("/", h) + // but we wrap that HTTP handler h to cater for a special case. + // + // The propfind_invalid2 litmus test case expects an empty namespace prefix + // declaration to be an error. The FAQ in the webdav litmus test says: + // + // "What does the "propfind_invalid2" test check for?... + // + // If a request was sent with an XML body which included an empty namespace + // prefix declaration (xmlns:ns1=""), then the server must reject that with + // a "400 Bad Request" response, as it is invalid according to the XML + // Namespace specification." + // + // On the other hand, the Go standard library's encoding/xml package + // accepts an empty xmlns namespace, as per the discussion at + // https://github.com/golang/go/issues/8068 + // + // Empty namespaces seem disallowed in the second (2006) edition of the XML + // standard, but allowed in a later edition. The grammar differs between + // http://www.w3.org/TR/2006/REC-xml-names-20060816/#ns-decl and + // http://www.w3.org/TR/REC-xml-names/#dt-prefix + // + // Thus, we assume that the propfind_invalid2 test is obsolete, and + // hard-code the 400 Bad Request response that the test expects. + http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("X-Litmus") == "props: 3 (propfind_invalid2)" { + http.Error(w, "400 Bad Request", http.StatusBadRequest) + return + } + h.ServeHTTP(w, r) + })) + + addr := fmt.Sprintf(":%d", *port) + log.Printf("Serving %v", addr) + log.Fatal(http.ListenAndServe(addr, nil)) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/lock.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/lock.go new file mode 100644 index 00000000..344ac5ce --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/lock.go @@ -0,0 +1,445 @@ +// 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. + +package webdav + +import ( + "container/heap" + "errors" + "strconv" + "strings" + "sync" + "time" +) + +var ( + // ErrConfirmationFailed is returned by a LockSystem's Confirm method. + ErrConfirmationFailed = errors.New("webdav: confirmation failed") + // ErrForbidden is returned by a LockSystem's Unlock method. + ErrForbidden = errors.New("webdav: forbidden") + // ErrLocked is returned by a LockSystem's Create, Refresh and Unlock methods. + ErrLocked = errors.New("webdav: locked") + // ErrNoSuchLock is returned by a LockSystem's Refresh and Unlock methods. + ErrNoSuchLock = errors.New("webdav: no such lock") +) + +// Condition can match a WebDAV resource, based on a token or ETag. +// Exactly one of Token and ETag should be non-empty. +type Condition struct { + Not bool + Token string + ETag string +} + +// LockSystem manages access to a collection of named resources. The elements +// in a lock name are separated by slash ('/', U+002F) characters, regardless +// of host operating system convention. +type LockSystem interface { + // Confirm confirms that the caller can claim all of the locks specified by + // the given conditions, and that holding the union of all of those locks + // gives exclusive access to all of the named resources. Up to two resources + // can be named. Empty names are ignored. + // + // Exactly one of release and err will be non-nil. If release is non-nil, + // all of the requested locks are held until release is called. Calling + // release does not unlock the lock, in the WebDAV UNLOCK sense, but once + // Confirm has confirmed that a lock claim is valid, that lock cannot be + // Confirmed again until it has been released. + // + // If Confirm returns ErrConfirmationFailed then the Handler will continue + // to try any other set of locks presented (a WebDAV HTTP request can + // present more than one set of locks). If it returns any other non-nil + // error, the Handler will write a "500 Internal Server Error" HTTP status. + Confirm(now time.Time, name0, name1 string, conditions ...Condition) (release func(), err error) + + // Create creates a lock with the given depth, duration, owner and root + // (name). The depth will either be negative (meaning infinite) or zero. + // + // If Create returns ErrLocked then the Handler will write a "423 Locked" + // HTTP status. If it returns any other non-nil error, the Handler will + // write a "500 Internal Server Error" HTTP status. + // + // See http://www.webdav.org/specs/rfc4918.html#rfc.section.9.10.6 for + // when to use each error. + // + // The token returned identifies the created lock. It should be an absolute + // URI as defined by RFC 3986, Section 4.3. In particular, it should not + // contain whitespace. + Create(now time.Time, details LockDetails) (token string, err error) + + // Refresh refreshes the lock with the given token. + // + // If Refresh returns ErrLocked then the Handler will write a "423 Locked" + // HTTP Status. If Refresh returns ErrNoSuchLock then the Handler will write + // a "412 Precondition Failed" HTTP Status. If it returns any other non-nil + // error, the Handler will write a "500 Internal Server Error" HTTP status. + // + // See http://www.webdav.org/specs/rfc4918.html#rfc.section.9.10.6 for + // when to use each error. + Refresh(now time.Time, token string, duration time.Duration) (LockDetails, error) + + // Unlock unlocks the lock with the given token. + // + // If Unlock returns ErrForbidden then the Handler will write a "403 + // Forbidden" HTTP Status. If Unlock returns ErrLocked then the Handler + // will write a "423 Locked" HTTP status. If Unlock returns ErrNoSuchLock + // then the Handler will write a "409 Conflict" HTTP Status. If it returns + // any other non-nil error, the Handler will write a "500 Internal Server + // Error" HTTP status. + // + // See http://www.webdav.org/specs/rfc4918.html#rfc.section.9.11.1 for + // when to use each error. + Unlock(now time.Time, token string) error +} + +// LockDetails are a lock's metadata. +type LockDetails struct { + // Root is the root resource name being locked. For a zero-depth lock, the + // root is the only resource being locked. + Root string + // Duration is the lock timeout. A negative duration means infinite. + Duration time.Duration + // OwnerXML is the verbatim XML given in a LOCK HTTP request. + // + // TODO: does the "verbatim" nature play well with XML namespaces? + // Does the OwnerXML field need to have more structure? See + // https://codereview.appspot.com/175140043/#msg2 + OwnerXML string + // ZeroDepth is whether the lock has zero depth. If it does not have zero + // depth, it has infinite depth. + ZeroDepth bool +} + +// NewMemLS returns a new in-memory LockSystem. +func NewMemLS() LockSystem { + return &memLS{ + byName: make(map[string]*memLSNode), + byToken: make(map[string]*memLSNode), + gen: uint64(time.Now().Unix()), + } +} + +type memLS struct { + mu sync.Mutex + byName map[string]*memLSNode + byToken map[string]*memLSNode + gen uint64 + // byExpiry only contains those nodes whose LockDetails have a finite + // Duration and are yet to expire. + byExpiry byExpiry +} + +func (m *memLS) nextToken() string { + m.gen++ + return strconv.FormatUint(m.gen, 10) +} + +func (m *memLS) collectExpiredNodes(now time.Time) { + for len(m.byExpiry) > 0 { + if now.Before(m.byExpiry[0].expiry) { + break + } + m.remove(m.byExpiry[0]) + } +} + +func (m *memLS) Confirm(now time.Time, name0, name1 string, conditions ...Condition) (func(), error) { + m.mu.Lock() + defer m.mu.Unlock() + m.collectExpiredNodes(now) + + var n0, n1 *memLSNode + if name0 != "" { + if n0 = m.lookup(slashClean(name0), conditions...); n0 == nil { + return nil, ErrConfirmationFailed + } + } + if name1 != "" { + if n1 = m.lookup(slashClean(name1), conditions...); n1 == nil { + return nil, ErrConfirmationFailed + } + } + + // Don't hold the same node twice. + if n1 == n0 { + n1 = nil + } + + if n0 != nil { + m.hold(n0) + } + if n1 != nil { + m.hold(n1) + } + return func() { + m.mu.Lock() + defer m.mu.Unlock() + if n1 != nil { + m.unhold(n1) + } + if n0 != nil { + m.unhold(n0) + } + }, nil +} + +// lookup returns the node n that locks the named resource, provided that n +// matches at least one of the given conditions and that lock isn't held by +// another party. Otherwise, it returns nil. +// +// n may be a parent of the named resource, if n is an infinite depth lock. +func (m *memLS) lookup(name string, conditions ...Condition) (n *memLSNode) { + // TODO: support Condition.Not and Condition.ETag. + for _, c := range conditions { + n = m.byToken[c.Token] + if n == nil || n.held { + continue + } + if name == n.details.Root { + return n + } + if n.details.ZeroDepth { + continue + } + if n.details.Root == "/" || strings.HasPrefix(name, n.details.Root+"/") { + return n + } + } + return nil +} + +func (m *memLS) hold(n *memLSNode) { + if n.held { + panic("webdav: memLS inconsistent held state") + } + n.held = true + if n.details.Duration >= 0 && n.byExpiryIndex >= 0 { + heap.Remove(&m.byExpiry, n.byExpiryIndex) + } +} + +func (m *memLS) unhold(n *memLSNode) { + if !n.held { + panic("webdav: memLS inconsistent held state") + } + n.held = false + if n.details.Duration >= 0 { + heap.Push(&m.byExpiry, n) + } +} + +func (m *memLS) Create(now time.Time, details LockDetails) (string, error) { + m.mu.Lock() + defer m.mu.Unlock() + m.collectExpiredNodes(now) + details.Root = slashClean(details.Root) + + if !m.canCreate(details.Root, details.ZeroDepth) { + return "", ErrLocked + } + n := m.create(details.Root) + n.token = m.nextToken() + m.byToken[n.token] = n + n.details = details + if n.details.Duration >= 0 { + n.expiry = now.Add(n.details.Duration) + heap.Push(&m.byExpiry, n) + } + return n.token, nil +} + +func (m *memLS) Refresh(now time.Time, token string, duration time.Duration) (LockDetails, error) { + m.mu.Lock() + defer m.mu.Unlock() + m.collectExpiredNodes(now) + + n := m.byToken[token] + if n == nil { + return LockDetails{}, ErrNoSuchLock + } + if n.held { + return LockDetails{}, ErrLocked + } + if n.byExpiryIndex >= 0 { + heap.Remove(&m.byExpiry, n.byExpiryIndex) + } + n.details.Duration = duration + if n.details.Duration >= 0 { + n.expiry = now.Add(n.details.Duration) + heap.Push(&m.byExpiry, n) + } + return n.details, nil +} + +func (m *memLS) Unlock(now time.Time, token string) error { + m.mu.Lock() + defer m.mu.Unlock() + m.collectExpiredNodes(now) + + n := m.byToken[token] + if n == nil { + return ErrNoSuchLock + } + if n.held { + return ErrLocked + } + m.remove(n) + return nil +} + +func (m *memLS) canCreate(name string, zeroDepth bool) bool { + return walkToRoot(name, func(name0 string, first bool) bool { + n := m.byName[name0] + if n == nil { + return true + } + if first { + if n.token != "" { + // The target node is already locked. + return false + } + if !zeroDepth { + // The requested lock depth is infinite, and the fact that n exists + // (n != nil) means that a descendent of the target node is locked. + return false + } + } else if n.token != "" && !n.details.ZeroDepth { + // An ancestor of the target node is locked with infinite depth. + return false + } + return true + }) +} + +func (m *memLS) create(name string) (ret *memLSNode) { + walkToRoot(name, func(name0 string, first bool) bool { + n := m.byName[name0] + if n == nil { + n = &memLSNode{ + details: LockDetails{ + Root: name0, + }, + byExpiryIndex: -1, + } + m.byName[name0] = n + } + n.refCount++ + if first { + ret = n + } + return true + }) + return ret +} + +func (m *memLS) remove(n *memLSNode) { + delete(m.byToken, n.token) + n.token = "" + walkToRoot(n.details.Root, func(name0 string, first bool) bool { + x := m.byName[name0] + x.refCount-- + if x.refCount == 0 { + delete(m.byName, name0) + } + return true + }) + if n.byExpiryIndex >= 0 { + heap.Remove(&m.byExpiry, n.byExpiryIndex) + } +} + +func walkToRoot(name string, f func(name0 string, first bool) bool) bool { + for first := true; ; first = false { + if !f(name, first) { + return false + } + if name == "/" { + break + } + name = name[:strings.LastIndex(name, "/")] + if name == "" { + name = "/" + } + } + return true +} + +type memLSNode struct { + // details are the lock metadata. Even if this node's name is not explicitly locked, + // details.Root will still equal the node's name. + details LockDetails + // token is the unique identifier for this node's lock. An empty token means that + // this node is not explicitly locked. + token string + // refCount is the number of self-or-descendent nodes that are explicitly locked. + refCount int + // expiry is when this node's lock expires. + expiry time.Time + // byExpiryIndex is the index of this node in memLS.byExpiry. It is -1 + // if this node does not expire, or has expired. + byExpiryIndex int + // held is whether this node's lock is actively held by a Confirm call. + held bool +} + +type byExpiry []*memLSNode + +func (b *byExpiry) Len() int { + return len(*b) +} + +func (b *byExpiry) Less(i, j int) bool { + return (*b)[i].expiry.Before((*b)[j].expiry) +} + +func (b *byExpiry) Swap(i, j int) { + (*b)[i], (*b)[j] = (*b)[j], (*b)[i] + (*b)[i].byExpiryIndex = i + (*b)[j].byExpiryIndex = j +} + +func (b *byExpiry) Push(x interface{}) { + n := x.(*memLSNode) + n.byExpiryIndex = len(*b) + *b = append(*b, n) +} + +func (b *byExpiry) Pop() interface{} { + i := len(*b) - 1 + n := (*b)[i] + (*b)[i] = nil + n.byExpiryIndex = -1 + *b = (*b)[:i] + return n +} + +const infiniteTimeout = -1 + +// parseTimeout parses the Timeout HTTP header, as per section 10.7. If s is +// empty, an infiniteTimeout is returned. +func parseTimeout(s string) (time.Duration, error) { + if s == "" { + return infiniteTimeout, nil + } + if i := strings.IndexByte(s, ','); i >= 0 { + s = s[:i] + } + s = strings.TrimSpace(s) + if s == "Infinite" { + return infiniteTimeout, nil + } + const pre = "Second-" + if !strings.HasPrefix(s, pre) { + return 0, errInvalidTimeout + } + s = s[len(pre):] + if s == "" || s[0] < '0' || '9' < s[0] { + return 0, errInvalidTimeout + } + n, err := strconv.ParseInt(s, 10, 64) + if err != nil || 1<<32-1 < n { + return 0, errInvalidTimeout + } + return time.Duration(n) * time.Second, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/lock_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/lock_test.go new file mode 100644 index 00000000..116d6c0d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/lock_test.go @@ -0,0 +1,731 @@ +// 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. + +package webdav + +import ( + "fmt" + "math/rand" + "path" + "reflect" + "sort" + "strconv" + "strings" + "testing" + "time" +) + +func TestWalkToRoot(t *testing.T) { + testCases := []struct { + name string + want []string + }{{ + "/a/b/c/d", + []string{ + "/a/b/c/d", + "/a/b/c", + "/a/b", + "/a", + "/", + }, + }, { + "/a", + []string{ + "/a", + "/", + }, + }, { + "/", + []string{ + "/", + }, + }} + + for _, tc := range testCases { + var got []string + if !walkToRoot(tc.name, func(name0 string, first bool) bool { + if first != (len(got) == 0) { + t.Errorf("name=%q: first=%t but len(got)==%d", tc.name, first, len(got)) + return false + } + got = append(got, name0) + return true + }) { + continue + } + if !reflect.DeepEqual(got, tc.want) { + t.Errorf("name=%q:\ngot %q\nwant %q", tc.name, got, tc.want) + } + } +} + +var lockTestDurations = []time.Duration{ + infiniteTimeout, // infiniteTimeout means to never expire. + 0, // A zero duration means to expire immediately. + 100 * time.Hour, // A very large duration will not expire in these tests. +} + +// lockTestNames are the names of a set of mutually compatible locks. For each +// name fragment: +// - _ means no explicit lock. +// - i means a infinite-depth lock, +// - z means a zero-depth lock, +var lockTestNames = []string{ + "/_/_/_/_/z", + "/_/_/i", + "/_/z", + "/_/z/i", + "/_/z/z", + "/_/z/_/i", + "/_/z/_/z", + "/i", + "/z", + "/z/_/i", + "/z/_/z", +} + +func lockTestZeroDepth(name string) bool { + switch name[len(name)-1] { + case 'i': + return false + case 'z': + return true + } + panic(fmt.Sprintf("lock name %q did not end with 'i' or 'z'", name)) +} + +func TestMemLSCanCreate(t *testing.T) { + now := time.Unix(0, 0) + m := NewMemLS().(*memLS) + + for _, name := range lockTestNames { + _, err := m.Create(now, LockDetails{ + Root: name, + Duration: infiniteTimeout, + ZeroDepth: lockTestZeroDepth(name), + }) + if err != nil { + t.Fatalf("creating lock for %q: %v", name, err) + } + } + + wantCanCreate := func(name string, zeroDepth bool) bool { + for _, n := range lockTestNames { + switch { + case n == name: + // An existing lock has the same name as the proposed lock. + return false + case strings.HasPrefix(n, name): + // An existing lock would be a child of the proposed lock, + // which conflicts if the proposed lock has infinite depth. + if !zeroDepth { + return false + } + case strings.HasPrefix(name, n): + // An existing lock would be an ancestor of the proposed lock, + // which conflicts if the ancestor has infinite depth. + if n[len(n)-1] == 'i' { + return false + } + } + } + return true + } + + var check func(int, string) + check = func(recursion int, name string) { + for _, zeroDepth := range []bool{false, true} { + got := m.canCreate(name, zeroDepth) + want := wantCanCreate(name, zeroDepth) + if got != want { + t.Errorf("canCreate name=%q zeroDepth=%t: got %t, want %t", name, zeroDepth, got, want) + } + } + if recursion == 6 { + return + } + if name != "/" { + name += "/" + } + for _, c := range "_iz" { + check(recursion+1, name+string(c)) + } + } + check(0, "/") +} + +func TestMemLSLookup(t *testing.T) { + now := time.Unix(0, 0) + m := NewMemLS().(*memLS) + + badToken := m.nextToken() + t.Logf("badToken=%q", badToken) + + for _, name := range lockTestNames { + token, err := m.Create(now, LockDetails{ + Root: name, + Duration: infiniteTimeout, + ZeroDepth: lockTestZeroDepth(name), + }) + if err != nil { + t.Fatalf("creating lock for %q: %v", name, err) + } + t.Logf("%-15q -> node=%p token=%q", name, m.byName[name], token) + } + + baseNames := append([]string{"/a", "/b/c"}, lockTestNames...) + for _, baseName := range baseNames { + for _, suffix := range []string{"", "/0", "/1/2/3"} { + name := baseName + suffix + + goodToken := "" + base := m.byName[baseName] + if base != nil && (suffix == "" || !lockTestZeroDepth(baseName)) { + goodToken = base.token + } + + for _, token := range []string{badToken, goodToken} { + if token == "" { + continue + } + + got := m.lookup(name, Condition{Token: token}) + want := base + if token == badToken { + want = nil + } + if got != want { + t.Errorf("name=%-20qtoken=%q (bad=%t): got %p, want %p", + name, token, token == badToken, got, want) + } + } + } + } +} + +func TestMemLSConfirm(t *testing.T) { + now := time.Unix(0, 0) + m := NewMemLS().(*memLS) + alice, err := m.Create(now, LockDetails{ + Root: "/alice", + Duration: infiniteTimeout, + ZeroDepth: false, + }) + tweedle, err := m.Create(now, LockDetails{ + Root: "/tweedle", + Duration: infiniteTimeout, + ZeroDepth: false, + }) + if err != nil { + t.Fatalf("Create: %v", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Create: inconsistent state: %v", err) + } + + // Test a mismatch between name and condition. + _, err = m.Confirm(now, "/tweedle/dee", "", Condition{Token: alice}) + if err != ErrConfirmationFailed { + t.Fatalf("Confirm (mismatch): got %v, want ErrConfirmationFailed", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Confirm (mismatch): inconsistent state: %v", err) + } + + // Test two names (that fall under the same lock) in the one Confirm call. + release, err := m.Confirm(now, "/tweedle/dee", "/tweedle/dum", Condition{Token: tweedle}) + if err != nil { + t.Fatalf("Confirm (twins): %v", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Confirm (twins): inconsistent state: %v", err) + } + release() + if err := m.consistent(); err != nil { + t.Fatalf("release (twins): inconsistent state: %v", err) + } + + // Test the same two names in overlapping Confirm / release calls. + releaseDee, err := m.Confirm(now, "/tweedle/dee", "", Condition{Token: tweedle}) + if err != nil { + t.Fatalf("Confirm (sequence #0): %v", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Confirm (sequence #0): inconsistent state: %v", err) + } + + _, err = m.Confirm(now, "/tweedle/dum", "", Condition{Token: tweedle}) + if err != ErrConfirmationFailed { + t.Fatalf("Confirm (sequence #1): got %v, want ErrConfirmationFailed", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Confirm (sequence #1): inconsistent state: %v", err) + } + + releaseDee() + if err := m.consistent(); err != nil { + t.Fatalf("release (sequence #2): inconsistent state: %v", err) + } + + releaseDum, err := m.Confirm(now, "/tweedle/dum", "", Condition{Token: tweedle}) + if err != nil { + t.Fatalf("Confirm (sequence #3): %v", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Confirm (sequence #3): inconsistent state: %v", err) + } + + // Test that you can't unlock a held lock. + err = m.Unlock(now, tweedle) + if err != ErrLocked { + t.Fatalf("Unlock (sequence #4): got %v, want ErrLocked", err) + } + + releaseDum() + if err := m.consistent(); err != nil { + t.Fatalf("release (sequence #5): inconsistent state: %v", err) + } + + err = m.Unlock(now, tweedle) + if err != nil { + t.Fatalf("Unlock (sequence #6): %v", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Unlock (sequence #6): inconsistent state: %v", err) + } +} + +func TestMemLSNonCanonicalRoot(t *testing.T) { + now := time.Unix(0, 0) + m := NewMemLS().(*memLS) + token, err := m.Create(now, LockDetails{ + Root: "/foo/./bar//", + Duration: 1 * time.Second, + }) + if err != nil { + t.Fatalf("Create: %v", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Create: inconsistent state: %v", err) + } + if err := m.Unlock(now, token); err != nil { + t.Fatalf("Unlock: %v", err) + } + if err := m.consistent(); err != nil { + t.Fatalf("Unlock: inconsistent state: %v", err) + } +} + +func TestMemLSExpiry(t *testing.T) { + m := NewMemLS().(*memLS) + testCases := []string{ + "setNow 0", + "create /a.5", + "want /a.5", + "create /c.6", + "want /a.5 /c.6", + "create /a/b.7", + "want /a.5 /a/b.7 /c.6", + "setNow 4", + "want /a.5 /a/b.7 /c.6", + "setNow 5", + "want /a/b.7 /c.6", + "setNow 6", + "want /a/b.7", + "setNow 7", + "want ", + "setNow 8", + "want ", + "create /a.12", + "create /b.13", + "create /c.15", + "create /a/d.16", + "want /a.12 /a/d.16 /b.13 /c.15", + "refresh /a.14", + "want /a.14 /a/d.16 /b.13 /c.15", + "setNow 12", + "want /a.14 /a/d.16 /b.13 /c.15", + "setNow 13", + "want /a.14 /a/d.16 /c.15", + "setNow 14", + "want /a/d.16 /c.15", + "refresh /a/d.20", + "refresh /c.20", + "want /a/d.20 /c.20", + "setNow 20", + "want ", + } + + tokens := map[string]string{} + zTime := time.Unix(0, 0) + now := zTime + for i, tc := range testCases { + j := strings.IndexByte(tc, ' ') + if j < 0 { + t.Fatalf("test case #%d %q: invalid command", i, tc) + } + op, arg := tc[:j], tc[j+1:] + switch op { + default: + t.Fatalf("test case #%d %q: invalid operation %q", i, tc, op) + + case "create", "refresh": + parts := strings.Split(arg, ".") + if len(parts) != 2 { + t.Fatalf("test case #%d %q: invalid create", i, tc) + } + root := parts[0] + d, err := strconv.Atoi(parts[1]) + if err != nil { + t.Fatalf("test case #%d %q: invalid duration", i, tc) + } + dur := time.Unix(0, 0).Add(time.Duration(d) * time.Second).Sub(now) + + switch op { + case "create": + token, err := m.Create(now, LockDetails{ + Root: root, + Duration: dur, + ZeroDepth: true, + }) + if err != nil { + t.Fatalf("test case #%d %q: Create: %v", i, tc, err) + } + tokens[root] = token + + case "refresh": + token := tokens[root] + if token == "" { + t.Fatalf("test case #%d %q: no token for %q", i, tc, root) + } + got, err := m.Refresh(now, token, dur) + if err != nil { + t.Fatalf("test case #%d %q: Refresh: %v", i, tc, err) + } + want := LockDetails{ + Root: root, + Duration: dur, + ZeroDepth: true, + } + if got != want { + t.Fatalf("test case #%d %q:\ngot %v\nwant %v", i, tc, got, want) + } + } + + case "setNow": + d, err := strconv.Atoi(arg) + if err != nil { + t.Fatalf("test case #%d %q: invalid duration", i, tc) + } + now = time.Unix(0, 0).Add(time.Duration(d) * time.Second) + + case "want": + m.mu.Lock() + m.collectExpiredNodes(now) + got := make([]string, 0, len(m.byToken)) + for _, n := range m.byToken { + got = append(got, fmt.Sprintf("%s.%d", + n.details.Root, n.expiry.Sub(zTime)/time.Second)) + } + m.mu.Unlock() + sort.Strings(got) + want := []string{} + if arg != "" { + want = strings.Split(arg, " ") + } + if !reflect.DeepEqual(got, want) { + t.Fatalf("test case #%d %q:\ngot %q\nwant %q", i, tc, got, want) + } + } + + if err := m.consistent(); err != nil { + t.Fatalf("test case #%d %q: inconsistent state: %v", i, tc, err) + } + } +} + +func TestMemLS(t *testing.T) { + now := time.Unix(0, 0) + m := NewMemLS().(*memLS) + rng := rand.New(rand.NewSource(0)) + tokens := map[string]string{} + nConfirm, nCreate, nRefresh, nUnlock := 0, 0, 0, 0 + const N = 2000 + + for i := 0; i < N; i++ { + name := lockTestNames[rng.Intn(len(lockTestNames))] + duration := lockTestDurations[rng.Intn(len(lockTestDurations))] + confirmed, unlocked := false, false + + // If the name was already locked, we randomly confirm/release, refresh + // or unlock it. Otherwise, we create a lock. + token := tokens[name] + if token != "" { + switch rng.Intn(3) { + case 0: + confirmed = true + nConfirm++ + release, err := m.Confirm(now, name, "", Condition{Token: token}) + if err != nil { + t.Fatalf("iteration #%d: Confirm %q: %v", i, name, err) + } + if err := m.consistent(); err != nil { + t.Fatalf("iteration #%d: inconsistent state: %v", i, err) + } + release() + + case 1: + nRefresh++ + if _, err := m.Refresh(now, token, duration); err != nil { + t.Fatalf("iteration #%d: Refresh %q: %v", i, name, err) + } + + case 2: + unlocked = true + nUnlock++ + if err := m.Unlock(now, token); err != nil { + t.Fatalf("iteration #%d: Unlock %q: %v", i, name, err) + } + } + + } else { + nCreate++ + var err error + token, err = m.Create(now, LockDetails{ + Root: name, + Duration: duration, + ZeroDepth: lockTestZeroDepth(name), + }) + if err != nil { + t.Fatalf("iteration #%d: Create %q: %v", i, name, err) + } + } + + if !confirmed { + if duration == 0 || unlocked { + // A zero-duration lock should expire immediately and is + // effectively equivalent to being unlocked. + tokens[name] = "" + } else { + tokens[name] = token + } + } + + if err := m.consistent(); err != nil { + t.Fatalf("iteration #%d: inconsistent state: %v", i, err) + } + } + + if nConfirm < N/10 { + t.Fatalf("too few Confirm calls: got %d, want >= %d", nConfirm, N/10) + } + if nCreate < N/10 { + t.Fatalf("too few Create calls: got %d, want >= %d", nCreate, N/10) + } + if nRefresh < N/10 { + t.Fatalf("too few Refresh calls: got %d, want >= %d", nRefresh, N/10) + } + if nUnlock < N/10 { + t.Fatalf("too few Unlock calls: got %d, want >= %d", nUnlock, N/10) + } +} + +func (m *memLS) consistent() error { + m.mu.Lock() + defer m.mu.Unlock() + + // If m.byName is non-empty, then it must contain an entry for the root "/", + // and its refCount should equal the number of locked nodes. + if len(m.byName) > 0 { + n := m.byName["/"] + if n == nil { + return fmt.Errorf(`non-empty m.byName does not contain the root "/"`) + } + if n.refCount != len(m.byToken) { + return fmt.Errorf("root node refCount=%d, differs from len(m.byToken)=%d", n.refCount, len(m.byToken)) + } + } + + for name, n := range m.byName { + // The map keys should be consistent with the node's copy of the key. + if n.details.Root != name { + return fmt.Errorf("node name %q != byName map key %q", n.details.Root, name) + } + + // A name must be clean, and start with a "/". + if len(name) == 0 || name[0] != '/' { + return fmt.Errorf(`node name %q does not start with "/"`, name) + } + if name != path.Clean(name) { + return fmt.Errorf(`node name %q is not clean`, name) + } + + // A node's refCount should be positive. + if n.refCount <= 0 { + return fmt.Errorf("non-positive refCount for node at name %q", name) + } + + // A node's refCount should be the number of self-or-descendents that + // are locked (i.e. have a non-empty token). + var list []string + for name0, n0 := range m.byName { + // All of lockTestNames' name fragments are one byte long: '_', 'i' or 'z', + // so strings.HasPrefix is equivalent to self-or-descendent name match. + // We don't have to worry about "/foo/bar" being a false positive match + // for "/foo/b". + if strings.HasPrefix(name0, name) && n0.token != "" { + list = append(list, name0) + } + } + if n.refCount != len(list) { + sort.Strings(list) + return fmt.Errorf("node at name %q has refCount %d but locked self-or-descendents are %q (len=%d)", + name, n.refCount, list, len(list)) + } + + // A node n is in m.byToken if it has a non-empty token. + if n.token != "" { + if _, ok := m.byToken[n.token]; !ok { + return fmt.Errorf("node at name %q has token %q but not in m.byToken", name, n.token) + } + } + + // A node n is in m.byExpiry if it has a non-negative byExpiryIndex. + if n.byExpiryIndex >= 0 { + if n.byExpiryIndex >= len(m.byExpiry) { + return fmt.Errorf("node at name %q has byExpiryIndex %d but m.byExpiry has length %d", name, n.byExpiryIndex, len(m.byExpiry)) + } + if n != m.byExpiry[n.byExpiryIndex] { + return fmt.Errorf("node at name %q has byExpiryIndex %d but that indexes a different node", name, n.byExpiryIndex) + } + } + } + + for token, n := range m.byToken { + // The map keys should be consistent with the node's copy of the key. + if n.token != token { + return fmt.Errorf("node token %q != byToken map key %q", n.token, token) + } + + // Every node in m.byToken is in m.byName. + if _, ok := m.byName[n.details.Root]; !ok { + return fmt.Errorf("node at name %q in m.byToken but not in m.byName", n.details.Root) + } + } + + for i, n := range m.byExpiry { + // The slice indices should be consistent with the node's copy of the index. + if n.byExpiryIndex != i { + return fmt.Errorf("node byExpiryIndex %d != byExpiry slice index %d", n.byExpiryIndex, i) + } + + // Every node in m.byExpiry is in m.byName. + if _, ok := m.byName[n.details.Root]; !ok { + return fmt.Errorf("node at name %q in m.byExpiry but not in m.byName", n.details.Root) + } + + // No node in m.byExpiry should be held. + if n.held { + return fmt.Errorf("node at name %q in m.byExpiry is held", n.details.Root) + } + } + return nil +} + +func TestParseTimeout(t *testing.T) { + testCases := []struct { + s string + want time.Duration + wantErr error + }{{ + "", + infiniteTimeout, + nil, + }, { + "Infinite", + infiniteTimeout, + nil, + }, { + "Infinitesimal", + 0, + errInvalidTimeout, + }, { + "infinite", + 0, + errInvalidTimeout, + }, { + "Second-0", + 0 * time.Second, + nil, + }, { + "Second-123", + 123 * time.Second, + nil, + }, { + " Second-456 ", + 456 * time.Second, + nil, + }, { + "Second-4100000000", + 4100000000 * time.Second, + nil, + }, { + "junk", + 0, + errInvalidTimeout, + }, { + "Second-", + 0, + errInvalidTimeout, + }, { + "Second--1", + 0, + errInvalidTimeout, + }, { + "Second--123", + 0, + errInvalidTimeout, + }, { + "Second-+123", + 0, + errInvalidTimeout, + }, { + "Second-0x123", + 0, + errInvalidTimeout, + }, { + "second-123", + 0, + errInvalidTimeout, + }, { + "Second-4294967295", + 4294967295 * time.Second, + nil, + }, { + // Section 10.7 says that "The timeout value for TimeType "Second" + // must not be greater than 2^32-1." + "Second-4294967296", + 0, + errInvalidTimeout, + }, { + // This test case comes from section 9.10.9 of the spec. It says, + // + // "In this request, the client has specified that it desires an + // infinite-length lock, if available, otherwise a timeout of 4.1 + // billion seconds, if available." + // + // The Go WebDAV package always supports infinite length locks, + // and ignores the fallback after the comma. + "Infinite, Second-4100000000", + infiniteTimeout, + nil, + }} + + for _, tc := range testCases { + got, gotErr := parseTimeout(tc.s) + if got != tc.want || gotErr != tc.wantErr { + t.Errorf("parsing %q:\ngot %v, %v\nwant %v, %v", tc.s, got, gotErr, tc.want, tc.wantErr) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/prop.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/prop.go new file mode 100644 index 00000000..88b9a3a3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/prop.go @@ -0,0 +1,389 @@ +// 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 webdav + +import ( + "fmt" + "io" + "mime" + "net/http" + "os" + "path/filepath" + "strconv" + + "golang.org/x/net/webdav/internal/xml" +) + +// Proppatch describes a property update instruction as defined in RFC 4918. +// See http://www.webdav.org/specs/rfc4918.html#METHOD_PROPPATCH +type Proppatch struct { + // Remove specifies whether this patch removes properties. If it does not + // remove them, it sets them. + Remove bool + // Props contains the properties to be set or removed. + Props []Property +} + +// Propstat describes a XML propstat element as defined in RFC 4918. +// See http://www.webdav.org/specs/rfc4918.html#ELEMENT_propstat +type Propstat struct { + // Props contains the properties for which Status applies. + Props []Property + + // Status defines the HTTP status code of the properties in Prop. + // Allowed values include, but are not limited to the WebDAV status + // code extensions for HTTP/1.1. + // http://www.webdav.org/specs/rfc4918.html#status.code.extensions.to.http11 + Status int + + // XMLError contains the XML representation of the optional error element. + // XML content within this field must not rely on any predefined + // namespace declarations or prefixes. If empty, the XML error element + // is omitted. + XMLError string + + // ResponseDescription contains the contents of the optional + // responsedescription field. If empty, the XML element is omitted. + ResponseDescription string +} + +// makePropstats returns a slice containing those of x and y whose Props slice +// is non-empty. If both are empty, it returns a slice containing an otherwise +// zero Propstat whose HTTP status code is 200 OK. +func makePropstats(x, y Propstat) []Propstat { + pstats := make([]Propstat, 0, 2) + if len(x.Props) != 0 { + pstats = append(pstats, x) + } + if len(y.Props) != 0 { + pstats = append(pstats, y) + } + if len(pstats) == 0 { + pstats = append(pstats, Propstat{ + Status: http.StatusOK, + }) + } + return pstats +} + +// DeadPropsHolder holds the dead properties of a resource. +// +// Dead properties are those properties that are explicitly defined. In +// comparison, live properties, such as DAV:getcontentlength, are implicitly +// defined by the underlying resource, and cannot be explicitly overridden or +// removed. See the Terminology section of +// http://www.webdav.org/specs/rfc4918.html#rfc.section.3 +// +// There is a whitelist of the names of live properties. This package handles +// all live properties, and will only pass non-whitelisted names to the Patch +// method of DeadPropsHolder implementations. +type DeadPropsHolder interface { + // DeadProps returns a copy of the dead properties held. + DeadProps() (map[xml.Name]Property, error) + + // Patch patches the dead properties held. + // + // Patching is atomic; either all or no patches succeed. It returns (nil, + // non-nil) if an internal server error occurred, otherwise the Propstats + // collectively contain one Property for each proposed patch Property. If + // all patches succeed, Patch returns a slice of length one and a Propstat + // element with a 200 OK HTTP status code. If none succeed, for reasons + // other than an internal server error, no Propstat has status 200 OK. + // + // For more details on when various HTTP status codes apply, see + // http://www.webdav.org/specs/rfc4918.html#PROPPATCH-status + Patch([]Proppatch) ([]Propstat, error) +} + +// liveProps contains all supported, protected DAV: properties. +var liveProps = map[xml.Name]struct { + // findFn implements the propfind function of this property. If nil, + // it indicates a hidden property. + findFn func(FileSystem, LockSystem, string, os.FileInfo) (string, error) + // dir is true if the property applies to directories. + dir bool +}{ + xml.Name{Space: "DAV:", Local: "resourcetype"}: { + findFn: findResourceType, + dir: true, + }, + xml.Name{Space: "DAV:", Local: "displayname"}: { + findFn: findDisplayName, + dir: true, + }, + xml.Name{Space: "DAV:", Local: "getcontentlength"}: { + findFn: findContentLength, + dir: false, + }, + xml.Name{Space: "DAV:", Local: "getlastmodified"}: { + findFn: findLastModified, + dir: false, + }, + xml.Name{Space: "DAV:", Local: "creationdate"}: { + findFn: nil, + dir: false, + }, + xml.Name{Space: "DAV:", Local: "getcontentlanguage"}: { + findFn: nil, + dir: false, + }, + xml.Name{Space: "DAV:", Local: "getcontenttype"}: { + findFn: findContentType, + dir: false, + }, + xml.Name{Space: "DAV:", Local: "getetag"}: { + findFn: findETag, + // findETag implements ETag as the concatenated hex values of a file's + // modification time and size. This is not a reliable synchronization + // mechanism for directories, so we do not advertise getetag for DAV + // collections. + dir: false, + }, + + // TODO: The lockdiscovery property requires LockSystem to list the + // active locks on a resource. + xml.Name{Space: "DAV:", Local: "lockdiscovery"}: {}, + xml.Name{Space: "DAV:", Local: "supportedlock"}: { + findFn: findSupportedLock, + dir: true, + }, +} + +// TODO(nigeltao) merge props and allprop? + +// Props returns the status of the properties named pnames for resource name. +// +// Each Propstat has a unique status and each property name will only be part +// of one Propstat element. +func props(fs FileSystem, ls LockSystem, name string, pnames []xml.Name) ([]Propstat, error) { + f, err := fs.OpenFile(name, os.O_RDONLY, 0) + if err != nil { + return nil, err + } + defer f.Close() + fi, err := f.Stat() + if err != nil { + return nil, err + } + isDir := fi.IsDir() + + var deadProps map[xml.Name]Property + if dph, ok := f.(DeadPropsHolder); ok { + deadProps, err = dph.DeadProps() + if err != nil { + return nil, err + } + } + + pstatOK := Propstat{Status: http.StatusOK} + pstatNotFound := Propstat{Status: http.StatusNotFound} + for _, pn := range pnames { + // If this file has dead properties, check if they contain pn. + if dp, ok := deadProps[pn]; ok { + pstatOK.Props = append(pstatOK.Props, dp) + continue + } + // Otherwise, it must either be a live property or we don't know it. + if prop := liveProps[pn]; prop.findFn != nil && (prop.dir || !isDir) { + innerXML, err := prop.findFn(fs, ls, name, fi) + if err != nil { + return nil, err + } + pstatOK.Props = append(pstatOK.Props, Property{ + XMLName: pn, + InnerXML: []byte(innerXML), + }) + } else { + pstatNotFound.Props = append(pstatNotFound.Props, Property{ + XMLName: pn, + }) + } + } + return makePropstats(pstatOK, pstatNotFound), nil +} + +// Propnames returns the property names defined for resource name. +func propnames(fs FileSystem, ls LockSystem, name string) ([]xml.Name, error) { + f, err := fs.OpenFile(name, os.O_RDONLY, 0) + if err != nil { + return nil, err + } + defer f.Close() + fi, err := f.Stat() + if err != nil { + return nil, err + } + isDir := fi.IsDir() + + var deadProps map[xml.Name]Property + if dph, ok := f.(DeadPropsHolder); ok { + deadProps, err = dph.DeadProps() + if err != nil { + return nil, err + } + } + + pnames := make([]xml.Name, 0, len(liveProps)+len(deadProps)) + for pn, prop := range liveProps { + if prop.findFn != nil && (prop.dir || !isDir) { + pnames = append(pnames, pn) + } + } + for pn := range deadProps { + pnames = append(pnames, pn) + } + return pnames, nil +} + +// Allprop returns the properties defined for resource name and the properties +// named in include. +// +// Note that RFC 4918 defines 'allprop' to return the DAV: properties defined +// within the RFC plus dead properties. Other live properties should only be +// returned if they are named in 'include'. +// +// See http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND +func allprop(fs FileSystem, ls LockSystem, name string, include []xml.Name) ([]Propstat, error) { + pnames, err := propnames(fs, ls, name) + if err != nil { + return nil, err + } + // Add names from include if they are not already covered in pnames. + nameset := make(map[xml.Name]bool) + for _, pn := range pnames { + nameset[pn] = true + } + for _, pn := range include { + if !nameset[pn] { + pnames = append(pnames, pn) + } + } + return props(fs, ls, name, pnames) +} + +// Patch patches the properties of resource name. The return values are +// constrained in the same manner as DeadPropsHolder.Patch. +func patch(fs FileSystem, ls LockSystem, name string, patches []Proppatch) ([]Propstat, error) { + conflict := false +loop: + for _, patch := range patches { + for _, p := range patch.Props { + if _, ok := liveProps[p.XMLName]; ok { + conflict = true + break loop + } + } + } + if conflict { + pstatForbidden := Propstat{ + Status: http.StatusForbidden, + XMLError: ``, + } + pstatFailedDep := Propstat{ + Status: StatusFailedDependency, + } + for _, patch := range patches { + for _, p := range patch.Props { + if _, ok := liveProps[p.XMLName]; ok { + pstatForbidden.Props = append(pstatForbidden.Props, Property{XMLName: p.XMLName}) + } else { + pstatFailedDep.Props = append(pstatFailedDep.Props, Property{XMLName: p.XMLName}) + } + } + } + return makePropstats(pstatForbidden, pstatFailedDep), nil + } + + f, err := fs.OpenFile(name, os.O_RDWR, 0) + if err != nil { + return nil, err + } + defer f.Close() + if dph, ok := f.(DeadPropsHolder); ok { + ret, err := dph.Patch(patches) + if err != nil { + return nil, err + } + // http://www.webdav.org/specs/rfc4918.html#ELEMENT_propstat says that + // "The contents of the prop XML element must only list the names of + // properties to which the result in the status element applies." + for _, pstat := range ret { + for i, p := range pstat.Props { + pstat.Props[i] = Property{XMLName: p.XMLName} + } + } + return ret, nil + } + // The file doesn't implement the optional DeadPropsHolder interface, so + // all patches are forbidden. + pstat := Propstat{Status: http.StatusForbidden} + for _, patch := range patches { + for _, p := range patch.Props { + pstat.Props = append(pstat.Props, Property{XMLName: p.XMLName}) + } + } + return []Propstat{pstat}, nil +} + +func findResourceType(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + if fi.IsDir() { + return ``, nil + } + return "", nil +} + +func findDisplayName(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + if slashClean(name) == "/" { + // Hide the real name of a possibly prefixed root directory. + return "", nil + } + return fi.Name(), nil +} + +func findContentLength(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + return strconv.FormatInt(fi.Size(), 10), nil +} + +func findLastModified(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + return fi.ModTime().Format(http.TimeFormat), nil +} + +func findContentType(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + f, err := fs.OpenFile(name, os.O_RDONLY, 0) + if err != nil { + return "", err + } + defer f.Close() + // This implementation is based on serveContent's code in the standard net/http package. + ctype := mime.TypeByExtension(filepath.Ext(name)) + if ctype != "" { + return ctype, nil + } + // Read a chunk to decide between utf-8 text and binary. + var buf [512]byte + n, err := io.ReadFull(f, buf[:]) + if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { + return "", err + } + ctype = http.DetectContentType(buf[:n]) + // Rewind file. + _, err = f.Seek(0, os.SEEK_SET) + return ctype, err +} + +func findETag(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + // The Apache http 2.4 web server by default concatenates the + // modification time and size of a file. We replicate the heuristic + // with nanosecond granularity. + return fmt.Sprintf(`"%x%x"`, fi.ModTime().UnixNano(), fi.Size()), nil +} + +func findSupportedLock(fs FileSystem, ls LockSystem, name string, fi os.FileInfo) (string, error) { + return `` + + `` + + `` + + `` + + ``, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/prop_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/prop_test.go new file mode 100644 index 00000000..ad4ec5b1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/prop_test.go @@ -0,0 +1,607 @@ +// 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 webdav + +import ( + "fmt" + "net/http" + "os" + "reflect" + "sort" + "testing" + + "golang.org/x/net/webdav/internal/xml" +) + +func TestMemPS(t *testing.T) { + // calcProps calculates the getlastmodified and getetag DAV: property + // values in pstats for resource name in file-system fs. + calcProps := func(name string, fs FileSystem, ls LockSystem, pstats []Propstat) error { + fi, err := fs.Stat(name) + if err != nil { + return err + } + for _, pst := range pstats { + for i, p := range pst.Props { + switch p.XMLName { + case xml.Name{Space: "DAV:", Local: "getlastmodified"}: + p.InnerXML = []byte(fi.ModTime().Format(http.TimeFormat)) + pst.Props[i] = p + case xml.Name{Space: "DAV:", Local: "getetag"}: + if fi.IsDir() { + continue + } + etag, err := findETag(fs, ls, name, fi) + if err != nil { + return err + } + p.InnerXML = []byte(etag) + pst.Props[i] = p + } + } + } + return nil + } + + const ( + lockEntry = `` + + `` + + `` + + `` + + `` + statForbiddenError = `` + ) + + type propOp struct { + op string + name string + pnames []xml.Name + patches []Proppatch + wantPnames []xml.Name + wantPropstats []Propstat + } + + testCases := []struct { + desc string + noDeadProps bool + buildfs []string + propOp []propOp + }{{ + desc: "propname", + buildfs: []string{"mkdir /dir", "touch /file"}, + propOp: []propOp{{ + op: "propname", + name: "/dir", + wantPnames: []xml.Name{ + xml.Name{Space: "DAV:", Local: "resourcetype"}, + xml.Name{Space: "DAV:", Local: "displayname"}, + xml.Name{Space: "DAV:", Local: "supportedlock"}, + }, + }, { + op: "propname", + name: "/file", + wantPnames: []xml.Name{ + xml.Name{Space: "DAV:", Local: "resourcetype"}, + xml.Name{Space: "DAV:", Local: "displayname"}, + xml.Name{Space: "DAV:", Local: "getcontentlength"}, + xml.Name{Space: "DAV:", Local: "getlastmodified"}, + xml.Name{Space: "DAV:", Local: "getcontenttype"}, + xml.Name{Space: "DAV:", Local: "getetag"}, + xml.Name{Space: "DAV:", Local: "supportedlock"}, + }, + }}, + }, { + desc: "allprop dir and file", + buildfs: []string{"mkdir /dir", "write /file foobarbaz"}, + propOp: []propOp{{ + op: "allprop", + name: "/dir", + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "resourcetype"}, + InnerXML: []byte(``), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "displayname"}, + InnerXML: []byte("dir"), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "supportedlock"}, + InnerXML: []byte(lockEntry), + }}, + }}, + }, { + op: "allprop", + name: "/file", + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "resourcetype"}, + InnerXML: []byte(""), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "displayname"}, + InnerXML: []byte("file"), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getcontentlength"}, + InnerXML: []byte("9"), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getlastmodified"}, + InnerXML: nil, // Calculated during test. + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getcontenttype"}, + InnerXML: []byte("text/plain; charset=utf-8"), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getetag"}, + InnerXML: nil, // Calculated during test. + }, { + XMLName: xml.Name{Space: "DAV:", Local: "supportedlock"}, + InnerXML: []byte(lockEntry), + }}, + }}, + }, { + op: "allprop", + name: "/file", + pnames: []xml.Name{ + {"DAV:", "resourcetype"}, + {"foo", "bar"}, + }, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "resourcetype"}, + InnerXML: []byte(""), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "displayname"}, + InnerXML: []byte("file"), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getcontentlength"}, + InnerXML: []byte("9"), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getlastmodified"}, + InnerXML: nil, // Calculated during test. + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getcontenttype"}, + InnerXML: []byte("text/plain; charset=utf-8"), + }, { + XMLName: xml.Name{Space: "DAV:", Local: "getetag"}, + InnerXML: nil, // Calculated during test. + }, { + XMLName: xml.Name{Space: "DAV:", Local: "supportedlock"}, + InnerXML: []byte(lockEntry), + }}}, { + Status: http.StatusNotFound, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}}, + }, + }}, + }, { + desc: "propfind DAV:resourcetype", + buildfs: []string{"mkdir /dir", "touch /file"}, + propOp: []propOp{{ + op: "propfind", + name: "/dir", + pnames: []xml.Name{{"DAV:", "resourcetype"}}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "resourcetype"}, + InnerXML: []byte(``), + }}, + }}, + }, { + op: "propfind", + name: "/file", + pnames: []xml.Name{{"DAV:", "resourcetype"}}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "resourcetype"}, + InnerXML: []byte(""), + }}, + }}, + }}, + }, { + desc: "propfind unsupported DAV properties", + buildfs: []string{"mkdir /dir"}, + propOp: []propOp{{ + op: "propfind", + name: "/dir", + pnames: []xml.Name{{"DAV:", "getcontentlanguage"}}, + wantPropstats: []Propstat{{ + Status: http.StatusNotFound, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "getcontentlanguage"}, + }}, + }}, + }, { + op: "propfind", + name: "/dir", + pnames: []xml.Name{{"DAV:", "creationdate"}}, + wantPropstats: []Propstat{{ + Status: http.StatusNotFound, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "creationdate"}, + }}, + }}, + }}, + }, { + desc: "propfind getetag for files but not for directories", + buildfs: []string{"mkdir /dir", "touch /file"}, + propOp: []propOp{{ + op: "propfind", + name: "/dir", + pnames: []xml.Name{{"DAV:", "getetag"}}, + wantPropstats: []Propstat{{ + Status: http.StatusNotFound, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "getetag"}, + }}, + }}, + }, { + op: "propfind", + name: "/file", + pnames: []xml.Name{{"DAV:", "getetag"}}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "getetag"}, + InnerXML: nil, // Calculated during test. + }}, + }}, + }}, + }, { + desc: "proppatch property on no-dead-properties file system", + buildfs: []string{"mkdir /dir"}, + noDeadProps: true, + propOp: []propOp{{ + op: "proppatch", + name: "/dir", + patches: []Proppatch{{ + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusForbidden, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + }, { + op: "proppatch", + name: "/dir", + patches: []Proppatch{{ + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "getetag"}, + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusForbidden, + XMLError: statForbiddenError, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "getetag"}, + }}, + }}, + }}, + }, { + desc: "proppatch dead property", + buildfs: []string{"mkdir /dir"}, + propOp: []propOp{{ + op: "proppatch", + name: "/dir", + patches: []Proppatch{{ + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + InnerXML: []byte("baz"), + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + }, { + op: "propfind", + name: "/dir", + pnames: []xml.Name{{Space: "foo", Local: "bar"}}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + InnerXML: []byte("baz"), + }}, + }}, + }}, + }, { + desc: "proppatch dead property with failed dependency", + buildfs: []string{"mkdir /dir"}, + propOp: []propOp{{ + op: "proppatch", + name: "/dir", + patches: []Proppatch{{ + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + InnerXML: []byte("baz"), + }}, + }, { + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "displayname"}, + InnerXML: []byte("xxx"), + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusForbidden, + XMLError: statForbiddenError, + Props: []Property{{ + XMLName: xml.Name{Space: "DAV:", Local: "displayname"}, + }}, + }, { + Status: StatusFailedDependency, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + }, { + op: "propfind", + name: "/dir", + pnames: []xml.Name{{Space: "foo", Local: "bar"}}, + wantPropstats: []Propstat{{ + Status: http.StatusNotFound, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + }}, + }, { + desc: "proppatch remove dead property", + buildfs: []string{"mkdir /dir"}, + propOp: []propOp{{ + op: "proppatch", + name: "/dir", + patches: []Proppatch{{ + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + InnerXML: []byte("baz"), + }, { + XMLName: xml.Name{Space: "spam", Local: "ham"}, + InnerXML: []byte("eggs"), + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }, { + XMLName: xml.Name{Space: "spam", Local: "ham"}, + }}, + }}, + }, { + op: "propfind", + name: "/dir", + pnames: []xml.Name{ + {Space: "foo", Local: "bar"}, + {Space: "spam", Local: "ham"}, + }, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + InnerXML: []byte("baz"), + }, { + XMLName: xml.Name{Space: "spam", Local: "ham"}, + InnerXML: []byte("eggs"), + }}, + }}, + }, { + op: "proppatch", + name: "/dir", + patches: []Proppatch{{ + Remove: true, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + }, { + op: "propfind", + name: "/dir", + pnames: []xml.Name{ + {Space: "foo", Local: "bar"}, + {Space: "spam", Local: "ham"}, + }, + wantPropstats: []Propstat{{ + Status: http.StatusNotFound, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }, { + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "spam", Local: "ham"}, + InnerXML: []byte("eggs"), + }}, + }}, + }}, + }, { + desc: "propname with dead property", + buildfs: []string{"touch /file"}, + propOp: []propOp{{ + op: "proppatch", + name: "/file", + patches: []Proppatch{{ + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + InnerXML: []byte("baz"), + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + }, { + op: "propname", + name: "/file", + wantPnames: []xml.Name{ + xml.Name{Space: "DAV:", Local: "resourcetype"}, + xml.Name{Space: "DAV:", Local: "displayname"}, + xml.Name{Space: "DAV:", Local: "getcontentlength"}, + xml.Name{Space: "DAV:", Local: "getlastmodified"}, + xml.Name{Space: "DAV:", Local: "getcontenttype"}, + xml.Name{Space: "DAV:", Local: "getetag"}, + xml.Name{Space: "DAV:", Local: "supportedlock"}, + xml.Name{Space: "foo", Local: "bar"}, + }, + }}, + }, { + desc: "proppatch remove unknown dead property", + buildfs: []string{"mkdir /dir"}, + propOp: []propOp{{ + op: "proppatch", + name: "/dir", + patches: []Proppatch{{ + Remove: true, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + wantPropstats: []Propstat{{ + Status: http.StatusOK, + Props: []Property{{ + XMLName: xml.Name{Space: "foo", Local: "bar"}, + }}, + }}, + }}, + }, { + desc: "bad: propfind unknown property", + buildfs: []string{"mkdir /dir"}, + propOp: []propOp{{ + op: "propfind", + name: "/dir", + pnames: []xml.Name{{"foo:", "bar"}}, + wantPropstats: []Propstat{{ + Status: http.StatusNotFound, + Props: []Property{{ + XMLName: xml.Name{Space: "foo:", Local: "bar"}, + }}, + }}, + }}, + }} + + for _, tc := range testCases { + fs, err := buildTestFS(tc.buildfs) + if err != nil { + t.Fatalf("%s: cannot create test filesystem: %v", tc.desc, err) + } + if tc.noDeadProps { + fs = noDeadPropsFS{fs} + } + ls := NewMemLS() + for _, op := range tc.propOp { + desc := fmt.Sprintf("%s: %s %s", tc.desc, op.op, op.name) + if err = calcProps(op.name, fs, ls, op.wantPropstats); err != nil { + t.Fatalf("%s: calcProps: %v", desc, err) + } + + // Call property system. + var propstats []Propstat + switch op.op { + case "propname": + pnames, err := propnames(fs, ls, op.name) + if err != nil { + t.Errorf("%s: got error %v, want nil", desc, err) + continue + } + sort.Sort(byXMLName(pnames)) + sort.Sort(byXMLName(op.wantPnames)) + if !reflect.DeepEqual(pnames, op.wantPnames) { + t.Errorf("%s: pnames\ngot %q\nwant %q", desc, pnames, op.wantPnames) + } + continue + case "allprop": + propstats, err = allprop(fs, ls, op.name, op.pnames) + case "propfind": + propstats, err = props(fs, ls, op.name, op.pnames) + case "proppatch": + propstats, err = patch(fs, ls, op.name, op.patches) + default: + t.Fatalf("%s: %s not implemented", desc, op.op) + } + if err != nil { + t.Errorf("%s: got error %v, want nil", desc, err) + continue + } + // Compare return values from allprop, propfind or proppatch. + for _, pst := range propstats { + sort.Sort(byPropname(pst.Props)) + } + for _, pst := range op.wantPropstats { + sort.Sort(byPropname(pst.Props)) + } + sort.Sort(byStatus(propstats)) + sort.Sort(byStatus(op.wantPropstats)) + if !reflect.DeepEqual(propstats, op.wantPropstats) { + t.Errorf("%s: propstat\ngot %q\nwant %q", desc, propstats, op.wantPropstats) + } + } + } +} + +func cmpXMLName(a, b xml.Name) bool { + if a.Space != b.Space { + return a.Space < b.Space + } + return a.Local < b.Local +} + +type byXMLName []xml.Name + +func (b byXMLName) Len() int { return len(b) } +func (b byXMLName) Swap(i, j int) { b[i], b[j] = b[j], b[i] } +func (b byXMLName) Less(i, j int) bool { return cmpXMLName(b[i], b[j]) } + +type byPropname []Property + +func (b byPropname) Len() int { return len(b) } +func (b byPropname) Swap(i, j int) { b[i], b[j] = b[j], b[i] } +func (b byPropname) Less(i, j int) bool { return cmpXMLName(b[i].XMLName, b[j].XMLName) } + +type byStatus []Propstat + +func (b byStatus) Len() int { return len(b) } +func (b byStatus) Swap(i, j int) { b[i], b[j] = b[j], b[i] } +func (b byStatus) Less(i, j int) bool { return b[i].Status < b[j].Status } + +type noDeadPropsFS struct { + FileSystem +} + +func (fs noDeadPropsFS) OpenFile(name string, flag int, perm os.FileMode) (File, error) { + f, err := fs.FileSystem.OpenFile(name, flag, perm) + if err != nil { + return nil, err + } + return noDeadPropsFile{f}, nil +} + +// noDeadPropsFile wraps a File but strips any optional DeadPropsHolder methods +// provided by the underlying File implementation. +type noDeadPropsFile struct { + f File +} + +func (f noDeadPropsFile) Close() error { return f.f.Close() } +func (f noDeadPropsFile) Read(p []byte) (int, error) { return f.f.Read(p) } +func (f noDeadPropsFile) Readdir(count int) ([]os.FileInfo, error) { return f.f.Readdir(count) } +func (f noDeadPropsFile) Seek(off int64, whence int) (int64, error) { return f.f.Seek(off, whence) } +func (f noDeadPropsFile) Stat() (os.FileInfo, error) { return f.f.Stat() } +func (f noDeadPropsFile) Write(p []byte) (int, error) { return f.f.Write(p) } diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/webdav.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/webdav.go new file mode 100644 index 00000000..df6ef450 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/webdav.go @@ -0,0 +1,707 @@ +// 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. + +// Package webdav etc etc TODO. +package webdav // import "golang.org/x/net/webdav" + +import ( + "errors" + "fmt" + "io" + "log" + "net/http" + "net/url" + "os" + "path" + "runtime" + "strings" + "time" +) + +// Package webdav's XML output requires the standard library's encoding/xml +// package version 1.5 or greater. Otherwise, it will produce malformed XML. +// +// As of May 2015, the Go stable release is version 1.4, so we print a message +// to let users know that this golang.org/x/etc package won't work yet. +// +// This package also won't work with Go 1.3 and earlier, but making this +// runtime version check catch all the earlier versions too, and not just +// "1.4.x", isn't worth the complexity. +// +// TODO: delete this check at some point after Go 1.5 is released. +var go1Dot4 = strings.HasPrefix(runtime.Version(), "go1.4.") + +func init() { + if go1Dot4 { + log.Println("package webdav requires Go version 1.5 or greater") + } +} + +type Handler struct { + // Prefix is the URL path prefix to strip from WebDAV resource paths. + Prefix string + // FileSystem is the virtual file system. + FileSystem FileSystem + // LockSystem is the lock management system. + LockSystem LockSystem + // Logger is an optional error logger. If non-nil, it will be called + // for all HTTP requests. + Logger func(*http.Request, error) +} + +func (h *Handler) stripPrefix(p string) (string, int, error) { + if h.Prefix == "" { + return p, http.StatusOK, nil + } + if r := strings.TrimPrefix(p, h.Prefix); len(r) < len(p) { + return r, http.StatusOK, nil + } + return p, http.StatusNotFound, errPrefixMismatch +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + status, err := http.StatusBadRequest, errUnsupportedMethod + if h.FileSystem == nil { + status, err = http.StatusInternalServerError, errNoFileSystem + } else if h.LockSystem == nil { + status, err = http.StatusInternalServerError, errNoLockSystem + } else { + switch r.Method { + case "OPTIONS": + status, err = h.handleOptions(w, r) + case "GET", "HEAD", "POST": + status, err = h.handleGetHeadPost(w, r) + case "DELETE": + status, err = h.handleDelete(w, r) + case "PUT": + status, err = h.handlePut(w, r) + case "MKCOL": + status, err = h.handleMkcol(w, r) + case "COPY", "MOVE": + status, err = h.handleCopyMove(w, r) + case "LOCK": + status, err = h.handleLock(w, r) + case "UNLOCK": + status, err = h.handleUnlock(w, r) + case "PROPFIND": + status, err = h.handlePropfind(w, r) + case "PROPPATCH": + status, err = h.handleProppatch(w, r) + } + } + + if status != 0 { + w.WriteHeader(status) + if status != http.StatusNoContent { + w.Write([]byte(StatusText(status))) + } + } + if h.Logger != nil { + h.Logger(r, err) + } +} + +func (h *Handler) lock(now time.Time, root string) (token string, status int, err error) { + token, err = h.LockSystem.Create(now, LockDetails{ + Root: root, + Duration: infiniteTimeout, + ZeroDepth: true, + }) + if err != nil { + if err == ErrLocked { + return "", StatusLocked, err + } + return "", http.StatusInternalServerError, err + } + return token, 0, nil +} + +func (h *Handler) confirmLocks(r *http.Request, src, dst string) (release func(), status int, err error) { + hdr := r.Header.Get("If") + if hdr == "" { + // An empty If header means that the client hasn't previously created locks. + // Even if this client doesn't care about locks, we still need to check that + // the resources aren't locked by another client, so we create temporary + // locks that would conflict with another client's locks. These temporary + // locks are unlocked at the end of the HTTP request. + now, srcToken, dstToken := time.Now(), "", "" + if src != "" { + srcToken, status, err = h.lock(now, src) + if err != nil { + return nil, status, err + } + } + if dst != "" { + dstToken, status, err = h.lock(now, dst) + if err != nil { + if srcToken != "" { + h.LockSystem.Unlock(now, srcToken) + } + return nil, status, err + } + } + + return func() { + if dstToken != "" { + h.LockSystem.Unlock(now, dstToken) + } + if srcToken != "" { + h.LockSystem.Unlock(now, srcToken) + } + }, 0, nil + } + + ih, ok := parseIfHeader(hdr) + if !ok { + return nil, http.StatusBadRequest, errInvalidIfHeader + } + // ih is a disjunction (OR) of ifLists, so any ifList will do. + for _, l := range ih.lists { + lsrc := l.resourceTag + if lsrc == "" { + lsrc = src + } else { + u, err := url.Parse(lsrc) + if err != nil { + continue + } + if u.Host != r.Host { + continue + } + lsrc = u.Path + } + release, err = h.LockSystem.Confirm(time.Now(), lsrc, dst, l.conditions...) + if err == ErrConfirmationFailed { + continue + } + if err != nil { + return nil, http.StatusInternalServerError, err + } + return release, 0, nil + } + // Section 10.4.1 says that "If this header is evaluated and all state lists + // fail, then the request must fail with a 412 (Precondition Failed) status." + // We follow the spec even though the cond_put_corrupt_token test case from + // the litmus test warns on seeing a 412 instead of a 423 (Locked). + return nil, http.StatusPreconditionFailed, ErrLocked +} + +func (h *Handler) handleOptions(w http.ResponseWriter, r *http.Request) (status int, err error) { + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + allow := "OPTIONS, LOCK, PUT, MKCOL" + if fi, err := h.FileSystem.Stat(reqPath); err == nil { + if fi.IsDir() { + allow = "OPTIONS, LOCK, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND" + } else { + allow = "OPTIONS, LOCK, GET, HEAD, POST, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND, PUT" + } + } + w.Header().Set("Allow", allow) + // http://www.webdav.org/specs/rfc4918.html#dav.compliance.classes + w.Header().Set("DAV", "1, 2") + // http://msdn.microsoft.com/en-au/library/cc250217.aspx + w.Header().Set("MS-Author-Via", "DAV") + return 0, nil +} + +func (h *Handler) handleGetHeadPost(w http.ResponseWriter, r *http.Request) (status int, err error) { + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + // TODO: check locks for read-only access?? + f, err := h.FileSystem.OpenFile(reqPath, os.O_RDONLY, 0) + if err != nil { + return http.StatusNotFound, err + } + defer f.Close() + fi, err := f.Stat() + if err != nil { + return http.StatusNotFound, err + } + if fi.IsDir() { + return http.StatusMethodNotAllowed, nil + } + etag, err := findETag(h.FileSystem, h.LockSystem, reqPath, fi) + if err != nil { + return http.StatusInternalServerError, err + } + w.Header().Set("ETag", etag) + // Let ServeContent determine the Content-Type header. + http.ServeContent(w, r, reqPath, fi.ModTime(), f) + return 0, nil +} + +func (h *Handler) handleDelete(w http.ResponseWriter, r *http.Request) (status int, err error) { + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + release, status, err := h.confirmLocks(r, reqPath, "") + if err != nil { + return status, err + } + defer release() + + // TODO: return MultiStatus where appropriate. + + // "godoc os RemoveAll" says that "If the path does not exist, RemoveAll + // returns nil (no error)." WebDAV semantics are that it should return a + // "404 Not Found". We therefore have to Stat before we RemoveAll. + if _, err := h.FileSystem.Stat(reqPath); err != nil { + if os.IsNotExist(err) { + return http.StatusNotFound, err + } + return http.StatusMethodNotAllowed, err + } + if err := h.FileSystem.RemoveAll(reqPath); err != nil { + return http.StatusMethodNotAllowed, err + } + return http.StatusNoContent, nil +} + +func (h *Handler) handlePut(w http.ResponseWriter, r *http.Request) (status int, err error) { + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + release, status, err := h.confirmLocks(r, reqPath, "") + if err != nil { + return status, err + } + defer release() + // TODO(rost): Support the If-Match, If-None-Match headers? See bradfitz' + // comments in http.checkEtag. + + f, err := h.FileSystem.OpenFile(reqPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + return http.StatusNotFound, err + } + _, copyErr := io.Copy(f, r.Body) + fi, statErr := f.Stat() + closeErr := f.Close() + // TODO(rost): Returning 405 Method Not Allowed might not be appropriate. + if copyErr != nil { + return http.StatusMethodNotAllowed, copyErr + } + if statErr != nil { + return http.StatusMethodNotAllowed, statErr + } + if closeErr != nil { + return http.StatusMethodNotAllowed, closeErr + } + etag, err := findETag(h.FileSystem, h.LockSystem, reqPath, fi) + if err != nil { + return http.StatusInternalServerError, err + } + w.Header().Set("ETag", etag) + return http.StatusCreated, nil +} + +func (h *Handler) handleMkcol(w http.ResponseWriter, r *http.Request) (status int, err error) { + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + release, status, err := h.confirmLocks(r, reqPath, "") + if err != nil { + return status, err + } + defer release() + + if r.ContentLength > 0 { + return http.StatusUnsupportedMediaType, nil + } + if err := h.FileSystem.Mkdir(reqPath, 0777); err != nil { + if os.IsNotExist(err) { + return http.StatusConflict, err + } + return http.StatusMethodNotAllowed, err + } + return http.StatusCreated, nil +} + +func (h *Handler) handleCopyMove(w http.ResponseWriter, r *http.Request) (status int, err error) { + hdr := r.Header.Get("Destination") + if hdr == "" { + return http.StatusBadRequest, errInvalidDestination + } + u, err := url.Parse(hdr) + if err != nil { + return http.StatusBadRequest, errInvalidDestination + } + if u.Host != r.Host { + return http.StatusBadGateway, errInvalidDestination + } + + src, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + + dst, status, err := h.stripPrefix(u.Path) + if err != nil { + return status, err + } + + if dst == "" { + return http.StatusBadGateway, errInvalidDestination + } + if dst == src { + return http.StatusForbidden, errDestinationEqualsSource + } + + if r.Method == "COPY" { + // Section 7.5.1 says that a COPY only needs to lock the destination, + // not both destination and source. Strictly speaking, this is racy, + // even though a COPY doesn't modify the source, if a concurrent + // operation modifies the source. However, the litmus test explicitly + // checks that COPYing a locked-by-another source is OK. + release, status, err := h.confirmLocks(r, "", dst) + if err != nil { + return status, err + } + defer release() + + // Section 9.8.3 says that "The COPY method on a collection without a Depth + // header must act as if a Depth header with value "infinity" was included". + depth := infiniteDepth + if hdr := r.Header.Get("Depth"); hdr != "" { + depth = parseDepth(hdr) + if depth != 0 && depth != infiniteDepth { + // Section 9.8.3 says that "A client may submit a Depth header on a + // COPY on a collection with a value of "0" or "infinity"." + return http.StatusBadRequest, errInvalidDepth + } + } + return copyFiles(h.FileSystem, src, dst, r.Header.Get("Overwrite") != "F", depth, 0) + } + + release, status, err := h.confirmLocks(r, src, dst) + if err != nil { + return status, err + } + defer release() + + // Section 9.9.2 says that "The MOVE method on a collection must act as if + // a "Depth: infinity" header was used on it. A client must not submit a + // Depth header on a MOVE on a collection with any value but "infinity"." + if hdr := r.Header.Get("Depth"); hdr != "" { + if parseDepth(hdr) != infiniteDepth { + return http.StatusBadRequest, errInvalidDepth + } + } + return moveFiles(h.FileSystem, src, dst, r.Header.Get("Overwrite") == "T") +} + +func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus int, retErr error) { + duration, err := parseTimeout(r.Header.Get("Timeout")) + if err != nil { + return http.StatusBadRequest, err + } + li, status, err := readLockInfo(r.Body) + if err != nil { + return status, err + } + + token, ld, now, created := "", LockDetails{}, time.Now(), false + if li == (lockInfo{}) { + // An empty lockInfo means to refresh the lock. + ih, ok := parseIfHeader(r.Header.Get("If")) + if !ok { + return http.StatusBadRequest, errInvalidIfHeader + } + if len(ih.lists) == 1 && len(ih.lists[0].conditions) == 1 { + token = ih.lists[0].conditions[0].Token + } + if token == "" { + return http.StatusBadRequest, errInvalidLockToken + } + ld, err = h.LockSystem.Refresh(now, token, duration) + if err != nil { + if err == ErrNoSuchLock { + return http.StatusPreconditionFailed, err + } + return http.StatusInternalServerError, err + } + + } else { + // Section 9.10.3 says that "If no Depth header is submitted on a LOCK request, + // then the request MUST act as if a "Depth:infinity" had been submitted." + depth := infiniteDepth + if hdr := r.Header.Get("Depth"); hdr != "" { + depth = parseDepth(hdr) + if depth != 0 && depth != infiniteDepth { + // Section 9.10.3 says that "Values other than 0 or infinity must not be + // used with the Depth header on a LOCK method". + return http.StatusBadRequest, errInvalidDepth + } + } + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + ld = LockDetails{ + Root: reqPath, + Duration: duration, + OwnerXML: li.Owner.InnerXML, + ZeroDepth: depth == 0, + } + token, err = h.LockSystem.Create(now, ld) + if err != nil { + if err == ErrLocked { + return StatusLocked, err + } + return http.StatusInternalServerError, err + } + defer func() { + if retErr != nil { + h.LockSystem.Unlock(now, token) + } + }() + + // Create the resource if it didn't previously exist. + if _, err := h.FileSystem.Stat(reqPath); err != nil { + f, err := h.FileSystem.OpenFile(reqPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + if err != nil { + // TODO: detect missing intermediate dirs and return http.StatusConflict? + return http.StatusInternalServerError, err + } + f.Close() + created = true + } + + // http://www.webdav.org/specs/rfc4918.html#HEADER_Lock-Token says that the + // Lock-Token value is a Coded-URL. We add angle brackets. + w.Header().Set("Lock-Token", "<"+token+">") + } + + w.Header().Set("Content-Type", "application/xml; charset=utf-8") + if created { + // This is "w.WriteHeader(http.StatusCreated)" and not "return + // http.StatusCreated, nil" because we write our own (XML) response to w + // and Handler.ServeHTTP would otherwise write "Created". + w.WriteHeader(http.StatusCreated) + } + writeLockInfo(w, token, ld) + return 0, nil +} + +func (h *Handler) handleUnlock(w http.ResponseWriter, r *http.Request) (status int, err error) { + // http://www.webdav.org/specs/rfc4918.html#HEADER_Lock-Token says that the + // Lock-Token value is a Coded-URL. We strip its angle brackets. + t := r.Header.Get("Lock-Token") + if len(t) < 2 || t[0] != '<' || t[len(t)-1] != '>' { + return http.StatusBadRequest, errInvalidLockToken + } + t = t[1 : len(t)-1] + + switch err = h.LockSystem.Unlock(time.Now(), t); err { + case nil: + return http.StatusNoContent, err + case ErrForbidden: + return http.StatusForbidden, err + case ErrLocked: + return StatusLocked, err + case ErrNoSuchLock: + return http.StatusConflict, err + default: + return http.StatusInternalServerError, err + } +} + +func (h *Handler) handlePropfind(w http.ResponseWriter, r *http.Request) (status int, err error) { + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + fi, err := h.FileSystem.Stat(reqPath) + if err != nil { + if os.IsNotExist(err) { + return http.StatusNotFound, err + } + return http.StatusMethodNotAllowed, err + } + depth := infiniteDepth + if hdr := r.Header.Get("Depth"); hdr != "" { + depth = parseDepth(hdr) + if depth == invalidDepth { + return http.StatusBadRequest, errInvalidDepth + } + } + pf, status, err := readPropfind(r.Body) + if err != nil { + return status, err + } + + mw := multistatusWriter{w: w} + + walkFn := func(reqPath string, info os.FileInfo, err error) error { + if err != nil { + return err + } + var pstats []Propstat + if pf.Propname != nil { + pnames, err := propnames(h.FileSystem, h.LockSystem, reqPath) + if err != nil { + return err + } + pstat := Propstat{Status: http.StatusOK} + for _, xmlname := range pnames { + pstat.Props = append(pstat.Props, Property{XMLName: xmlname}) + } + pstats = append(pstats, pstat) + } else if pf.Allprop != nil { + pstats, err = allprop(h.FileSystem, h.LockSystem, reqPath, pf.Prop) + } else { + pstats, err = props(h.FileSystem, h.LockSystem, reqPath, pf.Prop) + } + if err != nil { + return err + } + return mw.write(makePropstatResponse(path.Join(h.Prefix, reqPath), pstats)) + } + + walkErr := walkFS(h.FileSystem, depth, reqPath, fi, walkFn) + closeErr := mw.close() + if walkErr != nil { + return http.StatusInternalServerError, walkErr + } + if closeErr != nil { + return http.StatusInternalServerError, closeErr + } + return 0, nil +} + +func (h *Handler) handleProppatch(w http.ResponseWriter, r *http.Request) (status int, err error) { + reqPath, status, err := h.stripPrefix(r.URL.Path) + if err != nil { + return status, err + } + release, status, err := h.confirmLocks(r, reqPath, "") + if err != nil { + return status, err + } + defer release() + + if _, err := h.FileSystem.Stat(reqPath); err != nil { + if os.IsNotExist(err) { + return http.StatusNotFound, err + } + return http.StatusMethodNotAllowed, err + } + patches, status, err := readProppatch(r.Body) + if err != nil { + return status, err + } + pstats, err := patch(h.FileSystem, h.LockSystem, reqPath, patches) + if err != nil { + return http.StatusInternalServerError, err + } + mw := multistatusWriter{w: w} + writeErr := mw.write(makePropstatResponse(r.URL.Path, pstats)) + closeErr := mw.close() + if writeErr != nil { + return http.StatusInternalServerError, writeErr + } + if closeErr != nil { + return http.StatusInternalServerError, closeErr + } + return 0, nil +} + +func makePropstatResponse(href string, pstats []Propstat) *response { + resp := response{ + Href: []string{(&url.URL{Path: href}).EscapedPath()}, + Propstat: make([]propstat, 0, len(pstats)), + } + for _, p := range pstats { + var xmlErr *xmlError + if p.XMLError != "" { + xmlErr = &xmlError{InnerXML: []byte(p.XMLError)} + } + resp.Propstat = append(resp.Propstat, propstat{ + Status: fmt.Sprintf("HTTP/1.1 %d %s", p.Status, StatusText(p.Status)), + Prop: p.Props, + ResponseDescription: p.ResponseDescription, + Error: xmlErr, + }) + } + return &resp +} + +const ( + infiniteDepth = -1 + invalidDepth = -2 +) + +// parseDepth maps the strings "0", "1" and "infinity" to 0, 1 and +// infiniteDepth. Parsing any other string returns invalidDepth. +// +// Different WebDAV methods have further constraints on valid depths: +// - PROPFIND has no further restrictions, as per section 9.1. +// - COPY accepts only "0" or "infinity", as per section 9.8.3. +// - MOVE accepts only "infinity", as per section 9.9.2. +// - LOCK accepts only "0" or "infinity", as per section 9.10.3. +// These constraints are enforced by the handleXxx methods. +func parseDepth(s string) int { + switch s { + case "0": + return 0 + case "1": + return 1 + case "infinity": + return infiniteDepth + } + return invalidDepth +} + +// http://www.webdav.org/specs/rfc4918.html#status.code.extensions.to.http11 +const ( + StatusMulti = 207 + StatusUnprocessableEntity = 422 + StatusLocked = 423 + StatusFailedDependency = 424 + StatusInsufficientStorage = 507 +) + +func StatusText(code int) string { + switch code { + case StatusMulti: + return "Multi-Status" + case StatusUnprocessableEntity: + return "Unprocessable Entity" + case StatusLocked: + return "Locked" + case StatusFailedDependency: + return "Failed Dependency" + case StatusInsufficientStorage: + return "Insufficient Storage" + } + return http.StatusText(code) +} + +var ( + errDestinationEqualsSource = errors.New("webdav: destination equals source") + errDirectoryNotEmpty = errors.New("webdav: directory not empty") + errInvalidDepth = errors.New("webdav: invalid depth") + errInvalidDestination = errors.New("webdav: invalid destination") + errInvalidIfHeader = errors.New("webdav: invalid If header") + errInvalidLockInfo = errors.New("webdav: invalid lock info") + errInvalidLockToken = errors.New("webdav: invalid lock token") + errInvalidPropfind = errors.New("webdav: invalid propfind") + errInvalidProppatch = errors.New("webdav: invalid proppatch") + errInvalidResponse = errors.New("webdav: invalid response") + errInvalidTimeout = errors.New("webdav: invalid timeout") + errNoFileSystem = errors.New("webdav: no file system") + errNoLockSystem = errors.New("webdav: no lock system") + errNotADirectory = errors.New("webdav: not a directory") + errPrefixMismatch = errors.New("webdav: prefix mismatch") + errRecursionTooDeep = errors.New("webdav: recursion too deep") + errUnsupportedLockInfo = errors.New("webdav: unsupported lock info") + errUnsupportedMethod = errors.New("webdav: unsupported method") +) diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/webdav_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/webdav_test.go new file mode 100644 index 00000000..70a3bf2c --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/webdav_test.go @@ -0,0 +1,242 @@ +// 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 webdav + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/http/httptest" + "net/url" + "os" + "reflect" + "regexp" + "sort" + "strings" + "testing" +) + +// TODO: add tests to check XML responses with the expected prefix path +func TestPrefix(t *testing.T) { + const dst, blah = "Destination", "blah blah blah" + + do := func(method, urlStr string, body io.Reader, wantStatusCode int, headers ...string) error { + req, err := http.NewRequest(method, urlStr, body) + if err != nil { + return err + } + for len(headers) >= 2 { + req.Header.Add(headers[0], headers[1]) + headers = headers[2:] + } + res, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + if res.StatusCode != wantStatusCode { + return fmt.Errorf("got status code %d, want %d", res.StatusCode, wantStatusCode) + } + return nil + } + + prefixes := []string{ + "/", + "/a/", + "/a/b/", + "/a/b/c/", + } + for _, prefix := range prefixes { + fs := NewMemFS() + h := &Handler{ + FileSystem: fs, + LockSystem: NewMemLS(), + } + mux := http.NewServeMux() + if prefix != "/" { + h.Prefix = prefix + } + mux.Handle(prefix, h) + srv := httptest.NewServer(mux) + defer srv.Close() + + // The script is: + // MKCOL /a + // MKCOL /a/b + // PUT /a/b/c + // COPY /a/b/c /a/b/d + // MKCOL /a/b/e + // MOVE /a/b/d /a/b/e/f + // which should yield the (possibly stripped) filenames /a/b/c and + // /a/b/e/f, plus their parent directories. + + wantA := map[string]int{ + "/": http.StatusCreated, + "/a/": http.StatusMovedPermanently, + "/a/b/": http.StatusNotFound, + "/a/b/c/": http.StatusNotFound, + }[prefix] + if err := do("MKCOL", srv.URL+"/a", nil, wantA); err != nil { + t.Errorf("prefix=%-9q MKCOL /a: %v", prefix, err) + continue + } + + wantB := map[string]int{ + "/": http.StatusCreated, + "/a/": http.StatusCreated, + "/a/b/": http.StatusMovedPermanently, + "/a/b/c/": http.StatusNotFound, + }[prefix] + if err := do("MKCOL", srv.URL+"/a/b", nil, wantB); err != nil { + t.Errorf("prefix=%-9q MKCOL /a/b: %v", prefix, err) + continue + } + + wantC := map[string]int{ + "/": http.StatusCreated, + "/a/": http.StatusCreated, + "/a/b/": http.StatusCreated, + "/a/b/c/": http.StatusMovedPermanently, + }[prefix] + if err := do("PUT", srv.URL+"/a/b/c", strings.NewReader(blah), wantC); err != nil { + t.Errorf("prefix=%-9q PUT /a/b/c: %v", prefix, err) + continue + } + + wantD := map[string]int{ + "/": http.StatusCreated, + "/a/": http.StatusCreated, + "/a/b/": http.StatusCreated, + "/a/b/c/": http.StatusMovedPermanently, + }[prefix] + if err := do("COPY", srv.URL+"/a/b/c", nil, wantD, dst, srv.URL+"/a/b/d"); err != nil { + t.Errorf("prefix=%-9q COPY /a/b/c /a/b/d: %v", prefix, err) + continue + } + + wantE := map[string]int{ + "/": http.StatusCreated, + "/a/": http.StatusCreated, + "/a/b/": http.StatusCreated, + "/a/b/c/": http.StatusNotFound, + }[prefix] + if err := do("MKCOL", srv.URL+"/a/b/e", nil, wantE); err != nil { + t.Errorf("prefix=%-9q MKCOL /a/b/e: %v", prefix, err) + continue + } + + wantF := map[string]int{ + "/": http.StatusCreated, + "/a/": http.StatusCreated, + "/a/b/": http.StatusCreated, + "/a/b/c/": http.StatusNotFound, + }[prefix] + if err := do("MOVE", srv.URL+"/a/b/d", nil, wantF, dst, srv.URL+"/a/b/e/f"); err != nil { + t.Errorf("prefix=%-9q MOVE /a/b/d /a/b/e/f: %v", prefix, err) + continue + } + + got, err := find(nil, fs, "/") + if err != nil { + t.Errorf("prefix=%-9q find: %v", prefix, err) + continue + } + sort.Strings(got) + want := map[string][]string{ + "/": []string{"/", "/a", "/a/b", "/a/b/c", "/a/b/e", "/a/b/e/f"}, + "/a/": []string{"/", "/b", "/b/c", "/b/e", "/b/e/f"}, + "/a/b/": []string{"/", "/c", "/e", "/e/f"}, + "/a/b/c/": []string{"/"}, + }[prefix] + if !reflect.DeepEqual(got, want) { + t.Errorf("prefix=%-9q find:\ngot %v\nwant %v", prefix, got, want) + continue + } + } +} + +func TestFilenameEscape(t *testing.T) { + re := regexp.MustCompile(`([^<]*)`) + do := func(method, urlStr string) (string, error) { + req, err := http.NewRequest(method, urlStr, nil) + if err != nil { + return "", err + } + res, err := http.DefaultClient.Do(req) + if err != nil { + return "", err + } + defer res.Body.Close() + + b, err := ioutil.ReadAll(res.Body) + if err != nil { + return "", err + } + m := re.FindStringSubmatch(string(b)) + if len(m) != 2 { + return "", errors.New("D:href not found") + } + + return m[1], nil + } + + testCases := []struct { + name, want string + }{{ + name: `/foo%bar`, + want: `/foo%25bar`, + }, { + name: `/こんにちわ世界`, + want: `/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%82%8F%E4%B8%96%E7%95%8C`, + }, { + name: `/Program Files/`, + want: `/Program%20Files`, + }, { + name: `/go+lang`, + want: `/go+lang`, + }, { + name: `/go&lang`, + want: `/go&lang`, + }} + fs := NewMemFS() + for _, tc := range testCases { + if strings.HasSuffix(tc.name, "/") { + if err := fs.Mkdir(tc.name, 0755); err != nil { + t.Fatalf("name=%q: Mkdir: %v", tc.name, err) + } + } else { + f, err := fs.OpenFile(tc.name, os.O_CREATE, 0644) + if err != nil { + t.Fatalf("name=%q: OpenFile: %v", tc.name, err) + } + f.Close() + } + } + + srv := httptest.NewServer(&Handler{ + FileSystem: fs, + LockSystem: NewMemLS(), + }) + defer srv.Close() + + u, err := url.Parse(srv.URL) + if err != nil { + t.Fatal(err) + } + + for _, tc := range testCases { + u.Path = tc.name + got, err := do("PROPFIND", u.String()) + if err != nil { + t.Errorf("name=%q: PROPFIND: %v", tc.name, err) + continue + } + if got != tc.want { + t.Errorf("name=%q: got %q, want %q", tc.name, got, tc.want) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/xml.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/xml.go new file mode 100644 index 00000000..8705cda2 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/xml.go @@ -0,0 +1,469 @@ +// 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. + +package webdav + +// The XML encoding is covered by Section 14. +// http://www.webdav.org/specs/rfc4918.html#xml.element.definitions + +import ( + "bytes" + "fmt" + "io" + "net/http" + "time" + + "golang.org/x/net/webdav/internal/xml" +) + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_lockinfo +type lockInfo struct { + XMLName xml.Name `xml:"lockinfo"` + Exclusive *struct{} `xml:"lockscope>exclusive"` + Shared *struct{} `xml:"lockscope>shared"` + Write *struct{} `xml:"locktype>write"` + Owner owner `xml:"owner"` +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_owner +type owner struct { + InnerXML string `xml:",innerxml"` +} + +func readLockInfo(r io.Reader) (li lockInfo, status int, err error) { + c := &countingReader{r: r} + if err = xml.NewDecoder(c).Decode(&li); err != nil { + if err == io.EOF { + if c.n == 0 { + // An empty body means to refresh the lock. + // http://www.webdav.org/specs/rfc4918.html#refreshing-locks + return lockInfo{}, 0, nil + } + err = errInvalidLockInfo + } + return lockInfo{}, http.StatusBadRequest, err + } + // We only support exclusive (non-shared) write locks. In practice, these are + // the only types of locks that seem to matter. + if li.Exclusive == nil || li.Shared != nil || li.Write == nil { + return lockInfo{}, http.StatusNotImplemented, errUnsupportedLockInfo + } + return li, 0, nil +} + +type countingReader struct { + n int + r io.Reader +} + +func (c *countingReader) Read(p []byte) (int, error) { + n, err := c.r.Read(p) + c.n += n + return n, err +} + +func writeLockInfo(w io.Writer, token string, ld LockDetails) (int, error) { + depth := "infinity" + if ld.ZeroDepth { + depth = "0" + } + timeout := ld.Duration / time.Second + return fmt.Fprintf(w, "\n"+ + "\n"+ + " \n"+ + " \n"+ + " %s\n"+ + " %s\n"+ + " Second-%d\n"+ + " %s\n"+ + " %s\n"+ + "", + depth, ld.OwnerXML, timeout, escape(token), escape(ld.Root), + ) +} + +func escape(s string) string { + for i := 0; i < len(s); i++ { + switch s[i] { + case '"', '&', '\'', '<', '>': + b := bytes.NewBuffer(nil) + xml.EscapeText(b, []byte(s)) + return b.String() + } + } + return s +} + +// Next returns the next token, if any, in the XML stream of d. +// RFC 4918 requires to ignore comments, processing instructions +// and directives. +// http://www.webdav.org/specs/rfc4918.html#property_values +// http://www.webdav.org/specs/rfc4918.html#xml-extensibility +func next(d *xml.Decoder) (xml.Token, error) { + for { + t, err := d.Token() + if err != nil { + return t, err + } + switch t.(type) { + case xml.Comment, xml.Directive, xml.ProcInst: + continue + default: + return t, nil + } + } +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for propfind) +type propfindProps []xml.Name + +// UnmarshalXML appends the property names enclosed within start to pn. +// +// It returns an error if start does not contain any properties or if +// properties contain values. Character data between properties is ignored. +func (pn *propfindProps) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + for { + t, err := next(d) + if err != nil { + return err + } + switch t.(type) { + case xml.EndElement: + if len(*pn) == 0 { + return fmt.Errorf("%s must not be empty", start.Name.Local) + } + return nil + case xml.StartElement: + name := t.(xml.StartElement).Name + t, err = next(d) + if err != nil { + return err + } + if _, ok := t.(xml.EndElement); !ok { + return fmt.Errorf("unexpected token %T", t) + } + *pn = append(*pn, name) + } + } +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propfind +type propfind struct { + XMLName xml.Name `xml:"DAV: propfind"` + Allprop *struct{} `xml:"DAV: allprop"` + Propname *struct{} `xml:"DAV: propname"` + Prop propfindProps `xml:"DAV: prop"` + Include propfindProps `xml:"DAV: include"` +} + +func readPropfind(r io.Reader) (pf propfind, status int, err error) { + c := countingReader{r: r} + if err = xml.NewDecoder(&c).Decode(&pf); err != nil { + if err == io.EOF { + if c.n == 0 { + // An empty body means to propfind allprop. + // http://www.webdav.org/specs/rfc4918.html#METHOD_PROPFIND + return propfind{Allprop: new(struct{})}, 0, nil + } + err = errInvalidPropfind + } + return propfind{}, http.StatusBadRequest, err + } + + if pf.Allprop == nil && pf.Include != nil { + return propfind{}, http.StatusBadRequest, errInvalidPropfind + } + if pf.Allprop != nil && (pf.Prop != nil || pf.Propname != nil) { + return propfind{}, http.StatusBadRequest, errInvalidPropfind + } + if pf.Prop != nil && pf.Propname != nil { + return propfind{}, http.StatusBadRequest, errInvalidPropfind + } + if pf.Propname == nil && pf.Allprop == nil && pf.Prop == nil { + return propfind{}, http.StatusBadRequest, errInvalidPropfind + } + return pf, 0, nil +} + +// Property represents a single DAV resource property as defined in RFC 4918. +// See http://www.webdav.org/specs/rfc4918.html#data.model.for.resource.properties +type Property struct { + // XMLName is the fully qualified name that identifies this property. + XMLName xml.Name + + // Lang is an optional xml:lang attribute. + Lang string `xml:"xml:lang,attr,omitempty"` + + // InnerXML contains the XML representation of the property value. + // See http://www.webdav.org/specs/rfc4918.html#property_values + // + // Property values of complex type or mixed-content must have fully + // expanded XML namespaces or be self-contained with according + // XML namespace declarations. They must not rely on any XML + // namespace declarations within the scope of the XML document, + // even including the DAV: namespace. + InnerXML []byte `xml:",innerxml"` +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_error +// See multistatusWriter for the "D:" namespace prefix. +type xmlError struct { + XMLName xml.Name `xml:"D:error"` + InnerXML []byte `xml:",innerxml"` +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propstat +// See multistatusWriter for the "D:" namespace prefix. +type propstat struct { + Prop []Property `xml:"D:prop>_ignored_"` + Status string `xml:"D:status"` + Error *xmlError `xml:"D:error"` + ResponseDescription string `xml:"D:responsedescription,omitempty"` +} + +// MarshalXML prepends the "D:" namespace prefix on properties in the DAV: namespace +// before encoding. See multistatusWriter. +func (ps propstat) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + for k, prop := range ps.Prop { + if prop.XMLName.Space == "DAV:" { + prop.XMLName = xml.Name{Space: "", Local: "D:" + prop.XMLName.Local} + ps.Prop[k] = prop + } + } + // Distinct type to avoid infinite recursion of MarshalXML. + type newpropstat propstat + return e.EncodeElement(newpropstat(ps), start) +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_response +// See multistatusWriter for the "D:" namespace prefix. +type response struct { + XMLName xml.Name `xml:"D:response"` + Href []string `xml:"D:href"` + Propstat []propstat `xml:"D:propstat"` + Status string `xml:"D:status,omitempty"` + Error *xmlError `xml:"D:error"` + ResponseDescription string `xml:"D:responsedescription,omitempty"` +} + +// MultistatusWriter marshals one or more Responses into a XML +// multistatus response. +// See http://www.webdav.org/specs/rfc4918.html#ELEMENT_multistatus +// TODO(rsto, mpl): As a workaround, the "D:" namespace prefix, defined as +// "DAV:" on this element, is prepended on the nested response, as well as on all +// its nested elements. All property names in the DAV: namespace are prefixed as +// well. This is because some versions of Mini-Redirector (on windows 7) ignore +// elements with a default namespace (no prefixed namespace). A less intrusive fix +// should be possible after golang.org/cl/11074. See https://golang.org/issue/11177 +type multistatusWriter struct { + // ResponseDescription contains the optional responsedescription + // of the multistatus XML element. Only the latest content before + // close will be emitted. Empty response descriptions are not + // written. + responseDescription string + + w http.ResponseWriter + enc *xml.Encoder +} + +// Write validates and emits a DAV response as part of a multistatus response +// element. +// +// It sets the HTTP status code of its underlying http.ResponseWriter to 207 +// (Multi-Status) and populates the Content-Type header. If r is the +// first, valid response to be written, Write prepends the XML representation +// of r with a multistatus tag. Callers must call close after the last response +// has been written. +func (w *multistatusWriter) write(r *response) error { + switch len(r.Href) { + case 0: + return errInvalidResponse + case 1: + if len(r.Propstat) > 0 != (r.Status == "") { + return errInvalidResponse + } + default: + if len(r.Propstat) > 0 || r.Status == "" { + return errInvalidResponse + } + } + err := w.writeHeader() + if err != nil { + return err + } + return w.enc.Encode(r) +} + +// writeHeader writes a XML multistatus start element on w's underlying +// http.ResponseWriter and returns the result of the write operation. +// After the first write attempt, writeHeader becomes a no-op. +func (w *multistatusWriter) writeHeader() error { + if w.enc != nil { + return nil + } + w.w.Header().Add("Content-Type", "text/xml; charset=utf-8") + w.w.WriteHeader(StatusMulti) + _, err := fmt.Fprintf(w.w, ``) + if err != nil { + return err + } + w.enc = xml.NewEncoder(w.w) + return w.enc.EncodeToken(xml.StartElement{ + Name: xml.Name{ + Space: "DAV:", + Local: "multistatus", + }, + Attr: []xml.Attr{{ + Name: xml.Name{Space: "xmlns", Local: "D"}, + Value: "DAV:", + }}, + }) +} + +// Close completes the marshalling of the multistatus response. It returns +// an error if the multistatus response could not be completed. If both the +// return value and field enc of w are nil, then no multistatus response has +// been written. +func (w *multistatusWriter) close() error { + if w.enc == nil { + return nil + } + var end []xml.Token + if w.responseDescription != "" { + name := xml.Name{Space: "DAV:", Local: "responsedescription"} + end = append(end, + xml.StartElement{Name: name}, + xml.CharData(w.responseDescription), + xml.EndElement{Name: name}, + ) + } + end = append(end, xml.EndElement{ + Name: xml.Name{Space: "DAV:", Local: "multistatus"}, + }) + for _, t := range end { + err := w.enc.EncodeToken(t) + if err != nil { + return err + } + } + return w.enc.Flush() +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_prop (for proppatch) +type proppatchProps []Property + +var xmlLangName = xml.Name{Space: "http://www.w3.org/XML/1998/namespace", Local: "lang"} + +func xmlLang(s xml.StartElement, d string) string { + for _, attr := range s.Attr { + if attr.Name == xmlLangName { + return attr.Value + } + } + return d +} + +type xmlValue []byte + +func (v *xmlValue) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + // The XML value of a property can be arbitrary, mixed-content XML. + // To make sure that the unmarshalled value contains all required + // namespaces, we encode all the property value XML tokens into a + // buffer. This forces the encoder to redeclare any used namespaces. + var b bytes.Buffer + e := xml.NewEncoder(&b) + for { + t, err := next(d) + if err != nil { + return err + } + if e, ok := t.(xml.EndElement); ok && e.Name == start.Name { + break + } + if err = e.EncodeToken(t); err != nil { + return err + } + } + err := e.Flush() + if err != nil { + return err + } + *v = b.Bytes() + return nil +} + +// UnmarshalXML appends the property names and values enclosed within start +// to ps. +// +// An xml:lang attribute that is defined either on the DAV:prop or property +// name XML element is propagated to the property's Lang field. +// +// UnmarshalXML returns an error if start does not contain any properties or if +// property values contain syntactically incorrect XML. +func (ps *proppatchProps) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + lang := xmlLang(start, "") + for { + t, err := next(d) + if err != nil { + return err + } + switch elem := t.(type) { + case xml.EndElement: + if len(*ps) == 0 { + return fmt.Errorf("%s must not be empty", start.Name.Local) + } + return nil + case xml.StartElement: + p := Property{ + XMLName: t.(xml.StartElement).Name, + Lang: xmlLang(t.(xml.StartElement), lang), + } + err = d.DecodeElement(((*xmlValue)(&p.InnerXML)), &elem) + if err != nil { + return err + } + *ps = append(*ps, p) + } + } +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_set +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_remove +type setRemove struct { + XMLName xml.Name + Lang string `xml:"xml:lang,attr,omitempty"` + Prop proppatchProps `xml:"DAV: prop"` +} + +// http://www.webdav.org/specs/rfc4918.html#ELEMENT_propertyupdate +type propertyupdate struct { + XMLName xml.Name `xml:"DAV: propertyupdate"` + Lang string `xml:"xml:lang,attr,omitempty"` + SetRemove []setRemove `xml:",any"` +} + +func readProppatch(r io.Reader) (patches []Proppatch, status int, err error) { + var pu propertyupdate + if err = xml.NewDecoder(r).Decode(&pu); err != nil { + return nil, http.StatusBadRequest, err + } + for _, op := range pu.SetRemove { + remove := false + switch op.XMLName { + case xml.Name{Space: "DAV:", Local: "set"}: + // No-op. + case xml.Name{Space: "DAV:", Local: "remove"}: + for _, p := range op.Prop { + if len(p.InnerXML) > 0 { + return nil, http.StatusBadRequest, errInvalidProppatch + } + } + remove = true + default: + return nil, http.StatusBadRequest, errInvalidProppatch + } + patches = append(patches, Proppatch{Remove: remove, Props: op.Prop}) + } + return patches, 0, nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/xml_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/xml_test.go new file mode 100644 index 00000000..bc5641f4 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/webdav/xml_test.go @@ -0,0 +1,909 @@ +// 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. + +package webdav + +import ( + "bytes" + "fmt" + "io" + "net/http" + "net/http/httptest" + "reflect" + "sort" + "strings" + "testing" + + "golang.org/x/net/webdav/internal/xml" +) + +func TestReadLockInfo(t *testing.T) { + // The "section x.y.z" test cases come from section x.y.z of the spec at + // http://www.webdav.org/specs/rfc4918.html + testCases := []struct { + desc string + input string + wantLI lockInfo + wantStatus int + }{{ + "bad: junk", + "xxx", + lockInfo{}, + http.StatusBadRequest, + }, { + "bad: invalid owner XML", + "" + + "\n" + + " \n" + + " \n" + + " \n" + + " no end tag \n" + + " \n" + + "", + lockInfo{}, + http.StatusBadRequest, + }, { + "bad: invalid UTF-8", + "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \xff \n" + + " \n" + + "", + lockInfo{}, + http.StatusBadRequest, + }, { + "bad: unfinished XML #1", + "" + + "\n" + + " \n" + + " \n", + lockInfo{}, + http.StatusBadRequest, + }, { + "bad: unfinished XML #2", + "" + + "\n" + + " \n" + + " \n" + + " \n", + lockInfo{}, + http.StatusBadRequest, + }, { + "good: empty", + "", + lockInfo{}, + 0, + }, { + "good: plain-text owner", + "" + + "\n" + + " \n" + + " \n" + + " gopher\n" + + "", + lockInfo{ + XMLName: xml.Name{Space: "DAV:", Local: "lockinfo"}, + Exclusive: new(struct{}), + Write: new(struct{}), + Owner: owner{ + InnerXML: "gopher", + }, + }, + 0, + }, { + "section 9.10.7", + "" + + "\n" + + " \n" + + " \n" + + " \n" + + " http://example.org/~ejw/contact.html\n" + + " \n" + + "", + lockInfo{ + XMLName: xml.Name{Space: "DAV:", Local: "lockinfo"}, + Exclusive: new(struct{}), + Write: new(struct{}), + Owner: owner{ + InnerXML: "\n http://example.org/~ejw/contact.html\n ", + }, + }, + 0, + }} + + for _, tc := range testCases { + li, status, err := readLockInfo(strings.NewReader(tc.input)) + if tc.wantStatus != 0 { + if err == nil { + t.Errorf("%s: got nil error, want non-nil", tc.desc) + continue + } + } else if err != nil { + t.Errorf("%s: %v", tc.desc, err) + continue + } + if !reflect.DeepEqual(li, tc.wantLI) || status != tc.wantStatus { + t.Errorf("%s:\ngot lockInfo=%v, status=%v\nwant lockInfo=%v, status=%v", + tc.desc, li, status, tc.wantLI, tc.wantStatus) + continue + } + } +} + +func TestReadPropfind(t *testing.T) { + testCases := []struct { + desc string + input string + wantPF propfind + wantStatus int + }{{ + desc: "propfind: propname", + input: "" + + "\n" + + " \n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Propname: new(struct{}), + }, + }, { + desc: "propfind: empty body means allprop", + input: "", + wantPF: propfind{ + Allprop: new(struct{}), + }, + }, { + desc: "propfind: allprop", + input: "" + + "\n" + + " \n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Allprop: new(struct{}), + }, + }, { + desc: "propfind: allprop followed by include", + input: "" + + "\n" + + " \n" + + " \n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Allprop: new(struct{}), + Include: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}}, + }, + }, { + desc: "propfind: include followed by allprop", + input: "" + + "\n" + + " \n" + + " \n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Allprop: new(struct{}), + Include: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}}, + }, + }, { + desc: "propfind: propfind", + input: "" + + "\n" + + " \n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}}, + }, + }, { + desc: "propfind: prop with ignored comments", + input: "" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}}, + }, + }, { + desc: "propfind: propfind with ignored whitespace", + input: "" + + "\n" + + " \n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}}, + }, + }, { + desc: "propfind: propfind with ignored mixed-content", + input: "" + + "\n" + + " foobar\n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Prop: propfindProps{xml.Name{Space: "DAV:", Local: "displayname"}}, + }, + }, { + desc: "propfind: propname with ignored element (section A.4)", + input: "" + + "\n" + + " \n" + + " *boss*\n" + + "", + wantPF: propfind{ + XMLName: xml.Name{Space: "DAV:", Local: "propfind"}, + Propname: new(struct{}), + }, + }, { + desc: "propfind: bad: junk", + input: "xxx", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: propname and allprop (section A.3)", + input: "" + + "\n" + + " " + + " " + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: propname and prop", + input: "" + + "\n" + + " \n" + + " \n" + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: allprop and prop", + input: "" + + "\n" + + " \n" + + " \n" + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: empty propfind with ignored element (section A.4)", + input: "" + + "\n" + + " \n" + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: empty prop", + input: "" + + "\n" + + " \n" + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: prop with just chardata", + input: "" + + "\n" + + " foo\n" + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "bad: interrupted prop", + input: "" + + "\n" + + " \n", + wantStatus: http.StatusBadRequest, + }, { + desc: "bad: malformed end element prop", + input: "" + + "\n" + + " \n", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: property with chardata value", + input: "" + + "\n" + + " bar\n" + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: property with whitespace value", + input: "" + + "\n" + + " \n" + + "", + wantStatus: http.StatusBadRequest, + }, { + desc: "propfind: bad: include without allprop", + input: "" + + "\n" + + " \n" + + "", + wantStatus: http.StatusBadRequest, + }} + + for _, tc := range testCases { + pf, status, err := readPropfind(strings.NewReader(tc.input)) + if tc.wantStatus != 0 { + if err == nil { + t.Errorf("%s: got nil error, want non-nil", tc.desc) + continue + } + } else if err != nil { + t.Errorf("%s: %v", tc.desc, err) + continue + } + if !reflect.DeepEqual(pf, tc.wantPF) || status != tc.wantStatus { + t.Errorf("%s:\ngot propfind=%v, status=%v\nwant propfind=%v, status=%v", + tc.desc, pf, status, tc.wantPF, tc.wantStatus) + continue + } + } +} + +func TestMultistatusWriter(t *testing.T) { + if go1Dot4 { + t.Skip("TestMultistatusWriter requires Go version 1.5 or greater") + } + + ///The "section x.y.z" test cases come from section x.y.z of the spec at + // http://www.webdav.org/specs/rfc4918.html + testCases := []struct { + desc string + responses []response + respdesc string + writeHeader bool + wantXML string + wantCode int + wantErr error + }{{ + desc: "section 9.2.2 (failed dependency)", + responses: []response{{ + Href: []string{"http://example.com/foo"}, + Propstat: []propstat{{ + Prop: []Property{{ + XMLName: xml.Name{ + Space: "http://ns.example.com/", + Local: "Authors", + }, + }}, + Status: "HTTP/1.1 424 Failed Dependency", + }, { + Prop: []Property{{ + XMLName: xml.Name{ + Space: "http://ns.example.com/", + Local: "Copyright-Owner", + }, + }}, + Status: "HTTP/1.1 409 Conflict", + }}, + ResponseDescription: "Copyright Owner cannot be deleted or altered.", + }}, + wantXML: `` + + `` + + `` + + ` ` + + ` http://example.com/foo` + + ` ` + + ` ` + + ` ` + + ` ` + + ` HTTP/1.1 424 Failed Dependency` + + ` ` + + ` ` + + ` ` + + ` ` + + ` ` + + ` HTTP/1.1 409 Conflict` + + ` ` + + ` Copyright Owner cannot be deleted or altered.` + + `` + + ``, + wantCode: StatusMulti, + }, { + desc: "section 9.6.2 (lock-token-submitted)", + responses: []response{{ + Href: []string{"http://example.com/foo"}, + Status: "HTTP/1.1 423 Locked", + Error: &xmlError{ + InnerXML: []byte(``), + }, + }}, + wantXML: `` + + `` + + `` + + ` ` + + ` http://example.com/foo` + + ` HTTP/1.1 423 Locked` + + ` ` + + ` ` + + ``, + wantCode: StatusMulti, + }, { + desc: "section 9.1.3", + responses: []response{{ + Href: []string{"http://example.com/foo"}, + Propstat: []propstat{{ + Prop: []Property{{ + XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "bigbox"}, + InnerXML: []byte(`` + + `` + + `Box type A` + + ``), + }, { + XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "author"}, + InnerXML: []byte(`` + + `` + + `J.J. Johnson` + + ``), + }}, + Status: "HTTP/1.1 200 OK", + }, { + Prop: []Property{{ + XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "DingALing"}, + }, { + XMLName: xml.Name{Space: "http://ns.example.com/boxschema/", Local: "Random"}, + }}, + Status: "HTTP/1.1 403 Forbidden", + ResponseDescription: "The user does not have access to the DingALing property.", + }}, + }}, + respdesc: "There has been an access violation error.", + wantXML: `` + + `` + + `` + + ` ` + + ` http://example.com/foo` + + ` ` + + ` ` + + ` Box type A` + + ` J.J. Johnson` + + ` ` + + ` HTTP/1.1 200 OK` + + ` ` + + ` ` + + ` ` + + ` ` + + ` ` + + ` ` + + ` HTTP/1.1 403 Forbidden` + + ` The user does not have access to the DingALing property.` + + ` ` + + ` ` + + ` There has been an access violation error.` + + ``, + wantCode: StatusMulti, + }, { + desc: "no response written", + // default of http.responseWriter + wantCode: http.StatusOK, + }, { + desc: "no response written (with description)", + respdesc: "too bad", + // default of http.responseWriter + wantCode: http.StatusOK, + }, { + desc: "empty multistatus with header", + writeHeader: true, + wantXML: ``, + wantCode: StatusMulti, + }, { + desc: "bad: no href", + responses: []response{{ + Propstat: []propstat{{ + Prop: []Property{{ + XMLName: xml.Name{ + Space: "http://example.com/", + Local: "foo", + }, + }}, + Status: "HTTP/1.1 200 OK", + }}, + }}, + wantErr: errInvalidResponse, + // default of http.responseWriter + wantCode: http.StatusOK, + }, { + desc: "bad: multiple hrefs and no status", + responses: []response{{ + Href: []string{"http://example.com/foo", "http://example.com/bar"}, + }}, + wantErr: errInvalidResponse, + // default of http.responseWriter + wantCode: http.StatusOK, + }, { + desc: "bad: one href and no propstat", + responses: []response{{ + Href: []string{"http://example.com/foo"}, + }}, + wantErr: errInvalidResponse, + // default of http.responseWriter + wantCode: http.StatusOK, + }, { + desc: "bad: status with one href and propstat", + responses: []response{{ + Href: []string{"http://example.com/foo"}, + Propstat: []propstat{{ + Prop: []Property{{ + XMLName: xml.Name{ + Space: "http://example.com/", + Local: "foo", + }, + }}, + Status: "HTTP/1.1 200 OK", + }}, + Status: "HTTP/1.1 200 OK", + }}, + wantErr: errInvalidResponse, + // default of http.responseWriter + wantCode: http.StatusOK, + }, { + desc: "bad: multiple hrefs and propstat", + responses: []response{{ + Href: []string{ + "http://example.com/foo", + "http://example.com/bar", + }, + Propstat: []propstat{{ + Prop: []Property{{ + XMLName: xml.Name{ + Space: "http://example.com/", + Local: "foo", + }, + }}, + Status: "HTTP/1.1 200 OK", + }}, + }}, + wantErr: errInvalidResponse, + // default of http.responseWriter + wantCode: http.StatusOK, + }} + + n := xmlNormalizer{omitWhitespace: true} +loop: + for _, tc := range testCases { + rec := httptest.NewRecorder() + w := multistatusWriter{w: rec, responseDescription: tc.respdesc} + if tc.writeHeader { + if err := w.writeHeader(); err != nil { + t.Errorf("%s: got writeHeader error %v, want nil", tc.desc, err) + continue + } + } + for _, r := range tc.responses { + if err := w.write(&r); err != nil { + if err != tc.wantErr { + t.Errorf("%s: got write error %v, want %v", + tc.desc, err, tc.wantErr) + } + continue loop + } + } + if err := w.close(); err != tc.wantErr { + t.Errorf("%s: got close error %v, want %v", + tc.desc, err, tc.wantErr) + continue + } + if rec.Code != tc.wantCode { + t.Errorf("%s: got HTTP status code %d, want %d\n", + tc.desc, rec.Code, tc.wantCode) + continue + } + gotXML := rec.Body.String() + eq, err := n.equalXML(strings.NewReader(gotXML), strings.NewReader(tc.wantXML)) + if err != nil { + t.Errorf("%s: equalXML: %v", tc.desc, err) + continue + } + if !eq { + t.Errorf("%s: XML body\ngot %s\nwant %s", tc.desc, gotXML, tc.wantXML) + } + } +} + +func TestReadProppatch(t *testing.T) { + ppStr := func(pps []Proppatch) string { + var outer []string + for _, pp := range pps { + var inner []string + for _, p := range pp.Props { + inner = append(inner, fmt.Sprintf("{XMLName: %q, Lang: %q, InnerXML: %q}", + p.XMLName, p.Lang, p.InnerXML)) + } + outer = append(outer, fmt.Sprintf("{Remove: %t, Props: [%s]}", + pp.Remove, strings.Join(inner, ", "))) + } + return "[" + strings.Join(outer, ", ") + "]" + } + + testCases := []struct { + desc string + input string + wantPP []Proppatch + wantStatus int + }{{ + desc: "proppatch: section 9.2 (with simple property value)", + input: `` + + `` + + `` + + ` ` + + ` somevalue` + + ` ` + + ` ` + + ` ` + + ` ` + + ``, + wantPP: []Proppatch{{ + Props: []Property{{ + xml.Name{Space: "http://ns.example.com/z/", Local: "Authors"}, + "", + []byte(`somevalue`), + }}, + }, { + Remove: true, + Props: []Property{{ + xml.Name{Space: "http://ns.example.com/z/", Local: "Copyright-Owner"}, + "", + nil, + }}, + }}, + }, { + desc: "proppatch: lang attribute on prop", + input: `` + + `` + + `` + + ` ` + + ` ` + + ` ` + + ` ` + + ` ` + + ``, + wantPP: []Proppatch{{ + Props: []Property{{ + xml.Name{Space: "http://example.com/ns", Local: "foo"}, + "en", + nil, + }}, + }}, + }, { + desc: "bad: remove with value", + input: `` + + `` + + `` + + ` ` + + ` ` + + ` ` + + ` Jim Whitehead` + + ` ` + + ` ` + + ` ` + + ``, + wantStatus: http.StatusBadRequest, + }, { + desc: "bad: empty propertyupdate", + input: `` + + `` + + ``, + wantStatus: http.StatusBadRequest, + }, { + desc: "bad: empty prop", + input: `` + + `` + + `` + + ` ` + + ` ` + + ` ` + + ``, + wantStatus: http.StatusBadRequest, + }} + + for _, tc := range testCases { + pp, status, err := readProppatch(strings.NewReader(tc.input)) + if tc.wantStatus != 0 { + if err == nil { + t.Errorf("%s: got nil error, want non-nil", tc.desc) + continue + } + } else if err != nil { + t.Errorf("%s: %v", tc.desc, err) + continue + } + if status != tc.wantStatus { + t.Errorf("%s: got status %d, want %d", tc.desc, status, tc.wantStatus) + continue + } + if !reflect.DeepEqual(pp, tc.wantPP) || status != tc.wantStatus { + t.Errorf("%s: proppatch\ngot %v\nwant %v", tc.desc, ppStr(pp), ppStr(tc.wantPP)) + } + } +} + +func TestUnmarshalXMLValue(t *testing.T) { + testCases := []struct { + desc string + input string + wantVal string + }{{ + desc: "simple char data", + input: "foo", + wantVal: "foo", + }, { + desc: "empty element", + input: "", + wantVal: "", + }, { + desc: "preserve namespace", + input: ``, + wantVal: ``, + }, { + desc: "preserve root element namespace", + input: ``, + wantVal: ``, + }, { + desc: "preserve whitespace", + input: " \t ", + wantVal: " \t ", + }, { + desc: "preserve mixed content", + input: ` a `, + wantVal: ` a `, + }, { + desc: "section 9.2", + input: `` + + `` + + ` Jim Whitehead` + + ` Roy Fielding` + + ``, + wantVal: `` + + ` Jim Whitehead` + + ` Roy Fielding`, + }, { + desc: "section 4.3.1 (mixed content)", + input: `` + + `` + + ` Jane Doe` + + ` ` + + ` mailto:jane.doe@example.com` + + ` http://www.example.com` + + ` ` + + ` Jane has been working way too long on the` + + ` long-awaited revision of ]]>.` + + ` ` + + ``, + wantVal: `` + + ` Jane Doe` + + ` ` + + ` mailto:jane.doe@example.com` + + ` http://www.example.com` + + ` ` + + ` Jane has been working way too long on the` + + ` long-awaited revision of <RFC2518>.` + + ` `, + }} + + var n xmlNormalizer + for _, tc := range testCases { + d := xml.NewDecoder(strings.NewReader(tc.input)) + var v xmlValue + if err := d.Decode(&v); err != nil { + t.Errorf("%s: got error %v, want nil", tc.desc, err) + continue + } + eq, err := n.equalXML(bytes.NewReader(v), strings.NewReader(tc.wantVal)) + if err != nil { + t.Errorf("%s: equalXML: %v", tc.desc, err) + continue + } + if !eq { + t.Errorf("%s:\ngot %s\nwant %s", tc.desc, string(v), tc.wantVal) + } + } +} + +// xmlNormalizer normalizes XML. +type xmlNormalizer struct { + // omitWhitespace instructs to ignore whitespace between element tags. + omitWhitespace bool + // omitComments instructs to ignore XML comments. + omitComments bool +} + +// normalize writes the normalized XML content of r to w. It applies the +// following rules +// +// * Rename namespace prefixes according to an internal heuristic. +// * Remove unnecessary namespace declarations. +// * Sort attributes in XML start elements in lexical order of their +// fully qualified name. +// * Remove XML directives and processing instructions. +// * Remove CDATA between XML tags that only contains whitespace, if +// instructed to do so. +// * Remove comments, if instructed to do so. +// +func (n *xmlNormalizer) normalize(w io.Writer, r io.Reader) error { + d := xml.NewDecoder(r) + e := xml.NewEncoder(w) + for { + t, err := d.Token() + if err != nil { + if t == nil && err == io.EOF { + break + } + return err + } + switch val := t.(type) { + case xml.Directive, xml.ProcInst: + continue + case xml.Comment: + if n.omitComments { + continue + } + case xml.CharData: + if n.omitWhitespace && len(bytes.TrimSpace(val)) == 0 { + continue + } + case xml.StartElement: + start, _ := xml.CopyToken(val).(xml.StartElement) + attr := start.Attr[:0] + for _, a := range start.Attr { + if a.Name.Space == "xmlns" || a.Name.Local == "xmlns" { + continue + } + attr = append(attr, a) + } + sort.Sort(byName(attr)) + start.Attr = attr + t = start + } + err = e.EncodeToken(t) + if err != nil { + return err + } + } + return e.Flush() +} + +// equalXML tests for equality of the normalized XML contents of a and b. +func (n *xmlNormalizer) equalXML(a, b io.Reader) (bool, error) { + var buf bytes.Buffer + if err := n.normalize(&buf, a); err != nil { + return false, err + } + normA := buf.String() + buf.Reset() + if err := n.normalize(&buf, b); err != nil { + return false, err + } + normB := buf.String() + return normA == normB, nil +} + +type byName []xml.Attr + +func (a byName) Len() int { return len(a) } +func (a byName) Swap(i, j int) { a[i], a[j] = a[j], a[i] } +func (a byName) Less(i, j int) bool { + if a[i].Name.Space != a[j].Name.Space { + return a[i].Name.Space < a[j].Name.Space + } + return a[i].Name.Local < a[j].Name.Local +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/client.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/client.go new file mode 100644 index 00000000..20d1e1e3 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/client.go @@ -0,0 +1,113 @@ +// Copyright 2009 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 websocket + +import ( + "bufio" + "crypto/tls" + "io" + "net" + "net/http" + "net/url" +) + +// DialError is an error that occurs while dialling a websocket server. +type DialError struct { + *Config + Err error +} + +func (e *DialError) Error() string { + return "websocket.Dial " + e.Config.Location.String() + ": " + e.Err.Error() +} + +// NewConfig creates a new WebSocket config for client connection. +func NewConfig(server, origin string) (config *Config, err error) { + config = new(Config) + config.Version = ProtocolVersionHybi13 + config.Location, err = url.ParseRequestURI(server) + if err != nil { + return + } + config.Origin, err = url.ParseRequestURI(origin) + if err != nil { + return + } + config.Header = http.Header(make(map[string][]string)) + return +} + +// NewClient creates a new WebSocket client connection over rwc. +func NewClient(config *Config, rwc io.ReadWriteCloser) (ws *Conn, err error) { + br := bufio.NewReader(rwc) + bw := bufio.NewWriter(rwc) + err = hybiClientHandshake(config, br, bw) + if err != nil { + return + } + buf := bufio.NewReadWriter(br, bw) + ws = newHybiClientConn(config, buf, rwc) + return +} + +// Dial opens a new client connection to a WebSocket. +func Dial(url_, protocol, origin string) (ws *Conn, err error) { + config, err := NewConfig(url_, origin) + if err != nil { + return nil, err + } + if protocol != "" { + config.Protocol = []string{protocol} + } + return DialConfig(config) +} + +var portMap = map[string]string{ + "ws": "80", + "wss": "443", +} + +func parseAuthority(location *url.URL) string { + if _, ok := portMap[location.Scheme]; ok { + if _, _, err := net.SplitHostPort(location.Host); err != nil { + return net.JoinHostPort(location.Host, portMap[location.Scheme]) + } + } + return location.Host +} + +// DialConfig opens a new client connection to a WebSocket with a config. +func DialConfig(config *Config) (ws *Conn, err error) { + var client net.Conn + if config.Location == nil { + return nil, &DialError{config, ErrBadWebSocketLocation} + } + if config.Origin == nil { + return nil, &DialError{config, ErrBadWebSocketOrigin} + } + switch config.Location.Scheme { + case "ws": + client, err = net.Dial("tcp", parseAuthority(config.Location)) + + case "wss": + client, err = tls.Dial("tcp", parseAuthority(config.Location), config.TlsConfig) + + default: + err = ErrBadScheme + } + if err != nil { + goto Error + } + + ws, err = NewClient(config, client) + if err != nil { + client.Close() + goto Error + } + return + +Error: + return nil, &DialError{config, err} +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/exampledial_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/exampledial_test.go new file mode 100644 index 00000000..72bb9d48 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/exampledial_test.go @@ -0,0 +1,31 @@ +// 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 websocket_test + +import ( + "fmt" + "log" + + "golang.org/x/net/websocket" +) + +// This example demonstrates a trivial client. +func ExampleDial() { + origin := "http://localhost/" + url := "ws://localhost:12345/ws" + ws, err := websocket.Dial(url, "", origin) + if err != nil { + log.Fatal(err) + } + if _, err := ws.Write([]byte("hello, world!\n")); err != nil { + log.Fatal(err) + } + var msg = make([]byte, 512) + var n int + if n, err = ws.Read(msg); err != nil { + log.Fatal(err) + } + fmt.Printf("Received: %s.\n", msg[:n]) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/examplehandler_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/examplehandler_test.go new file mode 100644 index 00000000..f22a98fc --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/examplehandler_test.go @@ -0,0 +1,26 @@ +// 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 websocket_test + +import ( + "io" + "net/http" + + "golang.org/x/net/websocket" +) + +// Echo the data received on the WebSocket. +func EchoServer(ws *websocket.Conn) { + io.Copy(ws, ws) +} + +// This example demonstrates a trivial echo server. +func ExampleHandler() { + http.Handle("/echo", websocket.Handler(EchoServer)) + err := http.ListenAndServe(":12345", nil) + if err != nil { + panic("ListenAndServe: " + err.Error()) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/hybi.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/hybi.go new file mode 100644 index 00000000..60bbc841 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/hybi.go @@ -0,0 +1,586 @@ +// 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 websocket + +// This file implements a protocol of hybi draft. +// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 + +import ( + "bufio" + "bytes" + "crypto/rand" + "crypto/sha1" + "encoding/base64" + "encoding/binary" + "fmt" + "io" + "io/ioutil" + "net/http" + "net/url" + "strings" +) + +const ( + websocketGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" + + closeStatusNormal = 1000 + closeStatusGoingAway = 1001 + closeStatusProtocolError = 1002 + closeStatusUnsupportedData = 1003 + closeStatusFrameTooLarge = 1004 + closeStatusNoStatusRcvd = 1005 + closeStatusAbnormalClosure = 1006 + closeStatusBadMessageData = 1007 + closeStatusPolicyViolation = 1008 + closeStatusTooBigData = 1009 + closeStatusExtensionMismatch = 1010 + + maxControlFramePayloadLength = 125 +) + +var ( + ErrBadMaskingKey = &ProtocolError{"bad masking key"} + ErrBadPongMessage = &ProtocolError{"bad pong message"} + ErrBadClosingStatus = &ProtocolError{"bad closing status"} + ErrUnsupportedExtensions = &ProtocolError{"unsupported extensions"} + ErrNotImplemented = &ProtocolError{"not implemented"} + + handshakeHeader = map[string]bool{ + "Host": true, + "Upgrade": true, + "Connection": true, + "Sec-Websocket-Key": true, + "Sec-Websocket-Origin": true, + "Sec-Websocket-Version": true, + "Sec-Websocket-Protocol": true, + "Sec-Websocket-Accept": true, + } +) + +// A hybiFrameHeader is a frame header as defined in hybi draft. +type hybiFrameHeader struct { + Fin bool + Rsv [3]bool + OpCode byte + Length int64 + MaskingKey []byte + + data *bytes.Buffer +} + +// A hybiFrameReader is a reader for hybi frame. +type hybiFrameReader struct { + reader io.Reader + + header hybiFrameHeader + pos int64 + length int +} + +func (frame *hybiFrameReader) Read(msg []byte) (n int, err error) { + n, err = frame.reader.Read(msg) + if err != nil { + return 0, err + } + if frame.header.MaskingKey != nil { + for i := 0; i < n; i++ { + msg[i] = msg[i] ^ frame.header.MaskingKey[frame.pos%4] + frame.pos++ + } + } + return n, err +} + +func (frame *hybiFrameReader) PayloadType() byte { return frame.header.OpCode } + +func (frame *hybiFrameReader) HeaderReader() io.Reader { + if frame.header.data == nil { + return nil + } + if frame.header.data.Len() == 0 { + return nil + } + return frame.header.data +} + +func (frame *hybiFrameReader) TrailerReader() io.Reader { return nil } + +func (frame *hybiFrameReader) Len() (n int) { return frame.length } + +// A hybiFrameReaderFactory creates new frame reader based on its frame type. +type hybiFrameReaderFactory struct { + *bufio.Reader +} + +// NewFrameReader reads a frame header from the connection, and creates new reader for the frame. +// See Section 5.2 Base Framing protocol for detail. +// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17#section-5.2 +func (buf hybiFrameReaderFactory) NewFrameReader() (frame frameReader, err error) { + hybiFrame := new(hybiFrameReader) + frame = hybiFrame + var header []byte + var b byte + // First byte. FIN/RSV1/RSV2/RSV3/OpCode(4bits) + b, err = buf.ReadByte() + if err != nil { + return + } + header = append(header, b) + hybiFrame.header.Fin = ((header[0] >> 7) & 1) != 0 + for i := 0; i < 3; i++ { + j := uint(6 - i) + hybiFrame.header.Rsv[i] = ((header[0] >> j) & 1) != 0 + } + hybiFrame.header.OpCode = header[0] & 0x0f + + // Second byte. Mask/Payload len(7bits) + b, err = buf.ReadByte() + if err != nil { + return + } + header = append(header, b) + mask := (b & 0x80) != 0 + b &= 0x7f + lengthFields := 0 + switch { + case b <= 125: // Payload length 7bits. + hybiFrame.header.Length = int64(b) + case b == 126: // Payload length 7+16bits + lengthFields = 2 + case b == 127: // Payload length 7+64bits + lengthFields = 8 + } + for i := 0; i < lengthFields; i++ { + b, err = buf.ReadByte() + if err != nil { + return + } + if lengthFields == 8 && i == 0 { // MSB must be zero when 7+64 bits + b &= 0x7f + } + header = append(header, b) + hybiFrame.header.Length = hybiFrame.header.Length*256 + int64(b) + } + if mask { + // Masking key. 4 bytes. + for i := 0; i < 4; i++ { + b, err = buf.ReadByte() + if err != nil { + return + } + header = append(header, b) + hybiFrame.header.MaskingKey = append(hybiFrame.header.MaskingKey, b) + } + } + hybiFrame.reader = io.LimitReader(buf.Reader, hybiFrame.header.Length) + hybiFrame.header.data = bytes.NewBuffer(header) + hybiFrame.length = len(header) + int(hybiFrame.header.Length) + return +} + +// A HybiFrameWriter is a writer for hybi frame. +type hybiFrameWriter struct { + writer *bufio.Writer + + header *hybiFrameHeader +} + +func (frame *hybiFrameWriter) Write(msg []byte) (n int, err error) { + var header []byte + var b byte + if frame.header.Fin { + b |= 0x80 + } + for i := 0; i < 3; i++ { + if frame.header.Rsv[i] { + j := uint(6 - i) + b |= 1 << j + } + } + b |= frame.header.OpCode + header = append(header, b) + if frame.header.MaskingKey != nil { + b = 0x80 + } else { + b = 0 + } + lengthFields := 0 + length := len(msg) + switch { + case length <= 125: + b |= byte(length) + case length < 65536: + b |= 126 + lengthFields = 2 + default: + b |= 127 + lengthFields = 8 + } + header = append(header, b) + for i := 0; i < lengthFields; i++ { + j := uint((lengthFields - i - 1) * 8) + b = byte((length >> j) & 0xff) + header = append(header, b) + } + if frame.header.MaskingKey != nil { + if len(frame.header.MaskingKey) != 4 { + return 0, ErrBadMaskingKey + } + header = append(header, frame.header.MaskingKey...) + frame.writer.Write(header) + data := make([]byte, length) + for i := range data { + data[i] = msg[i] ^ frame.header.MaskingKey[i%4] + } + frame.writer.Write(data) + err = frame.writer.Flush() + return length, err + } + frame.writer.Write(header) + frame.writer.Write(msg) + err = frame.writer.Flush() + return length, err +} + +func (frame *hybiFrameWriter) Close() error { return nil } + +type hybiFrameWriterFactory struct { + *bufio.Writer + needMaskingKey bool +} + +func (buf hybiFrameWriterFactory) NewFrameWriter(payloadType byte) (frame frameWriter, err error) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: payloadType} + if buf.needMaskingKey { + frameHeader.MaskingKey, err = generateMaskingKey() + if err != nil { + return nil, err + } + } + return &hybiFrameWriter{writer: buf.Writer, header: frameHeader}, nil +} + +type hybiFrameHandler struct { + conn *Conn + payloadType byte +} + +func (handler *hybiFrameHandler) HandleFrame(frame frameReader) (frameReader, error) { + if handler.conn.IsServerConn() { + // The client MUST mask all frames sent to the server. + if frame.(*hybiFrameReader).header.MaskingKey == nil { + handler.WriteClose(closeStatusProtocolError) + return nil, io.EOF + } + } else { + // The server MUST NOT mask all frames. + if frame.(*hybiFrameReader).header.MaskingKey != nil { + handler.WriteClose(closeStatusProtocolError) + return nil, io.EOF + } + } + if header := frame.HeaderReader(); header != nil { + io.Copy(ioutil.Discard, header) + } + switch frame.PayloadType() { + case ContinuationFrame: + frame.(*hybiFrameReader).header.OpCode = handler.payloadType + case TextFrame, BinaryFrame: + handler.payloadType = frame.PayloadType() + case CloseFrame: + return nil, io.EOF + case PingFrame, PongFrame: + b := make([]byte, maxControlFramePayloadLength) + n, err := io.ReadFull(frame, b) + if err != nil && err != io.EOF && err != io.ErrUnexpectedEOF { + return nil, err + } + io.Copy(ioutil.Discard, frame) + if frame.PayloadType() == PingFrame { + if _, err := handler.WritePong(b[:n]); err != nil { + return nil, err + } + } + return nil, nil + } + return frame, nil +} + +func (handler *hybiFrameHandler) WriteClose(status int) (err error) { + handler.conn.wio.Lock() + defer handler.conn.wio.Unlock() + w, err := handler.conn.frameWriterFactory.NewFrameWriter(CloseFrame) + if err != nil { + return err + } + msg := make([]byte, 2) + binary.BigEndian.PutUint16(msg, uint16(status)) + _, err = w.Write(msg) + w.Close() + return err +} + +func (handler *hybiFrameHandler) WritePong(msg []byte) (n int, err error) { + handler.conn.wio.Lock() + defer handler.conn.wio.Unlock() + w, err := handler.conn.frameWriterFactory.NewFrameWriter(PongFrame) + if err != nil { + return 0, err + } + n, err = w.Write(msg) + w.Close() + return n, err +} + +// newHybiConn creates a new WebSocket connection speaking hybi draft protocol. +func newHybiConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { + if buf == nil { + br := bufio.NewReader(rwc) + bw := bufio.NewWriter(rwc) + buf = bufio.NewReadWriter(br, bw) + } + ws := &Conn{config: config, request: request, buf: buf, rwc: rwc, + frameReaderFactory: hybiFrameReaderFactory{buf.Reader}, + frameWriterFactory: hybiFrameWriterFactory{ + buf.Writer, request == nil}, + PayloadType: TextFrame, + defaultCloseStatus: closeStatusNormal} + ws.frameHandler = &hybiFrameHandler{conn: ws} + return ws +} + +// generateMaskingKey generates a masking key for a frame. +func generateMaskingKey() (maskingKey []byte, err error) { + maskingKey = make([]byte, 4) + if _, err = io.ReadFull(rand.Reader, maskingKey); err != nil { + return + } + return +} + +// generateNonce generates a nonce consisting of a randomly selected 16-byte +// value that has been base64-encoded. +func generateNonce() (nonce []byte) { + key := make([]byte, 16) + if _, err := io.ReadFull(rand.Reader, key); err != nil { + panic(err) + } + nonce = make([]byte, 24) + base64.StdEncoding.Encode(nonce, key) + return +} + +// removeZone removes IPv6 zone identifer from host. +// E.g., "[fe80::1%en0]:8080" to "[fe80::1]:8080" +func removeZone(host string) string { + if !strings.HasPrefix(host, "[") { + return host + } + i := strings.LastIndex(host, "]") + if i < 0 { + return host + } + j := strings.LastIndex(host[:i], "%") + if j < 0 { + return host + } + return host[:j] + host[i:] +} + +// getNonceAccept computes the base64-encoded SHA-1 of the concatenation of +// the nonce ("Sec-WebSocket-Key" value) with the websocket GUID string. +func getNonceAccept(nonce []byte) (expected []byte, err error) { + h := sha1.New() + if _, err = h.Write(nonce); err != nil { + return + } + if _, err = h.Write([]byte(websocketGUID)); err != nil { + return + } + expected = make([]byte, 28) + base64.StdEncoding.Encode(expected, h.Sum(nil)) + return +} + +// Client handshake described in draft-ietf-hybi-thewebsocket-protocol-17 +func hybiClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) (err error) { + bw.WriteString("GET " + config.Location.RequestURI() + " HTTP/1.1\r\n") + + // According to RFC 6874, an HTTP client, proxy, or other + // intermediary must remove any IPv6 zone identifier attached + // to an outgoing URI. + bw.WriteString("Host: " + removeZone(config.Location.Host) + "\r\n") + bw.WriteString("Upgrade: websocket\r\n") + bw.WriteString("Connection: Upgrade\r\n") + nonce := generateNonce() + if config.handshakeData != nil { + nonce = []byte(config.handshakeData["key"]) + } + bw.WriteString("Sec-WebSocket-Key: " + string(nonce) + "\r\n") + bw.WriteString("Origin: " + strings.ToLower(config.Origin.String()) + "\r\n") + + if config.Version != ProtocolVersionHybi13 { + return ErrBadProtocolVersion + } + + bw.WriteString("Sec-WebSocket-Version: " + fmt.Sprintf("%d", config.Version) + "\r\n") + if len(config.Protocol) > 0 { + bw.WriteString("Sec-WebSocket-Protocol: " + strings.Join(config.Protocol, ", ") + "\r\n") + } + // TODO(ukai): send Sec-WebSocket-Extensions. + err = config.Header.WriteSubset(bw, handshakeHeader) + if err != nil { + return err + } + + bw.WriteString("\r\n") + if err = bw.Flush(); err != nil { + return err + } + + resp, err := http.ReadResponse(br, &http.Request{Method: "GET"}) + if err != nil { + return err + } + if resp.StatusCode != 101 { + return ErrBadStatus + } + if strings.ToLower(resp.Header.Get("Upgrade")) != "websocket" || + strings.ToLower(resp.Header.Get("Connection")) != "upgrade" { + return ErrBadUpgrade + } + expectedAccept, err := getNonceAccept(nonce) + if err != nil { + return err + } + if resp.Header.Get("Sec-WebSocket-Accept") != string(expectedAccept) { + return ErrChallengeResponse + } + if resp.Header.Get("Sec-WebSocket-Extensions") != "" { + return ErrUnsupportedExtensions + } + offeredProtocol := resp.Header.Get("Sec-WebSocket-Protocol") + if offeredProtocol != "" { + protocolMatched := false + for i := 0; i < len(config.Protocol); i++ { + if config.Protocol[i] == offeredProtocol { + protocolMatched = true + break + } + } + if !protocolMatched { + return ErrBadWebSocketProtocol + } + config.Protocol = []string{offeredProtocol} + } + + return nil +} + +// newHybiClientConn creates a client WebSocket connection after handshake. +func newHybiClientConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser) *Conn { + return newHybiConn(config, buf, rwc, nil) +} + +// A HybiServerHandshaker performs a server handshake using hybi draft protocol. +type hybiServerHandshaker struct { + *Config + accept []byte +} + +func (c *hybiServerHandshaker) ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) { + c.Version = ProtocolVersionHybi13 + if req.Method != "GET" { + return http.StatusMethodNotAllowed, ErrBadRequestMethod + } + // HTTP version can be safely ignored. + + if strings.ToLower(req.Header.Get("Upgrade")) != "websocket" || + !strings.Contains(strings.ToLower(req.Header.Get("Connection")), "upgrade") { + return http.StatusBadRequest, ErrNotWebSocket + } + + key := req.Header.Get("Sec-Websocket-Key") + if key == "" { + return http.StatusBadRequest, ErrChallengeResponse + } + version := req.Header.Get("Sec-Websocket-Version") + switch version { + case "13": + c.Version = ProtocolVersionHybi13 + default: + return http.StatusBadRequest, ErrBadWebSocketVersion + } + var scheme string + if req.TLS != nil { + scheme = "wss" + } else { + scheme = "ws" + } + c.Location, err = url.ParseRequestURI(scheme + "://" + req.Host + req.URL.RequestURI()) + if err != nil { + return http.StatusBadRequest, err + } + protocol := strings.TrimSpace(req.Header.Get("Sec-Websocket-Protocol")) + if protocol != "" { + protocols := strings.Split(protocol, ",") + for i := 0; i < len(protocols); i++ { + c.Protocol = append(c.Protocol, strings.TrimSpace(protocols[i])) + } + } + c.accept, err = getNonceAccept([]byte(key)) + if err != nil { + return http.StatusInternalServerError, err + } + return http.StatusSwitchingProtocols, nil +} + +// Origin parses the Origin header in req. +// If the Origin header is not set, it returns nil and nil. +func Origin(config *Config, req *http.Request) (*url.URL, error) { + var origin string + switch config.Version { + case ProtocolVersionHybi13: + origin = req.Header.Get("Origin") + } + if origin == "" { + return nil, nil + } + return url.ParseRequestURI(origin) +} + +func (c *hybiServerHandshaker) AcceptHandshake(buf *bufio.Writer) (err error) { + if len(c.Protocol) > 0 { + if len(c.Protocol) != 1 { + // You need choose a Protocol in Handshake func in Server. + return ErrBadWebSocketProtocol + } + } + buf.WriteString("HTTP/1.1 101 Switching Protocols\r\n") + buf.WriteString("Upgrade: websocket\r\n") + buf.WriteString("Connection: Upgrade\r\n") + buf.WriteString("Sec-WebSocket-Accept: " + string(c.accept) + "\r\n") + if len(c.Protocol) > 0 { + buf.WriteString("Sec-WebSocket-Protocol: " + c.Protocol[0] + "\r\n") + } + // TODO(ukai): send Sec-WebSocket-Extensions. + if c.Header != nil { + err := c.Header.WriteSubset(buf, handshakeHeader) + if err != nil { + return err + } + } + buf.WriteString("\r\n") + return buf.Flush() +} + +func (c *hybiServerHandshaker) NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { + return newHybiServerConn(c.Config, buf, rwc, request) +} + +// newHybiServerConn returns a new WebSocket connection speaking hybi draft protocol. +func newHybiServerConn(config *Config, buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) *Conn { + return newHybiConn(config, buf, rwc, request) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/hybi_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/hybi_test.go new file mode 100644 index 00000000..9504aa2d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/hybi_test.go @@ -0,0 +1,608 @@ +// 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 websocket + +import ( + "bufio" + "bytes" + "fmt" + "io" + "net/http" + "net/url" + "strings" + "testing" +) + +// Test the getNonceAccept function with values in +// http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-17 +func TestSecWebSocketAccept(t *testing.T) { + nonce := []byte("dGhlIHNhbXBsZSBub25jZQ==") + expected := []byte("s3pPLMBiTxaQ9kYGzzhZRbK+xOo=") + accept, err := getNonceAccept(nonce) + if err != nil { + t.Errorf("getNonceAccept: returned error %v", err) + return + } + if !bytes.Equal(expected, accept) { + t.Errorf("getNonceAccept: expected %q got %q", expected, accept) + } +} + +func TestHybiClientHandshake(t *testing.T) { + type test struct { + url, host string + } + tests := []test{ + {"ws://server.example.com/chat", "server.example.com"}, + {"ws://127.0.0.1/chat", "127.0.0.1"}, + } + if _, err := url.ParseRequestURI("http://[fe80::1%25lo0]"); err == nil { + tests = append(tests, test{"ws://[fe80::1%25lo0]/chat", "[fe80::1]"}) + } + + for _, tt := range tests { + var b bytes.Buffer + bw := bufio.NewWriter(&b) + br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= +Sec-WebSocket-Protocol: chat + +`)) + var err error + var config Config + config.Location, err = url.ParseRequestURI(tt.url) + if err != nil { + t.Fatal("location url", err) + } + config.Origin, err = url.ParseRequestURI("http://example.com") + if err != nil { + t.Fatal("origin url", err) + } + config.Protocol = append(config.Protocol, "chat") + config.Protocol = append(config.Protocol, "superchat") + config.Version = ProtocolVersionHybi13 + config.handshakeData = map[string]string{ + "key": "dGhlIHNhbXBsZSBub25jZQ==", + } + if err := hybiClientHandshake(&config, br, bw); err != nil { + t.Fatal("handshake", err) + } + req, err := http.ReadRequest(bufio.NewReader(&b)) + if err != nil { + t.Fatal("read request", err) + } + if req.Method != "GET" { + t.Errorf("request method expected GET, but got %s", req.Method) + } + if req.URL.Path != "/chat" { + t.Errorf("request path expected /chat, but got %s", req.URL.Path) + } + if req.Proto != "HTTP/1.1" { + t.Errorf("request proto expected HTTP/1.1, but got %s", req.Proto) + } + if req.Host != tt.host { + t.Errorf("request host expected %s, but got %s", tt.host, req.Host) + } + var expectedHeader = map[string]string{ + "Connection": "Upgrade", + "Upgrade": "websocket", + "Sec-Websocket-Key": config.handshakeData["key"], + "Origin": config.Origin.String(), + "Sec-Websocket-Protocol": "chat, superchat", + "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), + } + for k, v := range expectedHeader { + if req.Header.Get(k) != v { + t.Errorf("%s expected %s, but got %v", k, v, req.Header.Get(k)) + } + } + } +} + +func TestHybiClientHandshakeWithHeader(t *testing.T) { + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + br := bufio.NewReader(strings.NewReader(`HTTP/1.1 101 Switching Protocols +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= +Sec-WebSocket-Protocol: chat + +`)) + var err error + config := new(Config) + config.Location, err = url.ParseRequestURI("ws://server.example.com/chat") + if err != nil { + t.Fatal("location url", err) + } + config.Origin, err = url.ParseRequestURI("http://example.com") + if err != nil { + t.Fatal("origin url", err) + } + config.Protocol = append(config.Protocol, "chat") + config.Protocol = append(config.Protocol, "superchat") + config.Version = ProtocolVersionHybi13 + config.Header = http.Header(make(map[string][]string)) + config.Header.Add("User-Agent", "test") + + config.handshakeData = map[string]string{ + "key": "dGhlIHNhbXBsZSBub25jZQ==", + } + err = hybiClientHandshake(config, br, bw) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + req, err := http.ReadRequest(bufio.NewReader(b)) + if err != nil { + t.Fatalf("read request: %v", err) + } + if req.Method != "GET" { + t.Errorf("request method expected GET, but got %q", req.Method) + } + if req.URL.Path != "/chat" { + t.Errorf("request path expected /chat, but got %q", req.URL.Path) + } + if req.Proto != "HTTP/1.1" { + t.Errorf("request proto expected HTTP/1.1, but got %q", req.Proto) + } + if req.Host != "server.example.com" { + t.Errorf("request Host expected server.example.com, but got %v", req.Host) + } + var expectedHeader = map[string]string{ + "Connection": "Upgrade", + "Upgrade": "websocket", + "Sec-Websocket-Key": config.handshakeData["key"], + "Origin": config.Origin.String(), + "Sec-Websocket-Protocol": "chat, superchat", + "Sec-Websocket-Version": fmt.Sprintf("%d", ProtocolVersionHybi13), + "User-Agent": "test", + } + for k, v := range expectedHeader { + if req.Header.Get(k) != v { + t.Errorf(fmt.Sprintf("%s expected %q but got %q", k, v, req.Header.Get(k))) + } + } +} + +func TestHybiServerHandshake(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +Sec-WebSocket-Protocol: chat, superchat +Sec-WebSocket-Version: 13 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + if code != http.StatusSwitchingProtocols { + t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) + } + expectedProtocols := []string{"chat", "superchat"} + if fmt.Sprintf("%v", config.Protocol) != fmt.Sprintf("%v", expectedProtocols) { + t.Errorf("protocol expected %q but got %q", expectedProtocols, config.Protocol) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + config.Protocol = config.Protocol[:1] + + err = handshaker.AcceptHandshake(bw) + if err != nil { + t.Errorf("handshake response failed: %v", err) + } + expectedResponse := strings.Join([]string{ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", + "Sec-WebSocket-Protocol: chat", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +} + +func TestHybiServerHandshakeNoSubProtocol(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +Sec-WebSocket-Version: 13 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + if code != http.StatusSwitchingProtocols { + t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) + } + if len(config.Protocol) != 0 { + t.Errorf("len(config.Protocol) expected 0, but got %q", len(config.Protocol)) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + err = handshaker.AcceptHandshake(bw) + if err != nil { + t.Errorf("handshake response failed: %v", err) + } + expectedResponse := strings.Join([]string{ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +} + +func TestHybiServerHandshakeHybiBadVersion(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Sec-WebSocket-Origin: http://example.com +Sec-WebSocket-Protocol: chat, superchat +Sec-WebSocket-Version: 9 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != ErrBadWebSocketVersion { + t.Errorf("handshake expected err %q but got %q", ErrBadWebSocketVersion, err) + } + if code != http.StatusBadRequest { + t.Errorf("status expected %q but got %q", http.StatusBadRequest, code) + } +} + +func testHybiFrame(t *testing.T, testHeader, testPayload, testMaskedPayload []byte, frameHeader *hybiFrameHeader) { + b := bytes.NewBuffer([]byte{}) + frameWriterFactory := &hybiFrameWriterFactory{bufio.NewWriter(b), false} + w, _ := frameWriterFactory.NewFrameWriter(TextFrame) + w.(*hybiFrameWriter).header = frameHeader + _, err := w.Write(testPayload) + w.Close() + if err != nil { + t.Errorf("Write error %q", err) + } + var expectedFrame []byte + expectedFrame = append(expectedFrame, testHeader...) + expectedFrame = append(expectedFrame, testMaskedPayload...) + if !bytes.Equal(expectedFrame, b.Bytes()) { + t.Errorf("frame expected %q got %q", expectedFrame, b.Bytes()) + } + frameReaderFactory := &hybiFrameReaderFactory{bufio.NewReader(b)} + r, err := frameReaderFactory.NewFrameReader() + if err != nil { + t.Errorf("Read error %q", err) + } + if header := r.HeaderReader(); header == nil { + t.Errorf("no header") + } else { + actualHeader := make([]byte, r.Len()) + n, err := header.Read(actualHeader) + if err != nil { + t.Errorf("Read header error %q", err) + } else { + if n < len(testHeader) { + t.Errorf("header too short %q got %q", testHeader, actualHeader[:n]) + } + if !bytes.Equal(testHeader, actualHeader[:n]) { + t.Errorf("header expected %q got %q", testHeader, actualHeader[:n]) + } + } + } + if trailer := r.TrailerReader(); trailer != nil { + t.Errorf("unexpected trailer %q", trailer) + } + frame := r.(*hybiFrameReader) + if frameHeader.Fin != frame.header.Fin || + frameHeader.OpCode != frame.header.OpCode || + len(testPayload) != int(frame.header.Length) { + t.Errorf("mismatch %v (%d) vs %v", frameHeader, len(testPayload), frame) + } + payload := make([]byte, len(testPayload)) + _, err = r.Read(payload) + if err != nil && err != io.EOF { + t.Errorf("read %v", err) + } + if !bytes.Equal(testPayload, payload) { + t.Errorf("payload %q vs %q", testPayload, payload) + } +} + +func TestHybiShortTextFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} + payload := []byte("hello") + testHybiFrame(t, []byte{0x81, 0x05}, payload, payload, frameHeader) + + payload = make([]byte, 125) + testHybiFrame(t, []byte{0x81, 125}, payload, payload, frameHeader) +} + +func TestHybiShortMaskedTextFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame, + MaskingKey: []byte{0xcc, 0x55, 0x80, 0x20}} + payload := []byte("hello") + maskedPayload := []byte{0xa4, 0x30, 0xec, 0x4c, 0xa3} + header := []byte{0x81, 0x85} + header = append(header, frameHeader.MaskingKey...) + testHybiFrame(t, header, payload, maskedPayload, frameHeader) +} + +func TestHybiShortBinaryFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: BinaryFrame} + payload := []byte("hello") + testHybiFrame(t, []byte{0x82, 0x05}, payload, payload, frameHeader) + + payload = make([]byte, 125) + testHybiFrame(t, []byte{0x82, 125}, payload, payload, frameHeader) +} + +func TestHybiControlFrame(t *testing.T) { + payload := []byte("hello") + + frameHeader := &hybiFrameHeader{Fin: true, OpCode: PingFrame} + testHybiFrame(t, []byte{0x89, 0x05}, payload, payload, frameHeader) + + frameHeader = &hybiFrameHeader{Fin: true, OpCode: PingFrame} + testHybiFrame(t, []byte{0x89, 0x00}, nil, nil, frameHeader) + + frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame} + testHybiFrame(t, []byte{0x8A, 0x05}, payload, payload, frameHeader) + + frameHeader = &hybiFrameHeader{Fin: true, OpCode: PongFrame} + testHybiFrame(t, []byte{0x8A, 0x00}, nil, nil, frameHeader) + + frameHeader = &hybiFrameHeader{Fin: true, OpCode: CloseFrame} + payload = []byte{0x03, 0xe8} // 1000 + testHybiFrame(t, []byte{0x88, 0x02}, payload, payload, frameHeader) +} + +func TestHybiLongFrame(t *testing.T) { + frameHeader := &hybiFrameHeader{Fin: true, OpCode: TextFrame} + payload := make([]byte, 126) + testHybiFrame(t, []byte{0x81, 126, 0x00, 126}, payload, payload, frameHeader) + + payload = make([]byte, 65535) + testHybiFrame(t, []byte{0x81, 126, 0xff, 0xff}, payload, payload, frameHeader) + + payload = make([]byte, 65536) + testHybiFrame(t, []byte{0x81, 127, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}, payload, payload, frameHeader) +} + +func TestHybiClientRead(t *testing.T) { + wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', + 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping + 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) + + msg := make([]byte, 512) + n, err := conn.Read(msg) + if err != nil { + t.Errorf("read 1st frame, error %q", err) + } + if n != 5 { + t.Errorf("read 1st frame, expect 5, got %d", n) + } + if !bytes.Equal(wireData[2:7], msg[:n]) { + t.Errorf("read 1st frame %v, got %v", wireData[2:7], msg[:n]) + } + n, err = conn.Read(msg) + if err != nil { + t.Errorf("read 2nd frame, error %q", err) + } + if n != 5 { + t.Errorf("read 2nd frame, expect 5, got %d", n) + } + if !bytes.Equal(wireData[16:21], msg[:n]) { + t.Errorf("read 2nd frame %v, got %v", wireData[16:21], msg[:n]) + } + n, err = conn.Read(msg) + if err == nil { + t.Errorf("read not EOF") + } + if n != 0 { + t.Errorf("expect read 0, got %d", n) + } +} + +func TestHybiShortRead(t *testing.T) { + wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o', + 0x89, 0x05, 'h', 'e', 'l', 'l', 'o', // ping + 0x81, 0x05, 'w', 'o', 'r', 'l', 'd'} + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) + + step := 0 + pos := 0 + expectedPos := []int{2, 5, 16, 19} + expectedLen := []int{3, 2, 3, 2} + for { + msg := make([]byte, 3) + n, err := conn.Read(msg) + if step >= len(expectedPos) { + if err == nil { + t.Errorf("read not EOF") + } + if n != 0 { + t.Errorf("expect read 0, got %d", n) + } + return + } + pos = expectedPos[step] + endPos := pos + expectedLen[step] + if err != nil { + t.Errorf("read from %d, got error %q", pos, err) + return + } + if n != endPos-pos { + t.Errorf("read from %d, expect %d, got %d", pos, endPos-pos, n) + } + if !bytes.Equal(wireData[pos:endPos], msg[:n]) { + t.Errorf("read from %d, frame %v, got %v", pos, wireData[pos:endPos], msg[:n]) + } + step++ + } +} + +func TestHybiServerRead(t *testing.T) { + wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, + 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello + 0x89, 0x85, 0xcc, 0x55, 0x80, 0x20, + 0xa4, 0x30, 0xec, 0x4c, 0xa3, // ping: hello + 0x81, 0x85, 0xed, 0x83, 0xb4, 0x24, + 0x9a, 0xec, 0xc6, 0x48, 0x89, // world + } + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) + + expected := [][]byte{[]byte("hello"), []byte("world")} + + msg := make([]byte, 512) + n, err := conn.Read(msg) + if err != nil { + t.Errorf("read 1st frame, error %q", err) + } + if n != 5 { + t.Errorf("read 1st frame, expect 5, got %d", n) + } + if !bytes.Equal(expected[0], msg[:n]) { + t.Errorf("read 1st frame %q, got %q", expected[0], msg[:n]) + } + + n, err = conn.Read(msg) + if err != nil { + t.Errorf("read 2nd frame, error %q", err) + } + if n != 5 { + t.Errorf("read 2nd frame, expect 5, got %d", n) + } + if !bytes.Equal(expected[1], msg[:n]) { + t.Errorf("read 2nd frame %q, got %q", expected[1], msg[:n]) + } + + n, err = conn.Read(msg) + if err == nil { + t.Errorf("read not EOF") + } + if n != 0 { + t.Errorf("expect read 0, got %d", n) + } +} + +func TestHybiServerReadWithoutMasking(t *testing.T) { + wireData := []byte{0x81, 0x05, 'h', 'e', 'l', 'l', 'o'} + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, new(http.Request)) + // server MUST close the connection upon receiving a non-masked frame. + msg := make([]byte, 512) + _, err := conn.Read(msg) + if err != io.EOF { + t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) + } +} + +func TestHybiClientReadWithMasking(t *testing.T) { + wireData := []byte{0x81, 0x85, 0xcc, 0x55, 0x80, 0x20, + 0xa4, 0x30, 0xec, 0x4c, 0xa3, // hello + } + br := bufio.NewReader(bytes.NewBuffer(wireData)) + bw := bufio.NewWriter(bytes.NewBuffer([]byte{})) + conn := newHybiConn(newConfig(t, "/"), bufio.NewReadWriter(br, bw), nil, nil) + + // client MUST close the connection upon receiving a masked frame. + msg := make([]byte, 512) + _, err := conn.Read(msg) + if err != io.EOF { + t.Errorf("read 1st frame, expect %q, but got %q", io.EOF, err) + } +} + +// Test the hybiServerHandshaker supports firefox implementation and +// checks Connection request header include (but it's not necessary +// equal to) "upgrade" +func TestHybiServerFirefoxHandshake(t *testing.T) { + config := new(Config) + handshaker := &hybiServerHandshaker{Config: config} + br := bufio.NewReader(strings.NewReader(`GET /chat HTTP/1.1 +Host: server.example.com +Upgrade: websocket +Connection: keep-alive, upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Origin: http://example.com +Sec-WebSocket-Protocol: chat, superchat +Sec-WebSocket-Version: 13 + +`)) + req, err := http.ReadRequest(br) + if err != nil { + t.Fatal("request", err) + } + code, err := handshaker.ReadHandshake(br, req) + if err != nil { + t.Errorf("handshake failed: %v", err) + } + if code != http.StatusSwitchingProtocols { + t.Errorf("status expected %q but got %q", http.StatusSwitchingProtocols, code) + } + b := bytes.NewBuffer([]byte{}) + bw := bufio.NewWriter(b) + + config.Protocol = []string{"chat"} + + err = handshaker.AcceptHandshake(bw) + if err != nil { + t.Errorf("handshake response failed: %v", err) + } + expectedResponse := strings.Join([]string{ + "HTTP/1.1 101 Switching Protocols", + "Upgrade: websocket", + "Connection: Upgrade", + "Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", + "Sec-WebSocket-Protocol: chat", + "", ""}, "\r\n") + + if b.String() != expectedResponse { + t.Errorf("handshake expected %q but got %q", expectedResponse, b.String()) + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/server.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/server.go new file mode 100644 index 00000000..0895dea1 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/server.go @@ -0,0 +1,113 @@ +// Copyright 2009 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 websocket + +import ( + "bufio" + "fmt" + "io" + "net/http" +) + +func newServerConn(rwc io.ReadWriteCloser, buf *bufio.ReadWriter, req *http.Request, config *Config, handshake func(*Config, *http.Request) error) (conn *Conn, err error) { + var hs serverHandshaker = &hybiServerHandshaker{Config: config} + code, err := hs.ReadHandshake(buf.Reader, req) + if err == ErrBadWebSocketVersion { + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + fmt.Fprintf(buf, "Sec-WebSocket-Version: %s\r\n", SupportedProtocolVersion) + buf.WriteString("\r\n") + buf.WriteString(err.Error()) + buf.Flush() + return + } + if err != nil { + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + buf.WriteString("\r\n") + buf.WriteString(err.Error()) + buf.Flush() + return + } + if handshake != nil { + err = handshake(config, req) + if err != nil { + code = http.StatusForbidden + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + buf.WriteString("\r\n") + buf.Flush() + return + } + } + err = hs.AcceptHandshake(buf.Writer) + if err != nil { + code = http.StatusBadRequest + fmt.Fprintf(buf, "HTTP/1.1 %03d %s\r\n", code, http.StatusText(code)) + buf.WriteString("\r\n") + buf.Flush() + return + } + conn = hs.NewServerConn(buf, rwc, req) + return +} + +// Server represents a server of a WebSocket. +type Server struct { + // Config is a WebSocket configuration for new WebSocket connection. + Config + + // Handshake is an optional function in WebSocket handshake. + // For example, you can check, or don't check Origin header. + // Another example, you can select config.Protocol. + Handshake func(*Config, *http.Request) error + + // Handler handles a WebSocket connection. + Handler +} + +// ServeHTTP implements the http.Handler interface for a WebSocket +func (s Server) ServeHTTP(w http.ResponseWriter, req *http.Request) { + s.serveWebSocket(w, req) +} + +func (s Server) serveWebSocket(w http.ResponseWriter, req *http.Request) { + rwc, buf, err := w.(http.Hijacker).Hijack() + if err != nil { + panic("Hijack failed: " + err.Error()) + } + // The server should abort the WebSocket connection if it finds + // the client did not send a handshake that matches with protocol + // specification. + defer rwc.Close() + conn, err := newServerConn(rwc, buf, req, &s.Config, s.Handshake) + if err != nil { + return + } + if conn == nil { + panic("unexpected nil conn") + } + s.Handler(conn) +} + +// Handler is a simple interface to a WebSocket browser client. +// It checks if Origin header is valid URL by default. +// You might want to verify websocket.Conn.Config().Origin in the func. +// If you use Server instead of Handler, you could call websocket.Origin and +// check the origin in your Handshake func. So, if you want to accept +// non-browser clients, which do not send an Origin header, set a +// Server.Handshake that does not check the origin. +type Handler func(*Conn) + +func checkOrigin(config *Config, req *http.Request) (err error) { + config.Origin, err = Origin(config, req) + if err == nil && config.Origin == nil { + return fmt.Errorf("null origin") + } + return err +} + +// ServeHTTP implements the http.Handler interface for a WebSocket +func (h Handler) ServeHTTP(w http.ResponseWriter, req *http.Request) { + s := Server{Handler: h, Handshake: checkOrigin} + s.serveWebSocket(w, req) +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/websocket.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/websocket.go new file mode 100644 index 00000000..60684009 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/websocket.go @@ -0,0 +1,412 @@ +// Copyright 2009 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 websocket implements a client and server for the WebSocket protocol +// as specified in RFC 6455. +package websocket // import "golang.org/x/net/websocket" + +import ( + "bufio" + "crypto/tls" + "encoding/json" + "errors" + "io" + "io/ioutil" + "net" + "net/http" + "net/url" + "sync" + "time" +) + +const ( + ProtocolVersionHybi13 = 13 + ProtocolVersionHybi = ProtocolVersionHybi13 + SupportedProtocolVersion = "13" + + ContinuationFrame = 0 + TextFrame = 1 + BinaryFrame = 2 + CloseFrame = 8 + PingFrame = 9 + PongFrame = 10 + UnknownFrame = 255 +) + +// ProtocolError represents WebSocket protocol errors. +type ProtocolError struct { + ErrorString string +} + +func (err *ProtocolError) Error() string { return err.ErrorString } + +var ( + ErrBadProtocolVersion = &ProtocolError{"bad protocol version"} + ErrBadScheme = &ProtocolError{"bad scheme"} + ErrBadStatus = &ProtocolError{"bad status"} + ErrBadUpgrade = &ProtocolError{"missing or bad upgrade"} + ErrBadWebSocketOrigin = &ProtocolError{"missing or bad WebSocket-Origin"} + ErrBadWebSocketLocation = &ProtocolError{"missing or bad WebSocket-Location"} + ErrBadWebSocketProtocol = &ProtocolError{"missing or bad WebSocket-Protocol"} + ErrBadWebSocketVersion = &ProtocolError{"missing or bad WebSocket Version"} + ErrChallengeResponse = &ProtocolError{"mismatch challenge/response"} + ErrBadFrame = &ProtocolError{"bad frame"} + ErrBadFrameBoundary = &ProtocolError{"not on frame boundary"} + ErrNotWebSocket = &ProtocolError{"not websocket protocol"} + ErrBadRequestMethod = &ProtocolError{"bad method"} + ErrNotSupported = &ProtocolError{"not supported"} +) + +// Addr is an implementation of net.Addr for WebSocket. +type Addr struct { + *url.URL +} + +// Network returns the network type for a WebSocket, "websocket". +func (addr *Addr) Network() string { return "websocket" } + +// Config is a WebSocket configuration +type Config struct { + // A WebSocket server address. + Location *url.URL + + // A Websocket client origin. + Origin *url.URL + + // WebSocket subprotocols. + Protocol []string + + // WebSocket protocol version. + Version int + + // TLS config for secure WebSocket (wss). + TlsConfig *tls.Config + + // Additional header fields to be sent in WebSocket opening handshake. + Header http.Header + + handshakeData map[string]string +} + +// serverHandshaker is an interface to handle WebSocket server side handshake. +type serverHandshaker interface { + // ReadHandshake reads handshake request message from client. + // Returns http response code and error if any. + ReadHandshake(buf *bufio.Reader, req *http.Request) (code int, err error) + + // AcceptHandshake accepts the client handshake request and sends + // handshake response back to client. + AcceptHandshake(buf *bufio.Writer) (err error) + + // NewServerConn creates a new WebSocket connection. + NewServerConn(buf *bufio.ReadWriter, rwc io.ReadWriteCloser, request *http.Request) (conn *Conn) +} + +// frameReader is an interface to read a WebSocket frame. +type frameReader interface { + // Reader is to read payload of the frame. + io.Reader + + // PayloadType returns payload type. + PayloadType() byte + + // HeaderReader returns a reader to read header of the frame. + HeaderReader() io.Reader + + // TrailerReader returns a reader to read trailer of the frame. + // If it returns nil, there is no trailer in the frame. + TrailerReader() io.Reader + + // Len returns total length of the frame, including header and trailer. + Len() int +} + +// frameReaderFactory is an interface to creates new frame reader. +type frameReaderFactory interface { + NewFrameReader() (r frameReader, err error) +} + +// frameWriter is an interface to write a WebSocket frame. +type frameWriter interface { + // Writer is to write payload of the frame. + io.WriteCloser +} + +// frameWriterFactory is an interface to create new frame writer. +type frameWriterFactory interface { + NewFrameWriter(payloadType byte) (w frameWriter, err error) +} + +type frameHandler interface { + HandleFrame(frame frameReader) (r frameReader, err error) + WriteClose(status int) (err error) +} + +// Conn represents a WebSocket connection. +type Conn struct { + config *Config + request *http.Request + + buf *bufio.ReadWriter + rwc io.ReadWriteCloser + + rio sync.Mutex + frameReaderFactory + frameReader + + wio sync.Mutex + frameWriterFactory + + frameHandler + PayloadType byte + defaultCloseStatus int +} + +// Read implements the io.Reader interface: +// it reads data of a frame from the WebSocket connection. +// if msg is not large enough for the frame data, it fills the msg and next Read +// will read the rest of the frame data. +// it reads Text frame or Binary frame. +func (ws *Conn) Read(msg []byte) (n int, err error) { + ws.rio.Lock() + defer ws.rio.Unlock() +again: + if ws.frameReader == nil { + frame, err := ws.frameReaderFactory.NewFrameReader() + if err != nil { + return 0, err + } + ws.frameReader, err = ws.frameHandler.HandleFrame(frame) + if err != nil { + return 0, err + } + if ws.frameReader == nil { + goto again + } + } + n, err = ws.frameReader.Read(msg) + if err == io.EOF { + if trailer := ws.frameReader.TrailerReader(); trailer != nil { + io.Copy(ioutil.Discard, trailer) + } + ws.frameReader = nil + goto again + } + return n, err +} + +// Write implements the io.Writer interface: +// it writes data as a frame to the WebSocket connection. +func (ws *Conn) Write(msg []byte) (n int, err error) { + ws.wio.Lock() + defer ws.wio.Unlock() + w, err := ws.frameWriterFactory.NewFrameWriter(ws.PayloadType) + if err != nil { + return 0, err + } + n, err = w.Write(msg) + w.Close() + if err != nil { + return n, err + } + return n, err +} + +// Close implements the io.Closer interface. +func (ws *Conn) Close() error { + err := ws.frameHandler.WriteClose(ws.defaultCloseStatus) + err1 := ws.rwc.Close() + if err != nil { + return err + } + return err1 +} + +func (ws *Conn) IsClientConn() bool { return ws.request == nil } +func (ws *Conn) IsServerConn() bool { return ws.request != nil } + +// LocalAddr returns the WebSocket Origin for the connection for client, or +// the WebSocket location for server. +func (ws *Conn) LocalAddr() net.Addr { + if ws.IsClientConn() { + return &Addr{ws.config.Origin} + } + return &Addr{ws.config.Location} +} + +// RemoteAddr returns the WebSocket location for the connection for client, or +// the Websocket Origin for server. +func (ws *Conn) RemoteAddr() net.Addr { + if ws.IsClientConn() { + return &Addr{ws.config.Location} + } + return &Addr{ws.config.Origin} +} + +var errSetDeadline = errors.New("websocket: cannot set deadline: not using a net.Conn") + +// SetDeadline sets the connection's network read & write deadlines. +func (ws *Conn) SetDeadline(t time.Time) error { + if conn, ok := ws.rwc.(net.Conn); ok { + return conn.SetDeadline(t) + } + return errSetDeadline +} + +// SetReadDeadline sets the connection's network read deadline. +func (ws *Conn) SetReadDeadline(t time.Time) error { + if conn, ok := ws.rwc.(net.Conn); ok { + return conn.SetReadDeadline(t) + } + return errSetDeadline +} + +// SetWriteDeadline sets the connection's network write deadline. +func (ws *Conn) SetWriteDeadline(t time.Time) error { + if conn, ok := ws.rwc.(net.Conn); ok { + return conn.SetWriteDeadline(t) + } + return errSetDeadline +} + +// Config returns the WebSocket config. +func (ws *Conn) Config() *Config { return ws.config } + +// Request returns the http request upgraded to the WebSocket. +// It is nil for client side. +func (ws *Conn) Request() *http.Request { return ws.request } + +// Codec represents a symmetric pair of functions that implement a codec. +type Codec struct { + Marshal func(v interface{}) (data []byte, payloadType byte, err error) + Unmarshal func(data []byte, payloadType byte, v interface{}) (err error) +} + +// Send sends v marshaled by cd.Marshal as single frame to ws. +func (cd Codec) Send(ws *Conn, v interface{}) (err error) { + data, payloadType, err := cd.Marshal(v) + if err != nil { + return err + } + ws.wio.Lock() + defer ws.wio.Unlock() + w, err := ws.frameWriterFactory.NewFrameWriter(payloadType) + if err != nil { + return err + } + _, err = w.Write(data) + w.Close() + return err +} + +// Receive receives single frame from ws, unmarshaled by cd.Unmarshal and stores in v. +func (cd Codec) Receive(ws *Conn, v interface{}) (err error) { + ws.rio.Lock() + defer ws.rio.Unlock() + if ws.frameReader != nil { + _, err = io.Copy(ioutil.Discard, ws.frameReader) + if err != nil { + return err + } + ws.frameReader = nil + } +again: + frame, err := ws.frameReaderFactory.NewFrameReader() + if err != nil { + return err + } + frame, err = ws.frameHandler.HandleFrame(frame) + if err != nil { + return err + } + if frame == nil { + goto again + } + payloadType := frame.PayloadType() + data, err := ioutil.ReadAll(frame) + if err != nil { + return err + } + return cd.Unmarshal(data, payloadType, v) +} + +func marshal(v interface{}) (msg []byte, payloadType byte, err error) { + switch data := v.(type) { + case string: + return []byte(data), TextFrame, nil + case []byte: + return data, BinaryFrame, nil + } + return nil, UnknownFrame, ErrNotSupported +} + +func unmarshal(msg []byte, payloadType byte, v interface{}) (err error) { + switch data := v.(type) { + case *string: + *data = string(msg) + return nil + case *[]byte: + *data = msg + return nil + } + return ErrNotSupported +} + +/* +Message is a codec to send/receive text/binary data in a frame on WebSocket connection. +To send/receive text frame, use string type. +To send/receive binary frame, use []byte type. + +Trivial usage: + + import "websocket" + + // receive text frame + var message string + websocket.Message.Receive(ws, &message) + + // send text frame + message = "hello" + websocket.Message.Send(ws, message) + + // receive binary frame + var data []byte + websocket.Message.Receive(ws, &data) + + // send binary frame + data = []byte{0, 1, 2} + websocket.Message.Send(ws, data) + +*/ +var Message = Codec{marshal, unmarshal} + +func jsonMarshal(v interface{}) (msg []byte, payloadType byte, err error) { + msg, err = json.Marshal(v) + return msg, TextFrame, err +} + +func jsonUnmarshal(msg []byte, payloadType byte, v interface{}) (err error) { + return json.Unmarshal(msg, v) +} + +/* +JSON is a codec to send/receive JSON data in a frame from a WebSocket connection. + +Trivial usage: + + import "websocket" + + type T struct { + Msg string + Count int + } + + // receive JSON type T + var data T + websocket.JSON.Receive(ws, &data) + + // send JSON type T + websocket.JSON.Send(ws, data) +*/ +var JSON = Codec{jsonMarshal, jsonUnmarshal} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/websocket_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/websocket_test.go new file mode 100644 index 00000000..05b7e535 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/websocket/websocket_test.go @@ -0,0 +1,587 @@ +// Copyright 2009 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 websocket + +import ( + "bytes" + "fmt" + "io" + "log" + "net" + "net/http" + "net/http/httptest" + "net/url" + "reflect" + "runtime" + "strings" + "sync" + "testing" + "time" +) + +var serverAddr string +var once sync.Once + +func echoServer(ws *Conn) { + defer ws.Close() + io.Copy(ws, ws) +} + +type Count struct { + S string + N int +} + +func countServer(ws *Conn) { + defer ws.Close() + for { + var count Count + err := JSON.Receive(ws, &count) + if err != nil { + return + } + count.N++ + count.S = strings.Repeat(count.S, count.N) + err = JSON.Send(ws, count) + if err != nil { + return + } + } +} + +type testCtrlAndDataHandler struct { + hybiFrameHandler +} + +func (h *testCtrlAndDataHandler) WritePing(b []byte) (int, error) { + h.hybiFrameHandler.conn.wio.Lock() + defer h.hybiFrameHandler.conn.wio.Unlock() + w, err := h.hybiFrameHandler.conn.frameWriterFactory.NewFrameWriter(PingFrame) + if err != nil { + return 0, err + } + n, err := w.Write(b) + w.Close() + return n, err +} + +func ctrlAndDataServer(ws *Conn) { + defer ws.Close() + h := &testCtrlAndDataHandler{hybiFrameHandler: hybiFrameHandler{conn: ws}} + ws.frameHandler = h + + go func() { + for i := 0; ; i++ { + var b []byte + if i%2 != 0 { // with or without payload + b = []byte(fmt.Sprintf("#%d-CONTROL-FRAME-FROM-SERVER", i)) + } + if _, err := h.WritePing(b); err != nil { + break + } + if _, err := h.WritePong(b); err != nil { // unsolicited pong + break + } + time.Sleep(10 * time.Millisecond) + } + }() + + b := make([]byte, 128) + for { + n, err := ws.Read(b) + if err != nil { + break + } + if _, err := ws.Write(b[:n]); err != nil { + break + } + } +} + +func subProtocolHandshake(config *Config, req *http.Request) error { + for _, proto := range config.Protocol { + if proto == "chat" { + config.Protocol = []string{proto} + return nil + } + } + return ErrBadWebSocketProtocol +} + +func subProtoServer(ws *Conn) { + for _, proto := range ws.Config().Protocol { + io.WriteString(ws, proto) + } +} + +func startServer() { + http.Handle("/echo", Handler(echoServer)) + http.Handle("/count", Handler(countServer)) + http.Handle("/ctrldata", Handler(ctrlAndDataServer)) + subproto := Server{ + Handshake: subProtocolHandshake, + Handler: Handler(subProtoServer), + } + http.Handle("/subproto", subproto) + server := httptest.NewServer(nil) + serverAddr = server.Listener.Addr().String() + log.Print("Test WebSocket server listening on ", serverAddr) +} + +func newConfig(t *testing.T, path string) *Config { + config, _ := NewConfig(fmt.Sprintf("ws://%s%s", serverAddr, path), "http://localhost") + return config +} + +func TestEcho(t *testing.T) { + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/echo"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + msg := []byte("hello, world\n") + if _, err := conn.Write(msg); err != nil { + t.Errorf("Write: %v", err) + } + var actual_msg = make([]byte, 512) + n, err := conn.Read(actual_msg) + if err != nil { + t.Errorf("Read: %v", err) + } + actual_msg = actual_msg[0:n] + if !bytes.Equal(msg, actual_msg) { + t.Errorf("Echo: expected %q got %q", msg, actual_msg) + } + conn.Close() +} + +func TestAddr(t *testing.T) { + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/echo"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + ra := conn.RemoteAddr().String() + if !strings.HasPrefix(ra, "ws://") || !strings.HasSuffix(ra, "/echo") { + t.Errorf("Bad remote addr: %v", ra) + } + la := conn.LocalAddr().String() + if !strings.HasPrefix(la, "http://") { + t.Errorf("Bad local addr: %v", la) + } + conn.Close() +} + +func TestCount(t *testing.T) { + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/count"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + var count Count + count.S = "hello" + if err := JSON.Send(conn, count); err != nil { + t.Errorf("Write: %v", err) + } + if err := JSON.Receive(conn, &count); err != nil { + t.Errorf("Read: %v", err) + } + if count.N != 1 { + t.Errorf("count: expected %d got %d", 1, count.N) + } + if count.S != "hello" { + t.Errorf("count: expected %q got %q", "hello", count.S) + } + if err := JSON.Send(conn, count); err != nil { + t.Errorf("Write: %v", err) + } + if err := JSON.Receive(conn, &count); err != nil { + t.Errorf("Read: %v", err) + } + if count.N != 2 { + t.Errorf("count: expected %d got %d", 2, count.N) + } + if count.S != "hellohello" { + t.Errorf("count: expected %q got %q", "hellohello", count.S) + } + conn.Close() +} + +func TestWithQuery(t *testing.T) { + once.Do(startServer) + + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + + config := newConfig(t, "/echo") + config.Location, err = url.ParseRequestURI(fmt.Sprintf("ws://%s/echo?q=v", serverAddr)) + if err != nil { + t.Fatal("location url", err) + } + + ws, err := NewClient(config, client) + if err != nil { + t.Errorf("WebSocket handshake: %v", err) + return + } + ws.Close() +} + +func testWithProtocol(t *testing.T, subproto []string) (string, error) { + once.Do(startServer) + + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + + config := newConfig(t, "/subproto") + config.Protocol = subproto + + ws, err := NewClient(config, client) + if err != nil { + return "", err + } + msg := make([]byte, 16) + n, err := ws.Read(msg) + if err != nil { + return "", err + } + ws.Close() + return string(msg[:n]), nil +} + +func TestWithProtocol(t *testing.T) { + proto, err := testWithProtocol(t, []string{"chat"}) + if err != nil { + t.Errorf("SubProto: unexpected error: %v", err) + } + if proto != "chat" { + t.Errorf("SubProto: expected %q, got %q", "chat", proto) + } +} + +func TestWithTwoProtocol(t *testing.T) { + proto, err := testWithProtocol(t, []string{"test", "chat"}) + if err != nil { + t.Errorf("SubProto: unexpected error: %v", err) + } + if proto != "chat" { + t.Errorf("SubProto: expected %q, got %q", "chat", proto) + } +} + +func TestWithBadProtocol(t *testing.T) { + _, err := testWithProtocol(t, []string{"test"}) + if err != ErrBadStatus { + t.Errorf("SubProto: expected %v, got %v", ErrBadStatus, err) + } +} + +func TestHTTP(t *testing.T) { + once.Do(startServer) + + // If the client did not send a handshake that matches the protocol + // specification, the server MUST return an HTTP response with an + // appropriate error code (such as 400 Bad Request) + resp, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr)) + if err != nil { + t.Errorf("Get: error %#v", err) + return + } + if resp == nil { + t.Error("Get: resp is null") + return + } + if resp.StatusCode != http.StatusBadRequest { + t.Errorf("Get: expected %q got %q", http.StatusBadRequest, resp.StatusCode) + } +} + +func TestTrailingSpaces(t *testing.T) { + // http://code.google.com/p/go/issues/detail?id=955 + // The last runs of this create keys with trailing spaces that should not be + // generated by the client. + once.Do(startServer) + config := newConfig(t, "/echo") + for i := 0; i < 30; i++ { + // body + ws, err := DialConfig(config) + if err != nil { + t.Errorf("Dial #%d failed: %v", i, err) + break + } + ws.Close() + } +} + +func TestDialConfigBadVersion(t *testing.T) { + once.Do(startServer) + config := newConfig(t, "/echo") + config.Version = 1234 + + _, err := DialConfig(config) + + if dialerr, ok := err.(*DialError); ok { + if dialerr.Err != ErrBadProtocolVersion { + t.Errorf("dial expected err %q but got %q", ErrBadProtocolVersion, dialerr.Err) + } + } +} + +func TestSmallBuffer(t *testing.T) { + // http://code.google.com/p/go/issues/detail?id=1145 + // Read should be able to handle reading a fragment of a frame. + once.Do(startServer) + + // websocket.Dial() + client, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + conn, err := NewClient(newConfig(t, "/echo"), client) + if err != nil { + t.Errorf("WebSocket handshake error: %v", err) + return + } + + msg := []byte("hello, world\n") + if _, err := conn.Write(msg); err != nil { + t.Errorf("Write: %v", err) + } + var small_msg = make([]byte, 8) + n, err := conn.Read(small_msg) + if err != nil { + t.Errorf("Read: %v", err) + } + if !bytes.Equal(msg[:len(small_msg)], small_msg) { + t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg) + } + var second_msg = make([]byte, len(msg)) + n, err = conn.Read(second_msg) + if err != nil { + t.Errorf("Read: %v", err) + } + second_msg = second_msg[0:n] + if !bytes.Equal(msg[len(small_msg):], second_msg) { + t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg) + } + conn.Close() +} + +var parseAuthorityTests = []struct { + in *url.URL + out string +}{ + { + &url.URL{ + Scheme: "ws", + Host: "www.google.com", + }, + "www.google.com:80", + }, + { + &url.URL{ + Scheme: "wss", + Host: "www.google.com", + }, + "www.google.com:443", + }, + { + &url.URL{ + Scheme: "ws", + Host: "www.google.com:80", + }, + "www.google.com:80", + }, + { + &url.URL{ + Scheme: "wss", + Host: "www.google.com:443", + }, + "www.google.com:443", + }, + // some invalid ones for parseAuthority. parseAuthority doesn't + // concern itself with the scheme unless it actually knows about it + { + &url.URL{ + Scheme: "http", + Host: "www.google.com", + }, + "www.google.com", + }, + { + &url.URL{ + Scheme: "http", + Host: "www.google.com:80", + }, + "www.google.com:80", + }, + { + &url.URL{ + Scheme: "asdf", + Host: "127.0.0.1", + }, + "127.0.0.1", + }, + { + &url.URL{ + Scheme: "asdf", + Host: "www.google.com", + }, + "www.google.com", + }, +} + +func TestParseAuthority(t *testing.T) { + for _, tt := range parseAuthorityTests { + out := parseAuthority(tt.in) + if out != tt.out { + t.Errorf("got %v; want %v", out, tt.out) + } + } +} + +type closerConn struct { + net.Conn + closed int // count of the number of times Close was called +} + +func (c *closerConn) Close() error { + c.closed++ + return c.Conn.Close() +} + +func TestClose(t *testing.T) { + if runtime.GOOS == "plan9" { + t.Skip("see golang.org/issue/11454") + } + + once.Do(startServer) + + conn, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal("dialing", err) + } + + cc := closerConn{Conn: conn} + + client, err := NewClient(newConfig(t, "/echo"), &cc) + if err != nil { + t.Fatalf("WebSocket handshake: %v", err) + } + + // set the deadline to ten minutes ago, which will have expired by the time + // client.Close sends the close status frame. + conn.SetDeadline(time.Now().Add(-10 * time.Minute)) + + if err := client.Close(); err == nil { + t.Errorf("ws.Close(): expected error, got %v", err) + } + if cc.closed < 1 { + t.Fatalf("ws.Close(): expected underlying ws.rwc.Close to be called > 0 times, got: %v", cc.closed) + } +} + +var originTests = []struct { + req *http.Request + origin *url.URL +}{ + { + req: &http.Request{ + Header: http.Header{ + "Origin": []string{"http://www.example.com"}, + }, + }, + origin: &url.URL{ + Scheme: "http", + Host: "www.example.com", + }, + }, + { + req: &http.Request{}, + }, +} + +func TestOrigin(t *testing.T) { + conf := newConfig(t, "/echo") + conf.Version = ProtocolVersionHybi13 + for i, tt := range originTests { + origin, err := Origin(conf, tt.req) + if err != nil { + t.Error(err) + continue + } + if !reflect.DeepEqual(origin, tt.origin) { + t.Errorf("#%d: got origin %v; want %v", i, origin, tt.origin) + continue + } + } +} + +func TestCtrlAndData(t *testing.T) { + once.Do(startServer) + + c, err := net.Dial("tcp", serverAddr) + if err != nil { + t.Fatal(err) + } + ws, err := NewClient(newConfig(t, "/ctrldata"), c) + if err != nil { + t.Fatal(err) + } + defer ws.Close() + + h := &testCtrlAndDataHandler{hybiFrameHandler: hybiFrameHandler{conn: ws}} + ws.frameHandler = h + + b := make([]byte, 128) + for i := 0; i < 2; i++ { + data := []byte(fmt.Sprintf("#%d-DATA-FRAME-FROM-CLIENT", i)) + if _, err := ws.Write(data); err != nil { + t.Fatalf("#%d: %v", i, err) + } + var ctrl []byte + if i%2 != 0 { // with or without payload + ctrl = []byte(fmt.Sprintf("#%d-CONTROL-FRAME-FROM-CLIENT", i)) + } + if _, err := h.WritePing(ctrl); err != nil { + t.Fatalf("#%d: %v", i, err) + } + n, err := ws.Read(b) + if err != nil { + t.Fatalf("#%d: %v", i, err) + } + if !bytes.Equal(b[:n], data) { + t.Fatalf("#%d: got %v; want %v", i, b[:n], data) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/xsrftoken/xsrf.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/xsrftoken/xsrf.go new file mode 100644 index 00000000..8d218787 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/xsrftoken/xsrf.go @@ -0,0 +1,88 @@ +// 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 xsrftoken provides methods for generating and validating secure XSRF tokens. +package xsrftoken // import "golang.org/x/net/xsrftoken" + +import ( + "crypto/hmac" + "crypto/sha1" + "crypto/subtle" + "encoding/base64" + "fmt" + "strconv" + "strings" + "time" +) + +// Timeout is the duration for which XSRF tokens are valid. +// It is exported so clients may set cookie timeouts that match generated tokens. +const Timeout = 24 * time.Hour + +// clean sanitizes a string for inclusion in a token by replacing all ":"s. +func clean(s string) string { + return strings.Replace(s, ":", "_", -1) +} + +// Generate returns a URL-safe secure XSRF token that expires in 24 hours. +// +// key is a secret key for your application. +// userID is a unique identifier for the user. +// actionID is the action the user is taking (e.g. POSTing to a particular path). +func Generate(key, userID, actionID string) string { + return generateTokenAtTime(key, userID, actionID, time.Now()) +} + +// generateTokenAtTime is like Generate, but returns a token that expires 24 hours from now. +func generateTokenAtTime(key, userID, actionID string, now time.Time) string { + // Round time up and convert to milliseconds. + milliTime := (now.UnixNano() + 1e6 - 1) / 1e6 + + h := hmac.New(sha1.New, []byte(key)) + fmt.Fprintf(h, "%s:%s:%d", clean(userID), clean(actionID), milliTime) + + // Get the padded base64 string then removing the padding. + tok := string(h.Sum(nil)) + tok = base64.URLEncoding.EncodeToString([]byte(tok)) + tok = strings.TrimRight(tok, "=") + + return fmt.Sprintf("%s:%d", tok, milliTime) +} + +// Valid reports whether a token is a valid, unexpired token returned by Generate. +func Valid(token, key, userID, actionID string) bool { + return validTokenAtTime(token, key, userID, actionID, time.Now()) +} + +// validTokenAtTime reports whether a token is valid at the given time. +func validTokenAtTime(token, key, userID, actionID string, now time.Time) bool { + // Extract the issue time of the token. + sep := strings.LastIndex(token, ":") + if sep < 0 { + return false + } + millis, err := strconv.ParseInt(token[sep+1:], 10, 64) + if err != nil { + return false + } + issueTime := time.Unix(0, millis*1e6) + + // Check that the token is not expired. + if now.Sub(issueTime) >= Timeout { + return false + } + + // Check that the token is not from the future. + // Allow 1 minute grace period in case the token is being verified on a + // machine whose clock is behind the machine that issued the token. + if issueTime.After(now.Add(1 * time.Minute)) { + return false + } + + expected := generateTokenAtTime(key, userID, actionID, issueTime) + + // Check that the token matches the expected value. + // Use constant time comparison to avoid timing attacks. + return subtle.ConstantTimeCompare([]byte(token), []byte(expected)) == 1 +} diff --git a/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/xsrftoken/xsrf_test.go b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/xsrftoken/xsrf_test.go new file mode 100644 index 00000000..9933f867 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/golang.org/x/net/xsrftoken/xsrf_test.go @@ -0,0 +1,83 @@ +// 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 xsrftoken + +import ( + "encoding/base64" + "testing" + "time" +) + +const ( + key = "quay" + userID = "12345678" + actionID = "POST /form" +) + +var ( + now = time.Now() + oneMinuteFromNow = now.Add(1 * time.Minute) +) + +func TestValidToken(t *testing.T) { + tok := generateTokenAtTime(key, userID, actionID, now) + if !validTokenAtTime(tok, key, userID, actionID, oneMinuteFromNow) { + t.Error("One second later: Expected token to be valid") + } + if !validTokenAtTime(tok, key, userID, actionID, now.Add(Timeout-1*time.Nanosecond)) { + t.Error("Just before timeout: Expected token to be valid") + } + if !validTokenAtTime(tok, key, userID, actionID, now.Add(-1*time.Minute+1*time.Millisecond)) { + t.Error("One minute in the past: Expected token to be valid") + } +} + +// TestSeparatorReplacement tests that separators are being correctly substituted +func TestSeparatorReplacement(t *testing.T) { + tok := generateTokenAtTime("foo:bar", "baz", "wah", now) + tok2 := generateTokenAtTime("foo", "bar:baz", "wah", now) + if tok == tok2 { + t.Errorf("Expected generated tokens to be different") + } +} + +func TestInvalidToken(t *testing.T) { + invalidTokenTests := []struct { + name, key, userID, actionID string + t time.Time + }{ + {"Bad key", "foobar", userID, actionID, oneMinuteFromNow}, + {"Bad userID", key, "foobar", actionID, oneMinuteFromNow}, + {"Bad actionID", key, userID, "foobar", oneMinuteFromNow}, + {"Expired", key, userID, actionID, now.Add(Timeout + 1*time.Millisecond)}, + {"More than 1 minute from the future", key, userID, actionID, now.Add(-1*time.Nanosecond - 1*time.Minute)}, + } + + tok := generateTokenAtTime(key, userID, actionID, now) + for _, itt := range invalidTokenTests { + if validTokenAtTime(tok, itt.key, itt.userID, itt.actionID, itt.t) { + t.Errorf("%v: Expected token to be invalid", itt.name) + } + } +} + +// TestValidateBadData primarily tests that no unexpected panics are triggered +// during parsing +func TestValidateBadData(t *testing.T) { + badDataTests := []struct { + name, tok string + }{ + {"Invalid Base64", "ASDab24(@)$*=="}, + {"No delimiter", base64.URLEncoding.EncodeToString([]byte("foobar12345678"))}, + {"Invalid time", base64.URLEncoding.EncodeToString([]byte("foobar:foobar"))}, + {"Wrong length", "1234" + generateTokenAtTime(key, userID, actionID, now)}, + } + + for _, bdt := range badDataTests { + if validTokenAtTime(bdt.tok, key, userID, actionID, oneMinuteFromNow) { + t.Errorf("%v: Expected token to be invalid", bdt.name) + } + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/.gitignore b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/.gitignore new file mode 100644 index 00000000..792ca00d --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/.gitignore @@ -0,0 +1,29 @@ +# 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 +*.test +*.prof +*.test +*.out +*.txt +cover.html +README.html \ No newline at end of file diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/LICENSE b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/LICENSE new file mode 100644 index 00000000..6a2ae9aa --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Dean Karn + +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/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/README.md b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/README.md new file mode 100644 index 00000000..de7bbe53 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/README.md @@ -0,0 +1,366 @@ +Package validator +================ + +[![Join the chat at https://gitter.im/bluesuncorp/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![Build Status](https://semaphoreci.com/api/v1/projects/ec20115f-ef1b-4c7d-9393-cc76aba74eb4/530054/badge.svg)](https://semaphoreci.com/joeybloggs/validator) +[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=v8&service=github)](https://coveralls.io/github/go-playground/validator?branch=v8) +[![Go Report Card](http://goreportcard.com/badge/go-playground/validator)](http://goreportcard.com/report/go-playground/validator) +[![GoDoc](https://godoc.org/gopkg.in/go-playground/validator.v8?status.svg)](https://godoc.org/gopkg.in/go-playground/validator.v8) + +Package validator implements value validations for structs and individual fields based on tags. + +It has the following **unique** features: + +- Cross Field and Cross Struct validations by using validation tags or custom validators. +- Slice, Array and Map diving, which allows any or all levels of a multidimensional field to be validated. +- Handles type interface by determining it's underlying type prior to validation. +- Handles custom field types such as sql driver Valuer see [Valuer](https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29) +- Alias validation tags, which allows for mapping of several validations to a single tag for easier defining of validations on structs +- Extraction of custom defined Field Name e.g. can specify to extract the JSON name while validating and have it available in the resulting FieldError + +Installation +------------ + +Use go get. + + go get gopkg.in/go-playground/validator.v8 + +or to update + + go get -u gopkg.in/go-playground/validator.v8 + +Then import the validator package into your own code. + + import "gopkg.in/go-playground/validator.v8" + +Error Return Value +------- + +Validation functions return type error + +They return type error to avoid the issue discussed in the following, where err is always != nil: + +* http://stackoverflow.com/a/29138676/3158232 +* https://github.com/go-playground/validator/issues/134 + +validator only returns nil or ValidationErrors as type error; so in you code all you need to do +is check if the error returned is not nil, and if it's not type cast it to type ValidationErrors +like so: + +```go +err := validate.Struct(mystruct) +validationErrors := err.(validator.ValidationErrors) + ``` + +Usage and documentation +------ + +Please see http://godoc.org/gopkg.in/go-playground/validator.v8 for detailed usage docs. + +##### Examples: + +Struct & Field validation +```go +package main + +import ( + "fmt" + + "gopkg.in/go-playground/validator.v8" +) + +// User contains user information +type User struct { + FirstName string `validate:"required"` + LastName string `validate:"required"` + Age uint8 `validate:"gte=0,lte=130"` + Email string `validate:"required,email"` + FavouriteColor string `validate:"hexcolor|rgb|rgba"` + Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage... +} + +// Address houses a users address information +type Address struct { + Street string `validate:"required"` + City string `validate:"required"` + Planet string `validate:"required"` + Phone string `validate:"required"` +} + +var validate *validator.Validate + +func main() { + + config := &validator.Config{TagName: "validate"} + + validate = validator.New(config) + + validateStruct() + validateField() +} + +func validateStruct() { + + address := &Address{ + Street: "Eavesdown Docks", + Planet: "Persphone", + Phone: "none", + } + + user := &User{ + FirstName: "Badger", + LastName: "Smith", + Age: 135, + Email: "Badger.Smith@gmail.com", + FavouriteColor: "#000", + Addresses: []*Address{address}, + } + + // returns nil or ValidationErrors ( map[string]*FieldError ) + errs := validate.Struct(user) + + if errs != nil { + + fmt.Println(errs) // output: Key: "User.Age" Error:Field validation for "Age" failed on the "lte" tag + // Key: "User.Addresses[0].City" Error:Field validation for "City" failed on the "required" tag + err := errs.(validator.ValidationErrors)["User.Addresses[0].City"] + fmt.Println(err.Field) // output: City + fmt.Println(err.Tag) // output: required + fmt.Println(err.Kind) // output: string + fmt.Println(err.Type) // output: string + fmt.Println(err.Param) // output: + fmt.Println(err.Value) // output: + + // from here you can create your own error messages in whatever language you wish + return + } + + // save user to database +} + +func validateField() { + myEmail := "joeybloggs.gmail.com" + + errs := validate.Field(myEmail, "required,email") + + if errs != nil { + fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag + return + } + + // email ok, move on +} +``` + +Custom Field Type +```go +package main + +import ( + "database/sql" + "database/sql/driver" + "fmt" + "reflect" + + "gopkg.in/go-playground/validator.v8" +) + +// DbBackedUser User struct +type DbBackedUser struct { + Name sql.NullString `validate:"required"` + Age sql.NullInt64 `validate:"required"` +} + +func main() { + + config := &validator.Config{TagName: "validate"} + + validate := validator.New(config) + + // register all sql.Null* types to use the ValidateValuer CustomTypeFunc + validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) + + x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}} + errs := validate.Struct(x) + + if len(errs.(validator.ValidationErrors)) > 0 { + fmt.Printf("Errs:\n%+v\n", errs) + } +} + +// ValidateValuer implements validator.CustomTypeFunc +func ValidateValuer(field reflect.Value) interface{} { + if valuer, ok := field.Interface().(driver.Valuer); ok { + val, err := valuer.Value() + if err == nil { + return val + } + // handle the error how you want + } + return nil +} +``` + +Struct Level Validation +```go +package main + +import ( + "fmt" + "reflect" + + "gopkg.in/go-playground/validator.v8" +) + +// User contains user information +type User struct { + FirstName string `json:"fname"` + LastName string `json:"lname"` + Age uint8 `validate:"gte=0,lte=130"` + Email string `validate:"required,email"` + FavouriteColor string `validate:"hexcolor|rgb|rgba"` + Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage... +} + +// Address houses a users address information +type Address struct { + Street string `validate:"required"` + City string `validate:"required"` + Planet string `validate:"required"` + Phone string `validate:"required"` +} + +var validate *validator.Validate + +func main() { + + config := &validator.Config{TagName: "validate"} + + validate = validator.New(config) + validate.RegisterStructValidation(UserStructLevelValidation, User{}) + + validateStruct() +} + +// UserStructLevelValidation contains custom struct level validations that don't always +// make sense at the field validation level. For Example this function validates that either +// FirstName or LastName exist; could have done that with a custom field validation but then +// would have had to add it to both fields duplicating the logic + overhead, this way it's +// only validated once. +// +// NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way +// hooks right into validator and you can combine with validation tags and still have a +// common error output format. +func UserStructLevelValidation(v *validator.Validate, structLevel *validator.StructLevel) { + + user := structLevel.CurrentStruct.Interface().(User) + + if len(user.FirstName) == 0 && len(user.LastName) == 0 { + structLevel.ReportError(reflect.ValueOf(user.FirstName), "FirstName", "fname", "fnameorlname") + structLevel.ReportError(reflect.ValueOf(user.LastName), "LastName", "lname", "fnameorlname") + } + + // plus can to more, even with different tag than "fnameorlname" +} + +func validateStruct() { + + address := &Address{ + Street: "Eavesdown Docks", + Planet: "Persphone", + Phone: "none", + City: "Unknown", + } + + user := &User{ + FirstName: "", + LastName: "", + Age: 45, + Email: "Badger.Smith@gmail.com", + FavouriteColor: "#000", + Addresses: []*Address{address}, + } + + // returns nil or ValidationErrors ( map[string]*FieldError ) + errs := validate.Struct(user) + + if errs != nil { + + fmt.Println(errs) // output: Key: 'User.LastName' Error:Field validation for 'LastName' failed on the 'fnameorlname' tag + // Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'fnameorlname' tag + err := errs.(validator.ValidationErrors)["User.FirstName"] + fmt.Println(err.Field) // output: FirstName + fmt.Println(err.Tag) // output: fnameorlname + fmt.Println(err.Kind) // output: string + fmt.Println(err.Type) // output: string + fmt.Println(err.Param) // output: + fmt.Println(err.Value) // output: + + // from here you can create your own error messages in whatever language you wish + return + } + + // save user to database +} +``` + +Benchmarks +------ +###### Run on MacBook Pro (Retina, 15-inch, Late 2013) 2.6 GHz Intel Core i7 16 GB 1600 MHz DDR3 using Go version go1.5.2 darwin/amd64 +```go +go test -cpu=4 -bench=. -benchmem=true +PASS +BenchmarkFieldSuccess-4 10000000 176 ns/op 0 B/op 0 allocs/op +BenchmarkFieldFailure-4 2000000 727 ns/op 432 B/op 4 allocs/op +BenchmarkFieldDiveSuccess-4 500000 3220 ns/op 480 B/op 27 allocs/op +BenchmarkFieldDiveFailure-4 500000 3823 ns/op 912 B/op 31 allocs/op +BenchmarkFieldCustomTypeSuccess-4 5000000 368 ns/op 32 B/op 2 allocs/op +BenchmarkFieldCustomTypeFailure-4 2000000 699 ns/op 432 B/op 4 allocs/op +BenchmarkFieldOrTagSuccess-4 1000000 1265 ns/op 16 B/op 1 allocs/op +BenchmarkFieldOrTagFailure-4 1000000 1182 ns/op 464 B/op 6 allocs/op +BenchmarkStructLevelValidationSuccess-4 2000000 739 ns/op 176 B/op 6 allocs/op +BenchmarkStructLevelValidationFailure-4 1000000 1368 ns/op 640 B/op 11 allocs/op +BenchmarkStructSimpleCustomTypeSuccess-4 2000000 965 ns/op 80 B/op 5 allocs/op +BenchmarkStructSimpleCustomTypeFailure-4 1000000 1561 ns/op 688 B/op 11 allocs/op +BenchmarkStructPartialSuccess-4 1000000 1285 ns/op 384 B/op 10 allocs/op +BenchmarkStructPartialFailure-4 1000000 1879 ns/op 832 B/op 15 allocs/op +BenchmarkStructExceptSuccess-4 2000000 1038 ns/op 336 B/op 7 allocs/op +BenchmarkStructExceptFailure-4 1000000 1330 ns/op 384 B/op 10 allocs/op +BenchmarkStructSimpleCrossFieldSuccess-4 1000000 1081 ns/op 128 B/op 6 allocs/op +BenchmarkStructSimpleCrossFieldFailure-4 1000000 1737 ns/op 592 B/op 11 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldSuccess-4 1000000 1790 ns/op 192 B/op 10 allocs/op +BenchmarkStructSimpleCrossStructCrossFieldFailure-4 500000 2431 ns/op 656 B/op 15 allocs/op +BenchmarkStructSimpleSuccess-4 2000000 950 ns/op 48 B/op 3 allocs/op +BenchmarkStructSimpleFailure-4 1000000 1672 ns/op 688 B/op 11 allocs/op +BenchmarkStructSimpleSuccessParallel-4 5000000 271 ns/op 48 B/op 3 allocs/op +BenchmarkStructSimpleFailureParallel-4 2000000 670 ns/op 688 B/op 11 allocs/op +BenchmarkStructComplexSuccess-4 300000 5828 ns/op 544 B/op 32 allocs/op +BenchmarkStructComplexFailure-4 200000 11382 ns/op 3912 B/op 77 allocs/op +BenchmarkStructComplexSuccessParallel-4 1000000 1739 ns/op 544 B/op 32 allocs/op +BenchmarkStructComplexFailureParallel-4 300000 4682 ns/op 3912 B/op 77 allocs/op +``` + +Complimentary Software +---------------------- + +Here is a list of software that compliments using this library either pre or post validation. + +* [Gorilla Schema](https://github.com/gorilla/schema) - Package gorilla/schema fills a struct with form values. +* [Conform](https://github.com/leebenson/conform) - Trims, sanitizes & scrubs data based on struct tags. + +How to Contribute +------ + +There will always be a development branch for each version i.e. `v1-development`. In order to contribute, +please make your pull requests against those branches. + +If the changes being proposed or requested are breaking changes, please create an issue, for discussion +or create a pull request against the highest development branch for example this package has a +v1 and v1-development branch however, there will also be a v2-development branch even though v2 doesn't exist yet. + +I strongly encourage everyone whom creates a custom validation function to contribute them and +help make this package even better. + +License +------ +Distributed under MIT License, please see license file in code for more details. diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/baked_in.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/baked_in.go new file mode 100644 index 00000000..2d60162b --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/baked_in.go @@ -0,0 +1,1395 @@ +package validator + +import ( + "fmt" + "net" + "net/url" + "reflect" + "strings" + "time" + "unicode/utf8" +) + +// BakedInAliasValidators is a default mapping of a single validationstag that +// defines a common or complex set of validation(s) to simplify +// adding validation to structs. i.e. set key "_ageok" and the tags +// are "gt=0,lte=130" or key "_preferredname" and tags "omitempty,gt=0,lte=60" +var bakedInAliasValidators = map[string]string{ + "iscolor": "hexcolor|rgb|rgba|hsl|hsla", +} + +// BakedInValidators is the default map of ValidationFunc +// you can add, remove or even replace items to suite your needs, +// or even disregard and use your own map if so desired. +var bakedInValidators = map[string]Func{ + "required": HasValue, + "len": HasLengthOf, + "min": HasMinOf, + "max": HasMaxOf, + "eq": IsEq, + "ne": IsNe, + "lt": IsLt, + "lte": IsLte, + "gt": IsGt, + "gte": IsGte, + "eqfield": IsEqField, + "eqcsfield": IsEqCrossStructField, + "necsfield": IsNeCrossStructField, + "gtcsfield": IsGtCrossStructField, + "gtecsfield": IsGteCrossStructField, + "ltcsfield": IsLtCrossStructField, + "ltecsfield": IsLteCrossStructField, + "nefield": IsNeField, + "gtefield": IsGteField, + "gtfield": IsGtField, + "ltefield": IsLteField, + "ltfield": IsLtField, + "alpha": IsAlpha, + "alphanum": IsAlphanum, + "numeric": IsNumeric, + "number": IsNumber, + "hexadecimal": IsHexadecimal, + "hexcolor": IsHEXColor, + "rgb": IsRGB, + "rgba": IsRGBA, + "hsl": IsHSL, + "hsla": IsHSLA, + "email": IsEmail, + "url": IsURL, + "uri": IsURI, + "base64": IsBase64, + "contains": Contains, + "containsany": ContainsAny, + "containsrune": ContainsRune, + "excludes": Excludes, + "excludesall": ExcludesAll, + "excludesrune": ExcludesRune, + "isbn": IsISBN, + "isbn10": IsISBN10, + "isbn13": IsISBN13, + "uuid": IsUUID, + "uuid3": IsUUID3, + "uuid4": IsUUID4, + "uuid5": IsUUID5, + "ascii": IsASCII, + "printascii": IsPrintableASCII, + "multibyte": HasMultiByteCharacter, + "datauri": IsDataURI, + "latitude": IsLatitude, + "longitude": IsLongitude, + "ssn": IsSSN, + "ipv4": IsIPv4, + "ipv6": IsIPv6, + "ip": IsIP, + "cidrv4": IsCIDRv4, + "cidrv6": IsCIDRv6, + "cidr": IsCIDR, + "tcp4_addr": IsTCP4AddrResolvable, + "tcp6_addr": IsTCP6AddrResolvable, + "tcp_addr": IsTCPAddrResolvable, + "udp4_addr": IsUDP4AddrResolvable, + "udp6_addr": IsUDP6AddrResolvable, + "udp_addr": IsUDPAddrResolvable, + "ip4_addr": IsIP4AddrResolvable, + "ip6_addr": IsIP6AddrResolvable, + "ip_addr": IsIPAddrResolvable, + "unix_addr": IsUnixAddrResolvable, + "mac": IsMAC, +} + +// IsMAC is the validation function for validating if the field's value is a valid MAC address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsMAC(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + _, err := net.ParseMAC(field.String()) + return err == nil +} + +// IsCIDRv4 is the validation function for validating if the field's value is a valid v4 CIDR address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsCIDRv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + ip, _, err := net.ParseCIDR(field.String()) + + return err == nil && ip.To4() != nil +} + +// IsCIDRv6 is the validation function for validating if the field's value is a valid v6 CIDR address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsCIDRv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + ip, _, err := net.ParseCIDR(field.String()) + + return err == nil && ip.To4() == nil +} + +// IsCIDR is the validation function for validating if the field's value is a valid v4 or v6 CIDR address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsCIDR(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + _, _, err := net.ParseCIDR(field.String()) + + return err == nil +} + +// IsIPv4 is the validation function for validating if a value is a valid v4 IP address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsIPv4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + ip := net.ParseIP(field.String()) + + return ip != nil && ip.To4() != nil +} + +// IsIPv6 is the validation function for validating if the field's value is a valid v6 IP address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsIPv6(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + ip := net.ParseIP(field.String()) + + return ip != nil && ip.To4() == nil +} + +// IsIP is the validation function for validating if the field's value is a valid v4 or v6 IP address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsIP(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + ip := net.ParseIP(field.String()) + + return ip != nil +} + +// IsSSN is the validation function for validating if the field's value is a valid SSN. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsSSN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if field.Len() != 11 { + return false + } + + return sSNRegex.MatchString(field.String()) +} + +// IsLongitude is the validation function for validating if the field's value is a valid longitude coordinate. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLongitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return longitudeRegex.MatchString(field.String()) +} + +// IsLatitude is the validation function for validating if the field's value is a valid latitude coordinate. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLatitude(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return latitudeRegex.MatchString(field.String()) +} + +// IsDataURI is the validation function for validating if the field's value is a valid data URI. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsDataURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + uri := strings.SplitN(field.String(), ",", 2) + + if len(uri) != 2 { + return false + } + + if !dataURIRegex.MatchString(uri[0]) { + return false + } + + fld := reflect.ValueOf(uri[1]) + + return IsBase64(v, topStruct, currentStructOrField, fld, fld.Type(), fld.Kind(), param) +} + +// HasMultiByteCharacter is the validation function for validating if the field's value has a multi byte character. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func HasMultiByteCharacter(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if field.Len() == 0 { + return true + } + + return multibyteRegex.MatchString(field.String()) +} + +// IsPrintableASCII is the validation function for validating if the field's value is a valid printable ASCII character. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsPrintableASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return printableASCIIRegex.MatchString(field.String()) +} + +// IsASCII is the validation function for validating if the field's value is a valid ASCII character. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsASCII(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return aSCIIRegex.MatchString(field.String()) +} + +// IsUUID5 is the validation function for validating if the field's value is a valid v5 UUID. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUUID5(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return uUID5Regex.MatchString(field.String()) +} + +// IsUUID4 is the validation function for validating if the field's value is a valid v4 UUID. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUUID4(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return uUID4Regex.MatchString(field.String()) +} + +// IsUUID3 is the validation function for validating if the field's value is a valid v3 UUID. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUUID3(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return uUID3Regex.MatchString(field.String()) +} + +// IsUUID is the validation function for validating if the field's value is a valid UUID of any version. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUUID(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return uUIDRegex.MatchString(field.String()) +} + +// IsISBN is the validation function for validating if the field's value is a valid v10 or v13 ISBN. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsISBN(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return IsISBN10(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) || IsISBN13(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) +} + +// IsISBN13 is the validation function for validating if the field's value is a valid v13 ISBN. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsISBN13(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + s := strings.Replace(strings.Replace(field.String(), "-", "", 4), " ", "", 4) + + if !iSBN13Regex.MatchString(s) { + return false + } + + var checksum int32 + var i int32 + + factor := []int32{1, 3} + + for i = 0; i < 12; i++ { + checksum += factor[i%2] * int32(s[i]-'0') + } + + if (int32(s[12]-'0'))-((10-(checksum%10))%10) == 0 { + return true + } + + return false +} + +// IsISBN10 is the validation function for validating if the field's value is a valid v10 ISBN. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsISBN10(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + s := strings.Replace(strings.Replace(field.String(), "-", "", 3), " ", "", 3) + + if !iSBN10Regex.MatchString(s) { + return false + } + + var checksum int32 + var i int32 + + for i = 0; i < 9; i++ { + checksum += (i + 1) * int32(s[i]-'0') + } + + if s[9] == 'X' { + checksum += 10 * 10 + } else { + checksum += 10 * int32(s[9]-'0') + } + + if checksum%11 == 0 { + return true + } + + return false +} + +// ExcludesRune is the validation function for validating that the field's value does not contain the rune specified withing the param. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func ExcludesRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return !ContainsRune(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) +} + +// ExcludesAll is the validation function for validating that the field's value does not contain any of the characters specified withing the param. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func ExcludesAll(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return !ContainsAny(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) +} + +// Excludes is the validation function for validating that the field's value does not contain the text specified withing the param. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func Excludes(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return !Contains(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) +} + +// ContainsRune is the validation function for validating that the field's value contains the rune specified withing the param. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func ContainsRune(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + r, _ := utf8.DecodeRuneInString(param) + + return strings.ContainsRune(field.String(), r) +} + +// ContainsAny is the validation function for validating that the field's value contains any of the characters specified withing the param. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func ContainsAny(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return strings.ContainsAny(field.String(), param) +} + +// Contains is the validation function for validating that the field's value contains the text specified withing the param. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func Contains(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return strings.Contains(field.String(), param) +} + +// IsNeField is the validation function for validating if the current field's value is not equal to the field specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsNeField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) + + if !ok || currentKind != fieldKind { + return true + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() != currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() != currentField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() != currentField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) != int64(currentField.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return true + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return !fieldTime.Equal(t) + } + + } + + // default reflect.String: + return field.String() != currentField.String() +} + +// IsNe is the validation function for validating that the field's value does not equal the provided param value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsNe(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return !IsEq(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) +} + +// IsLteCrossStructField is the validation function for validating if the current field's value is less than or equal to the field, within a separate struct, specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + topField, topKind, ok := v.GetStructFieldOK(topStruct, param) + if !ok || topKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() <= topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() <= topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() <= topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) <= int64(topField.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.Before(topTime) || fieldTime.Equal(topTime) + } + } + + // default reflect.String: + return field.String() <= topField.String() +} + +// IsLtCrossStructField is the validation function for validating if the current field's value is less than the field, within a separate struct, specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + topField, topKind, ok := v.GetStructFieldOK(topStruct, param) + if !ok || topKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() < topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() < topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() < topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) < int64(topField.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.Before(topTime) + } + } + + // default reflect.String: + return field.String() < topField.String() +} + +// IsGteCrossStructField is the validation function for validating if the current field's value is greater than or equal to the field, within a separate struct, specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsGteCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + topField, topKind, ok := v.GetStructFieldOK(topStruct, param) + if !ok || topKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() >= topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() >= topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() >= topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) >= int64(topField.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.After(topTime) || fieldTime.Equal(topTime) + } + } + + // default reflect.String: + return field.String() >= topField.String() +} + +// IsGtCrossStructField is the validation function for validating if the current field's value is greater than the field, within a separate struct, specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsGtCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + topField, topKind, ok := v.GetStructFieldOK(topStruct, param) + if !ok || topKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() > topField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() > topField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() > topField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) > int64(topField.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + fieldTime := field.Interface().(time.Time) + topTime := topField.Interface().(time.Time) + + return fieldTime.After(topTime) + } + } + + // default reflect.String: + return field.String() > topField.String() +} + +// IsNeCrossStructField is the validation function for validating that the current field's value is not equal to the field, within a separate struct, specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsNeCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + topField, currentKind, ok := v.GetStructFieldOK(topStruct, param) + if !ok || currentKind != fieldKind { + return true + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return topField.Int() != field.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return topField.Uint() != field.Uint() + + case reflect.Float32, reflect.Float64: + return topField.Float() != field.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(topField.Len()) != int64(field.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return true + } + + if fieldType == timeType { + + t := field.Interface().(time.Time) + fieldTime := topField.Interface().(time.Time) + + return !fieldTime.Equal(t) + } + } + + // default reflect.String: + return topField.String() != field.String() +} + +// IsEqCrossStructField is the validation function for validating that the current field's value is equal to the field, within a separate struct, specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsEqCrossStructField(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + topField, topKind, ok := v.GetStructFieldOK(topStruct, param) + if !ok || topKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return topField.Int() == field.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return topField.Uint() == field.Uint() + + case reflect.Float32, reflect.Float64: + return topField.Float() == field.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(topField.Len()) == int64(field.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != topField.Type() { + return false + } + + if fieldType == timeType { + + t := field.Interface().(time.Time) + fieldTime := topField.Interface().(time.Time) + + return fieldTime.Equal(t) + } + } + + // default reflect.String: + return topField.String() == field.String() +} + +// IsEqField is the validation function for validating if the current field's value is equal to the field specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsEqField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) + if !ok || currentKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() == currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + return field.Uint() == currentField.Uint() + + case reflect.Float32, reflect.Float64: + return field.Float() == currentField.Float() + + case reflect.Slice, reflect.Map, reflect.Array: + return int64(field.Len()) == int64(currentField.Len()) + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.Equal(t) + } + + } + + // default reflect.String: + return field.String() == currentField.String() +} + +// IsEq is the validation function for validating if the current field's value is equal to the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsEq(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + return field.String() == param + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) == p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asInt(param) + + return field.Int() == p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() == p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() == p + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// IsBase64 is the validation function for validating if the current field's value is a valid base 64. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsBase64(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return base64Regex.MatchString(field.String()) +} + +// IsURI is the validation function for validating if the current field's value is a valid URI. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsURI(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + _, err := url.ParseRequestURI(field.String()) + + return err == nil + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// IsURL is the validation function for validating if the current field's value is a valid URL. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsURL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + url, err := url.ParseRequestURI(field.String()) + + if err != nil { + return false + } + + if url.Scheme == blank { + return false + } + + return err == nil + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// IsEmail is the validation function for validating if the current field's value is a valid email address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsEmail(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return emailRegex.MatchString(field.String()) +} + +// IsHSLA is the validation function for validating if the current field's value is a valid HSLA color. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsHSLA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return hslaRegex.MatchString(field.String()) +} + +// IsHSL is the validation function for validating if the current field's value is a valid HSL color. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsHSL(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return hslRegex.MatchString(field.String()) +} + +// IsRGBA is the validation function for validating if the current field's value is a valid RGBA color. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsRGBA(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return rgbaRegex.MatchString(field.String()) +} + +// IsRGB is the validation function for validating if the current field's value is a valid RGB color. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsRGB(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return rgbRegex.MatchString(field.String()) +} + +// IsHEXColor is the validation function for validating if the current field's value is a valid HEX color. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsHEXColor(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return hexcolorRegex.MatchString(field.String()) +} + +// IsHexadecimal is the validation function for validating if the current field's value is a valid hexadecimal. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsHexadecimal(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return hexadecimalRegex.MatchString(field.String()) +} + +// IsNumber is the validation function for validating if the current field's value is a valid number. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsNumber(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return numberRegex.MatchString(field.String()) +} + +// IsNumeric is the validation function for validating if the current field's value is a valid numeric value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsNumeric(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return numericRegex.MatchString(field.String()) +} + +// IsAlphanum is the validation function for validating if the current field's value is a valid alphanumeric value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsAlphanum(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return alphaNumericRegex.MatchString(field.String()) +} + +// IsAlpha is the validation function for validating if the current field's value is a valid alpha value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsAlpha(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return alphaRegex.MatchString(field.String()) +} + +// HasValue is the validation function for validating if the current field's value is not the default static value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func HasValue(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + case reflect.Slice, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func: + return !field.IsNil() + default: + return field.IsValid() && field.Interface() != reflect.Zero(fieldType).Interface() + } +} + +// IsGteField is the validation function for validating if the current field's value is greater than or equal to the field specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsGteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) + if !ok || currentKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() >= currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() >= currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() >= currentField.Float() + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.After(t) || fieldTime.Equal(t) + } + } + + // default reflect.String + return len(field.String()) >= len(currentField.String()) +} + +// IsGtField is the validation function for validating if the current field's value is greater than the field specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsGtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) + if !ok || currentKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() > currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() > currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() > currentField.Float() + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.After(t) + } + } + + // default reflect.String + return len(field.String()) > len(currentField.String()) +} + +// IsGte is the validation function for validating if the current field's value is greater than or equal to the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsGte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) >= p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) >= p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asInt(param) + + return field.Int() >= p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() >= p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() >= p + + case reflect.Struct: + + if fieldType == timeType || fieldType == timePtrType { + + now := time.Now().UTC() + t := field.Interface().(time.Time) + + return t.After(now) || t.Equal(now) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// IsGt is the validation function for validating if the current field's value is greater than the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsGt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) > p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) > p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asInt(param) + + return field.Int() > p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() > p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() > p + case reflect.Struct: + + if field.Type() == timeType || field.Type() == timePtrType { + + return field.Interface().(time.Time).After(time.Now().UTC()) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// HasLengthOf is the validation function for validating if the current field's value is equal to the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func HasLengthOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) == p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) == p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asInt(param) + + return field.Int() == p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() == p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() == p + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// HasMinOf is the validation function for validating if the current field's value is greater than or equal to the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func HasMinOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + return IsGte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) +} + +// IsLteField is the validation function for validating if the current field's value is less than or equal to the field specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLteField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) + if !ok || currentKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() <= currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() <= currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() <= currentField.Float() + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.Before(t) || fieldTime.Equal(t) + } + } + + // default reflect.String + return len(field.String()) <= len(currentField.String()) +} + +// IsLtField is the validation function for validating if the current field's value is less than the field specified by the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLtField(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + currentField, currentKind, ok := v.GetStructFieldOK(currentStructOrField, param) + if !ok || currentKind != fieldKind { + return false + } + + switch fieldKind { + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + + return field.Int() < currentField.Int() + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + + return field.Uint() < currentField.Uint() + + case reflect.Float32, reflect.Float64: + + return field.Float() < currentField.Float() + + case reflect.Struct: + + // Not Same underlying type i.e. struct and time + if fieldType != currentField.Type() { + return false + } + + if fieldType == timeType { + + t := currentField.Interface().(time.Time) + fieldTime := field.Interface().(time.Time) + + return fieldTime.Before(t) + } + } + + // default reflect.String + return len(field.String()) < len(currentField.String()) +} + +// IsLte is the validation function for validating if the current field's value is less than or equal to the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLte(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) <= p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) <= p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asInt(param) + + return field.Int() <= p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() <= p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() <= p + + case reflect.Struct: + + if fieldType == timeType || fieldType == timePtrType { + + now := time.Now().UTC() + t := field.Interface().(time.Time) + + return t.Before(now) || t.Equal(now) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// IsLt is the validation function for validating if the current field's value is less than the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsLt(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + switch fieldKind { + + case reflect.String: + p := asInt(param) + + return int64(utf8.RuneCountInString(field.String())) < p + + case reflect.Slice, reflect.Map, reflect.Array: + p := asInt(param) + + return int64(field.Len()) < p + + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + p := asInt(param) + + return field.Int() < p + + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: + p := asUint(param) + + return field.Uint() < p + + case reflect.Float32, reflect.Float64: + p := asFloat(param) + + return field.Float() < p + + case reflect.Struct: + + if field.Type() == timeType || field.Type() == timePtrType { + + return field.Interface().(time.Time).Before(time.Now().UTC()) + } + } + + panic(fmt.Sprintf("Bad field type %T", field.Interface())) +} + +// HasMaxOf is the validation function for validating if the current field's value is less than or equal to the param's value. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func HasMaxOf(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + return IsLte(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) +} + +// IsTCP4AddrResolvable is the validation function for validating if the field's value is a resolvable tcp4 address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsTCP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveTCPAddr("tcp4", field.String()) + return err == nil +} + +// IsTCP6AddrResolvable is the validation function for validating if the field's value is a resolvable tcp6 address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsTCP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveTCPAddr("tcp6", field.String()) + return err == nil +} + +// IsTCPAddrResolvable is the validation function for validating if the field's value is a resolvable tcp address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsTCPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) && + !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveTCPAddr("tcp", field.String()) + return err == nil +} + +// IsUDP4AddrResolvable is the validation function for validating if the field's value is a resolvable udp4 address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUDP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveUDPAddr("udp4", field.String()) + return err == nil +} + +// IsUDP6AddrResolvable is the validation function for validating if the field's value is a resolvable udp6 address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUDP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveUDPAddr("udp6", field.String()) + return err == nil +} + +// IsUDPAddrResolvable is the validation function for validating if the field's value is a resolvable udp address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUDPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !isIP4Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) && + !isIP6Addr(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveUDPAddr("udp", field.String()) + return err == nil +} + +// IsIP4AddrResolvable is the validation function for validating if the field's value is a resolvable ip4 address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsIP4AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !IsIPv4(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveIPAddr("ip4", field.String()) + return err == nil +} + +// IsIP6AddrResolvable is the validation function for validating if the field's value is a resolvable ip6 address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsIP6AddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !IsIPv6(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveIPAddr("ip6", field.String()) + return err == nil +} + +// IsIPAddrResolvable is the validation function for validating if the field's value is a resolvable ip address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsIPAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if !IsIP(v, topStruct, currentStructOrField, field, fieldType, fieldKind, param) { + return false + } + + _, err := net.ResolveIPAddr("ip", field.String()) + return err == nil +} + +// IsUnixAddrResolvable is the validation function for validating if the field's value is a resolvable unix address. +// NOTE: This is exposed for use within your own custom functions and not intended to be called directly. +func IsUnixAddrResolvable(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + _, err := net.ResolveUnixAddr("unix", field.String()) + return err == nil +} + +func isIP4Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + val := field.String() + + if idx := strings.LastIndex(val, ":"); idx != -1 { + val = val[0:idx] + } + + if !IsIPv4(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) { + return false + } + + return true +} + +func isIP6Addr(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + val := field.String() + + if idx := strings.LastIndex(val, ":"); idx != -1 { + if idx != 0 && val[idx-1:idx] == "]" { + val = val[1 : idx-1] + } + } + + if !IsIPv6(v, topStruct, currentStructOrField, reflect.ValueOf(val), fieldType, fieldKind, param) { + return false + } + + return true +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/benchmarks_test.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/benchmarks_test.go new file mode 100644 index 00000000..84db7431 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/benchmarks_test.go @@ -0,0 +1,524 @@ +package validator + +import ( + sql "database/sql/driver" + "testing" + "time" +) + +func BenchmarkFieldSuccess(b *testing.B) { + + var s *string + tmp := "1" + s = &tmp + + for n := 0; n < b.N; n++ { + validate.Field(s, "len=1") + } +} + +func BenchmarkFieldFailure(b *testing.B) { + + var s *string + tmp := "12" + s = &tmp + + for n := 0; n < b.N; n++ { + validate.Field(s, "len=1") + } +} + +func BenchmarkFieldDiveSuccess(b *testing.B) { + + m := make([]*string, 3) + t1 := "val1" + t2 := "val2" + t3 := "val3" + + m[0] = &t1 + m[1] = &t2 + m[2] = &t3 + + for n := 0; n < b.N; n++ { + validate.Field(m, "required,dive,required") + } +} + +func BenchmarkFieldDiveFailure(b *testing.B) { + + m := make([]*string, 3) + t1 := "val1" + t2 := "" + t3 := "val3" + + m[0] = &t1 + m[1] = &t2 + m[2] = &t3 + + for n := 0; n < b.N; n++ { + validate.Field(m, "required,dive,required") + } +} + +func BenchmarkFieldCustomTypeSuccess(b *testing.B) { + + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{ + Name: "1", + } + + for n := 0; n < b.N; n++ { + validate.Field(val, "len=1") + } +} + +func BenchmarkFieldCustomTypeFailure(b *testing.B) { + + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{} + + for n := 0; n < b.N; n++ { + validate.Field(val, "len=1") + } +} + +func BenchmarkFieldOrTagSuccess(b *testing.B) { + + var s *string + tmp := "rgba(0,0,0,1)" + s = &tmp + + for n := 0; n < b.N; n++ { + validate.Field(s, "rgb|rgba") + } +} + +func BenchmarkFieldOrTagFailure(b *testing.B) { + + var s *string + tmp := "#000" + s = &tmp + + for n := 0; n < b.N; n++ { + validate.Field(s, "rgb|rgba") + } +} + +func BenchmarkStructLevelValidationSuccess(b *testing.B) { + + validate.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{}) + + tst := &TestStruct{ + String: "good value", + } + + for n := 0; n < b.N; n++ { + validate.Struct(tst) + } +} + +func BenchmarkStructLevelValidationFailure(b *testing.B) { + + validate.RegisterStructValidation(StructValidationTestStruct, TestStruct{}) + + tst := &TestStruct{ + String: "good value", + } + + for n := 0; n < b.N; n++ { + validate.Struct(tst) + } +} + +func BenchmarkStructSimpleCustomTypeSuccess(b *testing.B) { + + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{ + Name: "1", + } + + type Foo struct { + Valuer valuer `validate:"len=1"` + IntValue int `validate:"min=5,max=10"` + } + + validFoo := &Foo{Valuer: val, IntValue: 7} + + for n := 0; n < b.N; n++ { + validate.Struct(validFoo) + } +} + +func BenchmarkStructSimpleCustomTypeFailure(b *testing.B) { + + validate.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + val := valuer{} + + type Foo struct { + Valuer valuer `validate:"len=1"` + IntValue int `validate:"min=5,max=10"` + } + + validFoo := &Foo{Valuer: val, IntValue: 3} + + for n := 0; n < b.N; n++ { + validate.Struct(validFoo) + } +} + +func BenchmarkStructPartialSuccess(b *testing.B) { + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", + } + + for n := 0; n < b.N; n++ { + validate.StructPartial(test, "Name") + } +} + +func BenchmarkStructPartialFailure(b *testing.B) { + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", + } + + for n := 0; n < b.N; n++ { + validate.StructPartial(test, "NickName") + } +} + +func BenchmarkStructExceptSuccess(b *testing.B) { + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", + } + + for n := 0; n < b.N; n++ { + validate.StructPartial(test, "Nickname") + } +} + +func BenchmarkStructExceptFailure(b *testing.B) { + + type Test struct { + Name string `validate:"required"` + NickName string `validate:"required"` + } + + test := &Test{ + Name: "Joey Bloggs", + } + + for n := 0; n < b.N; n++ { + validate.StructPartial(test, "Name") + } +} + +func BenchmarkStructSimpleCrossFieldSuccess(b *testing.B) { + + type Test struct { + Start time.Time + End time.Time `validate:"gtfield=Start"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * 5) + + test := &Test{ + Start: now, + End: then, + } + + for n := 0; n < b.N; n++ { + validate.Struct(test) + } +} + +func BenchmarkStructSimpleCrossFieldFailure(b *testing.B) { + + type Test struct { + Start time.Time + End time.Time `validate:"gtfield=Start"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * -5) + + test := &Test{ + Start: now, + End: then, + } + + for n := 0; n < b.N; n++ { + validate.Struct(test) + } +} + +func BenchmarkStructSimpleCrossStructCrossFieldSuccess(b *testing.B) { + + type Inner struct { + Start time.Time + } + + type Outer struct { + Inner *Inner + CreatedAt time.Time `validate:"eqcsfield=Inner.Start"` + } + + now := time.Now().UTC() + + inner := &Inner{ + Start: now, + } + + outer := &Outer{ + Inner: inner, + CreatedAt: now, + } + + for n := 0; n < b.N; n++ { + validate.Struct(outer) + } +} + +func BenchmarkStructSimpleCrossStructCrossFieldFailure(b *testing.B) { + + type Inner struct { + Start time.Time + } + + type Outer struct { + Inner *Inner + CreatedAt time.Time `validate:"eqcsfield=Inner.Start"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * 5) + + inner := &Inner{ + Start: then, + } + + outer := &Outer{ + Inner: inner, + CreatedAt: now, + } + + for n := 0; n < b.N; n++ { + validate.Struct(outer) + } +} + +func BenchmarkStructSimpleSuccess(b *testing.B) { + + type Foo struct { + StringValue string `validate:"min=5,max=10"` + IntValue int `validate:"min=5,max=10"` + } + + validFoo := &Foo{StringValue: "Foobar", IntValue: 7} + + for n := 0; n < b.N; n++ { + validate.Struct(validFoo) + } +} + +func BenchmarkStructSimpleFailure(b *testing.B) { + + type Foo struct { + StringValue string `validate:"min=5,max=10"` + IntValue int `validate:"min=5,max=10"` + } + + invalidFoo := &Foo{StringValue: "Fo", IntValue: 3} + + for n := 0; n < b.N; n++ { + validate.Struct(invalidFoo) + } +} + +func BenchmarkStructSimpleSuccessParallel(b *testing.B) { + + type Foo struct { + StringValue string `validate:"min=5,max=10"` + IntValue int `validate:"min=5,max=10"` + } + + validFoo := &Foo{StringValue: "Foobar", IntValue: 7} + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(validFoo) + } + }) +} + +func BenchmarkStructSimpleFailureParallel(b *testing.B) { + + type Foo struct { + StringValue string `validate:"min=5,max=10"` + IntValue int `validate:"min=5,max=10"` + } + + invalidFoo := &Foo{StringValue: "Fo", IntValue: 3} + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(invalidFoo) + } + }) +} + +func BenchmarkStructComplexSuccess(b *testing.B) { + + tSuccess := &TestString{ + Required: "Required", + Len: "length==10", + Min: "min=1", + Max: "1234567890", + MinMax: "12345", + Lt: "012345678", + Lte: "0123456789", + Gt: "01234567890", + Gte: "0123456789", + OmitEmpty: "", + Sub: &SubTest{ + Test: "1", + }, + SubIgnore: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + }{ + A: "1", + }, + Iface: &Impl{ + F: "123", + }, + } + + for n := 0; n < b.N; n++ { + validate.Struct(tSuccess) + } +} + +func BenchmarkStructComplexFailure(b *testing.B) { + + tFail := &TestString{ + Required: "", + Len: "", + Min: "", + Max: "12345678901", + MinMax: "", + Lt: "0123456789", + Lte: "01234567890", + Gt: "1", + Gte: "1", + OmitEmpty: "12345678901", + Sub: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + }{ + A: "", + }, + Iface: &Impl{ + F: "12", + }, + } + + for n := 0; n < b.N; n++ { + validate.Struct(tFail) + } +} + +func BenchmarkStructComplexSuccessParallel(b *testing.B) { + + tSuccess := &TestString{ + Required: "Required", + Len: "length==10", + Min: "min=1", + Max: "1234567890", + MinMax: "12345", + Lt: "012345678", + Lte: "0123456789", + Gt: "01234567890", + Gte: "0123456789", + OmitEmpty: "", + Sub: &SubTest{ + Test: "1", + }, + SubIgnore: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + }{ + A: "1", + }, + Iface: &Impl{ + F: "123", + }, + } + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(tSuccess) + } + }) +} + +func BenchmarkStructComplexFailureParallel(b *testing.B) { + + tFail := &TestString{ + Required: "", + Len: "", + Min: "", + Max: "12345678901", + MinMax: "", + Lt: "0123456789", + Lte: "01234567890", + Gt: "1", + Gte: "1", + OmitEmpty: "12345678901", + Sub: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + }{ + A: "", + }, + Iface: &Impl{ + F: "12", + }, + } + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + validate.Struct(tFail) + } + }) +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/cache.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/cache.go new file mode 100644 index 00000000..289226eb --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/cache.go @@ -0,0 +1,71 @@ +package validator + +import ( + "reflect" + "sync" +) + +type cachedField struct { + Idx int + Name string + AltName string + CachedTag *cachedTag +} + +type cachedStruct struct { + Name string + fields map[int]cachedField +} + +type structCacheMap struct { + lock sync.RWMutex + m map[reflect.Type]*cachedStruct +} + +func (s *structCacheMap) Get(key reflect.Type) (*cachedStruct, bool) { + s.lock.RLock() + value, ok := s.m[key] + s.lock.RUnlock() + return value, ok +} + +func (s *structCacheMap) Set(key reflect.Type, value *cachedStruct) { + s.lock.Lock() + s.m[key] = value + s.lock.Unlock() +} + +type cachedTag struct { + tag string + isOmitEmpty bool + isNoStructLevel bool + isStructOnly bool + diveTag string + tags []*tagVals +} + +type tagVals struct { + tagVals [][]string + isOrVal bool + isAlias bool + tag string +} + +type tagCacheMap struct { + lock sync.RWMutex + m map[string]*cachedTag +} + +func (s *tagCacheMap) Get(key string) (*cachedTag, bool) { + s.lock.RLock() + value, ok := s.m[key] + s.lock.RUnlock() + + return value, ok +} + +func (s *tagCacheMap) Set(key string, value *cachedTag) { + s.lock.Lock() + s.m[key] = value + s.lock.Unlock() +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/doc.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/doc.go new file mode 100644 index 00000000..c351a612 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/doc.go @@ -0,0 +1,852 @@ +/* +Package validator implements value validations for structs and individual fields +based on tags. + +It can also handle Cross-Field and Cross-Struct validation for nested structs +and has the ability to dive into arrays and maps of any type. + +Why not a better error message? +Because this library intends for you to handle your own error messages. + +Why should I handle my own errors? +Many reasons. We built an internationalized application and needed to know the +field, and what validation failed so we could provide a localized error. + + if fieldErr.Field == "Name" { + switch fieldErr.ErrorTag + case "required": + return "Translated string based on field + error" + default: + return "Translated string based on field" + } + + +Validation Functions Return Type error + +Doing things this way is actually the way the standard library does, see the +file.Open method here: + + https://golang.org/pkg/os/#Open. + +The authors return type "error" to avoid the issue discussed in the following, +where err is always != nil: + + http://stackoverflow.com/a/29138676/3158232 + https://github.com/go-playground/validator/issues/134 + +Validator only returns nil or ValidationErrors as type error; so, in your code +all you need to do is check if the error returned is not nil, and if it's not +type cast it to type ValidationErrors like so err.(validator.ValidationErrors). + +Custom Functions + +Custom functions can be added. Example: + + // Structure + func customFunc(v *Validate, topStruct reflect.Value, currentStructOrField reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + if whatever { + return false + } + + return true + } + + validate.RegisterValidation("custom tag name", customFunc) + // NOTES: using the same tag name as an existing function + // will overwrite the existing one + +Cross-Field Validation + +Cross-Field Validation can be done via the following tags: + - eqfield + - nefield + - gtfield + - gtefield + - ltfield + - ltefield + - eqcsfield + - necsfield + - gtcsfield + - ftecsfield + - ltcsfield + - ltecsfield + +If, however, some custom cross-field validation is required, it can be done +using a custom validation. + +Why not just have cross-fields validation tags (i.e. only eqcsfield and not +eqfield)? + +The reason is efficiency. If you want to check a field within the same struct +"eqfield" only has to find the field on the same struct (1 level). But, if we +used "eqcsfield" it could be multiple levels down. Example: + + type Inner struct { + StartDate time.Time + } + + type Outer struct { + InnerStructField *Inner + CreatedAt time.Time `validate:"ltecsfield=InnerStructField.StartDate"` + } + + now := time.Now() + + inner := &Inner{ + StartDate: now, + } + + outer := &Outer{ + InnerStructField: inner, + CreatedAt: now, + } + + errs := validate.Struct(outer) + + // NOTE: when calling validate.Struct(val) topStruct will be the top level struct passed + // into the function + // when calling validate.FieldWithValue(val, field, tag) val will be + // whatever you pass, struct, field... + // when calling validate.Field(field, tag) val will be nil + +Multiple Validators + +Multiple validators on a field will process in the order defined. Example: + + type Test struct { + Field `validate:"max=10,min=1"` + } + + // max will be checked then min + +Bad Validator definitions are not handled by the library. Example: + + type Test struct { + Field `validate:"min=10,max=0"` + } + + // this definition of min max will never succeed + +Using Validator Tags + +Baked In Cross-Field validation only compares fields on the same struct. +If Cross-Field + Cross-Struct validation is needed you should implement your +own custom validator. + +Comma (",") is the default separator of validation tags. If you wish to +have a comma included within the parameter (i.e. excludesall=,) you will need to +use the UTF-8 hex representation 0x2C, which is replaced in the code as a comma, +so the above will become excludesall=0x2C. + + type Test struct { + Field `validate:"excludesall=,"` // BAD! Do not include a comma. + Field `validate:"excludesall=0x2C"` // GOOD! Use the UTF-8 hex representation. + } + +Pipe ("|") is the default separator of validation tags. If you wish to +have a pipe included within the parameter i.e. excludesall=| you will need to +use the UTF-8 hex representation 0x7C, which is replaced in the code as a pipe, +so the above will become excludesall=0x7C + + type Test struct { + Field `validate:"excludesall=|"` // BAD! Do not include a a pipe! + Field `validate:"excludesall=0x7C"` // GOOD! Use the UTF-8 hex representation. + } + + +Baked In Validators and Tags + +Here is a list of the current built in validators: + + +Skip Field + +Tells the validation to skip this struct field; this is particularily +handy in ignoring embedded structs from being validated. (Usage: -) + Usage: - + + +Or Operator + +This is the 'or' operator allowing multiple validators to be used and +accepted. (Usage: rbg|rgba) <-- this would allow either rgb or rgba +colors to be accepted. This can also be combined with 'and' for example +( Usage: omitempty,rgb|rgba) + + Usage: | + +StructOnly + +When a field that is a nested struct is encountered, and contains this flag +any validation on the nested struct will be run, but none of the nested +struct fields will be validated. This is usefull if inside of you program +you know the struct will be valid, but need to verify it has been assigned. +NOTE: only "required" and "omitempty" can be used on a struct itself. + + Usage: structonly + +NoStructLevel + +Same as structonly tag except that any struct level validations will not run. + + Usage: nostructlevel + +Exists + +Is a special tag without a validation function attached. It is used when a field +is a Pointer, Interface or Invalid and you wish to validate that it exists. +Example: want to ensure a bool exists if you define the bool as a pointer and +use exists it will ensure there is a value; couldn't use required as it would +fail when the bool was false. exists will fail is the value is a Pointer, Interface +or Invalid and is nil. + + Usage: exists + +Omit Empty + +Allows conditional validation, for example if a field is not set with +a value (Determined by the "required" validator) then other validation +such as min or max won't run, but if a value is set validation will run. + + Usage: omitempty + +Dive + +This tells the validator to dive into a slice, array or map and validate that +level of the slice, array or map with the validation tags that follow. +Multidimensional nesting is also supported, each level you wish to dive will +require another dive tag. + + Usage: dive + +Example #1 + + [][]string with validation tag "gt=0,dive,len=1,dive,required" + // gt=0 will be applied to [] + // len=1 will be applied to []string + // required will be applied to string + +Example #2 + + [][]string with validation tag "gt=0,dive,dive,required" + // gt=0 will be applied to [] + // []string will be spared validation + // required will be applied to string + +Required + +This validates that the value is not the data types default zero value. +For numbers ensures value is not zero. For strings ensures value is +not "". For slices, maps, pointers, interfaces, channels and functions +ensures the value is not nil. + + Usage: required + +Length + +For numbers, max will ensure that the value is +equal to the parameter given. For strings, it checks that +the string length is exactly that number of characters. For slices, +arrays, and maps, validates the number of items. + + Usage: len=10 + +Maximum + +For numbers, max will ensure that the value is +less than or equal to the parameter given. For strings, it checks +that the string length is at most that number of characters. For +slices, arrays, and maps, validates the number of items. + + Usage: max=10 + +Mininum + +For numbers, min will ensure that the value is +greater or equal to the parameter given. For strings, it checks that +the string length is at least that number of characters. For slices, +arrays, and maps, validates the number of items. + + Usage: min=10 + +Equals + +For strings & numbers, eq will ensure that the value is +equal to the parameter given. For slices, arrays, and maps, +validates the number of items. + + Usage: eq=10 + +Not Equal + +For strings & numbers, eq will ensure that the value is not +equal to the parameter given. For slices, arrays, and maps, +validates the number of items. + + Usage: eq=10 + +Greater Than + +For numbers, this will ensure that the value is greater than the +parameter given. For strings, it checks that the string length +is greater than that number of characters. For slices, arrays +and maps it validates the number of items. + +Example #1 + + Usage: gt=10 + +Example #2 (time.Time) + +For time.Time ensures the time value is greater than time.Now.UTC(). + + Usage: gt + +Greater Than or Equal + +Same as 'min' above. Kept both to make terminology with 'len' easier. + + +Example #1 + + Usage: gte=10 + +Example #2 (time.Time) + +For time.Time ensures the time value is greater than or equal to time.Now.UTC(). + + Usage: gte + +Less Than + +For numbers, this will ensure that the value is less than the parameter given. +For strings, it checks that the string length is less than that number of +characters. For slices, arrays, and maps it validates the number of items. + +Example #1 + + Usage: lt=10 + +Example #2 (time.Time) +For time.Time ensures the time value is less than time.Now.UTC(). + + Usage: lt + +Less Than or Equal + +Same as 'max' above. Kept both to make terminology with 'len' easier. + +Example #1 + + Usage: lte=10 + +Example #2 (time.Time) + +For time.Time ensures the time value is less than or equal to time.Now.UTC(). + + Usage: lte + +Field Equals Another Field + +This will validate the field value against another fields value either within +a struct or passed in field. + +Example #1: + + // Validation on Password field using: + Usage: eqfield=ConfirmPassword + +Example #2: + + // Validating by field: + validate.FieldWithValue(password, confirmpassword, "eqfield") + +Field Equals Another Field (relative) + +This does the same as eqfield except that it validates the field provided relative +to the top level struct. + + Usage: eqcsfield=InnerStructField.Field) + +Field Does Not Equal Another Field + +This will validate the field value against another fields value either within +a struct or passed in field. + +Examples: + + // Confirm two colors are not the same: + // + // Validation on Color field: + Usage: nefield=Color2 + + // Validating by field: + validate.FieldWithValue(color1, color2, "nefield") + +Field Does Not Equal Another Field (relative) + +This does the same as nefield except that it validates the field provided +relative to the top level struct. + + Usage: necsfield=InnerStructField.Field + +Field Greater Than Another Field + +Only valid for Numbers and time.Time types, this will validate the field value +against another fields value either within a struct or passed in field. +usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(gtfield=Start) + +Example #2: + + // Validating by field: + validate.FieldWithValue(start, end, "gtfield") + + +Field Greater Than Another Relative Field + +This does the same as gtfield except that it validates the field provided +relative to the top level struct. + + Usage: gtcsfield=InnerStructField.Field + +Field Greater Than or Equal To Another Field + +Only valid for Numbers and time.Time types, this will validate the field value +against another fields value either within a struct or passed in field. +usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(gtefield=Start) + +Example #2: + + // Validating by field: + validate.FieldWithValue(start, end, "gtefield") + +Field Greater Than or Equal To Another Relative Field + +This does the same as gtefield except that it validates the field provided relative +to the top level struct. + + Usage: gtecsfield=InnerStructField.Field + +Less Than Another Field + +Only valid for Numbers and time.Time types, this will validate the field value +against another fields value either within a struct or passed in field. +usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(ltfield=Start) + +Example #2: + + // Validating by field: + validate.FieldWithValue(start, end, "ltfield") + +Less Than Another Relative Field + +This does the same as ltfield except that it validates the field provided relative +to the top level struct. + + Usage: ltcsfield=InnerStructField.Field + +Less Than or Equal To Another Field + +Only valid for Numbers and time.Time types, this will validate the field value +against another fields value either within a struct or passed in field. +usage examples are for validation of a Start and End date: + +Example #1: + + // Validation on End field using: + validate.Struct Usage(ltefield=Start) + +Example #2: + + // Validating by field: + validate.FieldWithValue(start, end, "ltefield") + +Less Than or Equal To Another Relative Field + +This does the same as ltefield except that it validates the field provided relative +to the top level struct. + + Usage: ltecsfield=InnerStructField.Field + +Alpha Only + +This validates that a string value contains alpha characters only + + Usage: alpha + +Alphanumeric + +This validates that a string value contains alphanumeric characters only + + Usage: alphanum + +Numeric + +This validates that a string value contains a basic numeric value. +basic excludes exponents etc... + + Usage: numeric + +Hexadecimal String + +This validates that a string value contains a valid hexadecimal. + + Usage: hexadecimal + +Hexcolor String + +This validates that a string value contains a valid hex color including +hashtag (#) + + Usage: hexcolor + +RGB String + +This validates that a string value contains a valid rgb color + + Usage: rgb + +RGBA String + +This validates that a string value contains a valid rgba color + + Usage: rgba + +HSL String + +This validates that a string value contains a valid hsl color + + Usage: hsl + +HSLA String + +This validates that a string value contains a valid hsla color + + Usage: hsla + +E-mail String + +This validates that a string value contains a valid email +This may not conform to all possibilities of any rfc standard, but neither +does any email provider accept all posibilities. + + Usage: email + +URL String + +This validates that a string value contains a valid url +This will accept any url the golang request uri accepts but must contain +a schema for example http:// or rtmp:// + + Usage: url + +URI String + +This validates that a string value contains a valid uri +This will accept any uri the golang request uri accepts + + Usage: uri + +Base64 String + +This validates that a string value contains a valid base64 value. +Although an empty string is valid base64 this will report an empty string +as an error, if you wish to accept an empty string as valid you can use +this with the omitempty tag. + + Usage: base64 + +Contains + +This validates that a string value contains the substring value. + + Usage: contains=@ + +Contains Any + +This validates that a string value contains any Unicode code points +in the substring value. + + Usage: containsany=!@#? + +Contains Rune + +This validates that a string value contains the supplied rune value. + + Usage: containsrune=@ + +Excludes + +This validates that a string value does not contain the substring value. + + Usage: excludes=@ + +Excludes All + +This validates that a string value does not contain any Unicode code +points in the substring value. + + Usage: excludesall=!@#? + +Excludes Rune + +This validates that a string value does not contain the supplied rune value. + + Usage: excludesrune=@ + +International Standard Book Number + +This validates that a string value contains a valid isbn10 or isbn13 value. + + Usage: isbn + +International Standard Book Number 10 + +This validates that a string value contains a valid isbn10 value. + + Usage: isbn10 + +International Standard Book Number 13 + +This validates that a string value contains a valid isbn13 value. + + Usage: isbn13 + + +Universally Unique Identifier UUID + +This validates that a string value contains a valid UUID. + + Usage: uuid + +Universally Unique Identifier UUID v3 + +This validates that a string value contains a valid version 3 UUID. + + Usage: uuid3 + +Universally Unique Identifier UUID v4 + +This validates that a string value contains a valid version 4 UUID. + + Usage: uuid4 + +Universally Unique Identifier UUID v5 + +This validates that a string value contains a valid version 5 UUID. + + Usage: uuid5 + +ASCII + +This validates that a string value contains only ASCII characters. +NOTE: if the string is blank, this validates as true. + + Usage: ascii + +Printable ASCII + +This validates that a string value contains only printable ASCII characters. +NOTE: if the string is blank, this validates as true. + + Usage: asciiprint + +Multi-Byte Characters + +This validates that a string value contains one or more multibyte characters. +NOTE: if the string is blank, this validates as true. + + Usage: multibyte + +Data URL + +This validates that a string value contains a valid DataURI. +NOTE: this will also validate that the data portion is valid base64 + + Usage: datauri + +Latitude + +This validates that a string value contains a valid latitude. + + Usage: latitude + +Longitude + +This validates that a string value contains a valid longitude. + + Usage: longitude + +Social Security Number SSN + +This validates that a string value contains a valid U.S. Social Security Number. + + Usage: ssn + +Internet Protocol Address IP + +This validates that a string value contains a valid IP Adress. + + Usage: ip + +Internet Protocol Address IPv4 + +This validates that a string value contains a valid v4 IP Adress. + + Usage: ipv4 + +Internet Protocol Address IPv6 + +This validates that a string value contains a valid v6 IP Adress. + + Usage: ipv6 + +Classless Inter-Domain Routing CIDR + +This validates that a string value contains a valid CIDR Adress. + + Usage: cidr + +Classless Inter-Domain Routing CIDRv4 + +This validates that a string value contains a valid v4 CIDR Adress. + + Usage: cidrv4 + +Classless Inter-Domain Routing CIDRv6 + +This validates that a string value contains a valid v6 CIDR Adress. + + Usage: cidrv6 + +Transmission Control Protocol Address TCP + +This validates that a string value contains a valid resolvable TCP Adress. + + Usage: tcp_addr + +Transmission Control Protocol Address TCPv4 + +This validates that a string value contains a valid resolvable v4 TCP Adress. + + Usage: tcp4_addr + +Transmission Control Protocol Address TCPv6 + +This validates that a string value contains a valid resolvable v6 TCP Adress. + + Usage: tcp6_addr + +User Datagram Protocol Address UDP + +This validates that a string value contains a valid resolvable UDP Adress. + + Usage: udp_addr + +User Datagram Protocol Address UDPv4 + +This validates that a string value contains a valid resolvable v4 UDP Adress. + + Usage: udp4_addr + +User Datagram Protocol Address UDPv6 + +This validates that a string value contains a valid resolvable v6 UDP Adress. + + Usage: udp6_addr + +Internet Protocol Address IP + +This validates that a string value contains a valid resolvable IP Adress. + + Usage: ip_addr + +Internet Protocol Address IPv4 + +This validates that a string value contains a valid resolvable v4 IP Adress. + + Usage: ip4_addr + +Internet Protocol Address IPv6 + +This validates that a string value contains a valid resolvable v6 IP Adress. + + Usage: ip6_addr + +Unix domain socket end point Address + +This validates that a string value contains a valid Unix Adress. + + Usage: unix_addr + +Media Access Control Address MAC + +This validates that a string value contains a valid MAC Adress. + + Usage: mac + +Note: See Go's ParseMAC for accepted formats and types: + + http://golang.org/src/net/mac.go?s=866:918#L29 + +Alias Validators and Tags + +NOTE: When returning an error, the tag returned in "FieldError" will be +the alias tag unless the dive tag is part of the alias. Everything after the +dive tag is not reported as the alias tag. Also, the "ActualTag" in the before +case will be the actual tag within the alias that failed. + +Here is a list of the current built in alias tags: + + "iscolor" + alias is "hexcolor|rgb|rgba|hsl|hsla" (Usage: iscolor) + +Validator notes: + + regex + a regex validator won't be added because commas and = signs can be part + of a regex which conflict with the validation definitions. Although + workarounds can be made, they take away from using pure regex's. + Furthermore it's quick and dirty but the regex's become harder to + maintain and are not reusable, so it's as much a programming philosiphy + as anything. + + In place of this new validator functions should be created; a regex can + be used within the validator function and even be precompiled for better + efficiency within regexes.go. + + And the best reason, you can submit a pull request and we can keep on + adding to the validation library of this package! + +Panics + +This package panics when bad input is provided, this is by design, bad code like +that should not make it to production. + + type Test struct { + TestField string `validate:"nonexistantfunction=1"` + } + + t := &Test{ + TestField: "Test" + } + + validate.Struct(t) // this will panic +*/ +package validator diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/custom/custom.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/custom/custom.go new file mode 100644 index 00000000..ee14bd2f --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/custom/custom.go @@ -0,0 +1,45 @@ +package main + +import ( + "database/sql" + "database/sql/driver" + "fmt" + "reflect" + + "gopkg.in/go-playground/validator.v8" +) + +// DbBackedUser User struct +type DbBackedUser struct { + Name sql.NullString `validate:"required"` + Age sql.NullInt64 `validate:"required"` +} + +func main() { + + config := &validator.Config{TagName: "validate"} + + validate := validator.New(config) + + // register all sql.Null* types to use the ValidateValuer CustomTypeFunc + validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) + + x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: false}} + errs := validate.Struct(x) + + if errs != nil { + fmt.Printf("Errs:\n%+v\n", errs) + } +} + +// ValidateValuer implements validator.CustomTypeFunc +func ValidateValuer(field reflect.Value) interface{} { + if valuer, ok := field.Interface().(driver.Valuer); ok { + val, err := valuer.Value() + if err == nil { + return val + } + // handle the error how you want + } + return nil +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/simple/simple.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/simple/simple.go new file mode 100644 index 00000000..d16cc830 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/simple/simple.go @@ -0,0 +1,155 @@ +package main + +import ( + "errors" + "fmt" + "reflect" + + sql "database/sql/driver" + + "gopkg.in/go-playground/validator.v8" +) + +// User contains user information +type User struct { + FirstName string `validate:"required"` + LastName string `validate:"required"` + Age uint8 `validate:"gte=0,lte=130"` + Email string `validate:"required,email"` + FavouriteColor string `validate:"hexcolor|rgb|rgba"` + Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage... +} + +// Address houses a users address information +type Address struct { + Street string `validate:"required"` + City string `validate:"required"` + Planet string `validate:"required"` + Phone string `validate:"required"` +} + +var validate *validator.Validate + +func main() { + + config := &validator.Config{TagName: "validate"} + + validate = validator.New(config) + + validateStruct() + validateField() +} + +func validateStruct() { + + address := &Address{ + Street: "Eavesdown Docks", + Planet: "Persphone", + Phone: "none", + } + + user := &User{ + FirstName: "Badger", + LastName: "Smith", + Age: 135, + Email: "Badger.Smith@gmail.com", + FavouriteColor: "#000", + Addresses: []*Address{address}, + } + + // returns nil or ValidationErrors ( map[string]*FieldError ) + errs := validate.Struct(user) + + if errs != nil { + + fmt.Println(errs) // output: Key: "User.Age" Error:Field validation for "Age" failed on the "lte" tag + // Key: "User.Addresses[0].City" Error:Field validation for "City" failed on the "required" tag + err := errs.(validator.ValidationErrors)["User.Addresses[0].City"] + fmt.Println(err.Field) // output: City + fmt.Println(err.Tag) // output: required + fmt.Println(err.Kind) // output: string + fmt.Println(err.Type) // output: string + fmt.Println(err.Param) // output: + fmt.Println(err.Value) // output: + + // from here you can create your own error messages in whatever language you wish + return + } + + // save user to database +} + +func validateField() { + myEmail := "joeybloggs.gmail.com" + + errs := validate.Field(myEmail, "required,email") + + if errs != nil { + fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "email" tag + return + } + + // email ok, move on +} + +var validate2 *validator.Validate + +type valuer struct { + Name string +} + +func (v valuer) Value() (sql.Value, error) { + + if v.Name == "errorme" { + return nil, errors.New("some kind of error") + } + + if v.Name == "blankme" { + return "", nil + } + + if len(v.Name) == 0 { + return nil, nil + } + + return v.Name, nil +} + +// ValidateValuerType implements validator.CustomTypeFunc +func ValidateValuerType(field reflect.Value) interface{} { + if valuer, ok := field.Interface().(sql.Valuer); ok { + val, err := valuer.Value() + if err != nil { + // handle the error how you want + return nil + } + + return val + } + + return nil +} + +func main2() { + + config := &validator.Config{TagName: "validate"} + + validate2 = validator.New(config) + validate2.RegisterCustomTypeFunc(ValidateValuerType, (*sql.Valuer)(nil), valuer{}) + + validateCustomFieldType() +} + +func validateCustomFieldType() { + val := valuer{ + Name: "blankme", + } + + errs := validate2.Field(val, "required") + if errs != nil { + fmt.Println(errs) // output: Key: "" Error:Field validation for "" failed on the "required" tag + return + } + + // all ok +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/struct-level/struct_level.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/struct-level/struct_level.go new file mode 100644 index 00000000..92526c95 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples/struct-level/struct_level.go @@ -0,0 +1,99 @@ +package main + +import ( + "fmt" + "reflect" + + "gopkg.in/go-playground/validator.v8" +) + +// User contains user information +type User struct { + FirstName string `json:"fname"` + LastName string `json:"lname"` + Age uint8 `validate:"gte=0,lte=130"` + Email string `validate:"required,email"` + FavouriteColor string `validate:"hexcolor|rgb|rgba"` + Addresses []*Address `validate:"required,dive,required"` // a person can have a home and cottage... +} + +// Address houses a users address information +type Address struct { + Street string `validate:"required"` + City string `validate:"required"` + Planet string `validate:"required"` + Phone string `validate:"required"` +} + +var validate *validator.Validate + +func main() { + + config := &validator.Config{TagName: "validate"} + + validate = validator.New(config) + validate.RegisterStructValidation(UserStructLevelValidation, User{}) + + validateStruct() +} + +// UserStructLevelValidation contains custom struct level validations that don't always +// make sense at the field validation level. For Example this function validates that either +// FirstName or LastName exist; could have done that with a custom field validation but then +// would have had to add it to both fields duplicating the logic + overhead, this way it's +// only validated once. +// +// NOTE: you may ask why wouldn't I just do this outside of validator, because doing this way +// hooks right into validator and you can combine with validation tags and still have a +// common error output format. +func UserStructLevelValidation(v *validator.Validate, structLevel *validator.StructLevel) { + + user := structLevel.CurrentStruct.Interface().(User) + + if len(user.FirstName) == 0 && len(user.LastName) == 0 { + structLevel.ReportError(reflect.ValueOf(user.FirstName), "FirstName", "fname", "fnameorlname") + structLevel.ReportError(reflect.ValueOf(user.LastName), "LastName", "lname", "fnameorlname") + } + + // plus can to more, even with different tag than "fnameorlname" +} + +func validateStruct() { + + address := &Address{ + Street: "Eavesdown Docks", + Planet: "Persphone", + Phone: "none", + City: "Unknown", + } + + user := &User{ + FirstName: "", + LastName: "", + Age: 45, + Email: "Badger.Smith@gmail.com", + FavouriteColor: "#000", + Addresses: []*Address{address}, + } + + // returns nil or ValidationErrors ( map[string]*FieldError ) + errs := validate.Struct(user) + + if errs != nil { + + fmt.Println(errs) // output: Key: 'User.LastName' Error:Field validation for 'LastName' failed on the 'fnameorlname' tag + // Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'fnameorlname' tag + err := errs.(validator.ValidationErrors)["User.FirstName"] + fmt.Println(err.Field) // output: FirstName + fmt.Println(err.Tag) // output: fnameorlname + fmt.Println(err.Kind) // output: string + fmt.Println(err.Type) // output: string + fmt.Println(err.Param) // output: + fmt.Println(err.Value) // output: + + // from here you can create your own error messages in whatever language you wish + return + } + + // save user to database +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples_test.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples_test.go new file mode 100644 index 00000000..fde22461 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/examples_test.go @@ -0,0 +1,83 @@ +package validator_test + +import ( + "fmt" + + "gopkg.in/go-playground/validator.v8" +) + +func ExampleValidate_new() { + config := &validator.Config{TagName: "validate"} + + validator.New(config) +} + +func ExampleValidate_field() { + // This should be stored somewhere globally + var validate *validator.Validate + + config := &validator.Config{TagName: "validate"} + + validate = validator.New(config) + + i := 0 + errs := validate.Field(i, "gt=1,lte=10") + err := errs.(validator.ValidationErrors)[""] + fmt.Println(err.Field) + fmt.Println(err.Tag) + fmt.Println(err.Kind) // NOTE: Kind and Type can be different i.e. time Kind=struct and Type=time.Time + fmt.Println(err.Type) + fmt.Println(err.Param) + fmt.Println(err.Value) + //Output: + // + //gt + //int + //int + //1 + //0 +} + +func ExampleValidate_struct() { + // This should be stored somewhere globally + var validate *validator.Validate + + config := &validator.Config{TagName: "validate"} + + validate = validator.New(config) + + type ContactInformation struct { + Phone string `validate:"required"` + Street string `validate:"required"` + City string `validate:"required"` + } + + type User struct { + Name string `validate:"required,excludesall=!@#$%^&*()_+-=:;?/0x2C"` // 0x2C = comma (,) + Age int8 `validate:"required,gt=0,lt=150"` + Email string `validate:"email"` + ContactInformation []*ContactInformation + } + + contactInfo := &ContactInformation{ + Street: "26 Here Blvd.", + City: "Paradeso", + } + + user := &User{ + Name: "Joey Bloggs", + Age: 31, + Email: "joeybloggs@gmail.com", + ContactInformation: []*ContactInformation{contactInfo}, + } + + errs := validate.Struct(user) + for _, v := range errs.(validator.ValidationErrors) { + fmt.Println(v.Field) // Phone + fmt.Println(v.Tag) // required + //... and so forth + //Output: + //Phone + //required + } +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/logo.png b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/logo.png new file mode 100644 index 00000000..355000f5 Binary files /dev/null and b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/logo.png differ diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/regexes.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/regexes.go new file mode 100644 index 00000000..83ae1982 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/regexes.go @@ -0,0 +1,59 @@ +package validator + +import "regexp" + +const ( + alphaRegexString = "^[a-zA-Z]+$" + alphaNumericRegexString = "^[a-zA-Z0-9]+$" + numericRegexString = "^[-+]?[0-9]+(?:\\.[0-9]+)?$" + numberRegexString = "^[0-9]+$" + hexadecimalRegexString = "^[0-9a-fA-F]+$" + hexcolorRegexString = "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" + rgbRegexString = "^rgb\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*\\)$" + rgbaRegexString = "^rgba\\(\\s*(?:(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])|(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%\\s*,\\s*(?:0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$" + hslRegexString = "^hsl\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*\\)$" + hslaRegexString = "^hsla\\(\\s*(?:0|[1-9]\\d?|[12]\\d\\d|3[0-5]\\d|360)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0|[1-9]\\d?|100)%)\\s*,\\s*(?:(?:0.[1-9]*)|[01])\\s*\\)$" + emailRegexString = "^(?:(?:(?:(?:[a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+(?:\\.([a-zA-Z]|\\d|[!#\\$%&'\\*\\+\\-\\/=\\?\\^_`{\\|}~]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])+)*)|(?:(?:\\x22)(?:(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(?:\\x20|\\x09)+)?(?:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]|\\x21|[\\x23-\\x5b]|[\\x5d-\\x7e]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:\\(?:[\\x01-\\x09\\x0b\\x0c\\x0d-\\x7f]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}]))))*(?:(?:(?:\\x20|\\x09)*(?:\\x0d\\x0a))?(\\x20|\\x09)+)?(?:\\x22)))@(?:(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|\\d|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.)+(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])|(?:(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])(?:[a-zA-Z]|\\d|-|\\.|_|~|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])*(?:[a-zA-Z]|[\\x{00A0}-\\x{D7FF}\\x{F900}-\\x{FDCF}\\x{FDF0}-\\x{FFEF}])))\\.?$" + base64RegexString = "^(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\\/]{3}=|[A-Za-z0-9+\\/]{4})$" + iSBN10RegexString = "^(?:[0-9]{9}X|[0-9]{10})$" + iSBN13RegexString = "^(?:(?:97(?:8|9))[0-9]{10})$" + uUID3RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[0-9a-f]{4}-[0-9a-f]{12}$" + uUID4RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + uUID5RegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + uUIDRegexString = "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$" + aSCIIRegexString = "^[\x00-\x7F]*$" + printableASCIIRegexString = "^[\x20-\x7E]*$" + multibyteRegexString = "[^\x00-\x7F]" + dataURIRegexString = "^data:.+\\/(.+);base64$" + latitudeRegexString = "^[-+]?([1-8]?\\d(\\.\\d+)?|90(\\.0+)?)$" + longitudeRegexString = "^[-+]?(180(\\.0+)?|((1[0-7]\\d)|([1-9]?\\d))(\\.\\d+)?)$" + sSNRegexString = `^\d{3}[- ]?\d{2}[- ]?\d{4}$` +) + +var ( + alphaRegex = regexp.MustCompile(alphaRegexString) + alphaNumericRegex = regexp.MustCompile(alphaNumericRegexString) + numericRegex = regexp.MustCompile(numericRegexString) + numberRegex = regexp.MustCompile(numberRegexString) + hexadecimalRegex = regexp.MustCompile(hexadecimalRegexString) + hexcolorRegex = regexp.MustCompile(hexcolorRegexString) + rgbRegex = regexp.MustCompile(rgbRegexString) + rgbaRegex = regexp.MustCompile(rgbaRegexString) + hslRegex = regexp.MustCompile(hslRegexString) + hslaRegex = regexp.MustCompile(hslaRegexString) + emailRegex = regexp.MustCompile(emailRegexString) + base64Regex = regexp.MustCompile(base64RegexString) + iSBN10Regex = regexp.MustCompile(iSBN10RegexString) + iSBN13Regex = regexp.MustCompile(iSBN13RegexString) + uUID3Regex = regexp.MustCompile(uUID3RegexString) + uUID4Regex = regexp.MustCompile(uUID4RegexString) + uUID5Regex = regexp.MustCompile(uUID5RegexString) + uUIDRegex = regexp.MustCompile(uUIDRegexString) + aSCIIRegex = regexp.MustCompile(aSCIIRegexString) + printableASCIIRegex = regexp.MustCompile(printableASCIIRegexString) + multibyteRegex = regexp.MustCompile(multibyteRegexString) + dataURIRegex = regexp.MustCompile(dataURIRegexString) + latitudeRegex = regexp.MustCompile(latitudeRegexString) + longitudeRegex = regexp.MustCompile(longitudeRegexString) + sSNRegex = regexp.MustCompile(sSNRegexString) +) diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/util.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/util.go new file mode 100644 index 00000000..ce01c7c6 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/util.go @@ -0,0 +1,382 @@ +package validator + +import ( + "fmt" + "reflect" + "strconv" + "strings" +) + +const ( + dash = "-" + blank = "" + namespaceSeparator = "." + leftBracket = "[" + rightBracket = "]" + restrictedTagChars = ".[],|=+()`~!@#$%^&*\\\"/?<>{}" + restrictedAliasErr = "Alias '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation" + restrictedTagErr = "Tag '%s' either contains restricted characters or is the same as a restricted tag needed for normal operation" +) + +var ( + restrictedTags = map[string]*struct{}{ + diveTag: emptyStructPtr, + existsTag: emptyStructPtr, + structOnlyTag: emptyStructPtr, + omitempty: emptyStructPtr, + skipValidationTag: emptyStructPtr, + utf8HexComma: emptyStructPtr, + utf8Pipe: emptyStructPtr, + noStructLevelTag: emptyStructPtr, + } +) + +// ExtractType gets the actual underlying type of field value. +// It will dive into pointers, customTypes and return you the +// underlying value and it's kind. +// it is exposed for use within you Custom Functions +func (v *Validate) ExtractType(current reflect.Value) (reflect.Value, reflect.Kind) { + + switch current.Kind() { + case reflect.Ptr: + + if current.IsNil() { + return current, reflect.Ptr + } + + return v.ExtractType(current.Elem()) + + case reflect.Interface: + + if current.IsNil() { + return current, reflect.Interface + } + + return v.ExtractType(current.Elem()) + + case reflect.Invalid: + return current, reflect.Invalid + + default: + + if v.hasCustomFuncs { + // fmt.Println("Type", current.Type()) + if fn, ok := v.customTypeFuncs[current.Type()]; ok { + + // fmt.Println("OK") + + return v.ExtractType(reflect.ValueOf(fn(current))) + } + + // fmt.Println("NOT OK") + } + + return current, current.Kind() + } +} + +// GetStructFieldOK traverses a struct to retrieve a specific field denoted by the provided namespace and +// returns the field, field kind and whether is was successful in retrieving the field at all. +// NOTE: when not successful ok will be false, this can happen when a nested struct is nil and so the field +// could not be retrived because it didnt exist. +func (v *Validate) GetStructFieldOK(current reflect.Value, namespace string) (reflect.Value, reflect.Kind, bool) { + + current, kind := v.ExtractType(current) + + if kind == reflect.Invalid { + return current, kind, false + } + + if namespace == blank { + return current, kind, true + } + + switch kind { + + case reflect.Ptr, reflect.Interface: + + return current, kind, false + + case reflect.Struct: + + typ := current.Type() + fld := namespace + ns := namespace + + if typ != timeType && typ != timePtrType { + + idx := strings.Index(namespace, namespaceSeparator) + + if idx != -1 { + fld = namespace[:idx] + ns = namespace[idx+1:] + } else { + ns = blank + idx = len(namespace) + } + + bracketIdx := strings.Index(fld, leftBracket) + if bracketIdx != -1 { + fld = fld[:bracketIdx] + + ns = namespace[bracketIdx:] + } + + current = current.FieldByName(fld) + + return v.GetStructFieldOK(current, ns) + } + + case reflect.Array, reflect.Slice: + idx := strings.Index(namespace, leftBracket) + idx2 := strings.Index(namespace, rightBracket) + + arrIdx, _ := strconv.Atoi(namespace[idx+1 : idx2]) + + if arrIdx >= current.Len() { + return current, kind, false + } + + startIdx := idx2 + 1 + + if startIdx < len(namespace) { + if namespace[startIdx:startIdx+1] == namespaceSeparator { + startIdx++ + } + } + + return v.GetStructFieldOK(current.Index(arrIdx), namespace[startIdx:]) + + case reflect.Map: + idx := strings.Index(namespace, leftBracket) + 1 + idx2 := strings.Index(namespace, rightBracket) + + endIdx := idx2 + + if endIdx+1 < len(namespace) { + if namespace[endIdx+1:endIdx+2] == namespaceSeparator { + endIdx++ + } + } + + key := namespace[idx:idx2] + + switch current.Type().Key().Kind() { + case reflect.Int: + i, _ := strconv.Atoi(key) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:]) + case reflect.Int8: + i, _ := strconv.ParseInt(key, 10, 8) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(int8(i))), namespace[endIdx+1:]) + case reflect.Int16: + i, _ := strconv.ParseInt(key, 10, 16) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(int16(i))), namespace[endIdx+1:]) + case reflect.Int32: + i, _ := strconv.ParseInt(key, 10, 32) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(int32(i))), namespace[endIdx+1:]) + case reflect.Int64: + i, _ := strconv.ParseInt(key, 10, 64) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:]) + case reflect.Uint: + i, _ := strconv.ParseUint(key, 10, 0) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint(i))), namespace[endIdx+1:]) + case reflect.Uint8: + i, _ := strconv.ParseUint(key, 10, 8) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint8(i))), namespace[endIdx+1:]) + case reflect.Uint16: + i, _ := strconv.ParseUint(key, 10, 16) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint16(i))), namespace[endIdx+1:]) + case reflect.Uint32: + i, _ := strconv.ParseUint(key, 10, 32) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(uint32(i))), namespace[endIdx+1:]) + case reflect.Uint64: + i, _ := strconv.ParseUint(key, 10, 64) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(i)), namespace[endIdx+1:]) + case reflect.Float32: + f, _ := strconv.ParseFloat(key, 32) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(float32(f))), namespace[endIdx+1:]) + case reflect.Float64: + f, _ := strconv.ParseFloat(key, 64) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(f)), namespace[endIdx+1:]) + case reflect.Bool: + b, _ := strconv.ParseBool(key) + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(b)), namespace[endIdx+1:]) + + // reflect.Type = string + default: + return v.GetStructFieldOK(current.MapIndex(reflect.ValueOf(key)), namespace[endIdx+1:]) + } + } + + // if got here there was more namespace, cannot go any deeper + panic("Invalid field namespace") +} + +// asInt retuns the parameter as a int64 +// or panics if it can't convert +func asInt(param string) int64 { + + i, err := strconv.ParseInt(param, 0, 64) + panicIf(err) + + return i +} + +// asUint returns the parameter as a uint64 +// or panics if it can't convert +func asUint(param string) uint64 { + + i, err := strconv.ParseUint(param, 0, 64) + panicIf(err) + + return i +} + +// asFloat returns the parameter as a float64 +// or panics if it can't convert +func asFloat(param string) float64 { + + i, err := strconv.ParseFloat(param, 64) + panicIf(err) + + return i +} + +func panicIf(err error) { + if err != nil { + panic(err.Error()) + } +} + +func (v *Validate) parseStruct(current reflect.Value, sName string) *cachedStruct { + + typ := current.Type() + s := &cachedStruct{Name: sName, fields: map[int]cachedField{}} + + numFields := current.NumField() + + var fld reflect.StructField + var tag string + var customName string + + for i := 0; i < numFields; i++ { + + fld = typ.Field(i) + + if fld.PkgPath != blank { + continue + } + + tag = fld.Tag.Get(v.tagName) + + if tag == skipValidationTag { + continue + } + + customName = fld.Name + if v.fieldNameTag != blank { + + name := strings.SplitN(fld.Tag.Get(v.fieldNameTag), ",", 2)[0] + + // dash check is for json "-" (aka skipValidationTag) means don't output in json + if name != "" && name != skipValidationTag { + customName = name + } + } + + cTag, ok := v.tagCache.Get(tag) + if !ok { + cTag = v.parseTags(tag, fld.Name) + } + + s.fields[i] = cachedField{Idx: i, Name: fld.Name, AltName: customName, CachedTag: cTag} + } + + v.structCache.Set(typ, s) + + return s +} + +func (v *Validate) parseTags(tag, fieldName string) *cachedTag { + + cTag := &cachedTag{tag: tag} + + v.parseTagsRecursive(cTag, tag, fieldName, blank, false) + + v.tagCache.Set(tag, cTag) + + return cTag +} + +func (v *Validate) parseTagsRecursive(cTag *cachedTag, tag, fieldName, alias string, isAlias bool) bool { + + if tag == blank { + return true + } + + for _, t := range strings.Split(tag, tagSeparator) { + + if v.hasAliasValidators { + // check map for alias and process new tags, otherwise process as usual + if tagsVal, ok := v.aliasValidators[t]; ok { + + leave := v.parseTagsRecursive(cTag, tagsVal, fieldName, t, true) + + if leave { + return leave + } + + continue + } + } + + switch t { + + case diveTag: + cTag.diveTag = tag + tVals := &tagVals{tagVals: [][]string{{t}}} + cTag.tags = append(cTag.tags, tVals) + return true + + case omitempty: + cTag.isOmitEmpty = true + + case structOnlyTag: + cTag.isStructOnly = true + + case noStructLevelTag: + cTag.isNoStructLevel = true + } + + // if a pipe character is needed within the param you must use the utf8Pipe representation "0x7C" + orVals := strings.Split(t, orSeparator) + tagVal := &tagVals{isAlias: isAlias, isOrVal: len(orVals) > 1, tagVals: make([][]string, len(orVals))} + cTag.tags = append(cTag.tags, tagVal) + + var key string + var param string + + for i, val := range orVals { + vals := strings.SplitN(val, tagKeySeparator, 2) + key = vals[0] + + tagVal.tag = key + + if isAlias { + tagVal.tag = alias + } + + if key == blank { + panic(strings.TrimSpace(fmt.Sprintf(invalidValidation, fieldName))) + } + + if len(vals) > 1 { + param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1) + } + + tagVal.tagVals[i] = []string{key, param} + } + } + + return false +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/validator.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/validator.go new file mode 100644 index 00000000..d3cc5431 --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/validator.go @@ -0,0 +1,797 @@ +/** + * Package validator + * + * MISC: + * - anonymous structs - they don't have names so expect the Struct name within StructErrors to be blank + * + */ + +package validator + +import ( + "bytes" + "errors" + "fmt" + "reflect" + "strings" + "sync" + "time" +) + +const ( + utf8HexComma = "0x2C" + utf8Pipe = "0x7C" + tagSeparator = "," + orSeparator = "|" + tagKeySeparator = "=" + structOnlyTag = "structonly" + noStructLevelTag = "nostructlevel" + omitempty = "omitempty" + skipValidationTag = "-" + diveTag = "dive" + existsTag = "exists" + fieldErrMsg = "Key: '%s' Error:Field validation for '%s' failed on the '%s' tag" + arrayIndexFieldName = "%s" + leftBracket + "%d" + rightBracket + mapIndexFieldName = "%s" + leftBracket + "%v" + rightBracket + invalidValidation = "Invalid validation tag on field %s" + undefinedValidation = "Undefined validation function on field %s" + validatorNotInitialized = "Validator instance not initialized" + fieldNameRequired = "Field Name Required" + tagRequired = "Tag Required" +) + +var ( + timeType = reflect.TypeOf(time.Time{}) + timePtrType = reflect.TypeOf(&time.Time{}) + emptyStructPtr = new(struct{}) +) + +// StructLevel contains all of the information and helper methods +// for reporting errors during struct level validation +type StructLevel struct { + TopStruct reflect.Value + CurrentStruct reflect.Value + errPrefix string + nsPrefix string + errs ValidationErrors + v *Validate +} + +// ReportValidationErrors accepts the key relative to the top level struct and validatin errors. +// Example: had a triple nested struct User, ContactInfo, Country and ran errs := validate.Struct(country) +// from within a User struct level validation would call this method like so: +// ReportValidationErrors("ContactInfo.", errs) +// NOTE: relativeKey can contain both the Field Relative and Custom name relative paths +// i.e. ReportValidationErrors("ContactInfo.|cInfo", errs) where cInfo represents say the JSON name of +// the relative path; this will be split into 2 variables in the next valiator version. +func (sl *StructLevel) ReportValidationErrors(relativeKey string, errs ValidationErrors) { + for _, e := range errs { + + idx := strings.Index(relativeKey, "|") + var rel string + var cRel string + + if idx != -1 { + rel = relativeKey[:idx] + cRel = relativeKey[idx+1:] + } else { + rel = relativeKey + } + + key := sl.errPrefix + rel + e.Field + + e.FieldNamespace = key + e.NameNamespace = sl.nsPrefix + cRel + e.Name + + sl.errs[key] = e + } +} + +// ReportError reports an error just by passing the field and tag information +// NOTE: tag can be an existing validation tag or just something you make up +// and precess on the flip side it's up to you. +func (sl *StructLevel) ReportError(field reflect.Value, fieldName string, customName string, tag string) { + + field, kind := sl.v.ExtractType(field) + + if fieldName == blank { + panic(fieldNameRequired) + } + + if customName == blank { + customName = fieldName + } + + if tag == blank { + panic(tagRequired) + } + + ns := sl.errPrefix + fieldName + + switch kind { + case reflect.Invalid: + sl.errs[ns] = &FieldError{ + FieldNamespace: ns, + NameNamespace: sl.nsPrefix + customName, + Name: customName, + Field: fieldName, + Tag: tag, + ActualTag: tag, + Param: blank, + Kind: kind, + } + default: + sl.errs[ns] = &FieldError{ + FieldNamespace: ns, + NameNamespace: sl.nsPrefix + customName, + Name: customName, + Field: fieldName, + Tag: tag, + ActualTag: tag, + Param: blank, + Value: field.Interface(), + Kind: kind, + Type: field.Type(), + } + } +} + +// Validate contains the validator settings passed in using the Config struct +type Validate struct { + tagName string + fieldNameTag string + validationFuncs map[string]Func + structLevelFuncs map[reflect.Type]StructLevelFunc + customTypeFuncs map[reflect.Type]CustomTypeFunc + aliasValidators map[string]string + hasCustomFuncs bool + hasAliasValidators bool + hasStructLevelFuncs bool + tagCache *tagCacheMap + structCache *structCacheMap + errsPool *sync.Pool +} + +func (v *Validate) initCheck() { + if v == nil { + panic(validatorNotInitialized) + } +} + +// Config contains the options that a Validator instance will use. +// It is passed to the New() function +type Config struct { + TagName string + FieldNameTag string +} + +// CustomTypeFunc allows for overriding or adding custom field type handler functions +// field = field value of the type to return a value to be validated +// example Valuer from sql drive see https://golang.org/src/database/sql/driver/types.go?s=1210:1293#L29 +type CustomTypeFunc func(field reflect.Value) interface{} + +// Func accepts all values needed for file and cross field validation +// v = validator instance, needed but some built in functions for it's custom types +// topStruct = top level struct when validating by struct otherwise nil +// currentStruct = current level struct when validating by struct otherwise optional comparison value +// field = field value for validation +// param = parameter used in validation i.e. gt=0 param would be 0 +type Func func(v *Validate, topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldtype reflect.Type, fieldKind reflect.Kind, param string) bool + +// StructLevelFunc accepts all values needed for struct level validation +type StructLevelFunc func(v *Validate, structLevel *StructLevel) + +// ValidationErrors is a type of map[string]*FieldError +// it exists to allow for multiple errors to be passed from this library +// and yet still subscribe to the error interface +type ValidationErrors map[string]*FieldError + +// Error is intended for use in development + debugging and not intended to be a production error message. +// It allows ValidationErrors to subscribe to the Error interface. +// All information to create an error message specific to your application is contained within +// the FieldError found within the ValidationErrors map +func (ve ValidationErrors) Error() string { + + buff := bytes.NewBufferString(blank) + + for key, err := range ve { + buff.WriteString(fmt.Sprintf(fieldErrMsg, key, err.Field, err.Tag)) + buff.WriteString("\n") + } + + return strings.TrimSpace(buff.String()) +} + +// FieldError contains a single field's validation error along +// with other properties that may be needed for error message creation +type FieldError struct { + FieldNamespace string + NameNamespace string + Field string + Name string + Tag string + ActualTag string + Kind reflect.Kind + Type reflect.Type + Param string + Value interface{} +} + +// New creates a new Validate instance for use. +func New(config *Config) *Validate { + + v := &Validate{ + tagName: config.TagName, + fieldNameTag: config.FieldNameTag, + tagCache: &tagCacheMap{m: map[string]*cachedTag{}}, + structCache: &structCacheMap{m: map[reflect.Type]*cachedStruct{}}, + errsPool: &sync.Pool{New: func() interface{} { + return ValidationErrors{} + }}} + + if len(v.aliasValidators) == 0 { + // must copy alias validators for separate validations to be used in each validator instance + v.aliasValidators = map[string]string{} + for k, val := range bakedInAliasValidators { + v.RegisterAliasValidation(k, val) + } + } + + if len(v.validationFuncs) == 0 { + // must copy validators for separate validations to be used in each instance + v.validationFuncs = map[string]Func{} + for k, val := range bakedInValidators { + v.RegisterValidation(k, val) + } + } + + return v +} + +// RegisterStructValidation registers a StructLevelFunc against a number of types +// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterStructValidation(fn StructLevelFunc, types ...interface{}) { + v.initCheck() + + if v.structLevelFuncs == nil { + v.structLevelFuncs = map[reflect.Type]StructLevelFunc{} + } + + for _, t := range types { + v.structLevelFuncs[reflect.TypeOf(t)] = fn + } + + v.hasStructLevelFuncs = true +} + +// RegisterValidation adds a validation Func to a Validate's map of validators denoted by the key +// NOTE: if the key already exists, the previous validation function will be replaced. +// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterValidation(key string, fn Func) error { + v.initCheck() + + if key == blank { + return errors.New("Function Key cannot be empty") + } + + if fn == nil { + return errors.New("Function cannot be empty") + } + + _, ok := restrictedTags[key] + + if ok || strings.ContainsAny(key, restrictedTagChars) { + panic(fmt.Sprintf(restrictedTagErr, key)) + } + + v.validationFuncs[key] = fn + + return nil +} + +// RegisterCustomTypeFunc registers a CustomTypeFunc against a number of types +// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterCustomTypeFunc(fn CustomTypeFunc, types ...interface{}) { + v.initCheck() + + if v.customTypeFuncs == nil { + v.customTypeFuncs = map[reflect.Type]CustomTypeFunc{} + } + + for _, t := range types { + v.customTypeFuncs[reflect.TypeOf(t)] = fn + } + + v.hasCustomFuncs = true +} + +// RegisterAliasValidation registers a mapping of a single validationstag that +// defines a common or complex set of validation(s) to simplify adding validation +// to structs. NOTE: when returning an error the tag returned in FieldError will be +// the alias tag unless the dive tag is part of the alias; everything after the +// dive tag is not reported as the alias tag. Also the ActualTag in the before case +// will be the actual tag within the alias that failed. +// NOTE: this method is not thread-safe it is intended that these all be registered prior to any validation +func (v *Validate) RegisterAliasValidation(alias, tags string) { + v.initCheck() + + _, ok := restrictedTags[alias] + + if ok || strings.ContainsAny(alias, restrictedTagChars) { + panic(fmt.Sprintf(restrictedAliasErr, alias)) + } + + v.aliasValidators[alias] = tags + v.hasAliasValidators = true +} + +// Field validates a single field using tag style validation and returns nil or ValidationErrors as type error. +// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors. +// NOTE: it returns ValidationErrors instead of a single FieldError because this can also +// validate Array, Slice and maps fields which may contain more than one error +func (v *Validate) Field(field interface{}, tag string) error { + v.initCheck() + + errs := v.errsPool.Get().(ValidationErrors) + fieldVal := reflect.ValueOf(field) + + v.traverseField(fieldVal, fieldVal, fieldVal, blank, blank, errs, false, tag, blank, blank, false, false, nil, nil) + + if len(errs) == 0 { + v.errsPool.Put(errs) + return nil + } + + return errs +} + +// FieldWithValue validates a single field, against another fields value using tag style validation and returns nil or ValidationErrors. +// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors. +// NOTE: it returns ValidationErrors instead of a single FieldError because this can also +// validate Array, Slice and maps fields which may contain more than one error +func (v *Validate) FieldWithValue(val interface{}, field interface{}, tag string) error { + v.initCheck() + + errs := v.errsPool.Get().(ValidationErrors) + topVal := reflect.ValueOf(val) + + v.traverseField(topVal, topVal, reflect.ValueOf(field), blank, blank, errs, false, tag, blank, blank, false, false, nil, nil) + + if len(errs) == 0 { + v.errsPool.Put(errs) + return nil + } + + return errs +} + +// StructPartial validates the fields passed in only, ignoring all others. +// Fields may be provided in a namespaced fashion relative to the struct provided +// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name and returns nil or ValidationErrors as error +// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors. +func (v *Validate) StructPartial(current interface{}, fields ...string) error { + v.initCheck() + + sv, _ := v.ExtractType(reflect.ValueOf(current)) + name := sv.Type().Name() + m := map[string]*struct{}{} + + if fields != nil { + for _, k := range fields { + + flds := strings.Split(k, namespaceSeparator) + if len(flds) > 0 { + + key := name + namespaceSeparator + for _, s := range flds { + + idx := strings.Index(s, leftBracket) + + if idx != -1 { + for idx != -1 { + key += s[:idx] + m[key] = emptyStructPtr + + idx2 := strings.Index(s, rightBracket) + idx2++ + key += s[idx:idx2] + m[key] = emptyStructPtr + s = s[idx2:] + idx = strings.Index(s, leftBracket) + } + } else { + + key += s + m[key] = emptyStructPtr + } + + key += namespaceSeparator + } + } + } + } + + errs := v.errsPool.Get().(ValidationErrors) + + v.tranverseStruct(sv, sv, sv, blank, blank, errs, true, len(m) != 0, false, m, false) + + if len(errs) == 0 { + v.errsPool.Put(errs) + return nil + } + + return errs +} + +// StructExcept validates all fields except the ones passed in. +// Fields may be provided in a namespaced fashion relative to the struct provided +// i.e. NestedStruct.Field or NestedArrayField[0].Struct.Name and returns nil or ValidationErrors as error +// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors. +func (v *Validate) StructExcept(current interface{}, fields ...string) error { + v.initCheck() + + sv, _ := v.ExtractType(reflect.ValueOf(current)) + name := sv.Type().Name() + m := map[string]*struct{}{} + + for _, key := range fields { + m[name+namespaceSeparator+key] = emptyStructPtr + } + + errs := v.errsPool.Get().(ValidationErrors) + + v.tranverseStruct(sv, sv, sv, blank, blank, errs, true, len(m) != 0, true, m, false) + + if len(errs) == 0 { + v.errsPool.Put(errs) + return nil + } + + return errs +} + +// Struct validates a structs exposed fields, and automatically validates nested structs, unless otherwise specified. +// it returns nil or ValidationErrors as error. +// You will need to assert the error if it's not nil i.e. err.(validator.ValidationErrors) to access the map of errors. +func (v *Validate) Struct(current interface{}) error { + v.initCheck() + + errs := v.errsPool.Get().(ValidationErrors) + sv := reflect.ValueOf(current) + + v.tranverseStruct(sv, sv, sv, blank, blank, errs, true, false, false, nil, false) + + if len(errs) == 0 { + v.errsPool.Put(errs) + return nil + } + + return errs +} + +// tranverseStruct traverses a structs fields and then passes them to be validated by traverseField +func (v *Validate) tranverseStruct(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, useStructName bool, partial bool, exclude bool, includeExclude map[string]*struct{}, isStructOnly bool) { + + if current.Kind() == reflect.Ptr && !current.IsNil() { + current = current.Elem() + } + + if current.Kind() != reflect.Struct && current.Kind() != reflect.Interface { + panic("value passed for validation is not a struct") + } + + // var ok bool + typ := current.Type() + + sName := typ.Name() + + if useStructName { + errPrefix += sName + namespaceSeparator + + if v.fieldNameTag != blank { + nsPrefix += sName + namespaceSeparator + } + } + + // structonly tag present don't tranverseFields + // but must still check and run below struct level validation + // if present + if !isStructOnly { + + var fld reflect.StructField + + // is anonymous struct, cannot parse or cache as + // it has no name to index by + if sName == blank { + + var customName string + var ok bool + numFields := current.NumField() + + for i := 0; i < numFields; i++ { + + fld = typ.Field(i) + + if fld.PkgPath != blank { + continue + } + + if partial { + + _, ok = includeExclude[errPrefix+fld.Name] + + if (ok && exclude) || (!ok && !exclude) { + continue + } + } + + customName = fld.Name + + if v.fieldNameTag != blank { + + name := strings.SplitN(fld.Tag.Get(v.fieldNameTag), ",", 2)[0] + + // dash check is for json "-" means don't output in json + if name != blank && name != dash { + customName = name + } + } + + v.traverseField(topStruct, currentStruct, current.Field(i), errPrefix, nsPrefix, errs, true, fld.Tag.Get(v.tagName), fld.Name, customName, partial, exclude, includeExclude, nil) + } + } else { + s, ok := v.structCache.Get(typ) + if !ok { + s = v.parseStruct(current, sName) + } + + for i, f := range s.fields { + + if partial { + + _, ok = includeExclude[errPrefix+f.Name] + + if (ok && exclude) || (!ok && !exclude) { + continue + } + } + fld = typ.Field(i) + + v.traverseField(topStruct, currentStruct, current.Field(i), errPrefix, nsPrefix, errs, true, f.CachedTag.tag, fld.Name, f.AltName, partial, exclude, includeExclude, f.CachedTag) + } + } + } + + // check if any struct level validations, after all field validations already checked. + if v.hasStructLevelFuncs { + if fn, ok := v.structLevelFuncs[current.Type()]; ok { + fn(v, &StructLevel{v: v, TopStruct: topStruct, CurrentStruct: current, errPrefix: errPrefix, nsPrefix: nsPrefix, errs: errs}) + } + } +} + +// traverseField validates any field, be it a struct or single field, ensures it's validity and passes it along to be validated via it's tag options +func (v *Validate) traverseField(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, isStructField bool, tag, name, customName string, partial bool, exclude bool, includeExclude map[string]*struct{}, cTag *cachedTag) { + + if tag == skipValidationTag { + return + } + + if cTag == nil { + var isCached bool + cTag, isCached = v.tagCache.Get(tag) + + if !isCached { + cTag = v.parseTags(tag, name) + } + } + + current, kind := v.ExtractType(current) + var typ reflect.Type + + switch kind { + case reflect.Ptr, reflect.Interface, reflect.Invalid: + if cTag.isOmitEmpty { + return + } + + if tag != blank { + + ns := errPrefix + name + + if kind == reflect.Invalid { + errs[ns] = &FieldError{ + FieldNamespace: ns, + NameNamespace: nsPrefix + customName, + Name: customName, + Field: name, + Tag: cTag.tags[0].tag, + ActualTag: cTag.tags[0].tagVals[0][0], + Param: cTag.tags[0].tagVals[0][1], + Kind: kind, + } + return + } + + errs[ns] = &FieldError{ + FieldNamespace: ns, + NameNamespace: nsPrefix + customName, + Name: customName, + Field: name, + Tag: cTag.tags[0].tag, + ActualTag: cTag.tags[0].tagVals[0][0], + Param: cTag.tags[0].tagVals[0][1], + Value: current.Interface(), + Kind: kind, + Type: current.Type(), + } + + return + } + + // if we get here tag length is zero and we can leave + if kind == reflect.Invalid { + return + } + + case reflect.Struct: + typ = current.Type() + + if typ != timeType { + + if cTag.isNoStructLevel { + return + } + + v.tranverseStruct(topStruct, current, current, errPrefix+name+namespaceSeparator, nsPrefix+customName+namespaceSeparator, errs, false, partial, exclude, includeExclude, cTag.isStructOnly) + return + } + } + + if tag == blank { + return + } + + typ = current.Type() + + var dive bool + var diveSubTag string + + for _, valTag := range cTag.tags { + + if valTag.tagVals[0][0] == existsTag { + continue + } + + if valTag.tagVals[0][0] == diveTag { + dive = true + diveSubTag = strings.TrimLeft(strings.SplitN(cTag.diveTag, diveTag, 2)[1], ",") + break + } + + if valTag.tagVals[0][0] == omitempty { + + if !HasValue(v, topStruct, currentStruct, current, typ, kind, blank) { + return + } + continue + } + + if v.validateField(topStruct, currentStruct, current, typ, kind, errPrefix, nsPrefix, errs, valTag, name, customName) { + return + } + } + + if dive { + // traverse slice or map here + // or panic ;) + switch kind { + case reflect.Slice, reflect.Array: + v.traverseSlice(topStruct, currentStruct, current, errPrefix, nsPrefix, errs, diveSubTag, name, customName, partial, exclude, includeExclude, nil) + case reflect.Map: + v.traverseMap(topStruct, currentStruct, current, errPrefix, nsPrefix, errs, diveSubTag, name, customName, partial, exclude, includeExclude, nil) + default: + // throw error, if not a slice or map then should not have gotten here + // bad dive tag + panic("dive error! can't dive on a non slice or map") + } + } +} + +// traverseSlice traverses a Slice or Array's elements and passes them to traverseField for validation +func (v *Validate) traverseSlice(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, tag, name, customName string, partial bool, exclude bool, includeExclude map[string]*struct{}, cTag *cachedTag) { + + for i := 0; i < current.Len(); i++ { + v.traverseField(topStruct, currentStruct, current.Index(i), errPrefix, nsPrefix, errs, false, tag, fmt.Sprintf(arrayIndexFieldName, name, i), fmt.Sprintf(arrayIndexFieldName, customName, i), partial, exclude, includeExclude, cTag) + } +} + +// traverseMap traverses a map's elements and passes them to traverseField for validation +func (v *Validate) traverseMap(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, errPrefix string, nsPrefix string, errs ValidationErrors, tag, name, customName string, partial bool, exclude bool, includeExclude map[string]*struct{}, cTag *cachedTag) { + + for _, key := range current.MapKeys() { + v.traverseField(topStruct, currentStruct, current.MapIndex(key), errPrefix, nsPrefix, errs, false, tag, fmt.Sprintf(mapIndexFieldName, name, key.Interface()), fmt.Sprintf(mapIndexFieldName, customName, key.Interface()), partial, exclude, includeExclude, cTag) + } +} + +// validateField validates a field based on the provided tag's key and param values and returns true if there is an error or false if all ok +func (v *Validate) validateField(topStruct reflect.Value, currentStruct reflect.Value, current reflect.Value, currentType reflect.Type, currentKind reflect.Kind, errPrefix string, nsPrefix string, errs ValidationErrors, valTag *tagVals, name, customName string) bool { + + var valFunc Func + var ok bool + + if valTag.isOrVal { + + errTag := blank + + for _, val := range valTag.tagVals { + + valFunc, ok = v.validationFuncs[val[0]] + if !ok { + panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) + } + + if valFunc(v, topStruct, currentStruct, current, currentType, currentKind, val[1]) { + return false + } + + errTag += orSeparator + val[0] + } + + ns := errPrefix + name + + if valTag.isAlias { + errs[ns] = &FieldError{ + FieldNamespace: ns, + NameNamespace: nsPrefix + customName, + Name: customName, + Field: name, + Tag: valTag.tag, + ActualTag: errTag[1:], + Value: current.Interface(), + Type: currentType, + Kind: currentKind, + } + } else { + errs[errPrefix+name] = &FieldError{ + FieldNamespace: ns, + NameNamespace: nsPrefix + customName, + Name: customName, + Field: name, + Tag: errTag[1:], + ActualTag: errTag[1:], + Value: current.Interface(), + Type: currentType, + Kind: currentKind, + } + } + + return true + } + + valFunc, ok = v.validationFuncs[valTag.tagVals[0][0]] + if !ok { + panic(strings.TrimSpace(fmt.Sprintf(undefinedValidation, name))) + } + + if valFunc(v, topStruct, currentStruct, current, currentType, currentKind, valTag.tagVals[0][1]) { + return false + } + + ns := errPrefix + name + + errs[ns] = &FieldError{ + FieldNamespace: ns, + NameNamespace: nsPrefix + customName, + Name: customName, + Field: name, + Tag: valTag.tag, + ActualTag: valTag.tagVals[0][0], + Value: current.Interface(), + Param: valTag.tagVals[0][1], + Type: currentType, + Kind: currentKind, + } + + return true +} diff --git a/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/validator_test.go b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/validator_test.go new file mode 100644 index 00000000..63f3d9bf --- /dev/null +++ b/src/github.com/smira/aptly/_vendor/src/gopkg.in/go-playground/validator.v8/validator_test.go @@ -0,0 +1,5756 @@ +package validator + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "fmt" + "reflect" + "testing" + "time" + + . "gopkg.in/go-playground/assert.v1" +) + +// NOTES: +// - Run "go test" to run tests +// - Run "gocov test | gocov report" to report on test converage by file +// - Run "gocov test | gocov annotate -" to report on all code and functions, those ,marked with "MISS" were never called +// +// or +// +// -- may be a good idea to change to output path to somewherelike /tmp +// go test -coverprofile cover.out && go tool cover -html=cover.out -o cover.html +// +// +// go test -cpuprofile cpu.out +// ./validator.test -test.bench=. -test.cpuprofile=cpu.prof +// go tool pprof validator.test cpu.prof +// +// +// go test -memprofile mem.out + +type I interface { + Foo() string +} + +type Impl struct { + F string `validate:"len=3"` +} + +func (i *Impl) Foo() string { + return i.F +} + +type SubTest struct { + Test string `validate:"required"` +} + +type TestInterface struct { + Iface I +} + +type TestString struct { + BlankTag string `validate:""` + Required string `validate:"required"` + Len string `validate:"len=10"` + Min string `validate:"min=1"` + Max string `validate:"max=10"` + MinMax string `validate:"min=1,max=10"` + Lt string `validate:"lt=10"` + Lte string `validate:"lte=10"` + Gt string `validate:"gt=10"` + Gte string `validate:"gte=10"` + OmitEmpty string `validate:"omitempty,min=1,max=10"` + Sub *SubTest + SubIgnore *SubTest `validate:"-"` + Anonymous struct { + A string `validate:"required"` + } + Iface I +} + +type TestInt32 struct { + Required int `validate:"required"` + Len int `validate:"len=10"` + Min int `validate:"min=1"` + Max int `validate:"max=10"` + MinMax int `validate:"min=1,max=10"` + Lt int `validate:"lt=10"` + Lte int `validate:"lte=10"` + Gt int `validate:"gt=10"` + Gte int `validate:"gte=10"` + OmitEmpty int `validate:"omitempty,min=1,max=10"` +} + +type TestUint64 struct { + Required uint64 `validate:"required"` + Len uint64 `validate:"len=10"` + Min uint64 `validate:"min=1"` + Max uint64 `validate:"max=10"` + MinMax uint64 `validate:"min=1,max=10"` + OmitEmpty uint64 `validate:"omitempty,min=1,max=10"` +} + +type TestFloat64 struct { + Required float64 `validate:"required"` + Len float64 `validate:"len=10"` + Min float64 `validate:"min=1"` + Max float64 `validate:"max=10"` + MinMax float64 `validate:"min=1,max=10"` + Lte float64 `validate:"lte=10"` + OmitEmpty float64 `validate:"omitempty,min=1,max=10"` +} + +type TestSlice struct { + Required []int `validate:"required"` + Len []int `validate:"len=10"` + Min []int `validate:"min=1"` + Max []int `validate:"max=10"` + MinMax []int `validate:"min=1,max=10"` + OmitEmpty []int `validate:"omitempty,min=1,max=10"` +} + +var validate = New(&Config{TagName: "validate"}) + +func AssertError(t *testing.T, err error, key, field, expectedTag string) { + + errs := err.(ValidationErrors) + + val, ok := errs[key] + EqualSkip(t, 2, ok, true) + NotEqualSkip(t, 2, val, nil) + EqualSkip(t, 2, val.Field, field) + EqualSkip(t, 2, val.Tag, expectedTag) +} + +type valuer struct { + Name string +} + +func (v valuer) Value() (driver.Value, error) { + + if v.Name == "errorme" { + panic("SQL Driver Valuer error: some kind of error") + // return nil, errors.New("some kind of error") + } + + if len(v.Name) == 0 { + return nil, nil + } + + return v.Name, nil +} + +type MadeUpCustomType struct { + FirstName string + LastName string +} + +func ValidateCustomType(field reflect.Value) interface{} { + if cust, ok := field.Interface().(MadeUpCustomType); ok { + + if len(cust.FirstName) == 0 || len(cust.LastName) == 0 { + return "" + } + + return cust.FirstName + " " + cust.LastName + } + + return "" +} + +func OverrideIntTypeForSomeReason(field reflect.Value) interface{} { + + if i, ok := field.Interface().(int); ok { + if i == 1 { + return "1" + } + + if i == 2 { + return "12" + } + } + + return "" +} + +type CustomMadeUpStruct struct { + MadeUp MadeUpCustomType `validate:"required"` + OverriddenInt int `validate:"gt=1"` +} + +func ValidateValuerType(field reflect.Value) interface{} { + + if valuer, ok := field.Interface().(driver.Valuer); ok { + + val, err := valuer.Value() + if err != nil { + // handle the error how you want + return nil + } + + return val + } + + return nil +} + +type TestPartial struct { + NoTag string + BlankTag string `validate:""` + Required string `validate:"required"` + SubSlice []*SubTest `validate:"required,dive"` + Sub *SubTest + SubIgnore *SubTest `validate:"-"` + Anonymous struct { + A string `validate:"required"` + ASubSlice []*SubTest `validate:"required,dive"` + + SubAnonStruct []struct { + Test string `validate:"required"` + OtherTest string `validate:"required"` + } `validate:"required,dive"` + } +} + +type TestStruct struct { + String string `validate:"required" json:"StringVal"` +} + +func StructValidationTestStructSuccess(v *Validate, structLevel *StructLevel) { + + st := structLevel.CurrentStruct.Interface().(TestStruct) + + if st.String != "good value" { + structLevel.ReportError(reflect.ValueOf(st.String), "String", "StringVal", "badvalueteststruct") + } +} + +func StructValidationTestStruct(v *Validate, structLevel *StructLevel) { + + st := structLevel.CurrentStruct.Interface().(TestStruct) + + if st.String != "bad value" { + structLevel.ReportError(reflect.ValueOf(st.String), "String", "StringVal", "badvalueteststruct") + } +} + +func StructValidationBadTestStructFieldName(v *Validate, structLevel *StructLevel) { + + st := structLevel.CurrentStruct.Interface().(TestStruct) + + if st.String != "bad value" { + structLevel.ReportError(reflect.ValueOf(st.String), "", "StringVal", "badvalueteststruct") + } +} + +func StructValidationBadTestStructTag(v *Validate, structLevel *StructLevel) { + + st := structLevel.CurrentStruct.Interface().(TestStruct) + + if st.String != "bad value" { + structLevel.ReportError(reflect.ValueOf(st.String), "String", "StringVal", "") + } +} + +func StructValidationNoTestStructCustomName(v *Validate, structLevel *StructLevel) { + + st := structLevel.CurrentStruct.Interface().(TestStruct) + + if st.String != "bad value" { + structLevel.ReportError(reflect.ValueOf(st.String), "String", "", "badvalueteststruct") + } +} + +func StructValidationTestStructInvalid(v *Validate, structLevel *StructLevel) { + + st := structLevel.CurrentStruct.Interface().(TestStruct) + + if st.String != "bad value" { + structLevel.ReportError(reflect.ValueOf(nil), "String", "StringVal", "badvalueteststruct") + } +} + +func StructValidationTestStructReturnValidationErrors(v *Validate, structLevel *StructLevel) { + + s := structLevel.CurrentStruct.Interface().(TestStructReturnValidationErrors) + + errs := v.Struct(s.Inner1.Inner2) + if errs == nil { + return + } + + structLevel.ReportValidationErrors("Inner1.", errs.(ValidationErrors)) +} + +func StructValidationTestStructReturnValidationErrors2(v *Validate, structLevel *StructLevel) { + + s := structLevel.CurrentStruct.Interface().(TestStructReturnValidationErrors) + + errs := v.Struct(s.Inner1.Inner2) + if errs == nil { + return + } + + structLevel.ReportValidationErrors("Inner1.|Inner1JSON.", errs.(ValidationErrors)) +} + +type TestStructReturnValidationErrorsInner2 struct { + String string `validate:"required" json:"JSONString"` +} + +type TestStructReturnValidationErrorsInner1 struct { + Inner2 *TestStructReturnValidationErrorsInner2 +} + +type TestStructReturnValidationErrors struct { + Inner1 *TestStructReturnValidationErrorsInner1 `json:"Inner1JSON"` +} + +type Inner2Namespace struct { + String []string `validate:"dive,required" json:"JSONString"` +} + +type Inner1Namespace struct { + Inner2 *Inner2Namespace `json:"Inner2JSON"` +} + +type Namespace struct { + Inner1 *Inner1Namespace `json:"Inner1JSON"` +} + +func TestNameNamespace(t *testing.T) { + + config := &Config{ + TagName: "validate", + FieldNameTag: "json", + } + + v1 := New(config) + i2 := &Inner2Namespace{String: []string{"ok", "ok", "ok"}} + i1 := &Inner1Namespace{Inner2: i2} + ns := &Namespace{Inner1: i1} + + errs := v1.Struct(ns) + Equal(t, errs, nil) + + i2.String[1] = "" + + errs = v1.Struct(ns) + NotEqual(t, errs, nil) + + ve := errs.(ValidationErrors) + Equal(t, len(ve), 1) + AssertError(t, errs, "Namespace.Inner1.Inner2.String[1]", "String[1]", "required") + + fe, ok := ve["Namespace.Inner1.Inner2.String[1]"] + Equal(t, ok, true) + + Equal(t, fe.Field, "String[1]") + Equal(t, fe.FieldNamespace, "Namespace.Inner1.Inner2.String[1]") + Equal(t, fe.Name, "JSONString[1]") + Equal(t, fe.NameNamespace, "Namespace.Inner1JSON.Inner2JSON.JSONString[1]") +} + +func TestAnonymous(t *testing.T) { + + v2 := New(&Config{TagName: "validate", FieldNameTag: "json"}) + + type Test struct { + Anonymous struct { + A string `validate:"required" json:"EH"` + } + AnonymousB struct { + B string `validate:"required" json:"BEE"` + } + anonymousC struct { + c string `validate:"required" json:"SEE"` + } + } + + tst := &Test{ + Anonymous: struct { + A string `validate:"required" json:"EH"` + }{ + A: "1", + }, + AnonymousB: struct { + B string `validate:"required" json:"BEE"` + }{ + B: "", + }, + anonymousC: struct { + c string `validate:"required" json:"SEE"` + }{ + c: "", + }, + } + + err := v2.Struct(tst) + NotEqual(t, err, nil) + + errs := err.(ValidationErrors) + + Equal(t, len(errs), 1) + AssertError(t, errs, "Test.AnonymousB.B", "B", "required") + Equal(t, errs["Test.AnonymousB.B"].Field, "B") + Equal(t, errs["Test.AnonymousB.B"].Name, "BEE") + + s := struct { + c string `validate:"required" json:"SEE"` + }{ + c: "", + } + + err = v2.Struct(s) + Equal(t, err, nil) +} + +func TestStructLevelReturnValidationErrors(t *testing.T) { + config := &Config{ + TagName: "validate", + } + + v1 := New(config) + v1.RegisterStructValidation(StructValidationTestStructReturnValidationErrors, TestStructReturnValidationErrors{}) + + inner2 := &TestStructReturnValidationErrorsInner2{ + String: "I'm HERE", + } + + inner1 := &TestStructReturnValidationErrorsInner1{ + Inner2: inner2, + } + + val := &TestStructReturnValidationErrors{ + Inner1: inner1, + } + + errs := v1.Struct(val) + Equal(t, errs, nil) + + inner2.String = "" + + errs = v1.Struct(val) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 2) + AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.Inner2.String", "String", "required") + // this is an extra error reported from struct validation + AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.String", "String", "required") +} + +func TestStructLevelReturnValidationErrorsWithJSON(t *testing.T) { + config := &Config{ + TagName: "validate", + FieldNameTag: "json", + } + + v1 := New(config) + v1.RegisterStructValidation(StructValidationTestStructReturnValidationErrors2, TestStructReturnValidationErrors{}) + + inner2 := &TestStructReturnValidationErrorsInner2{ + String: "I'm HERE", + } + + inner1 := &TestStructReturnValidationErrorsInner1{ + Inner2: inner2, + } + + val := &TestStructReturnValidationErrors{ + Inner1: inner1, + } + + errs := v1.Struct(val) + Equal(t, errs, nil) + + inner2.String = "" + + errs = v1.Struct(val) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 2) + AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.Inner2.String", "String", "required") + // this is an extra error reported from struct validation, it's a badly formatted one, but on purpose + AssertError(t, errs, "TestStructReturnValidationErrors.Inner1.String", "String", "required") + + fe, ok := errs.(ValidationErrors)["TestStructReturnValidationErrors.Inner1.Inner2.String"] + Equal(t, ok, true) + + // check for proper JSON namespace + Equal(t, fe.Field, "String") + Equal(t, fe.Name, "JSONString") + Equal(t, fe.FieldNamespace, "TestStructReturnValidationErrors.Inner1.Inner2.String") + Equal(t, fe.NameNamespace, "TestStructReturnValidationErrors.Inner1JSON.Inner2.JSONString") + + fe, ok = errs.(ValidationErrors)["TestStructReturnValidationErrors.Inner1.String"] + Equal(t, ok, true) + + // check for proper JSON namespace + Equal(t, fe.Field, "String") + Equal(t, fe.Name, "JSONString") + Equal(t, fe.FieldNamespace, "TestStructReturnValidationErrors.Inner1.String") + Equal(t, fe.NameNamespace, "TestStructReturnValidationErrors.Inner1JSON.JSONString") +} + +func TestStructLevelValidations(t *testing.T) { + + config := &Config{ + TagName: "validate", + } + + v1 := New(config) + v1.RegisterStructValidation(StructValidationTestStruct, TestStruct{}) + + tst := &TestStruct{ + String: "good value", + } + + errs := v1.Struct(tst) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestStruct.String", "String", "badvalueteststruct") + + v2 := New(config) + v2.RegisterStructValidation(StructValidationBadTestStructFieldName, TestStruct{}) + + PanicMatches(t, func() { v2.Struct(tst) }, fieldNameRequired) + + v3 := New(config) + v3.RegisterStructValidation(StructValidationBadTestStructTag, TestStruct{}) + + PanicMatches(t, func() { v3.Struct(tst) }, tagRequired) + + v4 := New(config) + v4.RegisterStructValidation(StructValidationNoTestStructCustomName, TestStruct{}) + + errs = v4.Struct(tst) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestStruct.String", "String", "badvalueteststruct") + + v5 := New(config) + v5.RegisterStructValidation(StructValidationTestStructInvalid, TestStruct{}) + + errs = v5.Struct(tst) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestStruct.String", "String", "badvalueteststruct") + + v6 := New(config) + v6.RegisterStructValidation(StructValidationTestStructSuccess, TestStruct{}) + + errs = v6.Struct(tst) + Equal(t, errs, nil) +} + +func TestAliasTags(t *testing.T) { + + validate.RegisterAliasValidation("iscolor", "hexcolor|rgb|rgba|hsl|hsla") + + s := "rgb(255,255,255)" + errs := validate.Field(s, "iscolor") + Equal(t, errs, nil) + + s = "" + errs = validate.Field(s, "omitempty,iscolor") + Equal(t, errs, nil) + + s = "rgb(255,255,0)" + errs = validate.Field(s, "iscolor,len=5") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "len") + + type Test struct { + Color string `validate:"iscolor"` + } + + tst := &Test{ + Color: "#000", + } + + errs = validate.Struct(tst) + Equal(t, errs, nil) + + tst.Color = "cfvre" + errs = validate.Struct(tst) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Color", "Color", "iscolor") + Equal(t, errs.(ValidationErrors)["Test.Color"].ActualTag, "hexcolor|rgb|rgba|hsl|hsla") + + validate.RegisterAliasValidation("req", "required,dive,iscolor") + arr := []string{"val1", "#fff", "#000"} + errs = validate.Field(arr, "req") + NotEqual(t, errs, nil) + AssertError(t, errs, "[0]", "[0]", "iscolor") + + PanicMatches(t, func() { validate.RegisterAliasValidation("exists", "gt=5,lt=10") }, "Alias 'exists' either contains restricted characters or is the same as a restricted tag needed for normal operation") +} + +func TestNilValidator(t *testing.T) { + + type TestStruct struct { + Test string `validate:"required"` + } + + ts := TestStruct{} + + var val *Validate + + fn := func(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + return current.String() == field.String() + } + + PanicMatches(t, func() { val.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) }, validatorNotInitialized) + PanicMatches(t, func() { val.RegisterValidation("something", fn) }, validatorNotInitialized) + PanicMatches(t, func() { val.Field(ts.Test, "required") }, validatorNotInitialized) + PanicMatches(t, func() { val.FieldWithValue("test", ts.Test, "required") }, validatorNotInitialized) + PanicMatches(t, func() { val.Struct(ts) }, validatorNotInitialized) + PanicMatches(t, func() { val.StructExcept(ts, "Test") }, validatorNotInitialized) + PanicMatches(t, func() { val.StructPartial(ts, "Test") }, validatorNotInitialized) +} + +func TestStructPartial(t *testing.T) { + + p1 := []string{ + "NoTag", + "Required", + } + + p2 := []string{ + "SubSlice[0].Test", + "Sub", + "SubIgnore", + "Anonymous.A", + } + + p3 := []string{ + "SubTest.Test", + } + + p4 := []string{ + "A", + } + + tPartial := &TestPartial{ + NoTag: "NoTag", + Required: "Required", + + SubSlice: []*SubTest{ + { + + Test: "Required", + }, + { + + Test: "Required", + }, + }, + + Sub: &SubTest{ + Test: "1", + }, + SubIgnore: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + ASubSlice []*SubTest `validate:"required,dive"` + SubAnonStruct []struct { + Test string `validate:"required"` + OtherTest string `validate:"required"` + } `validate:"required,dive"` + }{ + A: "1", + ASubSlice: []*SubTest{ + { + Test: "Required", + }, + { + Test: "Required", + }, + }, + + SubAnonStruct: []struct { + Test string `validate:"required"` + OtherTest string `validate:"required"` + }{ + {"Required", "RequiredOther"}, + {"Required", "RequiredOther"}, + }, + }, + } + + // the following should all return no errors as everything is valid in + // the default state + errs := validate.StructPartial(tPartial, p1...) + Equal(t, errs, nil) + + errs = validate.StructPartial(tPartial, p2...) + Equal(t, errs, nil) + + // this isnt really a robust test, but is ment to illustrate the ANON CASE below + errs = validate.StructPartial(tPartial.SubSlice[0], p3...) + Equal(t, errs, nil) + + errs = validate.StructExcept(tPartial, p1...) + Equal(t, errs, nil) + + errs = validate.StructExcept(tPartial, p2...) + Equal(t, errs, nil) + + // mod tParial for required feild and re-test making sure invalid fields are NOT required: + tPartial.Required = "" + + errs = validate.StructExcept(tPartial, p1...) + Equal(t, errs, nil) + + errs = validate.StructPartial(tPartial, p2...) + Equal(t, errs, nil) + + // inversion and retesting Partial to generate failures: + errs = validate.StructPartial(tPartial, p1...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.Required", "Required", "required") + + errs = validate.StructExcept(tPartial, p2...) + AssertError(t, errs, "TestPartial.Required", "Required", "required") + + // reset Required field, and set nested struct + tPartial.Required = "Required" + tPartial.Anonymous.A = "" + + // will pass as unset feilds is not going to be tested + errs = validate.StructPartial(tPartial, p1...) + Equal(t, errs, nil) + + errs = validate.StructExcept(tPartial, p2...) + Equal(t, errs, nil) + + // ANON CASE the response here is strange, it clearly does what it is being told to + errs = validate.StructExcept(tPartial.Anonymous, p4...) + Equal(t, errs, nil) + + // will fail as unset feild is tested + errs = validate.StructPartial(tPartial, p2...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.Anonymous.A", "A", "required") + + errs = validate.StructExcept(tPartial, p1...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.Anonymous.A", "A", "required") + + // reset nested struct and unset struct in slice + tPartial.Anonymous.A = "Required" + tPartial.SubSlice[0].Test = "" + + // these will pass as unset item is NOT tested + errs = validate.StructPartial(tPartial, p1...) + Equal(t, errs, nil) + + errs = validate.StructExcept(tPartial, p2...) + Equal(t, errs, nil) + + // these will fail as unset item IS tested + errs = validate.StructExcept(tPartial, p1...) + AssertError(t, errs, "TestPartial.SubSlice[0].Test", "Test", "required") + Equal(t, len(errs.(ValidationErrors)), 1) + + errs = validate.StructPartial(tPartial, p2...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.SubSlice[0].Test", "Test", "required") + Equal(t, len(errs.(ValidationErrors)), 1) + + // Unset second slice member concurrently to test dive behavior: + tPartial.SubSlice[1].Test = "" + + errs = validate.StructPartial(tPartial, p1...) + Equal(t, errs, nil) + + // NOTE: When specifying nested items, it is still the users responsibility + // to specify the dive tag, the library does not override this. + errs = validate.StructExcept(tPartial, p2...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.SubSlice[1].Test", "Test", "required") + + errs = validate.StructExcept(tPartial, p1...) + Equal(t, len(errs.(ValidationErrors)), 2) + AssertError(t, errs, "TestPartial.SubSlice[0].Test", "Test", "required") + AssertError(t, errs, "TestPartial.SubSlice[1].Test", "Test", "required") + + errs = validate.StructPartial(tPartial, p2...) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "TestPartial.SubSlice[0].Test", "Test", "required") + + // reset struct in slice, and unset struct in slice in unset posistion + tPartial.SubSlice[0].Test = "Required" + + // these will pass as the unset item is NOT tested + errs = validate.StructPartial(tPartial, p1...) + Equal(t, errs, nil) + + errs = validate.StructPartial(tPartial, p2...) + Equal(t, errs, nil) + + // testing for missing item by exception, yes it dives and fails + errs = validate.StructExcept(tPartial, p1...) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "TestPartial.SubSlice[1].Test", "Test", "required") + + errs = validate.StructExcept(tPartial, p2...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.SubSlice[1].Test", "Test", "required") + + tPartial.SubSlice[1].Test = "Required" + + tPartial.Anonymous.SubAnonStruct[0].Test = "" + // these will pass as the unset item is NOT tested + errs = validate.StructPartial(tPartial, p1...) + Equal(t, errs, nil) + + errs = validate.StructPartial(tPartial, p2...) + Equal(t, errs, nil) + + errs = validate.StructExcept(tPartial, p1...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "required") + + errs = validate.StructExcept(tPartial, p2...) + NotEqual(t, errs, nil) + AssertError(t, errs, "TestPartial.Anonymous.SubAnonStruct[0].Test", "Test", "required") + +} + +func TestCrossStructLteFieldValidation(t *testing.T) { + + type Inner struct { + CreatedAt *time.Time + String string + Int int + Uint uint + Float float64 + Array []string + } + + type Test struct { + Inner *Inner + CreatedAt *time.Time `validate:"ltecsfield=Inner.CreatedAt"` + String string `validate:"ltecsfield=Inner.String"` + Int int `validate:"ltecsfield=Inner.Int"` + Uint uint `validate:"ltecsfield=Inner.Uint"` + Float float64 `validate:"ltecsfield=Inner.Float"` + Array []string `validate:"ltecsfield=Inner.Array"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * 5) + + inner := &Inner{ + CreatedAt: &then, + String: "abcd", + Int: 13, + Uint: 13, + Float: 1.13, + Array: []string{"val1", "val2"}, + } + + test := &Test{ + Inner: inner, + CreatedAt: &now, + String: "abc", + Int: 12, + Uint: 12, + Float: 1.12, + Array: []string{"val1"}, + } + + errs := validate.Struct(test) + Equal(t, errs, nil) + + test.CreatedAt = &then + test.String = "abcd" + test.Int = 13 + test.Uint = 13 + test.Float = 1.13 + test.Array = []string{"val1", "val2"} + + errs = validate.Struct(test) + Equal(t, errs, nil) + + after := now.Add(time.Hour * 10) + + test.CreatedAt = &after + test.String = "abce" + test.Int = 14 + test.Uint = 14 + test.Float = 1.14 + test.Array = []string{"val1", "val2", "val3"} + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.CreatedAt", "CreatedAt", "ltecsfield") + AssertError(t, errs, "Test.String", "String", "ltecsfield") + AssertError(t, errs, "Test.Int", "Int", "ltecsfield") + AssertError(t, errs, "Test.Uint", "Uint", "ltecsfield") + AssertError(t, errs, "Test.Float", "Float", "ltecsfield") + AssertError(t, errs, "Test.Array", "Array", "ltecsfield") + + errs = validate.FieldWithValue(1, "", "ltecsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltecsfield") + + errs = validate.FieldWithValue(test, now, "ltecsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltecsfield") +} + +func TestCrossStructLtFieldValidation(t *testing.T) { + + type Inner struct { + CreatedAt *time.Time + String string + Int int + Uint uint + Float float64 + Array []string + } + + type Test struct { + Inner *Inner + CreatedAt *time.Time `validate:"ltcsfield=Inner.CreatedAt"` + String string `validate:"ltcsfield=Inner.String"` + Int int `validate:"ltcsfield=Inner.Int"` + Uint uint `validate:"ltcsfield=Inner.Uint"` + Float float64 `validate:"ltcsfield=Inner.Float"` + Array []string `validate:"ltcsfield=Inner.Array"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * 5) + + inner := &Inner{ + CreatedAt: &then, + String: "abcd", + Int: 13, + Uint: 13, + Float: 1.13, + Array: []string{"val1", "val2"}, + } + + test := &Test{ + Inner: inner, + CreatedAt: &now, + String: "abc", + Int: 12, + Uint: 12, + Float: 1.12, + Array: []string{"val1"}, + } + + errs := validate.Struct(test) + Equal(t, errs, nil) + + test.CreatedAt = &then + test.String = "abcd" + test.Int = 13 + test.Uint = 13 + test.Float = 1.13 + test.Array = []string{"val1", "val2"} + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.CreatedAt", "CreatedAt", "ltcsfield") + AssertError(t, errs, "Test.String", "String", "ltcsfield") + AssertError(t, errs, "Test.Int", "Int", "ltcsfield") + AssertError(t, errs, "Test.Uint", "Uint", "ltcsfield") + AssertError(t, errs, "Test.Float", "Float", "ltcsfield") + AssertError(t, errs, "Test.Array", "Array", "ltcsfield") + + errs = validate.FieldWithValue(1, "", "ltcsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltcsfield") + + errs = validate.FieldWithValue(test, now, "ltcsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltcsfield") +} + +func TestCrossStructGteFieldValidation(t *testing.T) { + + type Inner struct { + CreatedAt *time.Time + String string + Int int + Uint uint + Float float64 + Array []string + } + + type Test struct { + Inner *Inner + CreatedAt *time.Time `validate:"gtecsfield=Inner.CreatedAt"` + String string `validate:"gtecsfield=Inner.String"` + Int int `validate:"gtecsfield=Inner.Int"` + Uint uint `validate:"gtecsfield=Inner.Uint"` + Float float64 `validate:"gtecsfield=Inner.Float"` + Array []string `validate:"gtecsfield=Inner.Array"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * -5) + + inner := &Inner{ + CreatedAt: &then, + String: "abcd", + Int: 13, + Uint: 13, + Float: 1.13, + Array: []string{"val1", "val2"}, + } + + test := &Test{ + Inner: inner, + CreatedAt: &now, + String: "abcde", + Int: 14, + Uint: 14, + Float: 1.14, + Array: []string{"val1", "val2", "val3"}, + } + + errs := validate.Struct(test) + Equal(t, errs, nil) + + test.CreatedAt = &then + test.String = "abcd" + test.Int = 13 + test.Uint = 13 + test.Float = 1.13 + test.Array = []string{"val1", "val2"} + + errs = validate.Struct(test) + Equal(t, errs, nil) + + before := now.Add(time.Hour * -10) + + test.CreatedAt = &before + test.String = "abc" + test.Int = 12 + test.Uint = 12 + test.Float = 1.12 + test.Array = []string{"val1"} + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.CreatedAt", "CreatedAt", "gtecsfield") + AssertError(t, errs, "Test.String", "String", "gtecsfield") + AssertError(t, errs, "Test.Int", "Int", "gtecsfield") + AssertError(t, errs, "Test.Uint", "Uint", "gtecsfield") + AssertError(t, errs, "Test.Float", "Float", "gtecsfield") + AssertError(t, errs, "Test.Array", "Array", "gtecsfield") + + errs = validate.FieldWithValue(1, "", "gtecsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtecsfield") + + errs = validate.FieldWithValue(test, now, "gtecsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtecsfield") +} + +func TestCrossStructGtFieldValidation(t *testing.T) { + + type Inner struct { + CreatedAt *time.Time + String string + Int int + Uint uint + Float float64 + Array []string + } + + type Test struct { + Inner *Inner + CreatedAt *time.Time `validate:"gtcsfield=Inner.CreatedAt"` + String string `validate:"gtcsfield=Inner.String"` + Int int `validate:"gtcsfield=Inner.Int"` + Uint uint `validate:"gtcsfield=Inner.Uint"` + Float float64 `validate:"gtcsfield=Inner.Float"` + Array []string `validate:"gtcsfield=Inner.Array"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * -5) + + inner := &Inner{ + CreatedAt: &then, + String: "abcd", + Int: 13, + Uint: 13, + Float: 1.13, + Array: []string{"val1", "val2"}, + } + + test := &Test{ + Inner: inner, + CreatedAt: &now, + String: "abcde", + Int: 14, + Uint: 14, + Float: 1.14, + Array: []string{"val1", "val2", "val3"}, + } + + errs := validate.Struct(test) + Equal(t, errs, nil) + + test.CreatedAt = &then + test.String = "abcd" + test.Int = 13 + test.Uint = 13 + test.Float = 1.13 + test.Array = []string{"val1", "val2"} + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.CreatedAt", "CreatedAt", "gtcsfield") + AssertError(t, errs, "Test.String", "String", "gtcsfield") + AssertError(t, errs, "Test.Int", "Int", "gtcsfield") + AssertError(t, errs, "Test.Uint", "Uint", "gtcsfield") + AssertError(t, errs, "Test.Float", "Float", "gtcsfield") + AssertError(t, errs, "Test.Array", "Array", "gtcsfield") + + errs = validate.FieldWithValue(1, "", "gtcsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtcsfield") + + errs = validate.FieldWithValue(test, now, "gtcsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtcsfield") +} + +func TestCrossStructNeFieldValidation(t *testing.T) { + + type Inner struct { + CreatedAt *time.Time + } + + type Test struct { + Inner *Inner + CreatedAt *time.Time `validate:"necsfield=Inner.CreatedAt"` + } + + now := time.Now().UTC() + then := now.Add(time.Hour * 5) + + inner := &Inner{ + CreatedAt: &then, + } + + test := &Test{ + Inner: inner, + CreatedAt: &now, + } + + errs := validate.Struct(test) + Equal(t, errs, nil) + + test.CreatedAt = &then + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.CreatedAt", "CreatedAt", "necsfield") + + var j uint64 + var k float64 + var j2 uint64 + var k2 float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + + s2 := "abcd" + i2 := 1 + j2 = 1 + k2 = 1.543 + arr2 := []string{"test"} + arr3 := []string{"test", "test2"} + now2 := now + + errs = validate.FieldWithValue(s, s2, "necsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "necsfield") + + errs = validate.FieldWithValue(i2, i, "necsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "necsfield") + + errs = validate.FieldWithValue(j2, j, "necsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "necsfield") + + errs = validate.FieldWithValue(k2, k, "necsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "necsfield") + + errs = validate.FieldWithValue(arr2, arr, "necsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "necsfield") + + errs = validate.FieldWithValue(now2, now, "necsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "necsfield") + + errs = validate.FieldWithValue(arr3, arr, "necsfield") + Equal(t, errs, nil) + + type SInner struct { + Name string + } + + type TStruct struct { + Inner *SInner + CreatedAt *time.Time `validate:"necsfield=Inner"` + } + + sinner := &SInner{ + Name: "NAME", + } + + test2 := &TStruct{ + Inner: sinner, + CreatedAt: &now, + } + + errs = validate.Struct(test2) + Equal(t, errs, nil) + + test2.Inner = nil + errs = validate.Struct(test2) + Equal(t, errs, nil) + + errs = validate.FieldWithValue(nil, 1, "necsfield") + Equal(t, errs, nil) +} + +func TestCrossStructEqFieldValidation(t *testing.T) { + + type Inner struct { + CreatedAt *time.Time + } + + type Test struct { + Inner *Inner + CreatedAt *time.Time `validate:"eqcsfield=Inner.CreatedAt"` + } + + now := time.Now().UTC() + + inner := &Inner{ + CreatedAt: &now, + } + + test := &Test{ + Inner: inner, + CreatedAt: &now, + } + + errs := validate.Struct(test) + Equal(t, errs, nil) + + newTime := time.Now().UTC() + test.CreatedAt = &newTime + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.CreatedAt", "CreatedAt", "eqcsfield") + + var j uint64 + var k float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + + var j2 uint64 + var k2 float64 + s2 := "abcd" + i2 := 1 + j2 = 1 + k2 = 1.543 + arr2 := []string{"test"} + arr3 := []string{"test", "test2"} + now2 := now + + errs = validate.FieldWithValue(s, s2, "eqcsfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(i2, i, "eqcsfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(j2, j, "eqcsfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(k2, k, "eqcsfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr2, arr, "eqcsfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(now2, now, "eqcsfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr3, arr, "eqcsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eqcsfield") + + type SInner struct { + Name string + } + + type TStruct struct { + Inner *SInner + CreatedAt *time.Time `validate:"eqcsfield=Inner"` + } + + sinner := &SInner{ + Name: "NAME", + } + + test2 := &TStruct{ + Inner: sinner, + CreatedAt: &now, + } + + errs = validate.Struct(test2) + NotEqual(t, errs, nil) + AssertError(t, errs, "TStruct.CreatedAt", "CreatedAt", "eqcsfield") + + test2.Inner = nil + errs = validate.Struct(test2) + NotEqual(t, errs, nil) + AssertError(t, errs, "TStruct.CreatedAt", "CreatedAt", "eqcsfield") + + errs = validate.FieldWithValue(nil, 1, "eqcsfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eqcsfield") +} + +func TestCrossNamespaceFieldValidation(t *testing.T) { + + type SliceStruct struct { + Name string + } + + type MapStruct struct { + Name string + } + + type Inner struct { + CreatedAt *time.Time + Slice []string + SliceStructs []*SliceStruct + SliceSlice [][]string + SliceSliceStruct [][]*SliceStruct + SliceMap []map[string]string + Map map[string]string + MapMap map[string]map[string]string + MapStructs map[string]*SliceStruct + MapMapStruct map[string]map[string]*SliceStruct + MapSlice map[string][]string + MapInt map[int]string + MapInt8 map[int8]string + MapInt16 map[int16]string + MapInt32 map[int32]string + MapInt64 map[int64]string + MapUint map[uint]string + MapUint8 map[uint8]string + MapUint16 map[uint16]string + MapUint32 map[uint32]string + MapUint64 map[uint64]string + MapFloat32 map[float32]string + MapFloat64 map[float64]string + MapBool map[bool]string + } + + type Test struct { + Inner *Inner + CreatedAt *time.Time + } + + now := time.Now() + + inner := &Inner{ + CreatedAt: &now, + Slice: []string{"val1", "val2", "val3"}, + SliceStructs: []*SliceStruct{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, + SliceSlice: [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}}, + SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}}, + SliceMap: []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}}, + Map: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"}, + MapStructs: map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}}, + MapMap: map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}}, + MapMapStruct: map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}}, + MapSlice: map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}}, + MapInt: map[int]string{1: "val1", 2: "val2", 3: "val3"}, + MapInt8: map[int8]string{1: "val1", 2: "val2", 3: "val3"}, + MapInt16: map[int16]string{1: "val1", 2: "val2", 3: "val3"}, + MapInt32: map[int32]string{1: "val1", 2: "val2", 3: "val3"}, + MapInt64: map[int64]string{1: "val1", 2: "val2", 3: "val3"}, + MapUint: map[uint]string{1: "val1", 2: "val2", 3: "val3"}, + MapUint8: map[uint8]string{1: "val1", 2: "val2", 3: "val3"}, + MapUint16: map[uint16]string{1: "val1", 2: "val2", 3: "val3"}, + MapUint32: map[uint32]string{1: "val1", 2: "val2", 3: "val3"}, + MapUint64: map[uint64]string{1: "val1", 2: "val2", 3: "val3"}, + MapFloat32: map[float32]string{1.01: "val1", 2.02: "val2", 3.03: "val3"}, + MapFloat64: map[float64]string{1.01: "val1", 2.02: "val2", 3.03: "val3"}, + MapBool: map[bool]string{true: "val1", false: "val2"}, + } + + test := &Test{ + Inner: inner, + CreatedAt: &now, + } + + val := reflect.ValueOf(test) + + current, kind, ok := validate.GetStructFieldOK(val, "Inner.CreatedAt") + Equal(t, ok, true) + Equal(t, kind, reflect.Struct) + tm, ok := current.Interface().(time.Time) + Equal(t, ok, true) + Equal(t, tm, now) + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.Slice[1]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.CrazyNonExistantField") + Equal(t, ok, false) + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.Slice[101]") + Equal(t, ok, false) + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.Map[key3]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val3") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapMap[key2][key2-1]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapStructs[key2].Name") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "name2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapMapStruct[key3][key3-1].Name") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "name3") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.SliceSlice[2][0]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "7") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.SliceSliceStruct[2][1].Name") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "name8") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.SliceMap[1][key5]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val5") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapSlice[key3][2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "9") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapInt[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapInt8[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapInt16[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapInt32[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapInt64[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapUint[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapUint8[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapUint16[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapUint32[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapUint64[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapFloat32[3.03]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val3") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapFloat64[2.02]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val2") + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.MapBool[true]") + Equal(t, ok, true) + Equal(t, kind, reflect.String) + Equal(t, current.String(), "val1") + + inner = &Inner{ + CreatedAt: &now, + Slice: []string{"val1", "val2", "val3"}, + SliceStructs: []*SliceStruct{{Name: "name1"}, {Name: "name2"}, nil}, + SliceSlice: [][]string{{"1", "2", "3"}, {"4", "5", "6"}, {"7", "8", "9"}}, + SliceSliceStruct: [][]*SliceStruct{{{Name: "name1"}, {Name: "name2"}, {Name: "name3"}}, {{Name: "name4"}, {Name: "name5"}, {Name: "name6"}}, {{Name: "name7"}, {Name: "name8"}, {Name: "name9"}}}, + SliceMap: []map[string]string{{"key1": "val1", "key2": "val2", "key3": "val3"}, {"key4": "val4", "key5": "val5", "key6": "val6"}}, + Map: map[string]string{"key1": "val1", "key2": "val2", "key3": "val3"}, + MapStructs: map[string]*SliceStruct{"key1": {Name: "name1"}, "key2": {Name: "name2"}, "key3": {Name: "name3"}}, + MapMap: map[string]map[string]string{"key1": {"key1-1": "val1"}, "key2": {"key2-1": "val2"}, "key3": {"key3-1": "val3"}}, + MapMapStruct: map[string]map[string]*SliceStruct{"key1": {"key1-1": {Name: "name1"}}, "key2": {"key2-1": {Name: "name2"}}, "key3": {"key3-1": {Name: "name3"}}}, + MapSlice: map[string][]string{"key1": {"1", "2", "3"}, "key2": {"4", "5", "6"}, "key3": {"7", "8", "9"}}, + } + + test = &Test{ + Inner: inner, + CreatedAt: nil, + } + + val = reflect.ValueOf(test) + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.SliceStructs[2]") + Equal(t, ok, true) + Equal(t, kind, reflect.Ptr) + Equal(t, current.String(), "<*validator.SliceStruct Value>") + Equal(t, current.IsNil(), true) + + current, kind, ok = validate.GetStructFieldOK(val, "Inner.SliceStructs[2].Name") + Equal(t, ok, false) + Equal(t, kind, reflect.Ptr) + Equal(t, current.String(), "<*validator.SliceStruct Value>") + Equal(t, current.IsNil(), true) + + PanicMatches(t, func() { validate.GetStructFieldOK(reflect.ValueOf(1), "crazyinput") }, "Invalid field namespace") +} + +func TestExistsValidation(t *testing.T) { + + jsonText := "{ \"truthiness2\": true }" + + type Thing struct { + Truthiness *bool `json:"truthiness" validate:"exists,required"` + } + + var ting Thing + + err := json.Unmarshal([]byte(jsonText), &ting) + Equal(t, err, nil) + NotEqual(t, ting, nil) + Equal(t, ting.Truthiness, nil) + + errs := validate.Struct(ting) + NotEqual(t, errs, nil) + AssertError(t, errs, "Thing.Truthiness", "Truthiness", "exists") + + jsonText = "{ \"truthiness\": true }" + + err = json.Unmarshal([]byte(jsonText), &ting) + Equal(t, err, nil) + NotEqual(t, ting, nil) + Equal(t, ting.Truthiness, true) + + errs = validate.Struct(ting) + Equal(t, errs, nil) +} + +func TestSQLValue2Validation(t *testing.T) { + + config := &Config{ + TagName: "validate", + } + + validate := New(config) + validate.RegisterCustomTypeFunc(ValidateValuerType, valuer{}, (*driver.Valuer)(nil), sql.NullString{}, sql.NullInt64{}, sql.NullBool{}, sql.NullFloat64{}) + validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) + validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1) + + val := valuer{ + Name: "", + } + + errs := validate.Field(val, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + val.Name = "Valid Name" + errs = validate.Field(val, "required") + Equal(t, errs, nil) + + val.Name = "errorme" + + PanicMatches(t, func() { validate.Field(val, "required") }, "SQL Driver Valuer error: some kind of error") + + type myValuer valuer + + myVal := valuer{ + Name: "", + } + + errs = validate.Field(myVal, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + cust := MadeUpCustomType{ + FirstName: "Joey", + LastName: "Bloggs", + } + + c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2} + + errs = validate.Struct(c) + Equal(t, errs, nil) + + c.MadeUp.FirstName = "" + c.OverriddenInt = 1 + + errs = validate.Struct(c) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 2) + AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "MadeUp", "required") + AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "gt") +} + +func TestSQLValueValidation(t *testing.T) { + + validate := New(&Config{TagName: "validate"}) + validate.RegisterCustomTypeFunc(ValidateValuerType, (*driver.Valuer)(nil), valuer{}) + validate.RegisterCustomTypeFunc(ValidateCustomType, MadeUpCustomType{}) + validate.RegisterCustomTypeFunc(OverrideIntTypeForSomeReason, 1) + + val := valuer{ + Name: "", + } + + errs := validate.Field(val, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + val.Name = "Valid Name" + errs = validate.Field(val, "required") + Equal(t, errs, nil) + + val.Name = "errorme" + + PanicMatches(t, func() { errs = validate.Field(val, "required") }, "SQL Driver Valuer error: some kind of error") + + type myValuer valuer + + myVal := valuer{ + Name: "", + } + + errs = validate.Field(myVal, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + cust := MadeUpCustomType{ + FirstName: "Joey", + LastName: "Bloggs", + } + + c := CustomMadeUpStruct{MadeUp: cust, OverriddenInt: 2} + + errs = validate.Struct(c) + Equal(t, errs, nil) + + c.MadeUp.FirstName = "" + c.OverriddenInt = 1 + + errs = validate.Struct(c) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 2) + AssertError(t, errs, "CustomMadeUpStruct.MadeUp", "MadeUp", "required") + AssertError(t, errs, "CustomMadeUpStruct.OverriddenInt", "OverriddenInt", "gt") +} + +func TestMACValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"3D:F2:C9:A6:B3:4F", true}, + {"3D-F2-C9-A6-B3:4F", false}, + {"123", false}, + {"", false}, + {"abacaba", false}, + {"00:25:96:FF:FE:12:34:56", true}, + {"0025:96FF:FE12:3456", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "mac") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d mac failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d mac failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "mac" { + t.Fatalf("Index: %d mac failed Error: %s", i, errs) + } + } + } + } +} + +func TestIPValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"10.0.0.1", true}, + {"172.16.0.1", true}, + {"192.168.0.1", true}, + {"192.168.255.254", true}, + {"192.168.255.256", false}, + {"172.16.255.254", true}, + {"172.16.256.255", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", true}, + {"2001:cdba:0:0:0:0:3257:9652", true}, + {"2001:cdba::3257:9652", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ip") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ip failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ip failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ip" { + t.Fatalf("Index: %d ip failed Error: %s", i, errs) + } + } + } + } +} + +func TestIPv6Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.1", false}, + {"172.16.0.1", false}, + {"192.168.0.1", false}, + {"192.168.255.254", false}, + {"192.168.255.256", false}, + {"172.16.255.254", false}, + {"172.16.256.255", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", true}, + {"2001:cdba:0:0:0:0:3257:9652", true}, + {"2001:cdba::3257:9652", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ipv6") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ipv6" { + t.Fatalf("Index: %d ipv6 failed Error: %s", i, errs) + } + } + } + } +} + +func TestIPv4Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.1", true}, + {"172.16.0.1", true}, + {"192.168.0.1", true}, + {"192.168.255.254", true}, + {"192.168.255.256", false}, + {"172.16.255.254", true}, + {"172.16.256.255", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652", false}, + {"2001:cdba:0:0:0:0:3257:9652", false}, + {"2001:cdba::3257:9652", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ipv4") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ipv4" { + t.Fatalf("Index: %d ipv4 failed Error: %s", i, errs) + } + } + } + } +} + +func TestCIDRValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.0/0", true}, + {"10.0.0.1/8", true}, + {"172.16.0.1/16", true}, + {"192.168.0.1/24", true}, + {"192.168.255.254/24", true}, + {"192.168.255.254/48", false}, + {"192.168.255.256/24", false}, + {"172.16.255.254/16", true}, + {"172.16.256.255/16", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true}, + {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false}, + {"2001:cdba:0:0:0:0:3257:9652/32", true}, + {"2001:cdba::3257:9652/16", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "cidr") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d cidr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d cidr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "cidr" { + t.Fatalf("Index: %d cidr failed Error: %s", i, errs) + } + } + } + } +} + +func TestCIDRv6Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.0/0", false}, + {"10.0.0.1/8", false}, + {"172.16.0.1/16", false}, + {"192.168.0.1/24", false}, + {"192.168.255.254/24", false}, + {"192.168.255.254/48", false}, + {"192.168.255.256/24", false}, + {"172.16.255.254/16", false}, + {"172.16.256.255/16", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652/64", true}, + {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false}, + {"2001:cdba:0:0:0:0:3257:9652/32", true}, + {"2001:cdba::3257:9652/16", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "cidrv6") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "cidrv6" { + t.Fatalf("Index: %d cidrv6 failed Error: %s", i, errs) + } + } + } + } +} + +func TestCIDRv4Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"10.0.0.0/0", true}, + {"10.0.0.1/8", true}, + {"172.16.0.1/16", true}, + {"192.168.0.1/24", true}, + {"192.168.255.254/24", true}, + {"192.168.255.254/48", false}, + {"192.168.255.256/24", false}, + {"172.16.255.254/16", true}, + {"172.16.256.255/16", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652/64", false}, + {"2001:cdba:0000:0000:0000:0000:3257:9652/256", false}, + {"2001:cdba:0:0:0:0:3257:9652/32", false}, + {"2001:cdba::3257:9652/16", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "cidrv4") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "cidrv4" { + t.Fatalf("Index: %d cidrv4 failed Error: %s", i, errs) + } + } + } + } +} + +func TestTCPAddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {":80", false}, + {"127.0.0.1:80", true}, + {"[::1]:80", true}, + {"256.0.0.0:1", false}, + {"[::1]", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "tcp_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "tcp_addr" { + t.Fatalf("Index: %d tcp_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestTCP6AddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {":80", false}, + {"127.0.0.1:80", false}, + {"[::1]:80", true}, + {"256.0.0.0:1", false}, + {"[::1]", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "tcp6_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "tcp6_addr" { + t.Fatalf("Index: %d tcp6_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestTCP4AddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {":80", false}, + {"127.0.0.1:80", true}, + {"[::1]:80", false}, // https://github.com/golang/go/issues/14037 + {"256.0.0.0:1", false}, + {"[::1]", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "tcp4_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Log(test.param, IsEqual(errs, nil)) + t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "tcp4_addr" { + t.Fatalf("Index: %d tcp4_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestUDPAddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {":80", false}, + {"127.0.0.1:80", true}, + {"[::1]:80", true}, + {"256.0.0.0:1", false}, + {"[::1]", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "udp_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "udp_addr" { + t.Fatalf("Index: %d udp_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestUDP6AddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {":80", false}, + {"127.0.0.1:80", false}, + {"[::1]:80", true}, + {"256.0.0.0:1", false}, + {"[::1]", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "udp6_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "udp6_addr" { + t.Fatalf("Index: %d udp6_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestUDP4AddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {":80", false}, + {"127.0.0.1:80", true}, + {"[::1]:80", false}, // https://github.com/golang/go/issues/14037 + {"256.0.0.0:1", false}, + {"[::1]", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "udp4_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Log(test.param, IsEqual(errs, nil)) + t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "udp4_addr" { + t.Fatalf("Index: %d udp4_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestIPAddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"127.0.0.1", true}, + {"127.0.0.1:80", false}, + {"::1", true}, + {"256.0.0.0", false}, + {"localhost", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "ip_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ip_addr" { + t.Fatalf("Index: %d ip_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestIP6AddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"127.0.0.1", false}, // https://github.com/golang/go/issues/14037 + {"127.0.0.1:80", false}, + {"::1", true}, + {"0:0:0:0:0:0:0:1", true}, + {"256.0.0.0", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "ip6_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ip6_addr" { + t.Fatalf("Index: %d ip6_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestIP4AddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"127.0.0.1", true}, + {"127.0.0.1:80", false}, + {"::1", false}, // https://github.com/golang/go/issues/14037 + {"256.0.0.0", false}, + {"localhost", false}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "ip4_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Log(test.param, IsEqual(errs, nil)) + t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ip4_addr" { + t.Fatalf("Index: %d ip4_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestUnixAddrValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", true}, + {"v.sock", true}, + } + + for i, test := range tests { + errs := validate.Field(test.param, "unix_addr") + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Log(test.param, IsEqual(errs, nil)) + t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "unix_addr" { + t.Fatalf("Index: %d unix_addr failed Error: %s", i, errs) + } + } + } + } +} + +func TestSliceMapArrayChanFuncPtrInterfaceRequiredValidation(t *testing.T) { + + var m map[string]string + + errs := validate.Field(m, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + m = map[string]string{} + errs = validate.Field(m, "required") + Equal(t, errs, nil) + + var arr [5]string + errs = validate.Field(arr, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + arr[0] = "ok" + errs = validate.Field(arr, "required") + Equal(t, errs, nil) + + var s []string + errs = validate.Field(s, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + s = []string{} + errs = validate.Field(s, "required") + Equal(t, errs, nil) + + var c chan string + errs = validate.Field(c, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + c = make(chan string) + errs = validate.Field(c, "required") + Equal(t, errs, nil) + + var tst *int + errs = validate.Field(tst, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + one := 1 + tst = &one + errs = validate.Field(tst, "required") + Equal(t, errs, nil) + + var iface interface{} + + errs = validate.Field(iface, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + errs = validate.Field(iface, "omitempty,required") + Equal(t, errs, nil) + + errs = validate.Field(iface, "") + Equal(t, errs, nil) + + var f func(string) + + errs = validate.Field(f, "required") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "required") + + f = func(name string) {} + + errs = validate.Field(f, "required") + Equal(t, errs, nil) +} + +func TestDatePtrValidationIssueValidation(t *testing.T) { + + type Test struct { + LastViewed *time.Time + Reminder *time.Time + } + + test := &Test{} + + errs := validate.Struct(test) + Equal(t, errs, nil) +} + +func TestCommaAndPipeObfuscationValidation(t *testing.T) { + s := "My Name Is, |joeybloggs|" + + errs := validate.Field(s, "excludesall=0x2C") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") + + errs = validate.Field(s, "excludesall=0x7C") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") +} + +func TestBadKeyValidation(t *testing.T) { + type Test struct { + Name string `validate:"required, "` + } + + tst := &Test{ + Name: "test", + } + + PanicMatches(t, func() { validate.Struct(tst) }, "Undefined validation function on field Name") + + type Test2 struct { + Name string `validate:"required,,len=2"` + } + + tst2 := &Test2{ + Name: "test", + } + + PanicMatches(t, func() { validate.Struct(tst2) }, "Invalid validation tag on field Name") +} + +func TestInterfaceErrValidation(t *testing.T) { + + var v1 interface{} + var v2 interface{} + + v2 = 1 + v1 = v2 + + errs := validate.Field(v1, "len=1") + Equal(t, errs, nil) + + errs = validate.Field(v2, "len=1") + Equal(t, errs, nil) + + type ExternalCMD struct { + Userid string `json:"userid"` + Action uint32 `json:"action"` + Data interface{} `json:"data,omitempty" validate:"required"` + } + + s := &ExternalCMD{ + Userid: "123456", + Action: 10000, + // Data: 1, + } + + errs = validate.Struct(s) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "ExternalCMD.Data", "Data", "required") + + type ExternalCMD2 struct { + Userid string `json:"userid"` + Action uint32 `json:"action"` + Data interface{} `json:"data,omitempty" validate:"len=1"` + } + + s2 := &ExternalCMD2{ + Userid: "123456", + Action: 10000, + // Data: 1, + } + + errs = validate.Struct(s2) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "ExternalCMD2.Data", "Data", "len") + + s3 := &ExternalCMD2{ + Userid: "123456", + Action: 10000, + Data: 2, + } + + errs = validate.Struct(s3) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "ExternalCMD2.Data", "Data", "len") + + type Inner struct { + Name string `validate:"required"` + } + + inner := &Inner{ + Name: "", + } + + s4 := &ExternalCMD{ + Userid: "123456", + Action: 10000, + Data: inner, + } + + errs = validate.Struct(s4) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "ExternalCMD.Data.Name", "Name", "required") + + type TestMapStructPtr struct { + Errs map[int]interface{} `validate:"gt=0,dive,len=2"` + } + + mip := map[int]interface{}{0: &Inner{"ok"}, 3: nil, 4: &Inner{"ok"}} + + msp := &TestMapStructPtr{ + Errs: mip, + } + + errs = validate.Struct(msp) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "TestMapStructPtr.Errs[3]", "Errs[3]", "len") + + type TestMultiDimensionalStructs struct { + Errs [][]interface{} `validate:"gt=0,dive,dive"` + } + + var errStructArray [][]interface{} + + errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + errStructArray = append(errStructArray, []interface{}{&Inner{"ok"}, &Inner{""}, &Inner{""}}) + + tms := &TestMultiDimensionalStructs{ + Errs: errStructArray, + } + + errs = validate.Struct(tms) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 4) + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "required") + + type TestMultiDimensionalStructsPtr2 struct { + Errs [][]*Inner `validate:"gt=0,dive,dive,required"` + } + + var errStructPtr2Array [][]*Inner + + errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil}) + + tmsp2 := &TestMultiDimensionalStructsPtr2{ + Errs: errStructPtr2Array, + } + + errs = validate.Struct(tmsp2) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 6) + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "required") + + m := map[int]interface{}{0: "ok", 3: "", 4: "ok"} + + errs = validate.Field(m, "len=3,dive,len=2") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "[3]", "[3]", "len") + + errs = validate.Field(m, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "", "", "len") + + arr := []interface{}{"ok", "", "ok"} + + errs = validate.Field(arr, "len=3,dive,len=2") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "[1]", "[1]", "len") + + errs = validate.Field(arr, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "", "", "len") + + type MyStruct struct { + A, B string + C interface{} + } + + var a MyStruct + + a.A = "value" + a.C = "nu" + + errs = validate.Struct(a) + Equal(t, errs, nil) +} + +func TestMapDiveValidation(t *testing.T) { + + n := map[int]interface{}{0: nil} + errs := validate.Field(n, "omitempty,required") + Equal(t, errs, nil) + + m := map[int]string{0: "ok", 3: "", 4: "ok"} + + errs = validate.Field(m, "len=3,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "[3]", "[3]", "required") + + errs = validate.Field(m, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "", "", "len") + + type Inner struct { + Name string `validate:"required"` + } + + type TestMapStruct struct { + Errs map[int]Inner `validate:"gt=0,dive"` + } + + mi := map[int]Inner{0: {"ok"}, 3: {""}, 4: {"ok"}} + + ms := &TestMapStruct{ + Errs: mi, + } + + errs = validate.Struct(ms) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "TestMapStruct.Errs[3].Name", "Name", "required") + + // for full test coverage + s := fmt.Sprint(errs.Error()) + NotEqual(t, s, "") + + type TestMapTimeStruct struct { + Errs map[int]*time.Time `validate:"gt=0,dive,required"` + } + + t1 := time.Now().UTC() + + mta := map[int]*time.Time{0: &t1, 3: nil, 4: nil} + + mt := &TestMapTimeStruct{ + Errs: mta, + } + + errs = validate.Struct(mt) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 2) + AssertError(t, errs, "TestMapTimeStruct.Errs[3]", "Errs[3]", "required") + AssertError(t, errs, "TestMapTimeStruct.Errs[4]", "Errs[4]", "required") + + type TestMapStructPtr struct { + Errs map[int]*Inner `validate:"gt=0,dive,required"` + } + + mip := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}} + + msp := &TestMapStructPtr{ + Errs: mip, + } + + errs = validate.Struct(msp) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "TestMapStructPtr.Errs[3]", "Errs[3]", "required") + + type TestMapStructPtr2 struct { + Errs map[int]*Inner `validate:"gt=0,dive,omitempty,required"` + } + + mip2 := map[int]*Inner{0: {"ok"}, 3: nil, 4: {"ok"}} + + msp2 := &TestMapStructPtr2{ + Errs: mip2, + } + + errs = validate.Struct(msp2) + Equal(t, errs, nil) +} + +func TestArrayDiveValidation(t *testing.T) { + + arr := []string{"ok", "", "ok"} + + errs := validate.Field(arr, "len=3,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "[1]", "[1]", "required") + + errs = validate.Field(arr, "len=2,dive,required") + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "", "", "len") + + type BadDive struct { + Name string `validate:"dive"` + } + + bd := &BadDive{ + Name: "TEST", + } + + PanicMatches(t, func() { validate.Struct(bd) }, "dive error! can't dive on a non slice or map") + + type Test struct { + Errs []string `validate:"gt=0,dive,required"` + } + + test := &Test{ + Errs: []string{"ok", "", "ok"}, + } + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "Test.Errs[1]", "Errs[1]", "required") + + test = &Test{ + Errs: []string{"ok", "ok", ""}, + } + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 1) + AssertError(t, errs, "Test.Errs[2]", "Errs[2]", "required") + + type TestMultiDimensional struct { + Errs [][]string `validate:"gt=0,dive,dive,required"` + } + + var errArray [][]string + + errArray = append(errArray, []string{"ok", "", ""}) + errArray = append(errArray, []string{"ok", "", ""}) + + tm := &TestMultiDimensional{ + Errs: errArray, + } + + errs = validate.Struct(tm) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 4) + AssertError(t, errs, "TestMultiDimensional.Errs[0][1]", "Errs[0][1]", "required") + AssertError(t, errs, "TestMultiDimensional.Errs[0][2]", "Errs[0][2]", "required") + AssertError(t, errs, "TestMultiDimensional.Errs[1][1]", "Errs[1][1]", "required") + AssertError(t, errs, "TestMultiDimensional.Errs[1][2]", "Errs[1][2]", "required") + + type Inner struct { + Name string `validate:"required"` + } + + type TestMultiDimensionalStructs struct { + Errs [][]Inner `validate:"gt=0,dive,dive"` + } + + var errStructArray [][]Inner + + errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}}) + errStructArray = append(errStructArray, []Inner{{"ok"}, {""}, {""}}) + + tms := &TestMultiDimensionalStructs{ + Errs: errStructArray, + } + + errs = validate.Struct(tms) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 4) + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructs.Errs[1][2].Name", "Name", "required") + + type TestMultiDimensionalStructsPtr struct { + Errs [][]*Inner `validate:"gt=0,dive,dive"` + } + + var errStructPtrArray [][]*Inner + + errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}}) + errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, {""}}) + errStructPtrArray = append(errStructPtrArray, []*Inner{{"ok"}, {""}, nil}) + + tmsp := &TestMultiDimensionalStructsPtr{ + Errs: errStructPtrArray, + } + + errs = validate.Struct(tmsp) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 5) + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr.Errs[2][1].Name", "Name", "required") + + // for full test coverage + s := fmt.Sprint(errs.Error()) + NotEqual(t, s, "") + + type TestMultiDimensionalStructsPtr2 struct { + Errs [][]*Inner `validate:"gt=0,dive,dive,required"` + } + + var errStructPtr2Array [][]*Inner + + errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, {""}}) + errStructPtr2Array = append(errStructPtr2Array, []*Inner{{"ok"}, {""}, nil}) + + tmsp2 := &TestMultiDimensionalStructsPtr2{ + Errs: errStructPtr2Array, + } + + errs = validate.Struct(tmsp2) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 6) + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr2.Errs[2][2]", "Errs[2][2]", "required") + + type TestMultiDimensionalStructsPtr3 struct { + Errs [][]*Inner `validate:"gt=0,dive,dive,omitempty"` + } + + var errStructPtr3Array [][]*Inner + + errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}}) + errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, {""}}) + errStructPtr3Array = append(errStructPtr3Array, []*Inner{{"ok"}, {""}, nil}) + + tmsp3 := &TestMultiDimensionalStructsPtr3{ + Errs: errStructPtr3Array, + } + + errs = validate.Struct(tmsp3) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 5) + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[0][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][1].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[1][2].Name", "Name", "required") + AssertError(t, errs, "TestMultiDimensionalStructsPtr3.Errs[2][1].Name", "Name", "required") + + type TestMultiDimensionalTimeTime struct { + Errs [][]*time.Time `validate:"gt=0,dive,dive,required"` + } + + var errTimePtr3Array [][]*time.Time + + t1 := time.Now().UTC() + t2 := time.Now().UTC() + t3 := time.Now().UTC().Add(time.Hour * 24) + + errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, &t3}) + errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, &t2, nil}) + errTimePtr3Array = append(errTimePtr3Array, []*time.Time{&t1, nil, nil}) + + tmtp3 := &TestMultiDimensionalTimeTime{ + Errs: errTimePtr3Array, + } + + errs = validate.Struct(tmtp3) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 3) + AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[1][2]", "Errs[1][2]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][1]", "Errs[2][1]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime.Errs[2][2]", "Errs[2][2]", "required") + + type TestMultiDimensionalTimeTime2 struct { + Errs [][]*time.Time `validate:"gt=0,dive,dive,required"` + } + + var errTimeArray [][]*time.Time + + t1 = time.Now().UTC() + t2 = time.Now().UTC() + t3 = time.Now().UTC().Add(time.Hour * 24) + + errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, &t3}) + errTimeArray = append(errTimeArray, []*time.Time{&t1, &t2, nil}) + errTimeArray = append(errTimeArray, []*time.Time{&t1, nil, nil}) + + tmtp := &TestMultiDimensionalTimeTime2{ + Errs: errTimeArray, + } + + errs = validate.Struct(tmtp) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 3) + AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[1][2]", "Errs[1][2]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][1]", "Errs[2][1]", "required") + AssertError(t, errs, "TestMultiDimensionalTimeTime2.Errs[2][2]", "Errs[2][2]", "required") +} + +func TestNilStructPointerValidation(t *testing.T) { + type Inner struct { + Data string + } + + type Outer struct { + Inner *Inner `validate:"omitempty"` + } + + inner := &Inner{ + Data: "test", + } + + outer := &Outer{ + Inner: inner, + } + + errs := validate.Struct(outer) + Equal(t, errs, nil) + + outer = &Outer{ + Inner: nil, + } + + errs = validate.Struct(outer) + Equal(t, errs, nil) + + type Inner2 struct { + Data string + } + + type Outer2 struct { + Inner2 *Inner2 `validate:"required"` + } + + inner2 := &Inner2{ + Data: "test", + } + + outer2 := &Outer2{ + Inner2: inner2, + } + + errs = validate.Struct(outer2) + Equal(t, errs, nil) + + outer2 = &Outer2{ + Inner2: nil, + } + + errs = validate.Struct(outer2) + NotEqual(t, errs, nil) + AssertError(t, errs, "Outer2.Inner2", "Inner2", "required") + + type Inner3 struct { + Data string + } + + type Outer3 struct { + Inner3 *Inner3 + } + + inner3 := &Inner3{ + Data: "test", + } + + outer3 := &Outer3{ + Inner3: inner3, + } + + errs = validate.Struct(outer3) + Equal(t, errs, nil) + + type Inner4 struct { + Data string + } + + type Outer4 struct { + Inner4 *Inner4 `validate:"-"` + } + + inner4 := &Inner4{ + Data: "test", + } + + outer4 := &Outer4{ + Inner4: inner4, + } + + errs = validate.Struct(outer4) + Equal(t, errs, nil) +} + +func TestSSNValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"00-90-8787", false}, + {"66690-76", false}, + {"191 60 2869", true}, + {"191-60-2869", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ssn") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d SSN failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d SSN failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ssn" { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } + } + } +} + +func TestLongitudeValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"-180.000", true}, + {"180.1", false}, + {"+73.234", true}, + {"+382.3811", false}, + {"23.11111111", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "longitude") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d Longitude failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d Longitude failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "longitude" { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } + } + } +} + +func TestLatitudeValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"-90.000", true}, + {"+90", true}, + {"47.1231231", true}, + {"+99.9", false}, + {"108", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "latitude") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "latitude" { + t.Fatalf("Index: %d Latitude failed Error: %s", i, errs) + } + } + } + } +} + +func TestDataURIValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"data:image/png;base64,TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4=", true}, + {"data:text/plain;base64,Vml2YW11cyBmZXJtZW50dW0gc2VtcGVyIHBvcnRhLg==", true}, + {"image/gif;base64,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, + {"data:image/gif;base64,MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuMPNS1Ufof9EW/M98FNw" + + "UAKrwflsqVxaxQjBQnHQmiI7Vac40t8x7pIb8gLGV6wL7sBTJiPovJ0V7y7oc0Ye" + + "rhKh0Rm4skP2z/jHwwZICgGzBvA0rH8xlhUiTvcwDCJ0kc+fh35hNt8srZQM4619" + + "FTgB66Xmp4EtVyhpQV+t02g6NzK72oZI0vnAvqhpkxLeLiMCyrI416wHm5Tkukhx" + + "QmcL2a6hNOyu0ixX/x2kSFXApEnVrJ+/IxGyfyw8kf4N2IZpW5nEP847lpfj0SZZ" + + "Fwrd1mnfnDbYohX2zRptLy2ZUn06Qo9pkG5ntvFEPo9bfZeULtjYzIl6K8gJ2uGZ" + "HQIDAQAB", true}, + {"data:image/png;base64,12345", false}, + {"", false}, + {"data:text,:;base85,U3VzcGVuZGlzc2UgbGVjdHVzIGxlbw==", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "datauri") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d DataURI failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d DataURI failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "datauri" { + t.Fatalf("Index: %d DataURI failed Error: %s", i, errs) + } + } + } + } +} + +func TestMultibyteValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", true}, + {"abc", false}, + {"123", false}, + {"<>@;.-=", false}, + {"ひらがな・カタカナ、.漢字", true}, + {"あいうえお foobar", true}, + {"test@example.com", true}, + {"test@example.com", true}, + {"1234abcDExyz", true}, + {"カタカナ", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "multibyte") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "multibyte" { + t.Fatalf("Index: %d Multibyte failed Error: %s", i, errs) + } + } + } + } +} + +func TestPrintableASCIIValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", true}, + {"foobar", false}, + {"xyz098", false}, + {"123456", false}, + {"カタカナ", false}, + {"foobar", true}, + {"0987654321", true}, + {"test@example.com", true}, + {"1234abcDEF", true}, + {"newline\n", false}, + {"\x19test\x7F", false}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "printascii") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "printascii" { + t.Fatalf("Index: %d Printable ASCII failed Error: %s", i, errs) + } + } + } + } +} + +func TestASCIIValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", true}, + {"foobar", false}, + {"xyz098", false}, + {"123456", false}, + {"カタカナ", false}, + {"foobar", true}, + {"0987654321", true}, + {"test@example.com", true}, + {"1234abcDEF", true}, + {"", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "ascii") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ASCII failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ASCII failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "ascii" { + t.Fatalf("Index: %d ASCII failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUID5Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"9c858901-8a57-4791-81fe-4c455b099bc9", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"987fbc97-4bed-5078-af07-9141ba07c9f3", true}, + {"987fbc97-4bed-5078-9f07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid5") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "uuid5" { + t.Fatalf("Index: %d UUID5 failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUID4Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-5078-af07-9141ba07c9f3", false}, + {"934859", false}, + {"57b73598-8764-4ad0-a76a-679bb6640eb1", true}, + {"625e63f3-58f5-40b7-83a1-a72ad31acffb", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid4") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "uuid4" { + t.Fatalf("Index: %d UUID4 failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUID3Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"412452646", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-4078-8f07-9141ba07c9f3", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid3") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "uuid3" { + t.Fatalf("Index: %d UUID3 failed Error: %s", i, errs) + } + } + } + } +} + +func TestUUIDValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"xxxa987fbc9-4bed-3078-cf07-9141ba07c9f3", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3xxx", false}, + {"a987fbc94bed3078cf079141ba07c9f3", false}, + {"934859", false}, + {"987fbc9-4bed-3078-cf07a-9141ba07c9f3", false}, + {"aaaaaaaa-1111-1111-aaag-111111111111", false}, + {"a987fbc9-4bed-3078-cf07-9141ba07c9f3", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "uuid") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d UUID failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "uuid" { + t.Fatalf("Index: %d UUID failed Error: %s", i, errs) + } + } + } + } +} + +func TestISBNValidation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"foo", false}, + {"3836221195", true}, + {"1-61729-085-8", true}, + {"3 423 21412 0", true}, + {"3 401 01319 X", true}, + {"9784873113685", true}, + {"978-4-87311-368-5", true}, + {"978 3401013190", true}, + {"978-3-8362-2119-1", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "isbn") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ISBN failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ISBN failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "isbn" { + t.Fatalf("Index: %d ISBN failed Error: %s", i, errs) + } + } + } + } +} + +func TestISBN13Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"foo", false}, + {"3-8362-2119-5", false}, + {"01234567890ab", false}, + {"978 3 8362 2119 0", false}, + {"9784873113685", true}, + {"978-4-87311-368-5", true}, + {"978 3401013190", true}, + {"978-3-8362-2119-1", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "isbn13") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "isbn13" { + t.Fatalf("Index: %d ISBN13 failed Error: %s", i, errs) + } + } + } + } +} + +func TestISBN10Validation(t *testing.T) { + tests := []struct { + param string + expected bool + }{ + {"", false}, + {"foo", false}, + {"3423214121", false}, + {"978-3836221191", false}, + {"3-423-21412-1", false}, + {"3 423 21412 1", false}, + {"3836221195", true}, + {"1-61729-085-8", true}, + {"3 423 21412 0", true}, + {"3 401 01319 X", true}, + } + + for i, test := range tests { + + errs := validate.Field(test.param, "isbn10") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "isbn10" { + t.Fatalf("Index: %d ISBN10 failed Error: %s", i, errs) + } + } + } + } +} + +func TestExcludesRuneValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"excludesrune=☻"` + Tag string + ExpectedNil bool + }{ + {Value: "a☺b☻c☹d", Tag: "excludesrune=☻", ExpectedNil: false}, + {Value: "abcd", Tag: "excludesrune=☻", ExpectedNil: true}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestExcludesAllValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"excludesall=@!{}[]"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "excludesall=@!{}[]", ExpectedNil: false}, + {Value: "abcdefg", Tag: "excludesall=@!{}[]", ExpectedNil: true}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } + + username := "joeybloggs " + + errs := validate.Field(username, "excludesall=@ ") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") + + excluded := "," + + errs = validate.Field(excluded, "excludesall=!@#$%^&*()_+.0x2C?") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") + + excluded = "=" + + errs = validate.Field(excluded, "excludesall=!@#$%^&*()_+.0x2C=?") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "excludesall") +} + +func TestExcludesValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"excludes=@"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "excludes=@", ExpectedNil: false}, + {Value: "abcdq!jfk", Tag: "excludes=@", ExpectedNil: true}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestContainsRuneValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"containsrune=☻"` + Tag string + ExpectedNil bool + }{ + {Value: "a☺b☻c☹d", Tag: "containsrune=☻", ExpectedNil: true}, + {Value: "abcd", Tag: "containsrune=☻", ExpectedNil: false}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestContainsAnyValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"containsany=@!{}[]"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "containsany=@!{}[]", ExpectedNil: true}, + {Value: "abcdefg", Tag: "containsany=@!{}[]", ExpectedNil: false}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestContainsValidation(t *testing.T) { + + tests := []struct { + Value string `validate:"contains=@"` + Tag string + ExpectedNil bool + }{ + {Value: "abcd@!jfk", Tag: "contains=@", ExpectedNil: true}, + {Value: "abcdq!jfk", Tag: "contains=@", ExpectedNil: false}, + } + + for i, s := range tests { + errs := validate.Field(s.Value, s.Tag) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + + errs = validate.Struct(s) + + if (s.ExpectedNil && errs != nil) || (!s.ExpectedNil && errs == nil) { + t.Fatalf("Index: %d failed Error: %s", i, errs) + } + } +} + +func TestIsNeFieldValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + now := time.Now().UTC() + + var j2 uint64 + var k2 float64 + s2 := "abcdef" + i2 := 3 + j2 = 2 + k2 = 1.5434456 + arr2 := []string{"test", "test2"} + arr3 := []string{"test"} + now2 := now + + errs := validate.FieldWithValue(s, s2, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(i2, i, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(j2, j, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(k2, k, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr2, arr, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(now2, now, "nefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "nefield") + + errs = validate.FieldWithValue(arr3, arr, "nefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "nefield") + + type Test struct { + Start *time.Time `validate:"nefield=End"` + End *time.Time + } + + sv := &Test{ + Start: &now, + End: &now, + } + + errs = validate.Struct(sv) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Start", "Start", "nefield") + + now3 := time.Now().UTC() + + sv = &Test{ + Start: &now, + End: &now3, + } + + errs = validate.Struct(sv) + Equal(t, errs, nil) + + errs = validate.FieldWithValue(nil, 1, "nefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(sv, now, "nefield") + Equal(t, errs, nil) + + type Test2 struct { + Start *time.Time `validate:"nefield=NonExistantField"` + End *time.Time + } + + sv2 := &Test2{ + Start: &now, + End: &now, + } + + errs = validate.Struct(sv2) + Equal(t, errs, nil) +} + +func TestIsNeValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcdef" + i := 3 + j = 2 + k = 1.5434 + arr := []string{"test"} + now := time.Now().UTC() + + errs := validate.Field(s, "ne=abcd") + Equal(t, errs, nil) + + errs = validate.Field(i, "ne=1") + Equal(t, errs, nil) + + errs = validate.Field(j, "ne=1") + Equal(t, errs, nil) + + errs = validate.Field(k, "ne=1.543") + Equal(t, errs, nil) + + errs = validate.Field(arr, "ne=2") + Equal(t, errs, nil) + + errs = validate.Field(arr, "ne=1") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ne") + + PanicMatches(t, func() { validate.Field(now, "ne=now") }, "Bad field type time.Time") +} + +func TestIsEqFieldValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + now := time.Now().UTC() + + var j2 uint64 + var k2 float64 + s2 := "abcd" + i2 := 1 + j2 = 1 + k2 = 1.543 + arr2 := []string{"test"} + arr3 := []string{"test", "test2"} + now2 := now + + errs := validate.FieldWithValue(s, s2, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(i2, i, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(j2, j, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(k2, k, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr2, arr, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(now2, now, "eqfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(arr3, arr, "eqfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eqfield") + + type Test struct { + Start *time.Time `validate:"eqfield=End"` + End *time.Time + } + + sv := &Test{ + Start: &now, + End: &now, + } + + errs = validate.Struct(sv) + Equal(t, errs, nil) + + now3 := time.Now().UTC() + + sv = &Test{ + Start: &now, + End: &now3, + } + + errs = validate.Struct(sv) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Start", "Start", "eqfield") + + errs = validate.FieldWithValue(nil, 1, "eqfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eqfield") + + channel := make(chan string) + errs = validate.FieldWithValue(5, channel, "eqfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eqfield") + + errs = validate.FieldWithValue(5, now, "eqfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eqfield") + + type Test2 struct { + Start *time.Time `validate:"eqfield=NonExistantField"` + End *time.Time + } + + sv2 := &Test2{ + Start: &now, + End: &now, + } + + errs = validate.Struct(sv2) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test2.Start", "Start", "eqfield") + + type Inner struct { + Name string + } + + type TStruct struct { + Inner *Inner + CreatedAt *time.Time `validate:"eqfield=Inner"` + } + + inner := &Inner{ + Name: "NAME", + } + + test := &TStruct{ + Inner: inner, + CreatedAt: &now, + } + + errs = validate.Struct(test) + NotEqual(t, errs, nil) + AssertError(t, errs, "TStruct.CreatedAt", "CreatedAt", "eqfield") +} + +func TestIsEqValidation(t *testing.T) { + + var j uint64 + var k float64 + s := "abcd" + i := 1 + j = 1 + k = 1.543 + arr := []string{"test"} + now := time.Now().UTC() + + errs := validate.Field(s, "eq=abcd") + Equal(t, errs, nil) + + errs = validate.Field(i, "eq=1") + Equal(t, errs, nil) + + errs = validate.Field(j, "eq=1") + Equal(t, errs, nil) + + errs = validate.Field(k, "eq=1.543") + Equal(t, errs, nil) + + errs = validate.Field(arr, "eq=1") + Equal(t, errs, nil) + + errs = validate.Field(arr, "eq=2") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "eq") + + PanicMatches(t, func() { validate.Field(now, "eq=now") }, "Bad field type time.Time") +} + +func TestBase64Validation(t *testing.T) { + + s := "dW5pY29ybg==" + + errs := validate.Field(s, "base64") + Equal(t, errs, nil) + + s = "dGhpIGlzIGEgdGVzdCBiYXNlNjQ=" + errs = validate.Field(s, "base64") + Equal(t, errs, nil) + + s = "" + errs = validate.Field(s, "base64") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "base64") + + s = "dW5pY29ybg== foo bar" + errs = validate.Field(s, "base64") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "base64") +} + +func TestNoStructLevelValidation(t *testing.T) { + + type Inner struct { + Test string `validate:"len=5"` + } + + type Outer struct { + InnerStruct *Inner `validate:"required,nostructlevel"` + } + + outer := &Outer{ + InnerStruct: nil, + } + + errs := validate.Struct(outer) + NotEqual(t, errs, nil) + AssertError(t, errs, "Outer.InnerStruct", "InnerStruct", "required") + + inner := &Inner{ + Test: "1234", + } + + outer = &Outer{ + InnerStruct: inner, + } + + errs = validate.Struct(outer) + Equal(t, errs, nil) +} + +func TestStructOnlyValidation(t *testing.T) { + + type Inner struct { + Test string `validate:"len=5"` + } + + type Outer struct { + InnerStruct *Inner `validate:"required,structonly"` + } + + outer := &Outer{ + InnerStruct: nil, + } + + errs := validate.Struct(outer) + NotEqual(t, errs, nil) + AssertError(t, errs, "Outer.InnerStruct", "InnerStruct", "required") + + inner := &Inner{ + Test: "1234", + } + + outer = &Outer{ + InnerStruct: inner, + } + + errs = validate.Struct(outer) + Equal(t, errs, nil) +} + +func TestGtField(t *testing.T) { + + type TimeTest struct { + Start *time.Time `validate:"required,gt"` + End *time.Time `validate:"required,gt,gtfield=Start"` + } + + now := time.Now() + start := now.Add(time.Hour * 24) + end := start.Add(time.Hour * 24) + + timeTest := &TimeTest{ + Start: &start, + End: &end, + } + + errs := validate.Struct(timeTest) + Equal(t, errs, nil) + + timeTest = &TimeTest{ + Start: &end, + End: &start, + } + + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.End", "End", "gtfield") + + errs = validate.FieldWithValue(&start, &end, "gtfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(&end, &start, "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") + + errs = validate.FieldWithValue(&timeTest, &end, "gtfield") + NotEqual(t, errs, nil) + + errs = validate.FieldWithValue("test", "test bigger", "gtfield") + Equal(t, errs, nil) + + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,gtfield=Val1"` + } + + intTest := &IntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(intTest) + Equal(t, errs, nil) + + intTest = &IntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "gtfield") + + errs = validate.FieldWithValue(int(1), int(5), "gtfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(int(5), int(1), "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") + + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,gtfield=Val1"` + } + + uIntTest := &UIntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) + + uIntTest = &UIntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "gtfield") + + errs = validate.FieldWithValue(uint(1), uint(5), "gtfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(uint(5), uint(1), "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") + + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,gtfield=Val1"` + } + + floatTest := &FloatTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(floatTest) + Equal(t, errs, nil) + + floatTest = &FloatTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "gtfield") + + errs = validate.FieldWithValue(float32(1), float32(5), "gtfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(float32(5), float32(1), "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") + + errs = validate.FieldWithValue(nil, 1, "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") + + errs = validate.FieldWithValue(5, "T", "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") + + errs = validate.FieldWithValue(5, start, "gtfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtfield") + + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,gtfield=NonExistantField"` + } + + timeTest2 := &TimeTest2{ + Start: &start, + End: &end, + } + + errs = validate.Struct(timeTest2) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest2.End", "End", "gtfield") +} + +func TestLtField(t *testing.T) { + + type TimeTest struct { + Start *time.Time `validate:"required,lt,ltfield=End"` + End *time.Time `validate:"required,lt"` + } + + now := time.Now() + start := now.Add(time.Hour * 24 * -1 * 2) + end := start.Add(time.Hour * 24) + + timeTest := &TimeTest{ + Start: &start, + End: &end, + } + + errs := validate.Struct(timeTest) + Equal(t, errs, nil) + + timeTest = &TimeTest{ + Start: &end, + End: &start, + } + + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.Start", "Start", "ltfield") + + errs = validate.FieldWithValue(&end, &start, "ltfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(&start, &end, "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + errs = validate.FieldWithValue(timeTest, &end, "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + errs = validate.FieldWithValue("test", "tes", "ltfield") + Equal(t, errs, nil) + + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,ltfield=Val1"` + } + + intTest := &IntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(intTest) + Equal(t, errs, nil) + + intTest = &IntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "ltfield") + + errs = validate.FieldWithValue(int(5), int(1), "ltfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(int(1), int(5), "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,ltfield=Val1"` + } + + uIntTest := &UIntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) + + uIntTest = &UIntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "ltfield") + + errs = validate.FieldWithValue(uint(5), uint(1), "ltfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(uint(1), uint(5), "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,ltfield=Val1"` + } + + floatTest := &FloatTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(floatTest) + Equal(t, errs, nil) + + floatTest = &FloatTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "ltfield") + + errs = validate.FieldWithValue(float32(5), float32(1), "ltfield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(float32(1), float32(5), "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + errs = validate.FieldWithValue(nil, 5, "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + errs = validate.FieldWithValue(1, "T", "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + errs = validate.FieldWithValue(1, end, "ltfield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltfield") + + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,ltfield=NonExistantField"` + } + + timeTest2 := &TimeTest2{ + Start: &end, + End: &start, + } + + errs = validate.Struct(timeTest2) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest2.End", "End", "ltfield") +} + +func TestLteField(t *testing.T) { + + type TimeTest struct { + Start *time.Time `validate:"required,lte,ltefield=End"` + End *time.Time `validate:"required,lte"` + } + + now := time.Now() + start := now.Add(time.Hour * 24 * -1 * 2) + end := start.Add(time.Hour * 24) + + timeTest := &TimeTest{ + Start: &start, + End: &end, + } + + errs := validate.Struct(timeTest) + Equal(t, errs, nil) + + timeTest = &TimeTest{ + Start: &end, + End: &start, + } + + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.Start", "Start", "ltefield") + + errs = validate.FieldWithValue(&end, &start, "ltefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(&start, &end, "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + errs = validate.FieldWithValue(timeTest, &end, "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + errs = validate.FieldWithValue("test", "tes", "ltefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue("test", "test", "ltefield") + Equal(t, errs, nil) + + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,ltefield=Val1"` + } + + intTest := &IntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(intTest) + Equal(t, errs, nil) + + intTest = &IntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "ltefield") + + errs = validate.FieldWithValue(int(5), int(1), "ltefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(int(1), int(5), "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,ltefield=Val1"` + } + + uIntTest := &UIntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) + + uIntTest = &UIntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "ltefield") + + errs = validate.FieldWithValue(uint(5), uint(1), "ltefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(uint(1), uint(5), "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,ltefield=Val1"` + } + + floatTest := &FloatTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(floatTest) + Equal(t, errs, nil) + + floatTest = &FloatTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "ltefield") + + errs = validate.FieldWithValue(float32(5), float32(1), "ltefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(float32(1), float32(5), "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + errs = validate.FieldWithValue(nil, 5, "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + errs = validate.FieldWithValue(1, "T", "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + errs = validate.FieldWithValue(1, end, "ltefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "ltefield") + + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,ltefield=NonExistantField"` + } + + timeTest2 := &TimeTest2{ + Start: &end, + End: &start, + } + + errs = validate.Struct(timeTest2) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest2.End", "End", "ltefield") +} + +func TestGteField(t *testing.T) { + + type TimeTest struct { + Start *time.Time `validate:"required,gte"` + End *time.Time `validate:"required,gte,gtefield=Start"` + } + + now := time.Now() + start := now.Add(time.Hour * 24) + end := start.Add(time.Hour * 24) + + timeTest := &TimeTest{ + Start: &start, + End: &end, + } + + errs := validate.Struct(timeTest) + Equal(t, errs, nil) + + timeTest = &TimeTest{ + Start: &end, + End: &start, + } + + errs = validate.Struct(timeTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest.End", "End", "gtefield") + + errs = validate.FieldWithValue(&start, &end, "gtefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(&end, &start, "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + errs = validate.FieldWithValue(timeTest, &start, "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + errs = validate.FieldWithValue("test", "test", "gtefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue("test", "test bigger", "gtefield") + Equal(t, errs, nil) + + type IntTest struct { + Val1 int `validate:"required"` + Val2 int `validate:"required,gtefield=Val1"` + } + + intTest := &IntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(intTest) + Equal(t, errs, nil) + + intTest = &IntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(intTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "IntTest.Val2", "Val2", "gtefield") + + errs = validate.FieldWithValue(int(1), int(5), "gtefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(int(5), int(1), "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + type UIntTest struct { + Val1 uint `validate:"required"` + Val2 uint `validate:"required,gtefield=Val1"` + } + + uIntTest := &UIntTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(uIntTest) + Equal(t, errs, nil) + + uIntTest = &UIntTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(uIntTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "UIntTest.Val2", "Val2", "gtefield") + + errs = validate.FieldWithValue(uint(1), uint(5), "gtefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(uint(5), uint(1), "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + type FloatTest struct { + Val1 float64 `validate:"required"` + Val2 float64 `validate:"required,gtefield=Val1"` + } + + floatTest := &FloatTest{ + Val1: 1, + Val2: 5, + } + + errs = validate.Struct(floatTest) + Equal(t, errs, nil) + + floatTest = &FloatTest{ + Val1: 5, + Val2: 1, + } + + errs = validate.Struct(floatTest) + NotEqual(t, errs, nil) + AssertError(t, errs, "FloatTest.Val2", "Val2", "gtefield") + + errs = validate.FieldWithValue(float32(1), float32(5), "gtefield") + Equal(t, errs, nil) + + errs = validate.FieldWithValue(float32(5), float32(1), "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + errs = validate.FieldWithValue(nil, 1, "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + errs = validate.FieldWithValue(5, "T", "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + errs = validate.FieldWithValue(5, start, "gtefield") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gtefield") + + type TimeTest2 struct { + Start *time.Time `validate:"required"` + End *time.Time `validate:"required,gtefield=NonExistantField"` + } + + timeTest2 := &TimeTest2{ + Start: &start, + End: &end, + } + + errs = validate.Struct(timeTest2) + NotEqual(t, errs, nil) + AssertError(t, errs, "TimeTest2.End", "End", "gtefield") +} + +func TestValidateByTagAndValue(t *testing.T) { + + val := "test" + field := "test" + errs := validate.FieldWithValue(val, field, "required") + Equal(t, errs, nil) + + fn := func(v *Validate, topStruct reflect.Value, current reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + return current.String() == field.String() + } + + validate.RegisterValidation("isequaltestfunc", fn) + + errs = validate.FieldWithValue(val, field, "isequaltestfunc") + Equal(t, errs, nil) + + val = "unequal" + + errs = validate.FieldWithValue(val, field, "isequaltestfunc") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "isequaltestfunc") +} + +func TestAddFunctions(t *testing.T) { + + fn := func(v *Validate, topStruct reflect.Value, currentStruct reflect.Value, field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string) bool { + + return true + } + + config := &Config{ + TagName: "validateme", + } + + validate := New(config) + + errs := validate.RegisterValidation("new", fn) + Equal(t, errs, nil) + + errs = validate.RegisterValidation("", fn) + NotEqual(t, errs, nil) + + validate.RegisterValidation("new", nil) + NotEqual(t, errs, nil) + + errs = validate.RegisterValidation("new", fn) + Equal(t, errs, nil) + + PanicMatches(t, func() { validate.RegisterValidation("dive", fn) }, "Tag 'dive' either contains restricted characters or is the same as a restricted tag needed for normal operation") +} + +func TestChangeTag(t *testing.T) { + + config := &Config{ + TagName: "val", + } + validate := New(config) + + type Test struct { + Name string `val:"len=4"` + } + s := &Test{ + Name: "TEST", + } + + errs := validate.Struct(s) + Equal(t, errs, nil) +} + +func TestUnexposedStruct(t *testing.T) { + + type Test struct { + Name string + unexposed struct { + A string `validate:"required"` + } + } + + s := &Test{ + Name: "TEST", + } + + errs := validate.Struct(s) + Equal(t, errs, nil) +} + +func TestBadParams(t *testing.T) { + + i := 1 + errs := validate.Field(i, "-") + Equal(t, errs, nil) + + PanicMatches(t, func() { validate.Field(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax") + PanicMatches(t, func() { validate.Field(i, "len=a") }, "strconv.ParseInt: parsing \"a\": invalid syntax") + + var ui uint = 1 + PanicMatches(t, func() { validate.Field(ui, "len=a") }, "strconv.ParseUint: parsing \"a\": invalid syntax") + + f := 1.23 + PanicMatches(t, func() { validate.Field(f, "len=a") }, "strconv.ParseFloat: parsing \"a\": invalid syntax") +} + +func TestLength(t *testing.T) { + + i := true + PanicMatches(t, func() { validate.Field(i, "len") }, "Bad field type bool") +} + +func TestIsGt(t *testing.T) { + + myMap := map[string]string{} + errs := validate.Field(myMap, "gt=0") + NotEqual(t, errs, nil) + + f := 1.23 + errs = validate.Field(f, "gt=5") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gt") + + var ui uint = 5 + errs = validate.Field(ui, "gt=10") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gt") + + i := true + PanicMatches(t, func() { validate.Field(i, "gt") }, "Bad field type bool") + + tm := time.Now().UTC() + tm = tm.Add(time.Hour * 24) + + errs = validate.Field(tm, "gt") + Equal(t, errs, nil) + + t2 := time.Now().UTC() + + errs = validate.Field(t2, "gt") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gt") + + type Test struct { + Now *time.Time `validate:"gt"` + } + s := &Test{ + Now: &tm, + } + + errs = validate.Struct(s) + Equal(t, errs, nil) + + s = &Test{ + Now: &t2, + } + + errs = validate.Struct(s) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Now", "Now", "gt") +} + +func TestIsGte(t *testing.T) { + + i := true + PanicMatches(t, func() { validate.Field(i, "gte") }, "Bad field type bool") + + t1 := time.Now().UTC() + t1 = t1.Add(time.Hour * 24) + + errs := validate.Field(t1, "gte") + Equal(t, errs, nil) + + t2 := time.Now().UTC() + + errs = validate.Field(t2, "gte") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "gte") + + type Test struct { + Now *time.Time `validate:"gte"` + } + s := &Test{ + Now: &t1, + } + + errs = validate.Struct(s) + Equal(t, errs, nil) + + s = &Test{ + Now: &t2, + } + + errs = validate.Struct(s) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Now", "Now", "gte") +} + +func TestIsLt(t *testing.T) { + + myMap := map[string]string{} + errs := validate.Field(myMap, "lt=0") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") + + f := 1.23 + errs = validate.Field(f, "lt=0") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") + + var ui uint = 5 + errs = validate.Field(ui, "lt=0") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") + + i := true + PanicMatches(t, func() { validate.Field(i, "lt") }, "Bad field type bool") + + t1 := time.Now().UTC() + + errs = validate.Field(t1, "lt") + Equal(t, errs, nil) + + t2 := time.Now().UTC() + t2 = t2.Add(time.Hour * 24) + + errs = validate.Field(t2, "lt") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lt") + + type Test struct { + Now *time.Time `validate:"lt"` + } + + s := &Test{ + Now: &t1, + } + + errs = validate.Struct(s) + Equal(t, errs, nil) + + s = &Test{ + Now: &t2, + } + + errs = validate.Struct(s) + NotEqual(t, errs, nil) + AssertError(t, errs, "Test.Now", "Now", "lt") +} + +func TestIsLte(t *testing.T) { + + i := true + PanicMatches(t, func() { validate.Field(i, "lte") }, "Bad field type bool") + + t1 := time.Now().UTC() + + errs := validate.Field(t1, "lte") + Equal(t, errs, nil) + + t2 := time.Now().UTC() + t2 = t2.Add(time.Hour * 24) + + errs = validate.Field(t2, "lte") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "lte") + + type Test struct { + Now *time.Time `validate:"lte"` + } + + s := &Test{ + Now: &t1, + } + + errs = validate.Struct(s) + Equal(t, errs, nil) + + s = &Test{ + Now: &t2, + } + + errs = validate.Struct(s) + NotEqual(t, errs, nil) +} + +func TestUrl(t *testing.T) { + + var tests = []struct { + param string + expected bool + }{ + {"http://foo.bar#com", true}, + {"http://foobar.com", true}, + {"https://foobar.com", true}, + {"foobar.com", false}, + {"http://foobar.coffee/", true}, + {"http://foobar.中文网/", true}, + {"http://foobar.org/", true}, + {"http://foobar.org:8080/", true}, + {"ftp://foobar.ru/", true}, + {"http://user:pass@www.foobar.com/", true}, + {"http://127.0.0.1/", true}, + {"http://duckduckgo.com/?q=%2F", true}, + {"http://localhost:3000/", true}, + {"http://foobar.com/?foo=bar#baz=qux", true}, + {"http://foobar.com?foo=bar", true}, + {"http://www.xn--froschgrn-x9a.net/", true}, + {"", false}, + {"xyz://foobar.com", true}, + {"invalid.", false}, + {".com", false}, + {"rtmp://foobar.com", true}, + {"http://www.foo_bar.com/", true}, + {"http://localhost:3000/", true}, + {"http://foobar.com#baz=qux", true}, + {"http://foobar.com/t$-_.+!*\\'(),", true}, + {"http://www.foobar.com/~foobar", true}, + {"http://www.-foobar.com/", true}, + {"http://www.foo---bar.com/", true}, + {"mailto:someone@example.com", true}, + {"irc://irc.server.org/channel", true}, + {"irc://#channel@network", true}, + {"/abs/test/dir", false}, + {"./rel/test/dir", false}, + } + for i, test := range tests { + + errs := validate.Field(test.param, "url") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d URL failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d URL failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "url" { + t.Fatalf("Index: %d URL failed Error: %s", i, errs) + } + } + } + } + + i := 1 + PanicMatches(t, func() { validate.Field(i, "url") }, "Bad field type int") +} + +func TestUri(t *testing.T) { + + var tests = []struct { + param string + expected bool + }{ + {"http://foo.bar#com", true}, + {"http://foobar.com", true}, + {"https://foobar.com", true}, + {"foobar.com", false}, + {"http://foobar.coffee/", true}, + {"http://foobar.中文网/", true}, + {"http://foobar.org/", true}, + {"http://foobar.org:8080/", true}, + {"ftp://foobar.ru/", true}, + {"http://user:pass@www.foobar.com/", true}, + {"http://127.0.0.1/", true}, + {"http://duckduckgo.com/?q=%2F", true}, + {"http://localhost:3000/", true}, + {"http://foobar.com/?foo=bar#baz=qux", true}, + {"http://foobar.com?foo=bar", true}, + {"http://www.xn--froschgrn-x9a.net/", true}, + {"", false}, + {"xyz://foobar.com", true}, + {"invalid.", false}, + {".com", false}, + {"rtmp://foobar.com", true}, + {"http://www.foo_bar.com/", true}, + {"http://localhost:3000/", true}, + {"http://foobar.com#baz=qux", true}, + {"http://foobar.com/t$-_.+!*\\'(),", true}, + {"http://www.foobar.com/~foobar", true}, + {"http://www.-foobar.com/", true}, + {"http://www.foo---bar.com/", true}, + {"mailto:someone@example.com", true}, + {"irc://irc.server.org/channel", true}, + {"irc://#channel@network", true}, + {"/abs/test/dir", true}, + {"./rel/test/dir", false}, + } + for i, test := range tests { + + errs := validate.Field(test.param, "uri") + + if test.expected == true { + if !IsEqual(errs, nil) { + t.Fatalf("Index: %d URI failed Error: %s", i, errs) + } + } else { + if IsEqual(errs, nil) { + t.Fatalf("Index: %d URI failed Error: %s", i, errs) + } else { + val := errs.(ValidationErrors)[""] + if val.Tag != "uri" { + t.Fatalf("Index: %d URI failed Error: %s", i, errs) + } + } + } + } + + i := 1 + PanicMatches(t, func() { validate.Field(i, "uri") }, "Bad field type int") +} + +func TestOrTag(t *testing.T) { + s := "rgba(0,31,255,0.5)" + errs := validate.Field(s, "rgb|rgba") + Equal(t, errs, nil) + + s = "rgba(0,31,255,0.5)" + errs = validate.Field(s, "rgb|rgba|len=18") + Equal(t, errs, nil) + + s = "this ain't right" + errs = validate.Field(s, "rgb|rgba") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgb|rgba") + + s = "this ain't right" + errs = validate.Field(s, "rgb|rgba|len=10") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgb|rgba|len") + + s = "this is right" + errs = validate.Field(s, "rgb|rgba|len=13") + Equal(t, errs, nil) + + s = "" + errs = validate.Field(s, "omitempty,rgb|rgba") + Equal(t, errs, nil) + + s = "this is right, but a blank or isn't" + + PanicMatches(t, func() { validate.Field(s, "rgb||len=13") }, "Invalid validation tag on field") + PanicMatches(t, func() { validate.Field(s, "rgb|rgbaa|len=13") }, "Undefined validation function on field") +} + +func TestHsla(t *testing.T) { + + s := "hsla(360,100%,100%,1)" + errs := validate.Field(s, "hsla") + Equal(t, errs, nil) + + s = "hsla(360,100%,100%,0.5)" + errs = validate.Field(s, "hsla") + Equal(t, errs, nil) + + s = "hsla(0,0%,0%, 0)" + errs = validate.Field(s, "hsla") + Equal(t, errs, nil) + + s = "hsl(361,100%,50%,1)" + errs = validate.Field(s, "hsla") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsla") + + s = "hsl(361,100%,50%)" + errs = validate.Field(s, "hsla") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsla") + + s = "hsla(361,100%,50%)" + errs = validate.Field(s, "hsla") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsla") + + s = "hsla(360,101%,50%)" + errs = validate.Field(s, "hsla") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsla") + + s = "hsla(360,100%,101%)" + errs = validate.Field(s, "hsla") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsla") + + i := 1 + validate.Field(i, "hsla") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsla") +} + +func TestHsl(t *testing.T) { + + s := "hsl(360,100%,50%)" + errs := validate.Field(s, "hsl") + Equal(t, errs, nil) + + s = "hsl(0,0%,0%)" + errs = validate.Field(s, "hsl") + Equal(t, errs, nil) + + s = "hsl(361,100%,50%)" + errs = validate.Field(s, "hsl") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsl") + + s = "hsl(361,101%,50%)" + errs = validate.Field(s, "hsl") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsl") + + s = "hsl(361,100%,101%)" + errs = validate.Field(s, "hsl") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsl") + + s = "hsl(-10,100%,100%)" + errs = validate.Field(s, "hsl") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsl") + + i := 1 + errs = validate.Field(i, "hsl") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hsl") +} + +func TestRgba(t *testing.T) { + + s := "rgba(0,31,255,0.5)" + errs := validate.Field(s, "rgba") + Equal(t, errs, nil) + + s = "rgba(0,31,255,0.12)" + errs = validate.Field(s, "rgba") + Equal(t, errs, nil) + + s = "rgba(12%,55%,100%,0.12)" + errs = validate.Field(s, "rgba") + Equal(t, errs, nil) + + s = "rgba( 0, 31, 255, 0.5)" + errs = validate.Field(s, "rgba") + Equal(t, errs, nil) + + s = "rgba(12%,55,100%,0.12)" + errs = validate.Field(s, "rgba") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgba") + + s = "rgb(0, 31, 255)" + errs = validate.Field(s, "rgba") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgba") + + s = "rgb(1,349,275,0.5)" + errs = validate.Field(s, "rgba") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgba") + + s = "rgb(01,31,255,0.5)" + errs = validate.Field(s, "rgba") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgba") + + i := 1 + errs = validate.Field(i, "rgba") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgba") +} + +func TestRgb(t *testing.T) { + + s := "rgb(0,31,255)" + errs := validate.Field(s, "rgb") + Equal(t, errs, nil) + + s = "rgb(0, 31, 255)" + errs = validate.Field(s, "rgb") + Equal(t, errs, nil) + + s = "rgb(10%, 50%, 100%)" + errs = validate.Field(s, "rgb") + Equal(t, errs, nil) + + s = "rgb(10%, 50%, 55)" + errs = validate.Field(s, "rgb") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgb") + + s = "rgb(1,349,275)" + errs = validate.Field(s, "rgb") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgb") + + s = "rgb(01,31,255)" + errs = validate.Field(s, "rgb") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgb") + + s = "rgba(0,31,255)" + errs = validate.Field(s, "rgb") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgb") + + i := 1 + errs = validate.Field(i, "rgb") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "rgb") +} + +func TestEmail(t *testing.T) { + + s := "test@mail.com" + errs := validate.Field(s, "email") + Equal(t, errs, nil) + + s = "" + errs = validate.Field(s, "email") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "email") + + s = "test@email" + errs = validate.Field(s, "email") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "email") + + s = "test@email." + errs = validate.Field(s, "email") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "email") + + s = "@email.com" + errs = validate.Field(s, "email") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "email") + + i := true + errs = validate.Field(i, "email") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "email") +} + +func TestHexColor(t *testing.T) { + + s := "#fff" + errs := validate.Field(s, "hexcolor") + Equal(t, errs, nil) + + s = "#c2c2c2" + errs = validate.Field(s, "hexcolor") + Equal(t, errs, nil) + + s = "fff" + errs = validate.Field(s, "hexcolor") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hexcolor") + + s = "fffFF" + errs = validate.Field(s, "hexcolor") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hexcolor") + + i := true + errs = validate.Field(i, "hexcolor") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hexcolor") +} + +func TestHexadecimal(t *testing.T) { + + s := "ff0044" + errs := validate.Field(s, "hexadecimal") + Equal(t, errs, nil) + + s = "abcdefg" + errs = validate.Field(s, "hexadecimal") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hexadecimal") + + i := true + errs = validate.Field(i, "hexadecimal") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "hexadecimal") +} + +func TestNumber(t *testing.T) { + + s := "1" + errs := validate.Field(s, "number") + Equal(t, errs, nil) + + s = "+1" + errs = validate.Field(s, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") + + s = "-1" + errs = validate.Field(s, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") + + s = "1.12" + errs = validate.Field(s, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") + + s = "+1.12" + errs = validate.Field(s, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") + + s = "-1.12" + errs = validate.Field(s, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") + + s = "1." + errs = validate.Field(s, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") + + s = "1.o" + errs = validate.Field(s, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") + + i := 1 + errs = validate.Field(i, "number") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "number") +} + +func TestNumeric(t *testing.T) { + + s := "1" + errs := validate.Field(s, "numeric") + Equal(t, errs, nil) + + s = "+1" + errs = validate.Field(s, "numeric") + Equal(t, errs, nil) + + s = "-1" + errs = validate.Field(s, "numeric") + Equal(t, errs, nil) + + s = "1.12" + errs = validate.Field(s, "numeric") + Equal(t, errs, nil) + + s = "+1.12" + errs = validate.Field(s, "numeric") + Equal(t, errs, nil) + + s = "-1.12" + errs = validate.Field(s, "numeric") + Equal(t, errs, nil) + + s = "1." + errs = validate.Field(s, "numeric") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "numeric") + + s = "1.o" + errs = validate.Field(s, "numeric") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "numeric") + + i := 1 + errs = validate.Field(i, "numeric") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "numeric") +} + +func TestAlphaNumeric(t *testing.T) { + + s := "abcd123" + errs := validate.Field(s, "alphanum") + Equal(t, errs, nil) + + s = "abc!23" + errs = validate.Field(s, "alphanum") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "alphanum") + + errs = validate.Field(1, "alphanum") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "alphanum") +} + +func TestAlpha(t *testing.T) { + + s := "abcd" + errs := validate.Field(s, "alpha") + Equal(t, errs, nil) + + s = "abc1" + errs = validate.Field(s, "alpha") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "alpha") + + errs = validate.Field(1, "alpha") + NotEqual(t, errs, nil) + AssertError(t, errs, "", "", "alpha") +} + +func TestStructStringValidation(t *testing.T) { + + tSuccess := &TestString{ + Required: "Required", + Len: "length==10", + Min: "min=1", + Max: "1234567890", + MinMax: "12345", + Lt: "012345678", + Lte: "0123456789", + Gt: "01234567890", + Gte: "0123456789", + OmitEmpty: "", + Sub: &SubTest{ + Test: "1", + }, + SubIgnore: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + }{ + A: "1", + }, + Iface: &Impl{ + F: "123", + }, + } + + errs := validate.Struct(tSuccess) + Equal(t, errs, nil) + + tFail := &TestString{ + Required: "", + Len: "", + Min: "", + Max: "12345678901", + MinMax: "", + Lt: "0123456789", + Lte: "01234567890", + Gt: "1", + Gte: "1", + OmitEmpty: "12345678901", + Sub: &SubTest{ + Test: "", + }, + Anonymous: struct { + A string `validate:"required"` + }{ + A: "", + }, + Iface: &Impl{ + F: "12", + }, + } + + errs = validate.Struct(tFail) + + // Assert Top Level + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 13) + + // Assert Fields + AssertError(t, errs, "TestString.Required", "Required", "required") + AssertError(t, errs, "TestString.Len", "Len", "len") + AssertError(t, errs, "TestString.Min", "Min", "min") + AssertError(t, errs, "TestString.Max", "Max", "max") + AssertError(t, errs, "TestString.MinMax", "MinMax", "min") + AssertError(t, errs, "TestString.Lt", "Lt", "lt") + AssertError(t, errs, "TestString.Lte", "Lte", "lte") + AssertError(t, errs, "TestString.Gt", "Gt", "gt") + AssertError(t, errs, "TestString.Gte", "Gte", "gte") + AssertError(t, errs, "TestString.OmitEmpty", "OmitEmpty", "max") + + // Nested Struct Field Errs + AssertError(t, errs, "TestString.Anonymous.A", "A", "required") + AssertError(t, errs, "TestString.Sub.Test", "Test", "required") + AssertError(t, errs, "TestString.Iface.F", "F", "len") +} + +func TestStructInt32Validation(t *testing.T) { + + tSuccess := &TestInt32{ + Required: 1, + Len: 10, + Min: 1, + Max: 10, + MinMax: 5, + Lt: 9, + Lte: 10, + Gt: 11, + Gte: 10, + OmitEmpty: 0, + } + + errs := validate.Struct(tSuccess) + Equal(t, errs, nil) + + tFail := &TestInt32{ + Required: 0, + Len: 11, + Min: -1, + Max: 11, + MinMax: -1, + Lt: 10, + Lte: 11, + Gt: 10, + Gte: 9, + OmitEmpty: 11, + } + + errs = validate.Struct(tFail) + + // Assert Top Level + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 10) + + // Assert Fields + AssertError(t, errs, "TestInt32.Required", "Required", "required") + AssertError(t, errs, "TestInt32.Len", "Len", "len") + AssertError(t, errs, "TestInt32.Min", "Min", "min") + AssertError(t, errs, "TestInt32.Max", "Max", "max") + AssertError(t, errs, "TestInt32.MinMax", "MinMax", "min") + AssertError(t, errs, "TestInt32.Lt", "Lt", "lt") + AssertError(t, errs, "TestInt32.Lte", "Lte", "lte") + AssertError(t, errs, "TestInt32.Gt", "Gt", "gt") + AssertError(t, errs, "TestInt32.Gte", "Gte", "gte") + AssertError(t, errs, "TestInt32.OmitEmpty", "OmitEmpty", "max") +} + +func TestStructUint64Validation(t *testing.T) { + + tSuccess := &TestUint64{ + Required: 1, + Len: 10, + Min: 1, + Max: 10, + MinMax: 5, + OmitEmpty: 0, + } + + errs := validate.Struct(tSuccess) + Equal(t, errs, nil) + + tFail := &TestUint64{ + Required: 0, + Len: 11, + Min: 0, + Max: 11, + MinMax: 0, + OmitEmpty: 11, + } + + errs = validate.Struct(tFail) + + // Assert Top Level + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 6) + + // Assert Fields + AssertError(t, errs, "TestUint64.Required", "Required", "required") + AssertError(t, errs, "TestUint64.Len", "Len", "len") + AssertError(t, errs, "TestUint64.Min", "Min", "min") + AssertError(t, errs, "TestUint64.Max", "Max", "max") + AssertError(t, errs, "TestUint64.MinMax", "MinMax", "min") + AssertError(t, errs, "TestUint64.OmitEmpty", "OmitEmpty", "max") +} + +func TestStructFloat64Validation(t *testing.T) { + + tSuccess := &TestFloat64{ + Required: 1, + Len: 10, + Min: 1, + Max: 10, + MinMax: 5, + OmitEmpty: 0, + } + + errs := validate.Struct(tSuccess) + Equal(t, errs, nil) + + tFail := &TestFloat64{ + Required: 0, + Len: 11, + Min: 0, + Max: 11, + MinMax: 0, + OmitEmpty: 11, + } + + errs = validate.Struct(tFail) + + // Assert Top Level + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 6) + + // Assert Fields + AssertError(t, errs, "TestFloat64.Required", "Required", "required") + AssertError(t, errs, "TestFloat64.Len", "Len", "len") + AssertError(t, errs, "TestFloat64.Min", "Min", "min") + AssertError(t, errs, "TestFloat64.Max", "Max", "max") + AssertError(t, errs, "TestFloat64.MinMax", "MinMax", "min") + AssertError(t, errs, "TestFloat64.OmitEmpty", "OmitEmpty", "max") +} + +func TestStructSliceValidation(t *testing.T) { + + tSuccess := &TestSlice{ + Required: []int{1}, + Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, + Min: []int{1, 2}, + Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, + MinMax: []int{1, 2, 3, 4, 5}, + OmitEmpty: nil, + } + + errs := validate.Struct(tSuccess) + Equal(t, errs, nil) + + tFail := &TestSlice{ + Required: nil, + Len: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, + Min: []int{}, + Max: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, + MinMax: []int{}, + OmitEmpty: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1}, + } + + errs = validate.Struct(tFail) + NotEqual(t, errs, nil) + Equal(t, len(errs.(ValidationErrors)), 6) + + // Assert Field Errors + AssertError(t, errs, "TestSlice.Required", "Required", "required") + AssertError(t, errs, "TestSlice.Len", "Len", "len") + AssertError(t, errs, "TestSlice.Min", "Min", "min") + AssertError(t, errs, "TestSlice.Max", "Max", "max") + AssertError(t, errs, "TestSlice.MinMax", "MinMax", "min") + AssertError(t, errs, "TestSlice.OmitEmpty", "OmitEmpty", "max") +} + +func TestInvalidStruct(t *testing.T) { + s := &SubTest{ + Test: "1", + } + + PanicMatches(t, func() { validate.Struct(s.Test) }, "value passed for validation is not a struct") +} + +func TestInvalidValidatorFunction(t *testing.T) { + s := &SubTest{ + Test: "1", + } + + PanicMatches(t, func() { validate.Field(s.Test, "zzxxBadFunction") }, "Undefined validation function on field") +} + +func TestCustomFieldName(t *testing.T) { + type A struct { + B string `schema:"b" validate:"required"` + C string `schema:"c" validate:"required"` + D []bool `schema:"d" validate:"required"` + E string `schema:"-" validate:"required"` + } + + a := &A{} + + errs := New(&Config{TagName: "validate", FieldNameTag: "schema"}).Struct(a).(ValidationErrors) + NotEqual(t, errs, nil) + Equal(t, len(errs), 4) + Equal(t, errs["A.B"].Name, "b") + Equal(t, errs["A.C"].Name, "c") + Equal(t, errs["A.D"].Name, "d") + Equal(t, errs["A.E"].Name, "E") + + errs = New(&Config{TagName: "validate"}).Struct(a).(ValidationErrors) + NotEqual(t, errs, nil) + Equal(t, len(errs), 4) + Equal(t, errs["A.B"].Name, "B") + Equal(t, errs["A.C"].Name, "C") + Equal(t, errs["A.D"].Name, "D") + Equal(t, errs["A.E"].Name, "E") +} diff --git a/src/github.com/smira/aptly/api/api.go b/src/github.com/smira/aptly/api/api.go index cadaae6d..6b8fc26a 100644 --- a/src/github.com/smira/aptly/api/api.go +++ b/src/github.com/smira/aptly/api/api.go @@ -22,35 +22,84 @@ func apiVersion(c *gin.Context) { c.JSON(200, gin.H{"Version": aptly.Version}) } -// Periodically flushes CollectionFactory to free up memory used by collections, -// flushing caches. +const ( + ACQUIREDB = iota + RELEASEDB +) + +// Periodically flushes CollectionFactory to free up memory used by +// collections, flushing caches. If the two channels are provided, +// they are used to acquire and release the database. // // Should be run in goroutine! -func cacheFlusher() { +func cacheFlusher(requests chan int, acks chan error) { ticker := time.Tick(15 * time.Minute) for { <-ticker - // lock everything to eliminate in-progress calls - r := context.CollectionFactory().RemoteRepoCollection() - r.Lock() - defer r.Unlock() + func() { + // lock database if needed + if requests != nil { + requests <- ACQUIREDB + err := <-acks + if err != nil { + return + } + defer func() { + requests <- RELEASEDB + <-acks + }() + } - l := context.CollectionFactory().LocalRepoCollection() - l.Lock() - defer l.Unlock() + // lock everything to eliminate in-progress calls + r := context.CollectionFactory().RemoteRepoCollection() + r.Lock() + defer r.Unlock() - s := context.CollectionFactory().SnapshotCollection() - s.Lock() - defer s.Unlock() + l := context.CollectionFactory().LocalRepoCollection() + l.Lock() + defer l.Unlock() - p := context.CollectionFactory().PublishedRepoCollection() - p.Lock() - defer p.Unlock() + s := context.CollectionFactory().SnapshotCollection() + s.Lock() + defer s.Unlock() - // all collections locked, flush them - context.CollectionFactory().Flush() + p := context.CollectionFactory().PublishedRepoCollection() + p.Lock() + defer p.Unlock() + + // all collections locked, flush them + context.CollectionFactory().Flush() + }() + } +} + +// Acquire database lock and release it when not needed anymore. Two +// channels must be provided. The first one is to receive requests to +// acquire/release the database and the second one is to send acks. +// +// Should be run in a goroutine! +func acquireDatabase(requests chan int, acks chan error) { + clients := 0 + for { + request := <-requests + switch request { + case ACQUIREDB: + if clients == 0 { + acks <- context.ReOpenDatabase() + } else { + acks <- nil + } + clients++ + case RELEASEDB: + clients-- + if clients == 0 { + acks <- context.CloseDatabase() + } else { + acks <- nil + } + } } } diff --git a/src/github.com/smira/aptly/api/repos.go b/src/github.com/smira/aptly/api/repos.go index 17e5b550..6d4f4a8a 100644 --- a/src/github.com/smira/aptly/api/repos.go +++ b/src/github.com/smira/aptly/api/repos.go @@ -315,12 +315,7 @@ func apiReposPackageFromDir(c *gin.Context) { sources = []string{filepath.Join(context.UploadPath(), c.Params.ByName("dir"), c.Params.ByName("file"))} } - packageFiles, failedFiles, err = deb.CollectPackageFiles(sources, reporter) - - if err != nil { - c.Fail(500, fmt.Errorf("unable to collect package files: %s", err)) - return - } + packageFiles, failedFiles = deb.CollectPackageFiles(sources, reporter) list, err = deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), nil) if err != nil { @@ -329,7 +324,7 @@ func apiReposPackageFromDir(c *gin.Context) { } processedFiles, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(), - context.CollectionFactory().PackageCollection(), reporter) + context.CollectionFactory().PackageCollection(), reporter, nil) failedFiles = append(failedFiles, failedFiles2...) if err != nil { diff --git a/src/github.com/smira/aptly/api/router.go b/src/github.com/smira/aptly/api/router.go index 8dcd8c6e..455cca80 100644 --- a/src/github.com/smira/aptly/api/router.go +++ b/src/github.com/smira/aptly/api/router.go @@ -12,11 +12,41 @@ var context *ctx.AptlyContext func Router(c *ctx.AptlyContext) http.Handler { context = c - go cacheFlusher() - router := gin.Default() router.Use(gin.ErrorLogger()) + if context.Flags().Lookup("no-lock").Value.Get().(bool) { + // We use a goroutine to count the number of + // concurrent requests. When no more requests are + // running, we close the database to free the lock. + requests := make(chan int) + acks := make(chan error) + + go acquireDatabase(requests, acks) + go cacheFlusher(requests, acks) + + router.Use(func(c *gin.Context) { + requests <- ACQUIREDB + err := <-acks + if err != nil { + c.Fail(500, err) + return + } + defer func() { + requests <- RELEASEDB + err = <-acks + if err != nil { + c.Fail(500, err) + return + } + }() + c.Next() + }) + + } else { + go cacheFlusher(nil, nil) + } + root := router.Group("/api") { diff --git a/src/github.com/smira/aptly/aptly/version.go b/src/github.com/smira/aptly/aptly/version.go index 76cf1d57..586a4847 100644 --- a/src/github.com/smira/aptly/aptly/version.go +++ b/src/github.com/smira/aptly/aptly/version.go @@ -1,7 +1,7 @@ package aptly // Version of aptly -const Version = "0.9.5" +const Version = "0.9.6" // Enable debugging features? const EnableDebug = false diff --git a/src/github.com/smira/aptly/cmd/api_serve.go b/src/github.com/smira/aptly/cmd/api_serve.go index 6d62322e..fd4c765b 100644 --- a/src/github.com/smira/aptly/cmd/api_serve.go +++ b/src/github.com/smira/aptly/cmd/api_serve.go @@ -46,6 +46,7 @@ Example: } cmd.Flag.String("listen", ":8080", "host:port for HTTP listening") + cmd.Flag.Bool("no-lock", false, "don't lock the database") return cmd diff --git a/src/github.com/smira/aptly/cmd/cmd.go b/src/github.com/smira/aptly/cmd/cmd.go index 4bec1f74..823abe9c 100644 --- a/src/github.com/smira/aptly/cmd/cmd.go +++ b/src/github.com/smira/aptly/cmd/cmd.go @@ -2,12 +2,14 @@ package cmd import ( + "bytes" "fmt" "github.com/smira/aptly/aptly" "github.com/smira/aptly/deb" "github.com/smira/commander" "github.com/smira/flag" "os" + "text/template" "time" ) @@ -34,6 +36,32 @@ func ListPackagesRefList(reflist *deb.PackageRefList) (err error) { return } +// PrintPackageList shows package list with specified format or default representation +func PrintPackageList(result *deb.PackageList, format string) error { + if format == "" { + return result.ForEach(func(p *deb.Package) error { + context.Progress().Printf("%s\n", p) + return nil + }) + } + + formatTemplate, err := template.New("format").Parse(format) + if err != nil { + return fmt.Errorf("error parsing -format template: %s", err) + } + + return result.ForEach(func(p *deb.Package) error { + b := &bytes.Buffer{} + err = formatTemplate.Execute(b, p.ExtendedStanza()) + if err != nil { + return fmt.Errorf("error applying template: %s", err) + } + context.Progress().Printf("%s\n", b.String()) + return nil + }) + +} + // LookupOption checks boolean flag with default (usually config) and command-line // setting func LookupOption(defaultValue bool, flags *flag.FlagSet, name string) (result bool) { @@ -83,7 +111,7 @@ package environment to new version.`, cmd.Flag.Bool("dep-follow-suggests", false, "when processing dependencies, follow Suggests") cmd.Flag.Bool("dep-follow-source", false, "when processing dependencies, follow from binary to Source packages") cmd.Flag.Bool("dep-follow-recommends", false, "when processing dependencies, follow Recommends") - cmd.Flag.Bool("dep-follow-all-variants", false, "when processing dependencies, follow a & b if depdency is 'a|b'") + cmd.Flag.Bool("dep-follow-all-variants", false, "when processing dependencies, follow a & b if dependency is 'a|b'") cmd.Flag.String("architectures", "", "list of architectures to consider during (comma-separated), default to all available") cmd.Flag.String("config", "", "location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf)") diff --git a/src/github.com/smira/aptly/cmd/graph.go b/src/github.com/smira/aptly/cmd/graph.go index 552066da..eb35559f 100644 --- a/src/github.com/smira/aptly/cmd/graph.go +++ b/src/github.com/smira/aptly/cmd/graph.go @@ -4,11 +4,13 @@ import ( "bytes" "fmt" "github.com/smira/aptly/deb" + "github.com/smira/aptly/utils" "github.com/smira/commander" "io" "io/ioutil" "os" "os/exec" + "path/filepath" ) func aptlyGraph(cmd *commander.Command, args []string) error { @@ -34,9 +36,16 @@ func aptlyGraph(cmd *commander.Command, args []string) error { tempfile.Close() os.Remove(tempfile.Name()) - tempfilename := tempfile.Name() + ".png" + format := context.Flags().Lookup("format").Value.String() + output := context.Flags().Lookup("output").Value.String() - command := exec.Command("dot", "-Tpng", "-o"+tempfilename) + if filepath.Ext(output) != "" { + format = filepath.Ext(output)[1:] + } + + tempfilename := tempfile.Name() + "." + format + + command := exec.Command("dot", "-T"+format, "-o"+tempfilename) command.Stderr = os.Stderr stdin, err := command.StdinPipe() @@ -64,10 +73,18 @@ func aptlyGraph(cmd *commander.Command, args []string) error { return err } - err = exec.Command("open", tempfilename).Run() - if err != nil { - fmt.Printf("Rendered to PNG file: %s\n", tempfilename) - err = nil + if output != "" { + err = utils.CopyFile(tempfilename, output) + if err != nil { + return fmt.Errorf("unable to copy %s -> %s: %s", tempfilename, output, err) + } + _ = os.Remove(tempfilename) + + fmt.Printf("Output saved to %s\n", output) + } else { + fmt.Printf("Rendered to %s file: %s, trying to open it...\n", format, tempfilename) + + _ = exec.Command("open", tempfilename).Run() } return err @@ -89,5 +106,8 @@ Example: `, } + cmd.Flag.String("format", "png", "render graph to specified format (png, svg, pdf, etc.)") + cmd.Flag.String("output", "", "specify output filename, default is to open result in viewer") + return cmd } diff --git a/src/github.com/smira/aptly/cmd/mirror_search.go b/src/github.com/smira/aptly/cmd/mirror_search.go index 23205a33..b98dfd57 100644 --- a/src/github.com/smira/aptly/cmd/mirror_search.go +++ b/src/github.com/smira/aptly/cmd/mirror_search.go @@ -21,6 +21,7 @@ Example: } cmd.Flag.Bool("with-deps", false, "include dependencies into search results") + cmd.Flag.String("format", "", "custom format for result printing") return cmd } diff --git a/src/github.com/smira/aptly/cmd/package_search.go b/src/github.com/smira/aptly/cmd/package_search.go index 27a159cb..709e2329 100644 --- a/src/github.com/smira/aptly/cmd/package_search.go +++ b/src/github.com/smira/aptly/cmd/package_search.go @@ -2,7 +2,6 @@ package cmd import ( "fmt" - "github.com/smira/aptly/deb" "github.com/smira/aptly/query" "github.com/smira/commander" "github.com/smira/flag" @@ -25,10 +24,8 @@ func aptlyPackageSearch(cmd *commander.Command, args []string) error { return fmt.Errorf("no results") } - result.ForEach(func(p *deb.Package) error { - context.Progress().Printf("%s\n", p) - return nil - }) + format := context.Flags().Lookup("format").Value.String() + PrintPackageList(result, format) return err } @@ -48,5 +45,7 @@ Example: Flag: *flag.NewFlagSet("aptly-package-search", flag.ExitOnError), } + cmd.Flag.String("format", "", "custom format for result printing") + return cmd } diff --git a/src/github.com/smira/aptly/cmd/publish_repo.go b/src/github.com/smira/aptly/cmd/publish_repo.go index 892d7a62..a7a05cac 100644 --- a/src/github.com/smira/aptly/cmd/publish_repo.go +++ b/src/github.com/smira/aptly/cmd/publish_repo.go @@ -41,6 +41,7 @@ Example: cmd.Flag.String("passphrase-file", "", "GPG passhprase-file for the key (warning: could be insecure)") cmd.Flag.Bool("batch", false, "run GPG with detached tty") cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG") + cmd.Flag.Bool("skip-contents", false, "don't generate Contents indexes") cmd.Flag.String("origin", "", "origin name to publish") cmd.Flag.String("label", "", "label to publish") cmd.Flag.Bool("force-overwrite", false, "overwrite files in package pool in case of mismatch") diff --git a/src/github.com/smira/aptly/cmd/publish_snapshot.go b/src/github.com/smira/aptly/cmd/publish_snapshot.go index b207c5b1..a796d33b 100644 --- a/src/github.com/smira/aptly/cmd/publish_snapshot.go +++ b/src/github.com/smira/aptly/cmd/publish_snapshot.go @@ -116,8 +116,12 @@ func aptlyPublishSnapshotOrRepo(cmd *commander.Command, args []string) error { if err != nil { return fmt.Errorf("unable to publish: %s", err) } - published.Origin = cmd.Flag.Lookup("origin").Value.String() - published.Label = cmd.Flag.Lookup("label").Value.String() + published.Origin = context.Flags().Lookup("origin").Value.String() + published.Label = context.Flags().Lookup("label").Value.String() + + if context.Flags().IsSet("skip-contents") { + published.SkipContents = context.Flags().Lookup("skip-contents").Value.Get().(bool) + } duplicate := context.CollectionFactory().PublishedRepoCollection().CheckDuplicate(published) if duplicate != nil { @@ -203,6 +207,7 @@ Example: cmd.Flag.String("passphrase-file", "", "GPG passhprase-file for the key (warning: could be insecure)") cmd.Flag.Bool("batch", false, "run GPG with detached tty") cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG") + cmd.Flag.Bool("skip-contents", false, "don't generate Contents indexes") cmd.Flag.String("origin", "", "origin name to publish") cmd.Flag.String("label", "", "label to publish") cmd.Flag.Bool("force-overwrite", false, "overwrite files in package pool in case of mismatch") diff --git a/src/github.com/smira/aptly/cmd/publish_switch.go b/src/github.com/smira/aptly/cmd/publish_switch.go index ea3402d0..23b3b7b5 100644 --- a/src/github.com/smira/aptly/cmd/publish_switch.go +++ b/src/github.com/smira/aptly/cmd/publish_switch.go @@ -90,6 +90,10 @@ func aptlyPublishSwitch(cmd *commander.Command, args []string) error { "the same package pool.\n") } + if context.Flags().IsSet("skip-contents") { + published.SkipContents = context.Flags().Lookup("skip-contents").Value.Get().(bool) + } + err = published.Publish(context.PackagePool(), context, context.CollectionFactory(), signer, context.Progress(), forceOverwrite) if err != nil { return fmt.Errorf("unable to publish: %s", err) @@ -143,6 +147,7 @@ This command would switch published repository (with one component) named ppa/wh cmd.Flag.String("passphrase-file", "", "GPG passhprase-file for the key (warning: could be insecure)") cmd.Flag.Bool("batch", false, "run GPG with detached tty") cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG") + cmd.Flag.Bool("skip-contents", false, "don't generate Contents indexes") cmd.Flag.String("component", "", "component names to update (for multi-component publishing, separate components with commas)") cmd.Flag.Bool("force-overwrite", false, "overwrite files in package pool in case of mismatch") diff --git a/src/github.com/smira/aptly/cmd/publish_update.go b/src/github.com/smira/aptly/cmd/publish_update.go index 93273a45..befb2312 100644 --- a/src/github.com/smira/aptly/cmd/publish_update.go +++ b/src/github.com/smira/aptly/cmd/publish_update.go @@ -54,6 +54,10 @@ func aptlyPublishUpdate(cmd *commander.Command, args []string) error { "the same package pool.\n") } + if context.Flags().IsSet("skip-contents") { + published.SkipContents = context.Flags().Lookup("skip-contents").Value.Get().(bool) + } + err = published.Publish(context.PackagePool(), context, context.CollectionFactory(), signer, context.Progress(), forceOverwrite) if err != nil { return fmt.Errorf("unable to publish: %s", err) @@ -102,6 +106,7 @@ Example: cmd.Flag.String("passphrase-file", "", "GPG passhprase-file for the key (warning: could be insecure)") cmd.Flag.Bool("batch", false, "run GPG with detached tty") cmd.Flag.Bool("skip-signing", false, "don't sign Release files with GPG") + cmd.Flag.Bool("skip-contents", false, "don't generate Contents indexes") cmd.Flag.Bool("force-overwrite", false, "overwrite files in package pool in case of mismatch") return cmd diff --git a/src/github.com/smira/aptly/cmd/repo.go b/src/github.com/smira/aptly/cmd/repo.go index 2823a149..2f54eb55 100644 --- a/src/github.com/smira/aptly/cmd/repo.go +++ b/src/github.com/smira/aptly/cmd/repo.go @@ -21,6 +21,7 @@ func makeCmdRepo() *commander.Command { makeCmdRepoShow(), makeCmdRepoRename(), makeCmdRepoSearch(), + makeCmdRepoInclude(), }, } } diff --git a/src/github.com/smira/aptly/cmd/repo_add.go b/src/github.com/smira/aptly/cmd/repo_add.go index 7529a105..f017c65e 100644 --- a/src/github.com/smira/aptly/cmd/repo_add.go +++ b/src/github.com/smira/aptly/cmd/repo_add.go @@ -42,15 +42,12 @@ func aptlyRepoAdd(cmd *commander.Command, args []string) error { var packageFiles, failedFiles []string - packageFiles, failedFiles, err = deb.CollectPackageFiles(args[1:], &aptly.ConsoleResultReporter{Progress: context.Progress()}) - if err != nil { - return fmt.Errorf("unable to collect package files: %s", err) - } + packageFiles, failedFiles = deb.CollectPackageFiles(args[1:], &aptly.ConsoleResultReporter{Progress: context.Progress()}) var processedFiles, failedFiles2 []string processedFiles, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(), - context.CollectionFactory().PackageCollection(), &aptly.ConsoleResultReporter{Progress: context.Progress()}) + context.CollectionFactory().PackageCollection(), &aptly.ConsoleResultReporter{Progress: context.Progress()}, nil) failedFiles = append(failedFiles, failedFiles2...) if err != nil { return fmt.Errorf("unable to import package files: %s", err) diff --git a/src/github.com/smira/aptly/cmd/repo_create.go b/src/github.com/smira/aptly/cmd/repo_create.go index 67540130..e04e6b90 100644 --- a/src/github.com/smira/aptly/cmd/repo_create.go +++ b/src/github.com/smira/aptly/cmd/repo_create.go @@ -18,6 +18,14 @@ func aptlyRepoCreate(cmd *commander.Command, args []string) error { repo.DefaultDistribution = context.Flags().Lookup("distribution").Value.String() repo.DefaultComponent = context.Flags().Lookup("component").Value.String() + uploadersFile := context.Flags().Lookup("uploaders-file").Value.Get().(string) + if uploadersFile != "" { + repo.Uploaders, err = deb.NewUploadersFromFile(uploadersFile) + if err != nil { + return err + } + } + err = context.CollectionFactory().LocalRepoCollection().Add(repo) if err != nil { return fmt.Errorf("unable to add local repo: %s", err) @@ -47,6 +55,7 @@ Example: cmd.Flag.String("comment", "", "any text that would be used to described local repository") cmd.Flag.String("distribution", "", "default distribution when publishing") cmd.Flag.String("component", "main", "default component when publishing") + cmd.Flag.String("uploaders-file", "", "uploaders.json to be used when including .changes into this repository") return cmd } diff --git a/src/github.com/smira/aptly/cmd/repo_edit.go b/src/github.com/smira/aptly/cmd/repo_edit.go index 648382b7..018374b4 100644 --- a/src/github.com/smira/aptly/cmd/repo_edit.go +++ b/src/github.com/smira/aptly/cmd/repo_edit.go @@ -2,6 +2,8 @@ package cmd import ( "fmt" + "github.com/AlekSi/pointer" + "github.com/smira/aptly/deb" "github.com/smira/commander" "github.com/smira/flag" ) @@ -23,16 +25,30 @@ func aptlyRepoEdit(cmd *commander.Command, args []string) error { return fmt.Errorf("unable to edit: %s", err) } - if context.Flags().Lookup("comment").Value.String() != "" { - repo.Comment = context.Flags().Lookup("comment").Value.String() - } + var uploadersFile *string - if context.Flags().Lookup("distribution").Value.String() != "" { - repo.DefaultDistribution = context.Flags().Lookup("distribution").Value.String() - } + context.Flags().Visit(func(flag *flag.Flag) { + switch flag.Name { + case "comment": + repo.Comment = flag.Value.String() + case "distribution": + repo.DefaultDistribution = flag.Value.String() + case "component": + repo.DefaultComponent = flag.Value.String() + case "uploaders-file": + uploadersFile = pointer.ToString(flag.Value.String()) + } + }) - if context.Flags().Lookup("component").Value.String() != "" { - repo.DefaultComponent = context.Flags().Lookup("component").Value.String() + if uploadersFile != nil { + if *uploadersFile != "" { + repo.Uploaders, err = deb.NewUploadersFromFile(*uploadersFile) + if err != nil { + return err + } + } else { + repo.Uploaders = nil + } } err = context.CollectionFactory().LocalRepoCollection().Update(repo) @@ -63,6 +79,7 @@ Example: cmd.Flag.String("comment", "", "any text that would be used to described local repository") cmd.Flag.String("distribution", "", "default distribution when publishing") cmd.Flag.String("component", "", "default component when publishing") + cmd.Flag.String("uploaders-file", "", "uploaders.json to be used when including .changes into this repository") return cmd } diff --git a/src/github.com/smira/aptly/cmd/repo_include.go b/src/github.com/smira/aptly/cmd/repo_include.go new file mode 100644 index 00000000..477e99ed --- /dev/null +++ b/src/github.com/smira/aptly/cmd/repo_include.go @@ -0,0 +1,234 @@ +package cmd + +import ( + "bytes" + "fmt" + "github.com/smira/aptly/aptly" + "github.com/smira/aptly/deb" + "github.com/smira/aptly/query" + "github.com/smira/aptly/utils" + "github.com/smira/commander" + "github.com/smira/flag" + "os" + "path/filepath" + "text/template" +) + +func aptlyRepoInclude(cmd *commander.Command, args []string) error { + var err error + if len(args) < 1 { + cmd.Usage() + return commander.ErrCommandError + } + + verifier, err := getVerifier(context.Flags()) + if err != nil { + return fmt.Errorf("unable to initialize GPG verifier: %s", err) + } + + if verifier == nil { + verifier = &utils.GpgVerifier{} + } + + forceReplace := context.Flags().Lookup("force-replace").Value.Get().(bool) + acceptUnsigned := context.Flags().Lookup("accept-unsigned").Value.Get().(bool) + ignoreSignatures := context.Flags().Lookup("ignore-signatures").Value.Get().(bool) + noRemoveFiles := context.Flags().Lookup("no-remove-files").Value.Get().(bool) + + repoTemplate, err := template.New("repo").Parse(context.Flags().Lookup("repo").Value.Get().(string)) + if err != nil { + return fmt.Errorf("error parsing -repo template: %s", err) + } + + uploaders := (*deb.Uploaders)(nil) + uploadersFile := context.Flags().Lookup("uploaders-file").Value.Get().(string) + if uploadersFile != "" { + uploaders, err = deb.NewUploadersFromFile(uploadersFile) + if err != nil { + return err + } + + for i := range uploaders.Rules { + uploaders.Rules[i].CompiledCondition, err = query.Parse(uploaders.Rules[i].Condition) + if err != nil { + return fmt.Errorf("error parsing query %s: %s", uploaders.Rules[i].Condition, err) + } + } + } + + reporter := &aptly.ConsoleResultReporter{Progress: context.Progress()} + + var changesFiles, failedFiles, processedFiles []string + + changesFiles, failedFiles = deb.CollectChangesFiles(args, reporter) + + for _, path := range changesFiles { + var changes *deb.Changes + + changes, err = deb.NewChanges(path) + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", path, err) + continue + } + + err = changes.VerifyAndParse(acceptUnsigned, ignoreSignatures, verifier) + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) + changes.Cleanup() + continue + } + + err = changes.Prepare() + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) + changes.Cleanup() + continue + } + + repoName := &bytes.Buffer{} + err = repoTemplate.Execute(repoName, changes.Stanza) + if err != nil { + return fmt.Errorf("error applying template to repo: %s", err) + } + + context.Progress().Printf("Loading repository %s for changes file %s...\n", repoName.String(), changes.ChangesName) + + repo, err := context.CollectionFactory().LocalRepoCollection().ByName(repoName.String()) + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) + changes.Cleanup() + continue + } + + currentUploaders := uploaders + if repo.Uploaders != nil { + currentUploaders = repo.Uploaders + for i := range currentUploaders.Rules { + currentUploaders.Rules[i].CompiledCondition, err = query.Parse(currentUploaders.Rules[i].Condition) + if err != nil { + return fmt.Errorf("error parsing query %s: %s", currentUploaders.Rules[i].Condition, err) + } + } + } + + if currentUploaders != nil { + if err = currentUploaders.IsAllowed(changes); err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("changes file skipped due to uploaders config: %s, keys %#v: %s", + changes.ChangesName, changes.SignatureKeys, err) + changes.Cleanup() + continue + } + } + + err = context.CollectionFactory().LocalRepoCollection().LoadComplete(repo) + if err != nil { + return fmt.Errorf("unable to load repo: %s", err) + } + + list, err := deb.NewPackageListFromRefList(repo.RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) + if err != nil { + return fmt.Errorf("unable to load packages: %s", err) + } + + packageFiles, _ := deb.CollectPackageFiles([]string{changes.TempDir}, reporter) + + var restriction deb.PackageQuery + + restriction, err = changes.PackageQuery() + if err != nil { + failedFiles = append(failedFiles, path) + reporter.Warning("unable to process file %s: %s", changes.ChangesName, err) + changes.Cleanup() + continue + } + + var processedFiles2, failedFiles2 []string + + processedFiles2, failedFiles2, err = deb.ImportPackageFiles(list, packageFiles, forceReplace, verifier, context.PackagePool(), + context.CollectionFactory().PackageCollection(), reporter, restriction) + + if err != nil { + return fmt.Errorf("unable to import package files: %s", err) + } + + repo.UpdateRefList(deb.NewPackageRefListFromPackageList(list)) + + err = context.CollectionFactory().LocalRepoCollection().Update(repo) + if err != nil { + return fmt.Errorf("unable to save: %s", err) + } + + err = changes.Cleanup() + if err != nil { + return err + } + + for _, file := range failedFiles2 { + failedFiles = append(failedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) + } + + for _, file := range processedFiles2 { + processedFiles = append(processedFiles, filepath.Join(changes.BasePath, filepath.Base(file))) + } + + processedFiles = append(processedFiles, path) + } + + if !noRemoveFiles { + processedFiles = utils.StrSliceDeduplicate(processedFiles) + + for _, file := range processedFiles { + err := os.Remove(file) + if err != nil { + return fmt.Errorf("unable to remove file: %s", err) + } + } + } + + if len(failedFiles) > 0 { + context.Progress().ColoredPrintf("@y[!]@| @!Some files were skipped due to errors:@|") + for _, file := range failedFiles { + context.Progress().ColoredPrintf(" %s", file) + } + + return fmt.Errorf("some files failed to be added") + } + + return err +} + +func makeCmdRepoInclude() *commander.Command { + cmd := &commander.Command{ + Run: aptlyRepoInclude, + UsageLine: "include | ...", + Short: "add packages to local repositories based on .changes files", + Long: ` +Command include looks for .changes files in list of arguments or specified directories. Each +.changes file is verified, parsed, referenced files are put into separate temporary directory +and added into local repository. Successfully imported files are removed by default. + +Additionally uploads could be restricted with file. Rules in this file control +uploads based on GPG key ID of .changes file signature and queries on .changes file fields. + +Example: + + $ aptly repo include -repo=foo-release incoming/ +`, + Flag: *flag.NewFlagSet("aptly-repo-include", flag.ExitOnError), + } + + cmd.Flag.Bool("no-remove-files", false, "don't remove files that have been imported successfully into repository") + cmd.Flag.Bool("force-replace", false, "when adding package that conflicts with existing package, remove existing package") + cmd.Flag.String("repo", "{{.Distribution}}", "which repo should files go to, defaults to Distribution field of .changes file") + cmd.Flag.Var(&keyRingsFlag{}, "keyring", "gpg keyring to use when verifying Release file (could be specified multiple times)") + cmd.Flag.Bool("ignore-signatures", false, "disable verification of .changes file signature") + cmd.Flag.Bool("accept-unsigned", false, "accept unsigned .changes files") + cmd.Flag.String("uploaders-file", "", "path to uploaders.json file") + + return cmd +} diff --git a/src/github.com/smira/aptly/cmd/repo_search.go b/src/github.com/smira/aptly/cmd/repo_search.go index e681a339..de613fbf 100644 --- a/src/github.com/smira/aptly/cmd/repo_search.go +++ b/src/github.com/smira/aptly/cmd/repo_search.go @@ -21,6 +21,7 @@ Example: } cmd.Flag.Bool("with-deps", false, "include dependencies into search results") + cmd.Flag.String("format", "", "custom format for result printing") return cmd } diff --git a/src/github.com/smira/aptly/cmd/repo_show.go b/src/github.com/smira/aptly/cmd/repo_show.go index a6ee9804..89a599db 100644 --- a/src/github.com/smira/aptly/cmd/repo_show.go +++ b/src/github.com/smira/aptly/cmd/repo_show.go @@ -29,6 +29,9 @@ func aptlyRepoShow(cmd *commander.Command, args []string) error { fmt.Printf("Comment: %s\n", repo.Comment) fmt.Printf("Default Distribution: %s\n", repo.DefaultDistribution) fmt.Printf("Default Component: %s\n", repo.DefaultComponent) + if repo.Uploaders != nil { + fmt.Printf("Uploaders: %s\n", repo.Uploaders) + } fmt.Printf("Number of packages: %d\n", repo.NumPackages()) withPackages := context.Flags().Lookup("with-packages").Value.Get().(bool) diff --git a/src/github.com/smira/aptly/cmd/run.go b/src/github.com/smira/aptly/cmd/run.go index 1e782225..ec78ae5b 100644 --- a/src/github.com/smira/aptly/cmd/run.go +++ b/src/github.com/smira/aptly/cmd/run.go @@ -4,6 +4,7 @@ import ( "fmt" ctx "github.com/smira/aptly/context" "github.com/smira/commander" + "os" ) // Run runs single command starting from root cmd with args, optionally initializing context @@ -14,7 +15,7 @@ func Run(cmd *commander.Command, cmdArgs []string, initContext bool) (returnCode if !ok { panic(r) } - fmt.Println("ERROR:", fatal.Message) + fmt.Fprintln(os.Stderr, "ERROR:", fatal.Message) returnCode = fatal.ReturnCode } }() diff --git a/src/github.com/smira/aptly/cmd/snapshot_search.go b/src/github.com/smira/aptly/cmd/snapshot_search.go index 6b896a5d..ec5558de 100644 --- a/src/github.com/smira/aptly/cmd/snapshot_search.go +++ b/src/github.com/smira/aptly/cmd/snapshot_search.go @@ -100,10 +100,8 @@ func aptlySnapshotMirrorRepoSearch(cmd *commander.Command, args []string) error return fmt.Errorf("no results") } - result.ForEach(func(p *deb.Package) error { - context.Progress().Printf("%s\n", p) - return nil - }) + format := context.Flags().Lookup("format").Value.String() + PrintPackageList(result, format) return err } @@ -124,6 +122,7 @@ Example: } cmd.Flag.Bool("with-deps", false, "include dependencies into search results") + cmd.Flag.String("format", "", "custom format for result printing") return cmd } diff --git a/src/github.com/smira/aptly/cmd/snapshot_verify.go b/src/github.com/smira/aptly/cmd/snapshot_verify.go index 9095efe8..a52443e3 100644 --- a/src/github.com/smira/aptly/cmd/snapshot_verify.go +++ b/src/github.com/smira/aptly/cmd/snapshot_verify.go @@ -31,25 +31,25 @@ func aptlySnapshotVerify(cmd *commander.Command, args []string) error { packageList, err := deb.NewPackageListFromRefList(snapshots[0].RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { - fmt.Errorf("unable to load packages: %s", err) + return fmt.Errorf("unable to load packages: %s", err) } sourcePackageList := deb.NewPackageList() err = sourcePackageList.Append(packageList) if err != nil { - fmt.Errorf("unable to merge sources: %s", err) + return fmt.Errorf("unable to merge sources: %s", err) } var pL *deb.PackageList for i := 1; i < len(snapshots); i++ { pL, err = deb.NewPackageListFromRefList(snapshots[i].RefList(), context.CollectionFactory().PackageCollection(), context.Progress()) if err != nil { - fmt.Errorf("unable to load packages: %s", err) + return fmt.Errorf("unable to load packages: %s", err) } err = sourcePackageList.Append(pL) if err != nil { - fmt.Errorf("unable to merge sources: %s", err) + return fmt.Errorf("unable to merge sources: %s", err) } } diff --git a/src/github.com/smira/aptly/context/context.go b/src/github.com/smira/aptly/context/context.go index 96fe1a14..609858db 100644 --- a/src/github.com/smira/aptly/context/context.go +++ b/src/github.com/smira/aptly/context/context.go @@ -99,7 +99,7 @@ func (context *AptlyContext) config() *utils.ConfigStructure { } if err != nil { - fmt.Printf("Config file not found, creating default config at %s\n\n", configLocations[0]) + fmt.Fprintf(os.Stderr, "Config file not found, creating default config at %s\n\n", configLocations[0]) utils.SaveConfig(configLocations[0], &utils.Config) } } @@ -322,8 +322,8 @@ func (context *AptlyContext) GetPublishedStorage(name string) aptly.PublishedSto var err error publishedStorage, err = s3.NewPublishedStorage(params.AccessKeyID, params.SecretAccessKey, - params.Region, params.Bucket, params.ACL, params.Prefix, params.StorageClass, - params.EncryptionMethod, params.PlusWorkaround) + params.Region, params.Endpoint, params.Bucket, params.ACL, params.Prefix, params.StorageClass, + params.EncryptionMethod, params.PlusWorkaround, params.DisableMultiDel) if err != nil { Fatal(err) } diff --git a/src/github.com/smira/aptly/database/leveldb.go b/src/github.com/smira/aptly/database/leveldb.go index 2ad2ff86..227ce940 100644 --- a/src/github.com/smira/aptly/database/leveldb.go +++ b/src/github.com/smira/aptly/database/leveldb.go @@ -43,7 +43,8 @@ var ( func internalOpen(path string) (*leveldb.DB, error) { o := &opt.Options{ - Filter: filter.NewBloomFilter(10), + Filter: filter.NewBloomFilter(10), + OpenFilesCacheCapacity: 256, } return leveldb.OpenFile(path, o) diff --git a/src/github.com/smira/aptly/deb/changes.go b/src/github.com/smira/aptly/deb/changes.go new file mode 100644 index 00000000..62eeb3b4 --- /dev/null +++ b/src/github.com/smira/aptly/deb/changes.go @@ -0,0 +1,267 @@ +package deb + +import ( + "fmt" + "github.com/smira/aptly/aptly" + "github.com/smira/aptly/utils" + "io/ioutil" + "os" + "path/filepath" + "sort" + "strings" +) + +// Changes is a result of .changes file parsing +type Changes struct { + Changes string + Distribution string + Files PackageFiles + BasePath, ChangesName string + TempDir string + Source string + Binary []string + Architectures []string + Stanza Stanza + SignatureKeys []utils.GpgKey +} + +// NewChanges moves .changes file into temporary directory and creates Changes structure +func NewChanges(path string) (*Changes, error) { + var err error + + c := &Changes{ + BasePath: filepath.Dir(path), + ChangesName: filepath.Base(path), + } + + c.TempDir, err = ioutil.TempDir(os.TempDir(), "aptly") + if err != nil { + return nil, err + } + + // copy .changes file into temporary directory + err = utils.CopyFile(filepath.Join(c.BasePath, c.ChangesName), filepath.Join(c.TempDir, c.ChangesName)) + if err != nil { + return nil, err + } + + return c, nil +} + +// VerifyAndParse does optional signature verification and parses changes files +func (c *Changes) VerifyAndParse(acceptUnsigned, ignoreSignature bool, verifier utils.Verifier) error { + input, err := os.Open(filepath.Join(c.TempDir, c.ChangesName)) + if err != nil { + return err + } + defer input.Close() + + isClearSigned, err := verifier.IsClearSigned(input) + if err != nil { + return err + } + + input.Seek(0, 0) + + if !isClearSigned && !acceptUnsigned { + return fmt.Errorf(".changes file is not signed and unsigned processing hasn't been enabled") + } + + if isClearSigned && !ignoreSignature { + keyInfo, err := verifier.VerifyClearsigned(input, false) + if err != nil { + return err + } + input.Seek(0, 0) + + c.SignatureKeys = keyInfo.GoodKeys + } + + var text *os.File + + if isClearSigned { + text, err = verifier.ExtractClearsigned(input) + if err != nil { + return err + } + defer text.Close() + } else { + text = input + } + + reader := NewControlFileReader(text) + c.Stanza, err = reader.ReadStanza(false) + if err != nil { + return err + } + + c.Distribution = c.Stanza["Distribution"] + c.Changes = c.Stanza["Changes"] + c.Source = c.Stanza["Source"] + c.Binary = strings.Fields(c.Stanza["Binary"]) + c.Architectures = strings.Fields(c.Stanza["Architecture"]) + + c.Files, err = c.Files.ParseSumFields(c.Stanza) + if err != nil { + return err + } + + return nil +} + +// Prepare creates temporary directory, copies file there and verifies checksums +func (c *Changes) Prepare() error { + var err error + + for _, file := range c.Files { + if filepath.Dir(file.Filename) != "." { + return fmt.Errorf("file is not in the same folder as .changes file: %s", file.Filename) + } + + file.Filename = filepath.Base(file.Filename) + + err = utils.CopyFile(filepath.Join(c.BasePath, file.Filename), filepath.Join(c.TempDir, file.Filename)) + if err != nil { + return err + } + } + + for _, file := range c.Files { + var info utils.ChecksumInfo + + info, err = utils.ChecksumsForFile(filepath.Join(c.TempDir, file.Filename)) + if err != nil { + return err + } + + if info.Size != file.Checksums.Size { + return fmt.Errorf("size mismatch: expected %v != obtained %v", file.Checksums.Size, info.Size) + } + + if info.MD5 != file.Checksums.MD5 { + return fmt.Errorf("checksum mismatch MD5: expected %v != obtained %v", file.Checksums.MD5, info.MD5) + } + + if info.SHA1 != file.Checksums.SHA1 { + return fmt.Errorf("checksum mismatch SHA1: expected %v != obtained %v", file.Checksums.SHA1, info.SHA1) + } + + if info.SHA256 != file.Checksums.SHA256 { + return fmt.Errorf("checksum mismatch SHA256 expected %v != obtained %v", file.Checksums.SHA256, info.SHA256) + } + } + + return nil +} + +// Cleanup removes all temporary files +func (c *Changes) Cleanup() error { + if c.TempDir == "" { + return nil + } + + return os.RemoveAll(c.TempDir) +} + +// PackageQuery returns query that every package should match to be included +func (c *Changes) PackageQuery() (PackageQuery, error) { + var archQuery PackageQuery = &FieldQuery{Field: "$Architecture", Relation: VersionEqual, Value: ""} + for _, arch := range c.Architectures { + archQuery = &OrQuery{L: &FieldQuery{Field: "$Architecture", Relation: VersionEqual, Value: arch}, R: archQuery} + } + + // if c.Source is empty, this would never match + sourceQuery := &AndQuery{ + L: &FieldQuery{Field: "$PackageType", Relation: VersionEqual, Value: "source"}, + R: &FieldQuery{Field: "Name", Relation: VersionEqual, Value: c.Source}, + } + + var binaryQuery PackageQuery + if len(c.Binary) > 0 { + binaryQuery = &FieldQuery{Field: "Name", Relation: VersionEqual, Value: c.Binary[0]} + for _, binary := range c.Binary[1:] { + binaryQuery = &OrQuery{ + L: &FieldQuery{Field: "Name", Relation: VersionEqual, Value: binary}, + R: binaryQuery, + } + } + + binaryQuery = &AndQuery{ + L: &NotQuery{Q: &FieldQuery{Field: "$PackageType", Relation: VersionEqual, Value: "source"}}, + R: binaryQuery} + } + + var nameQuery PackageQuery + if binaryQuery == nil { + nameQuery = sourceQuery + } else { + nameQuery = &OrQuery{L: sourceQuery, R: binaryQuery} + } + + return &AndQuery{L: archQuery, R: nameQuery}, nil +} + +// GetField implements PackageLike interface +func (c *Changes) GetField(field string) string { + return c.Stanza[field] +} + +// MatchesDependency implements PackageLike interface +func (c *Changes) MatchesDependency(d Dependency) bool { + return false +} + +// MatchesArchitecture implements PackageLike interface +func (c *Changes) MatchesArchitecture(arch string) bool { + return false +} + +// GetName implements PackageLike interface +func (c *Changes) GetName() string { + return "" +} + +// GetVersion implements PackageLike interface +func (c *Changes) GetVersion() string { + return "" + +} + +// GetArchitecture implements PackageLike interface +func (c *Changes) GetArchitecture() string { + return "" +} + +// CollectChangesFiles walks filesystem collecting all .changes files +func CollectChangesFiles(locations []string, reporter aptly.ResultReporter) (changesFiles, failedFiles []string) { + for _, location := range locations { + info, err2 := os.Stat(location) + if err2 != nil { + reporter.Warning("Unable to process %s: %s", location, err2) + failedFiles = append(failedFiles, location) + continue + } + if info.IsDir() { + err2 = filepath.Walk(location, func(path string, info os.FileInfo, err3 error) error { + if err3 != nil { + return err3 + } + if info.IsDir() { + return nil + } + + if strings.HasSuffix(info.Name(), ".changes") { + changesFiles = append(changesFiles, path) + } + + return nil + }) + } else if strings.HasSuffix(info.Name(), ".changes") { + changesFiles = append(changesFiles, location) + } + } + + sort.Strings(changesFiles) + + return +} diff --git a/src/github.com/smira/aptly/deb/changes_test.go b/src/github.com/smira/aptly/deb/changes_test.go new file mode 100644 index 00000000..9d99fa5e --- /dev/null +++ b/src/github.com/smira/aptly/deb/changes_test.go @@ -0,0 +1,91 @@ +package deb + +import ( + . "gopkg.in/check.v1" + "os" + "path/filepath" +) + +type ChangesSuite struct { + Dir, Path string +} + +var _ = Suite(&ChangesSuite{}) + +func (s *ChangesSuite) SetUpTest(c *C) { + s.Dir = c.MkDir() + s.Path = filepath.Join(s.Dir, "calamares.changes") + + f, err := os.Create(s.Path) + c.Assert(err, IsNil) + + f.WriteString(changesFile) + f.Close() +} + +func (s *ChangesSuite) TestParseAndVerify(c *C) { + changes, err := NewChanges(s.Path) + c.Assert(err, IsNil) + + err = changes.VerifyAndParse(true, true, &NullVerifier{}) + c.Check(err, IsNil) + + c.Check(changes.Distribution, Equals, "sid") + c.Check(changes.Files, HasLen, 4) + c.Check(changes.Files[0].Filename, Equals, "calamares_0+git20141127.99.dsc") + c.Check(changes.Files[0].Checksums.Size, Equals, int64(1106)) + c.Check(changes.Files[0].Checksums.MD5, Equals, "05fd8f3ffe8f362c5ef9bad2f936a56e") + c.Check(changes.Files[0].Checksums.SHA1, Equals, "79f10e955dab6eb25b7f7bae18213f367a3a0396") + c.Check(changes.Files[0].Checksums.SHA256, Equals, "35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc") + c.Check(changes.BasePath, Equals, s.Dir) + c.Check(changes.Architectures, DeepEquals, []string{"source", "amd64"}) + c.Check(changes.Source, Equals, "calamares") + c.Check(changes.Binary, DeepEquals, []string{"calamares", "calamares-dbg"}) +} + +func (s *ChangesSuite) TestPackageQuery(c *C) { + changes, err := NewChanges(s.Path) + c.Assert(err, IsNil) + + err = changes.VerifyAndParse(true, true, &NullVerifier{}) + c.Check(err, IsNil) + + q, err := changes.PackageQuery() + c.Check(err, IsNil) + + c.Check(q.String(), Equals, + "(($Architecture (= amd64)) | (($Architecture (= source)) | ($Architecture (= )))), ((($PackageType (= source)), (Name (= calamares))) | ((!($PackageType (= source))), ((Name (= calamares-dbg)) | (Name (= calamares)))))") +} + +var changesFile = `Format: 1.8 +Date: Thu, 27 Nov 2014 13:24:53 +0000 +Source: calamares +Binary: calamares calamares-dbg +Architecture: source amd64 +Version: 0+git20141127.99 +Distribution: sid +Urgency: medium +Maintainer: Rohan Garg +Changed-By: Rohan +Description: + calamares - distribution-independent installer framework + calamares-dbg - distribution-independent installer framework -- debug symbols +Changes: + calamares (0+git20141127.99) sid; urgency=medium + . + * Update from git +Checksums-Sha1: + 79f10e955dab6eb25b7f7bae18213f367a3a0396 1106 calamares_0+git20141127.99.dsc + 294c28e2c8e34e72ca9ee0d9da5c14f3bf4188db 2694800 calamares_0+git20141127.99.tar.xz + d6c26c04b5407c7511f61cb3e3de60c4a1d6c4ff 1698924 calamares_0+git20141127.99_amd64.deb + a3da632d193007b0d4a1aff73159fde1b532d7a8 12835902 calamares-dbg_0+git20141127.99_amd64.deb +Checksums-Sha256: + 35b3280a7b1ffe159a276128cb5c408d687318f60ecbb8ab6dedb2e49c4e82dc 1106 calamares_0+git20141127.99.dsc + 5576b9caaf814564830f95561227e4f04ee87b31da22c1371aab155cbf7ce395 2694800 calamares_0+git20141127.99.tar.xz + 2e6e2f232ed7ffe52369928ebdf5436d90feb37840286ffba79e87d57a43a2e9 1698924 calamares_0+git20141127.99_amd64.deb + 8dd926080ed7bad2e2439e37e49ce12d5f1357c5041b7da4d860a1041f878a8a 12835902 calamares-dbg_0+git20141127.99_amd64.deb +Files: + 05fd8f3ffe8f362c5ef9bad2f936a56e 1106 devel optional calamares_0+git20141127.99.dsc + 097e55c81abd8e5f30bb2eed90c2c1e9 2694800 devel optional calamares_0+git20141127.99.tar.xz + 827fb3b12534241e119815d331e8197b 1698924 devel optional calamares_0+git20141127.99_amd64.deb + e6f8ce70f564d1f68cb57758b15b13e3 12835902 debug optional calamares-dbg_0+git20141127.99_amd64.deb` diff --git a/src/github.com/smira/aptly/deb/contents.go b/src/github.com/smira/aptly/deb/contents.go new file mode 100644 index 00000000..514516e6 --- /dev/null +++ b/src/github.com/smira/aptly/deb/contents.go @@ -0,0 +1,75 @@ +package deb + +import ( + "fmt" + "github.com/smira/aptly/aptly" + "github.com/smira/aptly/utils" + "io" + "sort" + "strings" +) + +// ContentsIndex calculates mapping from files to packages, with sorting and aggregation +type ContentsIndex struct { + index map[string][]*Package +} + +// NewContentsIndex creates empty ContentsIndex +func NewContentsIndex() *ContentsIndex { + return &ContentsIndex{ + index: make(map[string][]*Package), + } +} + +// Push adds package to contents index, calculating package contents as required +func (index *ContentsIndex) Push(p *Package, packagePool aptly.PackagePool) { + contents := p.Contents(packagePool) + + for _, path := range contents { + index.index[path] = append(index.index[path], p) + } +} + +// Empty checks whether index contains no packages +func (index *ContentsIndex) Empty() bool { + return len(index.index) == 0 +} + +// WriteTo dumps sorted mapping of files to qualified package names +func (index *ContentsIndex) WriteTo(w io.Writer) (int64, error) { + var n int64 + + paths := make([]string, len(index.index)) + + i := 0 + for path := range index.index { + paths[i] = path + i++ + } + + sort.Strings(paths) + + nn, err := fmt.Fprintf(w, "%s %s\n", "FILE", "LOCATION") + n += int64(nn) + if err != nil { + return n, err + } + + for _, path := range paths { + packages := index.index[path] + parts := make([]string, 0, len(packages)) + for i := range packages { + name := packages[i].QualifiedName() + if !utils.StrSliceHasItem(parts, name) { + parts = append(parts, name) + } + } + nn, err = fmt.Fprintf(w, "%s %s\n", path, strings.Join(parts, ",")) + n += int64(nn) + if err != nil { + return n, err + } + } + + return n, nil +} diff --git a/src/github.com/smira/aptly/deb/deb.go b/src/github.com/smira/aptly/deb/deb.go index c4985558..42b42f40 100644 --- a/src/github.com/smira/aptly/deb/deb.go +++ b/src/github.com/smira/aptly/deb/deb.go @@ -2,11 +2,13 @@ package deb import ( "archive/tar" - "bufio" + "compress/bzip2" "compress/gzip" "fmt" "github.com/mkrautz/goar" "github.com/smira/aptly/utils" + "github.com/smira/go-xz" + "github.com/smira/lzma" "io" "os" "strings" @@ -24,16 +26,16 @@ func GetControlFileFromDeb(packageFile string) (Stanza, error) { for { header, err := library.Next() if err == io.EOF { - return nil, fmt.Errorf("unable to find control.tar.gz part") + return nil, fmt.Errorf("unable to find control.tar.gz part in package %s", packageFile) } if err != nil { - return nil, fmt.Errorf("unable to read .deb archive: %s", err) + return nil, fmt.Errorf("unable to read .deb archive %s: %s", packageFile, err) } if header.Name == "control.tar.gz" { ungzip, err := gzip.NewReader(library) if err != nil { - return nil, fmt.Errorf("unable to ungzip: %s", err) + return nil, fmt.Errorf("unable to ungzip control file from %s. Error: %s", packageFile, err) } defer ungzip.Close() @@ -41,15 +43,15 @@ func GetControlFileFromDeb(packageFile string) (Stanza, error) { for { tarHeader, err := untar.Next() if err == io.EOF { - return nil, fmt.Errorf("unable to find control file") + return nil, fmt.Errorf("unable to find control file in %s", packageFile) } if err != nil { - return nil, fmt.Errorf("unable to read .tar archive: %s", err) + return nil, fmt.Errorf("unable to read .tar archive from %s. Error: %s", packageFile, err) } if tarHeader.Name == "./control" || tarHeader.Name == "control" { reader := NewControlFileReader(untar) - stanza, err := reader.ReadStanza() + stanza, err := reader.ReadStanza(false) if err != nil { return nil, err } @@ -69,16 +71,16 @@ func GetControlFileFromDsc(dscFile string, verifier utils.Verifier) (Stanza, err } defer file.Close() - line, err := bufio.NewReader(file).ReadString('\n') + isClearSigned, err := verifier.IsClearSigned(file) + file.Seek(0, 0) + if err != nil { return nil, err } - file.Seek(0, 0) - var text *os.File - if strings.Index(line, "BEGIN PGP SIGN") != -1 { + if isClearSigned { text, err = verifier.ExtractClearsigned(file) if err != nil { return nil, err @@ -89,7 +91,7 @@ func GetControlFileFromDsc(dscFile string, verifier utils.Verifier) (Stanza, err } reader := NewControlFileReader(text) - stanza, err := reader.ReadStanza() + stanza, err := reader.ReadStanza(false) if err != nil { return nil, err } @@ -97,3 +99,75 @@ func GetControlFileFromDsc(dscFile string, verifier utils.Verifier) (Stanza, err return stanza, nil } + +// GetContentsFromDeb returns list of files installed by .deb package +func GetContentsFromDeb(packageFile string) ([]string, error) { + file, err := os.Open(packageFile) + if err != nil { + return nil, err + } + defer file.Close() + + library := ar.NewReader(file) + for { + header, err := library.Next() + if err == io.EOF { + return nil, fmt.Errorf("unable to find data.tar.* part in %s", packageFile) + } + if err != nil { + return nil, fmt.Errorf("unable to read .deb archive from %s: %s", packageFile, err) + } + + if strings.HasPrefix(header.Name, "data.tar") { + var tarInput io.Reader + + switch header.Name { + case "data.tar": + tarInput = library + case "data.tar.gz": + ungzip, err := gzip.NewReader(library) + if err != nil { + return nil, fmt.Errorf("unable to ungzip data.tar.gz from %s: %s", packageFile,err) + } + defer ungzip.Close() + tarInput = ungzip + case "data.tar.bz2": + tarInput = bzip2.NewReader(library) + case "data.tar.xz": + unxz, err := xz.NewReader(library) + if err != nil { + return nil, fmt.Errorf("unable to unxz data.tar.xz from %s: %s", packageFile, err) + } + defer unxz.Close() + tarInput = unxz + case "data.tar.lzma": + unlzma := lzma.NewReader(library) + defer unlzma.Close() + tarInput = unlzma + default: + return nil, fmt.Errorf("unsupported tar compression in %s: %s", packageFile, header.Name) + } + + untar := tar.NewReader(tarInput) + var results []string + for { + tarHeader, err := untar.Next() + if err == io.EOF { + return results, nil + } + if err != nil { + return nil, fmt.Errorf("unable to read .tar archive from %s: %s", packageFile, err) + } + + if tarHeader.Typeflag == tar.TypeDir { + continue + } + + if strings.HasPrefix(tarHeader.Name, "./") { + tarHeader.Name = tarHeader.Name[2:] + } + results = append(results, tarHeader.Name) + } + } + } +} diff --git a/src/github.com/smira/aptly/deb/deb_test.go b/src/github.com/smira/aptly/deb/deb_test.go index 4c329c04..797320fc 100644 --- a/src/github.com/smira/aptly/deb/deb_test.go +++ b/src/github.com/smira/aptly/deb/deb_test.go @@ -9,7 +9,7 @@ import ( ) type DebSuite struct { - debFile, dscFile, dscFileNoSign string + debFile, debFile2, dscFile, dscFileNoSign string } var _ = Suite(&DebSuite{}) @@ -17,6 +17,7 @@ var _ = Suite(&DebSuite{}) func (s *DebSuite) SetUpSuite(c *C) { _, _File, _, _ := runtime.Caller(0) s.debFile = filepath.Join(filepath.Dir(_File), "../system/files/libboost-program-options-dev_1.49.0.1_i386.deb") + s.debFile2 = filepath.Join(filepath.Dir(_File), "../system/changes/hardlink_0.2.1_amd64.deb") s.dscFile = filepath.Join(filepath.Dir(_File), "../system/files/pyspi_0.6.1-1.3.dsc") s.dscFileNoSign = filepath.Join(filepath.Dir(_File), "../system/files/pyspi-0.6.1-1.3.stripped.dsc") } @@ -27,7 +28,7 @@ func (s *DebSuite) TestGetControlFileFromDeb(c *C) { _, _File, _, _ := runtime.Caller(0) _, err = GetControlFileFromDeb(_File) - c.Check(err, ErrorMatches, "unable to read .deb archive: ar: missing global header") + c.Check(err, ErrorMatches, "^.+ar: missing global header") st, err := GetControlFileFromDeb(s.debFile) c.Check(err, IsNil) @@ -55,3 +56,15 @@ func (s *DebSuite) TestGetControlFileFromDsc(c *C) { c.Check(st["Version"], Equals, "0.6.1-1.4") c.Check(st["Source"], Equals, "pyspi") } + +func (s *DebSuite) TestGetContentsFromDeb(c *C) { + contents, err := GetContentsFromDeb(s.debFile) + c.Check(err, IsNil) + c.Check(contents, DeepEquals, []string{"usr/share/doc/libboost-program-options-dev/changelog.gz", + "usr/share/doc/libboost-program-options-dev/copyright"}) + + contents, err = GetContentsFromDeb(s.debFile2) + c.Check(err, IsNil) + c.Check(contents, DeepEquals, []string{"usr/bin/hardlink", "usr/share/man/man1/hardlink.1.gz", + "usr/share/doc/hardlink/changelog.gz", "usr/share/doc/hardlink/copyright", "usr/share/doc/hardlink/NEWS.Debian.gz"}) +} diff --git a/src/github.com/smira/aptly/deb/format.go b/src/github.com/smira/aptly/deb/format.go index 1348fe2c..bf453d15 100644 --- a/src/github.com/smira/aptly/deb/format.go +++ b/src/github.com/smira/aptly/deb/format.go @@ -92,16 +92,42 @@ func (s Stanza) Copy() (result Stanza) { return } -// Write single field from Stanza to writer -func writeField(w *bufio.Writer, field, value string) (err error) { - _, multiline := multilineFields[field] +func isMultilineField(field string, isRelease bool) bool { + switch field { + case "Description": + return true + case "Files": + return true + case "Changes": + return true + case "Checksums-Sha1": + return true + case "Checksums-Sha256": + return true + case "Package-List": + return true + case "MD5Sum": + return isRelease + case "SHA1": + return isRelease + case "SHA256": + return isRelease + } + return false +} - if !multiline { +// Write single field from Stanza to writer +func writeField(w *bufio.Writer, field, value string, isRelease bool) (err error) { + if !isMultilineField(field, isRelease) { _, err = w.WriteString(field + ": " + value + "\n") } else { if !strings.HasSuffix(value, "\n") { value = value + "\n" } + + if field != "Description" { + value = "\n" + value + } _, err = w.WriteString(field + ":" + value) } @@ -122,7 +148,7 @@ func (s Stanza) WriteTo(w *bufio.Writer, isSource, isRelease bool) error { value, ok := s[field] if ok { delete(s, field) - err := writeField(w, field, value) + err := writeField(w, field, value, isRelease) if err != nil { return err } @@ -130,7 +156,7 @@ func (s Stanza) WriteTo(w *bufio.Writer, isSource, isRelease bool) error { } for field, value := range s { - err := writeField(w, field, value) + err := writeField(w, field, value, isRelease) if err != nil { return err } @@ -144,20 +170,6 @@ var ( ErrMalformedStanza = errors.New("malformed stanza syntax") ) -var multilineFields = make(map[string]bool) - -func init() { - multilineFields["Description"] = true - multilineFields["Files"] = true - multilineFields["Changes"] = true - multilineFields["Checksums-Sha1"] = true - multilineFields["Checksums-Sha256"] = true - multilineFields["Package-List"] = true - multilineFields["SHA256"] = true - multilineFields["SHA1"] = true - multilineFields["MD5Sum"] = true -} - func canonicalCase(field string) string { upper := strings.ToUpper(field) switch upper { @@ -198,7 +210,7 @@ func NewControlFileReader(r io.Reader) *ControlFileReader { } // ReadStanza reeads one stanza from control file -func (c *ControlFileReader) ReadStanza() (Stanza, error) { +func (c *ControlFileReader) ReadStanza(isRelease bool) (Stanza, error) { stanza := make(Stanza, 32) lastField := "" lastFieldMultiline := false @@ -218,7 +230,7 @@ func (c *ControlFileReader) ReadStanza() (Stanza, error) { if lastFieldMultiline { stanza[lastField] += line + "\n" } else { - stanza[lastField] += strings.TrimSpace(line) + stanza[lastField] += " " + strings.TrimSpace(line) } } else { parts := strings.SplitN(line, ":", 2) @@ -226,7 +238,7 @@ func (c *ControlFileReader) ReadStanza() (Stanza, error) { return nil, ErrMalformedStanza } lastField = canonicalCase(parts[0]) - _, lastFieldMultiline = multilineFields[lastField] + lastFieldMultiline = isMultilineField(lastField, isRelease) if lastFieldMultiline { stanza[lastField] = parts[1] if parts[1] != "" { diff --git a/src/github.com/smira/aptly/deb/format_test.go b/src/github.com/smira/aptly/deb/format_test.go index d7f43acc..92e02f47 100644 --- a/src/github.com/smira/aptly/deb/format_test.go +++ b/src/github.com/smira/aptly/deb/format_test.go @@ -84,18 +84,18 @@ func (s *ControlFileSuite) SetUpTest(c *C) { func (s *ControlFileSuite) TestReadStanza(c *C) { r := NewControlFileReader(s.reader) - stanza1, err := r.ReadStanza() + stanza1, err := r.ReadStanza(false) c.Assert(err, IsNil) - stanza2, err := r.ReadStanza() + stanza2, err := r.ReadStanza(false) c.Assert(err, IsNil) - stanza3, err := r.ReadStanza() + stanza3, err := r.ReadStanza(false) c.Assert(err, IsNil) c.Assert(stanza3, IsNil) c.Check(stanza1["Format"], Equals, "3.0 (quilt)") - c.Check(stanza1["Build-Depends"], Equals, "debhelper (>= 8),bash-completion (>= 1:1.1-3),libcurl4-nss-dev, libreadline-dev, libxml2-dev, libpcre3-dev, liboauth-dev, xsltproc, docbook-xsl, docbook-xml, dh-autoreconf") + c.Check(stanza1["Build-Depends"], Equals, "debhelper (>= 8), bash-completion (>= 1:1.1-3), libcurl4-nss-dev, libreadline-dev, libxml2-dev, libpcre3-dev, liboauth-dev, xsltproc, docbook-xsl, docbook-xml, dh-autoreconf") c.Check(stanza1["Files"], Equals, " 3d5f65778bf3f89be03c313b0024b62c 1980 bti_032-1.dsc\n"+ " 1e0d0b693fdeebec268004ba41701baf 59773 bti_032.orig.tar.gz\n"+" ac1229a6d685023aeb8fcb0806324aa8 5065 bti_032-1.debian.tar.gz\n") c.Check(len(stanza2), Equals, 20) @@ -103,12 +103,12 @@ func (s *ControlFileSuite) TestReadStanza(c *C) { func (s *ControlFileSuite) TestReadWriteStanza(c *C) { r := NewControlFileReader(s.reader) - stanza, err := r.ReadStanza() + stanza, err := r.ReadStanza(false) c.Assert(err, IsNil) buf := &bytes.Buffer{} w := bufio.NewWriter(buf) - err = stanza.Copy().WriteTo(w, false, false) + err = stanza.Copy().WriteTo(w, true, false) c.Assert(err, IsNil) err = w.Flush() c.Assert(err, IsNil) @@ -116,7 +116,7 @@ func (s *ControlFileSuite) TestReadWriteStanza(c *C) { str := buf.String() r = NewControlFileReader(buf) - stanza2, err := r.ReadStanza() + stanza2, err := r.ReadStanza(false) c.Assert(err, IsNil) c.Assert(stanza2, DeepEquals, stanza) @@ -140,7 +140,7 @@ func (s *ControlFileSuite) BenchmarkReadStanza(c *C) { reader := bytes.NewBufferString(controlFile) r := NewControlFileReader(reader) for { - s, e := r.ReadStanza() + s, e := r.ReadStanza(false) if s == nil && e == nil { break } diff --git a/src/github.com/smira/aptly/deb/graph.go b/src/github.com/smira/aptly/deb/graph.go index fe75862b..37abd692 100644 --- a/src/github.com/smira/aptly/deb/graph.go +++ b/src/github.com/smira/aptly/deb/graph.go @@ -1,8 +1,8 @@ package deb import ( - "code.google.com/p/gographviz" "fmt" + "github.com/awalterschulze/gographviz" "strings" ) diff --git a/src/github.com/smira/aptly/deb/import.go b/src/github.com/smira/aptly/deb/import.go index 2aa9a037..7ab0ddc1 100644 --- a/src/github.com/smira/aptly/deb/import.go +++ b/src/github.com/smira/aptly/deb/import.go @@ -10,7 +10,7 @@ import ( ) // CollectPackageFiles walks filesystem collecting all candidates for package files -func CollectPackageFiles(locations []string, reporter aptly.ResultReporter) (packageFiles, failedFiles []string, err error) { +func CollectPackageFiles(locations []string, reporter aptly.ResultReporter) (packageFiles, failedFiles []string) { for _, location := range locations { info, err2 := os.Stat(location) if err2 != nil { @@ -28,7 +28,7 @@ func CollectPackageFiles(locations []string, reporter aptly.ResultReporter) (pac } if strings.HasSuffix(info.Name(), ".deb") || strings.HasSuffix(info.Name(), ".udeb") || - strings.HasSuffix(info.Name(), ".dsc") { + strings.HasSuffix(info.Name(), ".dsc") || strings.HasSuffix(info.Name(), ".ddeb") { packageFiles = append(packageFiles, path) } @@ -36,7 +36,7 @@ func CollectPackageFiles(locations []string, reporter aptly.ResultReporter) (pac }) } else { if strings.HasSuffix(info.Name(), ".deb") || strings.HasSuffix(info.Name(), ".udeb") || - strings.HasSuffix(info.Name(), ".dsc") { + strings.HasSuffix(info.Name(), ".dsc") || strings.HasSuffix(info.Name(), ".ddeb") { packageFiles = append(packageFiles, location) } else { reporter.Warning("Unknown file extension: %s", location) @@ -53,7 +53,7 @@ func CollectPackageFiles(locations []string, reporter aptly.ResultReporter) (pac // ImportPackageFiles imports files into local repository func ImportPackageFiles(list *PackageList, packageFiles []string, forceReplace bool, verifier utils.Verifier, - pool aptly.PackagePool, collection *PackageCollection, reporter aptly.ResultReporter) (processedFiles []string, failedFiles []string, err error) { + pool aptly.PackagePool, collection *PackageCollection, reporter aptly.ResultReporter, restriction PackageQuery) (processedFiles []string, failedFiles []string, err error) { if forceReplace { list.PrepareIndex() } @@ -150,6 +150,12 @@ func ImportPackageFiles(list *PackageList, packageFiles []string, forceReplace b continue } + if restriction != nil && !restriction.Matches(p) { + reporter.Warning("%s has been ignored as it doesn't match restriction", p) + failedFiles = append(failedFiles, file) + continue + } + err = collection.Update(p) if err != nil { reporter.Warning("Unable to save package %s: %s", p, err) diff --git a/src/github.com/smira/aptly/deb/index_files.go b/src/github.com/smira/aptly/deb/index_files.go index 962c988b..3a7a194e 100644 --- a/src/github.com/smira/aptly/deb/index_files.go +++ b/src/github.com/smira/aptly/deb/index_files.go @@ -24,6 +24,7 @@ type indexFile struct { parent *indexFiles discardable bool compressable bool + onlyGzip bool signable bool relativePath string tempFilename string @@ -73,6 +74,9 @@ func (file *indexFile) Finalize(signer utils.Signer) error { exts := []string{""} if file.compressable { exts = append(exts, ".gz", ".bz2") + if file.onlyGzip { + exts = []string{".gz"} + } } for _, ext := range exts { @@ -215,6 +219,36 @@ func (files *indexFiles) ReleaseIndex(component, arch string, udeb bool) *indexF return file } +func (files *indexFiles) ContentsIndex(component, arch string, udeb bool) *indexFile { + if arch == "source" { + udeb = false + } + key := fmt.Sprintf("ci-%s-%s-%v", component, arch, udeb) + file, ok := files.indexes[key] + if !ok { + var relativePath string + + if udeb { + relativePath = filepath.Join(component, fmt.Sprintf("Contents-udeb-%s", arch)) + } else { + relativePath = filepath.Join(component, fmt.Sprintf("Contents-%s", arch)) + } + + file = &indexFile{ + parent: files, + discardable: true, + compressable: true, + onlyGzip: true, + signable: false, + relativePath: relativePath, + } + + files.indexes[key] = file + } + + return file +} + func (files *indexFiles) ReleaseFile() *indexFile { return &indexFile{ parent: files, diff --git a/src/github.com/smira/aptly/deb/list_test.go b/src/github.com/smira/aptly/deb/list_test.go index c9075401..91769179 100644 --- a/src/github.com/smira/aptly/deb/list_test.go +++ b/src/github.com/smira/aptly/deb/list_test.go @@ -379,6 +379,20 @@ func (s *PackageListSuite) TestFilter(c *C) { &FieldQuery{Field: "$Architecture", Relation: VersionRegexp, Value: "i.*6", Regexp: regexp.MustCompile("i.*6")}, &PkgQuery{"app", "1.1~bp1", "i386"}}}, false, nil, 0, nil) c.Check(err, IsNil) c.Check(plString(result), Equals, "app_1.1~bp1_i386") + + result, err = s.il.Filter([]PackageQuery{&AndQuery{ + &FieldQuery{Field: "Name", Relation: VersionRegexp, Value: "a", Regexp: regexp.MustCompile("a")}, + &NotQuery{Q: &FieldQuery{Field: "Name", Relation: VersionEqual, Value: "data"}}, + }}, false, nil, 0, nil) + c.Check(err, IsNil) + c.Check(plString(result), Equals, "aa_2.0-1_i386 app_1.0_s390 app_1.1~bp1_amd64 app_1.1~bp1_arm app_1.1~bp1_i386 mailer_3.5.8_i386") + + result, err = s.il.Filter([]PackageQuery{&AndQuery{ + &NotQuery{Q: &FieldQuery{Field: "Name", Relation: VersionEqual, Value: "data"}}, + &FieldQuery{Field: "Name", Relation: VersionRegexp, Value: "a", Regexp: regexp.MustCompile("a")}, + }}, false, nil, 0, nil) + c.Check(err, IsNil) + c.Check(plString(result), Equals, "aa_2.0-1_i386 app_1.0_s390 app_1.1~bp1_amd64 app_1.1~bp1_arm app_1.1~bp1_i386 mailer_3.5.8_i386") } func (s *PackageListSuite) TestVerifyDependencies(c *C) { diff --git a/src/github.com/smira/aptly/deb/local.go b/src/github.com/smira/aptly/deb/local.go index f57e4dde..a7e6f877 100644 --- a/src/github.com/smira/aptly/deb/local.go +++ b/src/github.com/smira/aptly/deb/local.go @@ -2,9 +2,9 @@ package deb import ( "bytes" - "code.google.com/p/go-uuid/uuid" "fmt" "github.com/smira/aptly/database" + "github.com/smira/go-uuid/uuid" "github.com/ugorji/go/codec" "log" "sync" @@ -22,6 +22,8 @@ type LocalRepo struct { DefaultDistribution string `codec:",omitempty"` // DefaultComponent DefaultComponent string `codec:",omitempty"` + // Uploaders configuration + Uploaders *Uploaders `code:",omitempty" json:"-"` // "Snapshot" of current list of packages packageRefs *PackageRefList } diff --git a/src/github.com/smira/aptly/deb/package.go b/src/github.com/smira/aptly/deb/package.go index f032a222..d7b1f6af 100644 --- a/src/github.com/smira/aptly/deb/package.go +++ b/src/github.com/smira/aptly/deb/package.go @@ -32,9 +32,10 @@ type Package struct { // Is this >= 0.6 package? V06Plus bool // Offload fields - deps *PackageDependencies - extra *Stanza - files *PackageFiles + deps *PackageDependencies + extra *Stanza + files *PackageFiles + contents []string // Mother collection collection *PackageCollection } @@ -114,62 +115,20 @@ func NewSourcePackageFromControlFile(input Stanza) (*Package, error) { delete(input, "Version") delete(input, "Architecture") + var err error + files := make(PackageFiles, 0, 3) - - parseSums := func(field string, setter func(sum *utils.ChecksumInfo, data string)) error { - for _, line := range strings.Split(input[field], "\n") { - line = strings.TrimSpace(line) - if line == "" { - continue - } - parts := strings.Fields(line) - - if len(parts) != 3 { - return fmt.Errorf("unparseable hash sum line: %#v", line) - } - - size, err := strconv.ParseInt(parts[1], 10, 64) - if err != nil { - return fmt.Errorf("unable to parse size: %s", err) - } - - filename := filepath.Base(parts[2]) - - found := false - pos := 0 - for i, file := range files { - if file.Filename == filename { - found = true - pos = i - break - } - } - - if !found { - files = append(files, PackageFile{Filename: filename, downloadPath: input["Directory"]}) - pos = len(files) - 1 - } - - files[pos].Checksums.Size = size - setter(&files[pos].Checksums, parts[0]) - } - - delete(input, field) - - return nil - } - - err := parseSums("Files", func(sum *utils.ChecksumInfo, data string) { sum.MD5 = data }) + files, err = files.ParseSumFields(input) if err != nil { return nil, err } - err = parseSums("Checksums-Sha1", func(sum *utils.ChecksumInfo, data string) { sum.SHA1 = data }) - if err != nil { - return nil, err - } - err = parseSums("Checksums-Sha256", func(sum *utils.ChecksumInfo, data string) { sum.SHA256 = data }) - if err != nil { - return nil, err + + delete(input, "Files") + delete(input, "Checksums-Sha1") + delete(input, "Checksums-Sha256") + + for i := range files { + files[i].downloadPath = input["Directory"] } result.UpdateFiles(files) @@ -211,14 +170,19 @@ func (p *Package) String() string { return fmt.Sprintf("%s_%s_%s", p.Name, p.Version, p.Architecture) } -// MarshalJSON implements json.Marshaller interface -func (p *Package) MarshalJSON() ([]byte, error) { +// ExtendedStanza returns package stanza enhanced with aptly-specific fields +func (p *Package) ExtendedStanza() Stanza { stanza := p.Stanza() stanza["FilesHash"] = fmt.Sprintf("%08x", p.FilesHash) stanza["Key"] = string(p.Key("")) stanza["ShortKey"] = string(p.ShortKey("")) - return json.Marshal(stanza) + return stanza +} + +// MarshalJSON implements json.Marshaller interface +func (p *Package) MarshalJSON() ([]byte, error) { + return json.Marshal(p.ExtendedStanza()) } // GetField returns fields from package @@ -336,6 +300,21 @@ func (p *Package) MatchesDependency(dep Dependency) bool { panic("unknown relation") } +// GetName returns package name +func (p *Package) GetName() string { + return p.Name +} + +// GetVersion returns package version +func (p *Package) GetVersion() string { + return p.Version +} + +// GetArchitecture returns package arch +func (p *Package) GetArchitecture() string { + return p.Architecture +} + // GetDependencies compiles list of dependenices by flags from options func (p *Package) GetDependencies(options int) (dependencies []string) { deps := p.Deps() @@ -372,6 +351,16 @@ func (p *Package) GetDependencies(options int) (dependencies []string) { return } +// QualifiedName returns [$SECTION/]$NAME +func (p *Package) QualifiedName() string { + section := p.Extra()["Section"] + if section != "" { + return section + "/" + p.Name + } + + return p.Name +} + // Extra returns Stanza of extra fields (it may load it from collection) func (p *Package) Extra() Stanza { if p.extra == nil { @@ -410,6 +399,43 @@ func (p *Package) Files() PackageFiles { return *p.files } +// Contents returns cached package contents +func (p *Package) Contents(packagePool aptly.PackagePool) []string { + if p.IsSource { + return nil + } + + if p.contents == nil { + if p.collection == nil { + panic("contents == nil && collection == nil") + } + + p.contents = p.collection.loadContents(p, packagePool) + } + + return p.contents +} + +// CalculateContents looks up contents in package file +func (p *Package) CalculateContents(packagePool aptly.PackagePool) []string { + if p.IsSource { + return nil + } + + file := p.Files()[0] + path, err := packagePool.Path(file.Filename, file.Checksums.MD5) + if err != nil { + panic(err) + } + + contents, err := GetContentsFromDeb(path) + if err != nil { + panic(err) + } + + return contents +} + // UpdateFiles saves new state of files func (p *Package) UpdateFiles(files PackageFiles) { p.files = &files @@ -456,10 +482,10 @@ func (p *Package) Stanza() (result Stanza) { result["MD5sum"] = f.Checksums.MD5 } if f.Checksums.SHA1 != "" { - result["SHA1"] = " " + f.Checksums.SHA1 + result["SHA1"] = f.Checksums.SHA1 } if f.Checksums.SHA256 != "" { - result["SHA256"] = " " + f.Checksums.SHA256 + result["SHA256"] = f.Checksums.SHA256 } result["Size"] = fmt.Sprintf("%d", f.Checksums.Size) } diff --git a/src/github.com/smira/aptly/deb/package_collection.go b/src/github.com/smira/aptly/deb/package_collection.go index 10050788..56a5e5a2 100644 --- a/src/github.com/smira/aptly/deb/package_collection.go +++ b/src/github.com/smira/aptly/deb/package_collection.go @@ -3,6 +3,7 @@ package deb import ( "bytes" "fmt" + "github.com/smira/aptly/aptly" "github.com/smira/aptly/database" "github.com/ugorji/go/codec" "path/filepath" @@ -10,9 +11,8 @@ import ( // PackageCollection does management of packages in DB type PackageCollection struct { - db database.Storage - encodeBuffer bytes.Buffer - codecHandle *codec.MsgpackHandle + db database.Storage + codecHandle *codec.MsgpackHandle } // Verify interface @@ -161,45 +161,82 @@ func (collection *PackageCollection) loadFiles(p *Package) *PackageFiles { return files } +// loadContents loads or calculates and saves package contents +func (collection *PackageCollection) loadContents(p *Package, packagePool aptly.PackagePool) []string { + encoded, err := collection.db.Get(p.Key("xC")) + if err == nil { + contents := []string{} + + decoder := codec.NewDecoderBytes(encoded, collection.codecHandle) + err = decoder.Decode(&contents) + if err != nil { + panic("unable to decode contents") + } + + return contents + } + + if err != database.ErrNotFound { + panic("unable to load contents") + } + + contents := p.CalculateContents(packagePool) + + var buf bytes.Buffer + err = codec.NewEncoder(&buf, collection.codecHandle).Encode(contents) + if err != nil { + panic("unable to encode contents") + } + + err = collection.db.Put(p.Key("xC"), buf.Bytes()) + if err != nil { + panic("unable to save contents") + } + + return contents +} + // Update adds or updates information about package in DB checking for conficts first func (collection *PackageCollection) Update(p *Package) error { - encoder := codec.NewEncoder(&collection.encodeBuffer, collection.codecHandle) + var encodeBuffer bytes.Buffer - collection.encodeBuffer.Reset() - collection.encodeBuffer.WriteByte(0xc1) - collection.encodeBuffer.WriteByte(0x1) + encoder := codec.NewEncoder(&encodeBuffer, collection.codecHandle) + + encodeBuffer.Reset() + encodeBuffer.WriteByte(0xc1) + encodeBuffer.WriteByte(0x1) err := encoder.Encode(p) if err != nil { return err } - err = collection.db.Put(p.Key(""), collection.encodeBuffer.Bytes()) + err = collection.db.Put(p.Key(""), encodeBuffer.Bytes()) if err != nil { return err } // Encode offloaded fields one by one if p.files != nil { - collection.encodeBuffer.Reset() + encodeBuffer.Reset() err = encoder.Encode(*p.files) if err != nil { return err } - err = collection.db.Put(p.Key("xF"), collection.encodeBuffer.Bytes()) + err = collection.db.Put(p.Key("xF"), encodeBuffer.Bytes()) if err != nil { return err } } if p.deps != nil { - collection.encodeBuffer.Reset() + encodeBuffer.Reset() err = encoder.Encode(*p.deps) if err != nil { return err } - err = collection.db.Put(p.Key("xD"), collection.encodeBuffer.Bytes()) + err = collection.db.Put(p.Key("xD"), encodeBuffer.Bytes()) if err != nil { return err } @@ -208,13 +245,13 @@ func (collection *PackageCollection) Update(p *Package) error { } if p.extra != nil { - collection.encodeBuffer.Reset() + encodeBuffer.Reset() err = encoder.Encode(*p.extra) if err != nil { return err } - err = collection.db.Put(p.Key("xE"), collection.encodeBuffer.Bytes()) + err = collection.db.Put(p.Key("xE"), encodeBuffer.Bytes()) if err != nil { return err } diff --git a/src/github.com/smira/aptly/deb/package_deps.go b/src/github.com/smira/aptly/deb/package_deps.go index 097709db..157d8d29 100644 --- a/src/github.com/smira/aptly/deb/package_deps.go +++ b/src/github.com/smira/aptly/deb/package_deps.go @@ -22,6 +22,12 @@ func parseDependencies(input Stanza, key string) []string { delete(input, key) + value = strings.TrimSpace(value) + if value == "" { + // empty line is no depdencies + return nil + } + result := strings.Split(value, ",") for i := range result { result[i] = strings.TrimSpace(result[i]) diff --git a/src/github.com/smira/aptly/deb/package_files.go b/src/github.com/smira/aptly/deb/package_files.go index 31a37cbe..489b67b1 100644 --- a/src/github.com/smira/aptly/deb/package_files.go +++ b/src/github.com/smira/aptly/deb/package_files.go @@ -2,12 +2,15 @@ package deb import ( "encoding/binary" + "fmt" "github.com/smira/aptly/aptly" "github.com/smira/aptly/utils" "hash/fnv" "os" "path/filepath" "sort" + "strconv" + "strings" ) // PackageFile is a single file entry in package @@ -76,3 +79,65 @@ func (files PackageFiles) Swap(i, j int) { func (files PackageFiles) Less(i, j int) bool { return files[i].Filename < files[j].Filename } + +func (files PackageFiles) parseSumField(input string, setter func(sum *utils.ChecksumInfo, data string)) (PackageFiles, error) { + for _, line := range strings.Split(input, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + parts := strings.Fields(line) + + if len(parts) < 3 { + return nil, fmt.Errorf("unparseable hash sum line: %#v", line) + } + + size, err := strconv.ParseInt(parts[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("unable to parse size: %s", err) + } + + filename := filepath.Base(parts[len(parts)-1]) + + found := false + pos := 0 + for i, file := range files { + if file.Filename == filename { + found = true + pos = i + break + } + } + + if !found { + files = append(files, PackageFile{Filename: filename}) + pos = len(files) - 1 + } + + files[pos].Checksums.Size = size + setter(&files[pos].Checksums, parts[0]) + } + + return files, nil +} + +// ParseSumFields populates PackageFiles by parsing stanza checksums fields +func (files PackageFiles) ParseSumFields(stanza Stanza) (PackageFiles, error) { + var err error + + files, err = files.parseSumField(stanza["Files"], func(sum *utils.ChecksumInfo, data string) { sum.MD5 = data }) + if err != nil { + return nil, err + } + + files, err = files.parseSumField(stanza["Checksums-Sha1"], func(sum *utils.ChecksumInfo, data string) { sum.SHA1 = data }) + if err != nil { + return nil, err + } + files, err = files.parseSumField(stanza["Checksums-Sha256"], func(sum *utils.ChecksumInfo, data string) { sum.SHA256 = data }) + if err != nil { + return nil, err + } + + return files, nil +} diff --git a/src/github.com/smira/aptly/deb/package_test.go b/src/github.com/smira/aptly/deb/package_test.go index c1dc9829..ec522500 100644 --- a/src/github.com/smira/aptly/deb/package_test.go +++ b/src/github.com/smira/aptly/deb/package_test.go @@ -22,7 +22,7 @@ func (s *PackageSuite) SetUpTest(c *C) { s.stanza = packageStanza.Copy() buf := bytes.NewBufferString(sourcePackageMeta) - s.sourceStanza, _ = NewControlFileReader(buf).ReadStanza() + s.sourceStanza, _ = NewControlFileReader(buf).ReadStanza(false) } func (s *PackageSuite) TestNewFromPara(c *C) { @@ -43,7 +43,7 @@ func (s *PackageSuite) TestNewFromPara(c *C) { } func (s *PackageSuite) TestNewUdebFromPara(c *C) { - stanza, _ := NewControlFileReader(bytes.NewBufferString(udebPackageMeta)).ReadStanza() + stanza, _ := NewControlFileReader(bytes.NewBufferString(udebPackageMeta)).ReadStanza(false) p := NewUdebPackageFromControlFile(stanza) c.Check(p.IsSource, Equals, false) @@ -125,6 +125,10 @@ func (s *PackageSuite) TestStanza(c *C) { p := NewPackageFromControlFile(s.stanza.Copy()) stanza := p.Stanza() + for k := range s.stanza { + c.Check(stanza[k], Equals, s.stanza[k]) + } + c.Assert(stanza, DeepEquals, s.stanza) p, _ = NewSourcePackageFromControlFile(s.sourceStanza.Copy()) @@ -152,7 +156,7 @@ func (s *PackageSuite) TestGetField(c *C) { p4, _ := NewSourcePackageFromControlFile(s.sourceStanza.Copy()) - stanza5, _ := NewControlFileReader(bytes.NewBufferString(udebPackageMeta)).ReadStanza() + stanza5, _ := NewControlFileReader(bytes.NewBufferString(udebPackageMeta)).ReadStanza(false) p5 := NewUdebPackageFromControlFile(stanza5) c.Check(p.GetField("$Source"), Equals, "alien-arena") @@ -445,7 +449,7 @@ func (s *PackageSuite) TestVerifyFiles(c *C) { c.Check(result, Equals, true) } -var packageStanza = Stanza{"Source": "alien-arena", "Pre-Depends": "dpkg (>= 1.6)", "Suggests": "alien-arena-mars", "Recommends": "aliean-arena-luna", "Depends": "libc6 (>= 2.7), alien-arena-data (>= 7.40)", "Filename": "pool/contrib/a/alien-arena/alien-arena-common_7.40-2_i386.deb", "SHA1": " 46955e48cad27410a83740a21d766ce362364024", "SHA256": " eb4afb9885cba6dc70cccd05b910b2dbccc02c5900578be5e99f0d3dbf9d76a5", "Priority": "extra", "Maintainer": "Debian Games Team ", "Description": "Common files for Alien Arena client and server ALIEN ARENA is a standalone 3D first person online deathmatch shooter\n crafted from the original source code of Quake II and Quake III, released\n by id Software under the GPL license. With features including 32 bit\n graphics, new particle engine and effects, light blooms, reflective water,\n hi resolution textures and skins, hi poly models, stain maps, ALIEN ARENA\n pushes the envelope of graphical beauty rivaling today's top games.\n .\n This package installs the common files for Alien Arena.\n", "Homepage": "http://red.planetarena.org", "Tag": "role::app-data, role::shared-lib, special::auto-inst-parts", "Installed-Size": "456", "Version": "7.40-2", "Replaces": "alien-arena (<< 7.33-1)", "Size": "187518", "MD5sum": "1e8cba92c41420aa7baa8a5718d67122", "Package": "alien-arena-common", "Section": "contrib/games", "Architecture": "i386"} +var packageStanza = Stanza{"Source": "alien-arena", "Pre-Depends": "dpkg (>= 1.6)", "Suggests": "alien-arena-mars", "Recommends": "aliean-arena-luna", "Depends": "libc6 (>= 2.7), alien-arena-data (>= 7.40)", "Filename": "pool/contrib/a/alien-arena/alien-arena-common_7.40-2_i386.deb", "SHA1": "46955e48cad27410a83740a21d766ce362364024", "SHA256": "eb4afb9885cba6dc70cccd05b910b2dbccc02c5900578be5e99f0d3dbf9d76a5", "Priority": "extra", "Maintainer": "Debian Games Team ", "Description": "Common files for Alien Arena client and server ALIEN ARENA is a standalone 3D first person online deathmatch shooter\n crafted from the original source code of Quake II and Quake III, released\n by id Software under the GPL license. With features including 32 bit\n graphics, new particle engine and effects, light blooms, reflective water,\n hi resolution textures and skins, hi poly models, stain maps, ALIEN ARENA\n pushes the envelope of graphical beauty rivaling today's top games.\n .\n This package installs the common files for Alien Arena.\n", "Homepage": "http://red.planetarena.org", "Tag": "role::app-data, role::shared-lib, special::auto-inst-parts", "Installed-Size": "456", "Version": "7.40-2", "Replaces": "alien-arena (<< 7.33-1)", "Size": "187518", "MD5sum": "1e8cba92c41420aa7baa8a5718d67122", "Package": "alien-arena-common", "Section": "contrib/games", "Architecture": "i386"} const sourcePackageMeta = `Package: access-modifier-checker Binary: libaccess-modifier-checker-java, libaccess-modifier-checker-java-doc diff --git a/src/github.com/smira/aptly/deb/publish.go b/src/github.com/smira/aptly/deb/publish.go index 82ea06ab..8b98cc45 100644 --- a/src/github.com/smira/aptly/deb/publish.go +++ b/src/github.com/smira/aptly/deb/publish.go @@ -3,12 +3,12 @@ package deb import ( "bufio" "bytes" - "code.google.com/p/go-uuid/uuid" "encoding/json" "fmt" "github.com/smira/aptly/aptly" "github.com/smira/aptly/database" "github.com/smira/aptly/utils" + "github.com/smira/go-uuid/uuid" "github.com/ugorji/go/codec" "io/ioutil" "log" @@ -43,6 +43,8 @@ type PublishedRepo struct { Architectures []string // SourceKind is "local"/"repo" SourceKind string + // Skip contents generation + SkipContents bool // Map of sources by each component: component name -> source UUID Sources map[string]string @@ -525,6 +527,8 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP list.PrepareIndex() + contentIndexes := map[string]*ContentsIndex{} + err = list.ForEachIndexed(func(pkg *Package) error { if progress != nil { progress.AddBar(1) @@ -550,6 +554,19 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP if pkg.MatchesArchitecture(arch) { var bufWriter *bufio.Writer + if !p.SkipContents { + key := fmt.Sprintf("%s-%v", arch, pkg.IsUdeb) + + contentIndex := contentIndexes[key] + + if contentIndex == nil { + contentIndex = NewContentsIndex() + contentIndexes[key] = contentIndex + } + + contentIndex.Push(pkg, packagePool) + } + bufWriter, err = indexes.PackageIndex(component, arch, pkg.IsUdeb).BufWriter() if err != nil { return err @@ -569,6 +586,7 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP pkg.files = nil pkg.deps = nil pkg.extra = nil + pkg.contents = nil return nil }) @@ -577,6 +595,25 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP return fmt.Errorf("unable to process packages: %s", err) } + for _, arch := range p.Architectures { + for _, udeb := range []bool{true, false} { + index := contentIndexes[fmt.Sprintf("%s-%v", arch, udeb)] + if index == nil || index.Empty() { + continue + } + + bufWriter, err := indexes.ContentsIndex(component, arch, udeb).BufWriter() + if err != nil { + return fmt.Errorf("unable to generate contents index: %v", err) + } + + _, err = index.WriteTo(bufWriter) + if err != nil { + return fmt.Errorf("unable to generate contents index: %v", err) + } + } + } + if progress != nil { progress.ShutdownBar() } @@ -629,9 +666,9 @@ func (p *PublishedRepo) Publish(packagePool aptly.PackagePool, publishedStorageP release["Date"] = time.Now().UTC().Format("Mon, 2 Jan 2006 15:04:05 MST") release["Architectures"] = strings.Join(utils.StrSlicesSubstract(p.Architectures, []string{"source"}), " ") release["Description"] = " Generated by aptly\n" - release["MD5Sum"] = "\n" - release["SHA1"] = "\n" - release["SHA256"] = "\n" + release["MD5Sum"] = "" + release["SHA1"] = "" + release["SHA256"] = "" release["Components"] = strings.Join(p.Components(), " ") diff --git a/src/github.com/smira/aptly/deb/publish_test.go b/src/github.com/smira/aptly/deb/publish_test.go index 05e2f730..d2be9a03 100644 --- a/src/github.com/smira/aptly/deb/publish_test.go +++ b/src/github.com/smira/aptly/deb/publish_test.go @@ -117,14 +117,19 @@ func (s *PublishedRepoSuite) SetUpTest(c *C) { s.packageCollection.Update(s.p3) s.repo, _ = NewPublishedRepo("", "ppa", "squeeze", nil, []string{"main"}, []interface{}{s.snapshot}, s.factory) + s.repo.SkipContents = true s.repo2, _ = NewPublishedRepo("", "ppa", "maverick", nil, []string{"main"}, []interface{}{s.localRepo}, s.factory) + s.repo2.SkipContents = true s.repo3, _ = NewPublishedRepo("", "linux", "natty", nil, []string{"main", "contrib"}, []interface{}{s.snapshot, s.snapshot2}, s.factory) + s.repo3.SkipContents = true s.repo4, _ = NewPublishedRepo("", "ppa", "maverick", []string{"source"}, []string{"main"}, []interface{}{s.localRepo}, s.factory) + s.repo4.SkipContents = true s.repo5, _ = NewPublishedRepo("files:other", "ppa", "maverick", []string{"source"}, []string{"main"}, []interface{}{s.localRepo}, s.factory) + s.repo5.SkipContents = true poolPath, _ := s.packagePool.Path(s.p1.Files()[0].Filename, s.p1.Files()[0].Checksums.MD5) err := os.MkdirAll(filepath.Dir(poolPath), 0755) @@ -300,7 +305,7 @@ func (s *PublishedRepoSuite) TestPublish(c *C) { c.Assert(err, IsNil) cfr := NewControlFileReader(rf) - st, err := cfr.ReadStanza() + st, err := cfr.ReadStanza(true) c.Assert(err, IsNil) c.Check(st["Origin"], Equals, "ppa squeeze") @@ -313,13 +318,13 @@ func (s *PublishedRepoSuite) TestPublish(c *C) { cfr = NewControlFileReader(pf) for i := 0; i < 3; i++ { - st, err = cfr.ReadStanza() + st, err = cfr.ReadStanza(false) c.Assert(err, IsNil) c.Check(st["Filename"], Equals, "pool/main/a/alien-arena/alien-arena-common_7.40-2_i386.deb") } - st, err = cfr.ReadStanza() + st, err = cfr.ReadStanza(false) c.Assert(err, IsNil) c.Assert(st, IsNil) @@ -327,7 +332,7 @@ func (s *PublishedRepoSuite) TestPublish(c *C) { c.Assert(err, IsNil) cfr = NewControlFileReader(drf) - st, err = cfr.ReadStanza() + st, err = cfr.ReadStanza(true) c.Assert(err, IsNil) c.Check(st["Archive"], Equals, "squeeze") diff --git a/src/github.com/smira/aptly/deb/query.go b/src/github.com/smira/aptly/deb/query.go index 4dac528c..86803430 100644 --- a/src/github.com/smira/aptly/deb/query.go +++ b/src/github.com/smira/aptly/deb/query.go @@ -7,6 +7,16 @@ import ( "strings" ) +// PackageLike is something like Package :) To be refined later +type PackageLike interface { + GetField(string) string + MatchesDependency(Dependency) bool + MatchesArchitecture(string) bool + GetName() string + GetVersion() string + GetArchitecture() string +} + // PackageCatalog is abstraction on top of PackageCollection and PackageList type PackageCatalog interface { Scan(q PackageQuery) (result *PackageList) @@ -18,7 +28,7 @@ type PackageCatalog interface { // PackageQuery is interface of predicate on Package type PackageQuery interface { // Matches calculates match of condition against package - Matches(pkg *Package) bool + Matches(pkg PackageLike) bool // Fast returns if search strategy is possible for this query Fast(list PackageCatalog) bool // Query performs search on package list @@ -63,7 +73,7 @@ type DependencyQuery struct { } // Matches if any of L, R matches -func (q *OrQuery) Matches(pkg *Package) bool { +func (q *OrQuery) Matches(pkg PackageLike) bool { return q.L.Matches(pkg) || q.R.Matches(pkg) } @@ -89,7 +99,7 @@ func (q *OrQuery) String() string { } // Matches if both of L, R matches -func (q *AndQuery) Matches(pkg *Package) bool { +func (q *AndQuery) Matches(pkg PackageLike) bool { return q.L.Matches(pkg) && q.R.Matches(pkg) } @@ -120,7 +130,7 @@ func (q *AndQuery) String() string { } // Matches if not matches -func (q *NotQuery) Matches(pkg *Package) bool { +func (q *NotQuery) Matches(pkg PackageLike) bool { return !q.Q.Matches(pkg) } @@ -141,9 +151,9 @@ func (q *NotQuery) String() string { } // Matches on generic field -func (q *FieldQuery) Matches(pkg *Package) bool { +func (q *FieldQuery) Matches(pkg PackageLike) bool { if q.Field == "$Version" { - return pkg.MatchesDependency(Dependency{Pkg: pkg.Name, Relation: q.Relation, Version: q.Value, Regexp: q.Regexp}) + return pkg.MatchesDependency(Dependency{Pkg: pkg.GetName(), Relation: q.Relation, Version: q.Value, Regexp: q.Regexp}) } if q.Field == "$Architecture" && q.Relation == VersionEqual { return pkg.MatchesArchitecture(q.Value) @@ -218,7 +228,7 @@ func (q *FieldQuery) String() string { } // Matches on dependency condition -func (q *DependencyQuery) Matches(pkg *Package) bool { +func (q *DependencyQuery) Matches(pkg PackageLike) bool { return pkg.MatchesDependency(q.Dep) } @@ -247,8 +257,8 @@ func (q *DependencyQuery) String() string { } // Matches on specific properties -func (q *PkgQuery) Matches(pkg *Package) bool { - return pkg.Name == q.Pkg && pkg.Version == q.Version && pkg.Architecture == q.Arch +func (q *PkgQuery) Matches(pkg PackageLike) bool { + return pkg.GetName() == q.Pkg && pkg.GetVersion() == q.Version && pkg.GetArchitecture() == q.Arch } // Fast is always true for package query diff --git a/src/github.com/smira/aptly/deb/remote.go b/src/github.com/smira/aptly/deb/remote.go index 881fe292..52a0774c 100644 --- a/src/github.com/smira/aptly/deb/remote.go +++ b/src/github.com/smira/aptly/deb/remote.go @@ -2,12 +2,12 @@ package deb import ( "bytes" - "code.google.com/p/go-uuid/uuid" "fmt" "github.com/smira/aptly/aptly" "github.com/smira/aptly/database" "github.com/smira/aptly/http" "github.com/smira/aptly/utils" + "github.com/smira/go-uuid/uuid" "github.com/ugorji/go/codec" "log" "net/url" @@ -263,7 +263,7 @@ func (repo *RemoteRepo) Fetch(d aptly.Downloader, verifier utils.Verifier) error } defer inrelease.Close() - err = verifier.VerifyClearsigned(inrelease) + _, err = verifier.VerifyClearsigned(inrelease, true) if err != nil { goto splitsignature } @@ -304,7 +304,7 @@ ok: defer release.Close() sreader := NewControlFileReader(release) - stanza, err := sreader.ReadStanza() + stanza, err := sreader.ReadStanza(true) if err != nil { return err } @@ -443,7 +443,7 @@ func (repo *RemoteRepo) DownloadPackageIndexes(progress aptly.Progress, d aptly. sreader := NewControlFileReader(packagesReader) for { - stanza, err := sreader.ReadStanza() + stanza, err := sreader.ReadStanza(false) if err != nil { return err } diff --git a/src/github.com/smira/aptly/deb/remote_test.go b/src/github.com/smira/aptly/deb/remote_test.go index 4bdfbbaf..7d0f64dc 100644 --- a/src/github.com/smira/aptly/deb/remote_test.go +++ b/src/github.com/smira/aptly/deb/remote_test.go @@ -30,8 +30,8 @@ func (n *NullVerifier) VerifyDetachedSignature(signature, cleartext io.Reader) e return nil } -func (n *NullVerifier) VerifyClearsigned(clearsigned io.Reader) error { - return nil +func (n *NullVerifier) VerifyClearsigned(clearsigned io.Reader, hint bool) (*utils.GpgKeyInfo, error) { + return nil, nil } func (n *NullVerifier) ExtractClearsigned(clearsigned io.Reader) (text *os.File, err error) { @@ -43,6 +43,10 @@ func (n *NullVerifier) ExtractClearsigned(clearsigned io.Reader) (text *os.File, return } +func (n *NullVerifier) IsClearSigned(clearsign io.Reader) (bool, error) { + return false, nil +} + type PackageListMixinSuite struct { p1, p2, p3 *Package list *PackageList @@ -99,7 +103,7 @@ func (s *RemoteRepoSuite) TearDownTest(c *C) { func (s *RemoteRepoSuite) TestInvalidURL(c *C) { _, err := NewRemoteRepo("s", "http://lolo%2", "squeeze", []string{"main"}, []string{}, false, false) - c.Assert(err, ErrorMatches, ".*hexadecimal escape in host.*") + c.Assert(err, ErrorMatches, ".*(hexadecimal escape|percent-encoded characters) in host.*") } func (s *RemoteRepoSuite) TestFlatCreation(c *C) { @@ -330,7 +334,7 @@ func (s *RemoteRepoSuite) TestDownloadFlat(c *C) { err := s.flat.Fetch(downloader, nil) c.Assert(err, IsNil) - err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, false) + err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, true) c.Assert(err, IsNil) c.Assert(downloader.Empty(), Equals, true) @@ -363,7 +367,7 @@ func (s *RemoteRepoSuite) TestDownloadWithSourcesFlat(c *C) { err := s.flat.Fetch(downloader, nil) c.Assert(err, IsNil) - err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, false) + err = s.flat.DownloadPackageIndexes(s.progress, downloader, s.collectionFactory, true) c.Assert(err, IsNil) c.Assert(downloader.Empty(), Equals, true) diff --git a/src/github.com/smira/aptly/deb/snapshot.go b/src/github.com/smira/aptly/deb/snapshot.go index 3a7ff829..f366e00e 100644 --- a/src/github.com/smira/aptly/deb/snapshot.go +++ b/src/github.com/smira/aptly/deb/snapshot.go @@ -2,11 +2,11 @@ package deb import ( "bytes" - "code.google.com/p/go-uuid/uuid" "errors" "fmt" "github.com/smira/aptly/database" "github.com/smira/aptly/utils" + "github.com/smira/go-uuid/uuid" "github.com/ugorji/go/codec" "log" "sort" diff --git a/src/github.com/smira/aptly/deb/uploaders.go b/src/github.com/smira/aptly/deb/uploaders.go new file mode 100644 index 00000000..17193c10 --- /dev/null +++ b/src/github.com/smira/aptly/deb/uploaders.go @@ -0,0 +1,105 @@ +package deb + +import ( + "encoding/json" + "fmt" + "github.com/DisposaBoy/JsonConfigReader" + "github.com/smira/aptly/utils" + "os" +) + +// UploadersRule is single rule of format: what packages can group or key upload +type UploadersRule struct { + Condition string `json:"condition"` + Allow []string `json:"allow"` + Deny []string `json:"deny"` + CompiledCondition PackageQuery `json:"-" codec:"-"` +} + +func (u UploadersRule) String() string { + b, _ := json.Marshal(u) + return string(b) +} + +// Uploaders is configuration of restrictions for .changes file importing +type Uploaders struct { + Groups map[string][]string `json:"groups"` + Rules []UploadersRule `json:"rules"` +} + +func (u *Uploaders) String() string { + b, _ := json.Marshal(u) + return string(b) +} + +// NewUploadersFromFile loads Uploaders structue from .json file +func NewUploadersFromFile(path string) (*Uploaders, error) { + uploaders := &Uploaders{} + f, err := os.Open(path) + if err != nil { + return nil, fmt.Errorf("error loading uploaders file: %s", err) + } + defer f.Close() + + err = json.NewDecoder(JsonConfigReader.New(f)).Decode(&uploaders) + if err != nil { + return nil, fmt.Errorf("error loading uploaders file: %s", err) + } + + return uploaders, nil +} + +func (u *Uploaders) expandGroupsInternal(items []string, trail []string) []string { + result := []string{} + + for _, item := range items { + // stop infinite recursion + if utils.StrSliceHasItem(trail, item) { + continue + } + + group, ok := u.Groups[item] + if !ok { + result = append(result, item) + } else { + newTrail := append([]string(nil), trail...) + result = append(result, u.expandGroupsInternal(group, append(newTrail, item))...) + } + } + + return result +} + +// ExpandGroups expands list of keys/groups into list of keys +func (u *Uploaders) ExpandGroups(items []string) []string { + result := u.expandGroupsInternal(items, []string{}) + + return utils.StrSliceDeduplicate(result) +} + +// IsAllowed checks whether listed keys are allowed to upload given .changes file +func (u *Uploaders) IsAllowed(changes *Changes) error { + for _, rule := range u.Rules { + if rule.CompiledCondition.Matches(changes) { + deny := u.ExpandGroups(rule.Deny) + for _, key := range changes.SignatureKeys { + for _, item := range deny { + if item == "*" || key.Matches(utils.GpgKey(item)) { + return fmt.Errorf("denied according to rule: %s", rule) + } + } + } + + allow := u.ExpandGroups(rule.Allow) + for _, key := range changes.SignatureKeys { + for _, item := range allow { + if item == "*" || key.Matches(utils.GpgKey(item)) { + return nil + } + } + } + } + } + + return fmt.Errorf("denied as no rule matches") +} diff --git a/src/github.com/smira/aptly/deb/uploaders_test.go b/src/github.com/smira/aptly/deb/uploaders_test.go new file mode 100644 index 00000000..89258011 --- /dev/null +++ b/src/github.com/smira/aptly/deb/uploaders_test.go @@ -0,0 +1,81 @@ +package deb + +import ( + "github.com/smira/aptly/utils" + . "gopkg.in/check.v1" +) + +type UploadersSuite struct { +} + +var _ = Suite(&UploadersSuite{}) + +func (s *UploadersSuite) TestExpandGroups(c *C) { + u := &Uploaders{ + Groups: map[string][]string{ + "group1": {"key1", "group2"}, + "group2": {"key1", "key2", "key3", "group3"}, + "group3": {}, + "group4": {"key1", "group5"}, + "group6": {"key1", "group8"}, + "group7": {"key2", "group6"}, + "group8": {"group7"}, + }, + } + + c.Check(u.ExpandGroups([]string{"group1"}), DeepEquals, []string{"key1", "key2", "key3"}) + c.Check(u.ExpandGroups([]string{"group2"}), DeepEquals, []string{"key1", "key2", "key3"}) + c.Check(u.ExpandGroups([]string{"group3"}), DeepEquals, []string{}) + c.Check(u.ExpandGroups([]string{"group4"}), DeepEquals, []string{"key1", "group5"}) + c.Check(u.ExpandGroups([]string{"group6"}), DeepEquals, []string{"key1", "key2"}) + c.Check(u.ExpandGroups([]string{"group7"}), DeepEquals, []string{"key2", "key1"}) + c.Check(u.ExpandGroups([]string{"group8"}), DeepEquals, []string{"key2", "key1"}) +} + +func (s *UploadersSuite) TestIsAllowed(c *C) { + u := &Uploaders{ + Groups: map[string][]string{ + "group1": {"37E1C17570096AD1", "EC4B033C70096AD1"}, + }, + Rules: []UploadersRule{ + { + CompiledCondition: &FieldQuery{Field: "Source", Relation: VersionEqual, Value: "calamares"}, + Allow: []string{"*"}, + }, + { + CompiledCondition: &FieldQuery{Field: "Source", Relation: VersionEqual, Value: "never-calamares"}, + Deny: []string{"*"}, + }, + { + CompiledCondition: &FieldQuery{Field: "Source", Relation: VersionEqual, Value: "some-calamares"}, + Allow: []string{"group1", "12345678"}, + }, + { + CompiledCondition: &FieldQuery{Field: "Source", Relation: VersionEqual, Value: "some-calamares"}, + Deny: []string{"45678901", "12345678"}, + }, + }, + } + + // no keys - not allowed + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{}, Stanza: Stanza{"Source": "calamares"}}), ErrorMatches, "denied as no rule matches") + + // no rule - not allowed + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{"37E1C17570096AD1", "EC4B033C70096AD1"}, Stanza: Stanza{"Source": "unknown-calamares"}}), ErrorMatches, "denied as no rule matches") + + // first rule: allow anyone do stuff with calamares + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{"ABCD1234", "1234ABCD"}, Stanza: Stanza{"Source": "calamares"}}), IsNil) + + // second rule: nobody is allowed to do stuff with never-calamares + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{"ABCD1234", "1234ABCD"}, Stanza: Stanza{"Source": "never-calamares"}}), + ErrorMatches, "denied according to rule: {\"condition\":\"\",\"allow\":null,\"deny\":\\[\"\\*\"\\]}") + + // third rule: anyone from the group or explicit key + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{"45678901", "12345678"}, Stanza: Stanza{"Source": "some-calamares"}}), IsNil) + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{"37E1C17570096AD1"}, Stanza: Stanza{"Source": "some-calamares"}}), IsNil) + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{"70096AD1"}, Stanza: Stanza{"Source": "some-calamares"}}), IsNil) + + // fourth rule: some are not allowed + c.Check(u.IsAllowed(&Changes{SignatureKeys: []utils.GpgKey{"ABCD1234", "45678901"}, Stanza: Stanza{"Source": "some-calamares"}}), + ErrorMatches, "denied according to rule: {\"condition\":\"\",\"allow\":null,\"deny\":\\[\"45678901\",\"12345678\"\\]}") +} diff --git a/src/github.com/smira/aptly/http/download.go b/src/github.com/smira/aptly/http/download.go index ee117f31..c2aef32a 100644 --- a/src/github.com/smira/aptly/http/download.go +++ b/src/github.com/smira/aptly/http/download.go @@ -1,10 +1,10 @@ package http import ( - "code.google.com/p/mxk/go1/flowcontrol" "compress/bzip2" "compress/gzip" "fmt" + "github.com/mxk/go-flowrate/flowrate" "github.com/smira/aptly/aptly" "github.com/smira/aptly/utils" "github.com/smira/go-ftp-protocol/protocol" @@ -75,7 +75,7 @@ func NewDownloader(threads int, downLimit int64, progress aptly.Progress) aptly. } if downLimit > 0 { - downloader.aggWriter = flowcontrol.NewWriter(progress, downLimit) + downloader.aggWriter = flowrate.NewWriter(progress, downLimit) } else { downloader.aggWriter = progress } @@ -145,6 +145,7 @@ func (downloader *downloaderImpl) handleTask(task *downloadTask) { task.result <- fmt.Errorf("%s: %s", task.url, err) return } + req.Close = true proxyURL, _ := downloader.client.Transport.(*http.Transport).Proxy(req) if proxyURL == nil && (req.URL.Scheme == "http" || req.URL.Scheme == "https") { @@ -326,6 +327,10 @@ func DownloadTryCompression(downloader aptly.Downloader, url string, expectedChe } if !foundChecksum { + if !ignoreMismatch { + continue + } + file, err = DownloadTemp(downloader, tryURL) } @@ -344,5 +349,9 @@ func DownloadTryCompression(downloader aptly.Downloader, url string, expectedChe return uncompressed, file, err } + + if err == nil { + err = fmt.Errorf("no candidates for %s found", url) + } return nil, nil, err } diff --git a/src/github.com/smira/aptly/http/download_test.go b/src/github.com/smira/aptly/http/download_test.go index d5eda5b4..b63fd665 100644 --- a/src/github.com/smira/aptly/http/download_test.go +++ b/src/github.com/smira/aptly/http/download_test.go @@ -257,27 +257,32 @@ func (s *DownloaderSuite) TestDownloadTryCompression(c *C) { d = NewFakeDownloader() d.ExpectError("http://example.com/file.bz2", &HTTPError{Code: 404}) d.ExpectResponse("http://example.com/file.gz", "x") - r, file, err = DownloadTryCompression(d, "http://example.com/file", nil, false) + r, file, err = DownloadTryCompression(d, "http://example.com/file", nil, true) c.Assert(err, ErrorMatches, "unexpected EOF") c.Assert(d.Empty(), Equals, true) } func (s *DownloaderSuite) TestDownloadTryCompressionErrors(c *C) { d := NewFakeDownloader() - _, _, err := DownloadTryCompression(d, "http://example.com/file", nil, false) + _, _, err := DownloadTryCompression(d, "http://example.com/file", nil, true) c.Assert(err, ErrorMatches, "unexpected request.*") d = NewFakeDownloader() d.ExpectError("http://example.com/file.bz2", &HTTPError{Code: 404}) d.ExpectError("http://example.com/file.gz", &HTTPError{Code: 404}) d.ExpectError("http://example.com/file", errors.New("403")) - _, _, err = DownloadTryCompression(d, "http://example.com/file", nil, false) + _, _, err = DownloadTryCompression(d, "http://example.com/file", nil, true) c.Assert(err, ErrorMatches, "403") d = NewFakeDownloader() d.ExpectError("http://example.com/file.bz2", &HTTPError{Code: 404}) d.ExpectError("http://example.com/file.gz", &HTTPError{Code: 404}) d.ExpectResponse("http://example.com/file", rawData) - _, _, err = DownloadTryCompression(d, "http://example.com/file", map[string]utils.ChecksumInfo{"file": {Size: 7}}, false) + expectedChecksums := map[string]utils.ChecksumInfo{ + "file.bz2": {Size: 7}, + "file.gz": {Size: 7}, + "file": {Size: 7}, + } + _, _, err = DownloadTryCompression(d, "http://example.com/file", expectedChecksums, false) c.Assert(err, ErrorMatches, "checksums don't match.*") } diff --git a/src/github.com/smira/aptly/man/aptly.1 b/src/github.com/smira/aptly/man/aptly.1 index f4ed4b38..d7992777 100644 --- a/src/github.com/smira/aptly/man/aptly.1 +++ b/src/github.com/smira/aptly/man/aptly.1 @@ -1,7 +1,7 @@ .\" generated with Ronn/v0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3 . -.TH "APTLY" "1" "March 2015" "" "" +.TH "APTLY" "1" "January 2016" "" "" . .SH "NAME" \fBaptly\fR \- Debian repository management tool @@ -52,13 +52,15 @@ Configuration file is stored in JSON format (default values shown below): "test": { "region": "us\-east\-1", "bucket": "repo", + "endpoint": "", "awsAccessKeyID": "", "awsSecretAccessKey": "", "prefix": "", "acl": "public\-read", "storageClass": "", "encryptionMethod": "", - "plusWorkaround": false + "plusWorkaround": false, + "disableMultiDel": false } }, "SwiftPublishEndpoints": { @@ -138,7 +140,7 @@ configuration of Amazon S3 publishing endpoints (see below) configuration of OpenStack Swift publishing endpoints (see below) . .SH "S3 PUBLISHING ENDPOINTS" -aptly could be configured to publish repository directly to Amazon S3\. First, publishing endpoints should be described in aptly configuration file\. Each endpoint has name and associated settings: +aptly could be configured to publish repository directly to Amazon S3 (or S3\-compatible cloud storage)\. First, publishing endpoints should be described in aptly configuration file\. Each endpoint has name and associated settings: . .TP \fBregion\fR @@ -149,6 +151,10 @@ Amazon region for S3 bucket (e\.g\. \fBus\-east\-1\fR) bucket name . .TP +\fBendpoint\fR +(optional) when using S3\-compatible cloud storage, specify hostname of service endpoint here, region is ignored if endpoint is set (set region to some human\-readable name) (should be left blank for real Amazon S3) +. +.TP \fBprefix\fR (optional) do publishing under specified prefix in the bucket, defaults to no prefix (bucket root) . @@ -170,7 +176,11 @@ bucket name . .TP \fBplusWorkaround\fR -(optional) workaround misbehavior in apt and Amazon S3 for files with \fB+\fR in filename by creating two copies of package files with \fB+\fR in filename: one original and another one with spaces instead of plus signs With \fBplusWorkaround\fR enabled, package files with plus sign would be stored twice\. aptly might not cleanup files with spaces when published repository is dropped or updated (switched) to new version of repository (snapshot)\. +(optional) workaround misbehavior in apt and Amazon S3 for files with \fB+\fR in filename by creating two copies of package files with \fB+\fR in filename: one original and another one with spaces instead of plus signs With \fBplusWorkaround\fR enabled, package files with plus sign would be stored twice\. aptly might not cleanup files with spaces when published repository is dropped or updated (switched) to new version of repository (snapshot) +. +.TP +\fBdisableMultiDel\fR +(optional) for S3\-compatible cloud storages which do not support \fBMultiDel\fR S3 API, enable this setting (file deletion would be slower with this setting enabled) . .P In order to publish to S3, specify endpoint as \fBs3:endpoint\-name:\fR before publishing prefix on the command line, e\.g\.: @@ -304,6 +314,24 @@ When specified on command line, query may have to be quoted according to shell r .P \fBaptly repo import percona stable \(cqmysql\-client (>= 3\.6)\(cq\fR . +.SH "PACKAGE DISPLAY FORMAT" +Some aptly commands (\fBaptly mirror search\fR, \fBaptly package search\fR, \|\.\|\.\|\.) support \fB\-format\fR flag which allows to customize how search results are printed\. Golang templates are used to specify display format, with all package stanza fields available to template\. In addition to package stanza fields aptly provides: +. +.TP +\fBKey\fR +internal aptly package ID, unique for all packages in aptly (combination of \fBShortKey\fR and \fBFilesHash\fR)\. +. +.TP +\fBFilesHash\fR +hash that includes MD5 of all packages files\. +. +.TP +\fBShortKey\fR +package ID, which is unique in single list (mirror, repo, snapshot, \|\.\|\.\|\.), but not unique in whole aptly package collection\. +. +.P +For example, default aptly display format could be presented with the following template: \fB{{\.Package}}_{{\.Version}}_{{\.Architecture}}\fR\. To display package name with dependencies: \fB{{\.Package}} | {{\.Depends}}\fR\. More information on Golang template syntax: http://godoc\.org/text/template +. .SH "GLOBAL OPTIONS" . .TP @@ -316,7 +344,7 @@ location of configuration file (default locations are /etc/aptly\.conf, ~/\.aptl . .TP \-\fBdep\-follow\-all\-variants\fR=false -when processing dependencies, follow a & b if depdency is \(cqa|b\(cq +when processing dependencies, follow a & b if dependency is \(cqa|b\(cq . .TP \-\fBdep\-follow\-recommends\fR=false @@ -537,6 +565,10 @@ $ aptly mirror search wheezy\-main \(cq$Architecture (i386), Name (% *\-dev)\(cq Options: . .TP +\-\fBformat\fR= +custom format for result printing +. +.TP \-\fBwith\-deps\fR=false include dependencies into search results . @@ -613,6 +645,10 @@ default component when publishing \-\fBdistribution\fR= default distribution when publishing . +.TP +\-\fBuploaders\-file\fR= +uploaders\.json to be used when including \.changes into this repository +. .SH "DELETE LOCAL REPOSITORY" \fBaptly\fR \fBrepo\fR \fBdrop\fR \fIname\fR . @@ -659,6 +695,10 @@ default component when publishing \-\fBdistribution\fR= default distribution when publishing . +.TP +\-\fBuploaders\-file\fR= +uploaders\.json to be used when including \.changes into this repository +. .SH "IMPORT PACKAGES FROM MIRROR TO LOCAL REPOSITORY" \fBaptly\fR \fBrepo\fR \fBimport\fR \fIsrc\-mirror\fR \fIdst\-repo\fR \fIpackage\-query\fR \fB\|\.\|\.\|\.\fR . @@ -794,9 +834,59 @@ $ aptly repo search my\-software \(cq$Architecture (i386), Name (% *\-dev)\(cq Options: . .TP +\-\fBformat\fR= +custom format for result printing +. +.TP \-\fBwith\-deps\fR=false include dependencies into search results . +.SH "ADD PACKAGES TO LOCAL REPOSITORIES BASED ON \.CHANGES FILES" +\fBaptly\fR \fBrepo\fR \fBinclude\fR |\fIdirectory\fR \fB\|\.\|\.\|\.\fR +. +.P +Command include looks for \.changes files in list of arguments or specified directories\. Each \.changes file is verified, parsed, referenced files are put into separate temporary directory and added into local repository\. Successfully imported files are removed by default\. +. +.P +Additionally uploads could be restricted with file\. Rules in this file control uploads based on GPG key ID of \.changes file signature and queries on \.changes file fields\. +. +.P +Example: +. +.P +$ aptly repo include \-repo=foo\-release incoming/ +. +.P +Options: +. +.TP +\-\fBaccept\-unsigned\fR=false +accept unsigned \.changes files +. +.TP +\-\fBforce\-replace\fR=false +when adding package that conflicts with existing package, remove existing package +. +.TP +\-\fBignore\-signatures\fR=false +disable verification of \.changes file signature +. +.TP +\-\fBkeyring\fR= +gpg keyring to use when verifying Release file (could be specified multiple times) +. +.TP +\-\fBno\-remove\-files\fR=false +don\(cqt remove files that have been imported successfully into repository +. +.TP +\-\fBrepo\fR={{\.Distribution}} +which repo should files go to, defaults to Distribution field of \.changes file +. +.TP +\-\fBuploaders\-file\fR= +path to uploaders\.json file +. .SH "CREATES SNAPSHOT OF MIRROR (LOCAL REPOSITORY) CONTENTS" \fBaptly\fR \fBsnapshot\fR \fBcreate\fR \fIname\fR \fBfrom\fR \fBmirror\fR \fImirror\-name\fR \fB|\fR \fBfrom\fR \fBrepo\fR \fIrepo\-name\fR \fB|\fR \fBempty\fR . @@ -1038,6 +1128,10 @@ $ aptly snapshot search wheezy\-main \(cq$Architecture (i386), Name (% *\-dev)\( Options: . .TP +\-\fBformat\fR= +custom format for result printing +. +.TP \-\fBwith\-deps\fR=false include dependencies into search results . @@ -1202,6 +1296,10 @@ GPG passhprase\-file for the key (warning: could be insecure) GPG secret keyring to use (instead of default) . .TP +\-\fBskip\-contents\fR=false +don\(cqt generate Contents indexes +. +.TP \-\fBskip\-signing\fR=false don\(cqt sign Release files with GPG . @@ -1285,6 +1383,10 @@ GPG passhprase\-file for the key (warning: could be insecure) GPG secret keyring to use (instead of default) . .TP +\-\fBskip\-contents\fR=false +don\(cqt generate Contents indexes +. +.TP \-\fBskip\-signing\fR=false don\(cqt sign Release files with GPG . @@ -1359,6 +1461,10 @@ GPG passhprase\-file for the key (warning: could be insecure) GPG secret keyring to use (instead of default) . .TP +\-\fBskip\-contents\fR=false +don\(cqt generate Contents indexes +. +.TP \-\fBskip\-signing\fR=false don\(cqt sign Release files with GPG . @@ -1416,6 +1522,10 @@ GPG passhprase\-file for the key (warning: could be insecure) GPG secret keyring to use (instead of default) . .TP +\-\fBskip\-contents\fR=false +don\(cqt generate Contents indexes +. +.TP \-\fBskip\-signing\fR=false don\(cqt sign Release files with GPG . @@ -1438,6 +1548,13 @@ $ aptly package search \(cq$Architecture (i386), Name (% *\-dev)\(cq . .IP "" 0 . +.P +Options: +. +.TP +\-\fBformat\fR= +custom format for result printing +. .SH "SHOW DETAILS ABOUT PACKAGES MATCHING QUERY" \fBaptly\fR \fBpackage\fR \fBshow\fR \fIpackage\-query\fR . @@ -1522,6 +1639,29 @@ Options: \-\fBlisten\fR=:8080 host:port for HTTP listening . +.SH "START API HTTP SERVICE" +\fBaptly\fR \fBapi\fR \fBserve\fR +. +.P +Stat HTTP server with aptly REST API\. +. +.P +Example: +. +.P +$ aptly api serve \-listen=:8080 +. +.P +Options: +. +.TP +\-\fBlisten\fR=:8080 +host:port for HTTP listening +. +.TP +\-\fBno\-lock\fR=false +don\(cqt lock the database +. .SH "RENDER GRAPH OF RELATIONSHIPS" \fBaptly\fR \fBgraph\fR . @@ -1534,6 +1674,17 @@ Example: .P $ aptly graph . +.P +Options: +. +.TP +\-\fBformat\fR=png +render graph to specified format (png, svg, pdf, etc\.) +. +.TP +\-\fBoutput\fR= +specify output filename, default is to open result in viewer +. .SH "SHOW CURRENT APTLY\(cqS CONFIG" \fBaptly\fR \fBconfig\fR \fBshow\fR . @@ -1577,6 +1728,18 @@ Options: \-\fBfilename\fR= specifies the filename that contains the commands to run . +.SH "SHOW CURRENT APTLY\(cqS CONFIG" +\fBaptly\fR \fBconfig\fR \fBshow\fR +. +.P +Command show displays the current aptly configuration\. +. +.P +Example: +. +.P +$ aptly config show +. .SH "ENVIRONMENT" If environment variable \fBHTTP_PROXY\fR is set \fBaptly\fR would use its value to proxy all HTTP requests\. . @@ -1596,4 +1759,64 @@ general failure command parse failure . .SH "AUTHORS" -Andrey Smirnov (me@smira\.ru) +List of contributors, in chronological order: +. +.IP "\[ci]" 4 +Andrey Smirnov (https://github\.com/smira) +. +.IP "\[ci]" 4 +Sebastien Binet (https://github\.com/sbinet) +. +.IP "\[ci]" 4 +Ryan Uber (https://github\.com/ryanuber) +. +.IP "\[ci]" 4 +Simon Aquino (https://github\.com/queeno) +. +.IP "\[ci]" 4 +Vincent Batoufflet (https://github\.com/vbatoufflet) +. +.IP "\[ci]" 4 +Ivan Kurnosov (https://github\.com/zerkms) +. +.IP "\[ci]" 4 +Dmitrii Kashin (https://github\.com/freehck) +. +.IP "\[ci]" 4 +Chris Read (https://github\.com/cread) +. +.IP "\[ci]" 4 +Rohan Garg (https://github\.com/shadeslayer) +. +.IP "\[ci]" 4 +Russ Allbery (https://github\.com/rra) +. +.IP "\[ci]" 4 +Sylvain Baubeau (https://github\.com/lebauce) +. +.IP "\[ci]" 4 +Andrea Bernardo Ciddio (https://github\.com/bcandrea) +. +.IP "\[ci]" 4 +Michael Koval (https://github\.com/mkoval) +. +.IP "\[ci]" 4 +Alexander Guy (https://github\.com/alexanderguy) +. +.IP "\[ci]" 4 +Sebastien Badia (https://github\.com/sbadia) +. +.IP "\[ci]" 4 +Szymon Sobik (https://github\.com/sobczyk) +. +.IP "\[ci]" 4 +Paul Krohn (https://github\.com/paul\-krohn) +. +.IP "\[ci]" 4 +Vincent Bernat (https://github\.com/vincentbernat) +. +.IP "\[ci]" 4 +x539 (https://github\.com/x539) +. +.IP "" 0 + diff --git a/src/github.com/smira/aptly/man/aptly.1.ronn.tmpl b/src/github.com/smira/aptly/man/aptly.1.ronn.tmpl index 3d6528b2..a85b93dd 100644 --- a/src/github.com/smira/aptly/man/aptly.1.ronn.tmpl +++ b/src/github.com/smira/aptly/man/aptly.1.ronn.tmpl @@ -44,13 +44,15 @@ Configuration file is stored in JSON format (default values shown below): "test": { "region": "us-east-1", "bucket": "repo", + "endpoint": "", "awsAccessKeyID": "", "awsSecretAccessKey": "", "prefix": "", "acl": "public-read", "storageClass": "", "encryptionMethod": "", - "plusWorkaround": false + "plusWorkaround": false, + "disableMultiDel": false } }, "SwiftPublishEndpoints": { @@ -118,7 +120,8 @@ Options: ## S3 PUBLISHING ENDPOINTS -aptly could be configured to publish repository directly to Amazon S3. First, publishing +aptly could be configured to publish repository directly to Amazon S3 (or S3-compatible +cloud storage). First, publishing endpoints should be described in aptly configuration file. Each endpoint has name and associated settings: @@ -126,6 +129,10 @@ and associated settings: Amazon region for S3 bucket (e.g. `us-east-1`) * `bucket`: bucket name + * `endpoint`: + (optional) when using S3-compatible cloud storage, specify hostname of service endpoint here, + region is ignored if endpoint is set (set region to some human-readable name) + (should be left blank for real Amazon S3) * `prefix`: (optional) do publishing under specified prefix in the bucket, defaults to no prefix (bucket root) @@ -152,7 +159,10 @@ and associated settings: and another one with spaces instead of plus signs With `plusWorkaround` enabled, package files with plus sign would be stored twice. aptly might not cleanup files with spaces when published - repository is dropped or updated (switched) to new version of repository (snapshot). + repository is dropped or updated (switched) to new version of repository (snapshot) + * `disableMultiDel`: + (optional) for S3-compatible cloud storages which do not support `MultiDel` S3 API, + enable this setting (file deletion would be slower with this setting enabled) In order to publish to S3, specify endpoint as `s3:endpoint-name:` before publishing prefix on the command line, e.g.: @@ -264,6 +274,27 @@ When specified on command line, query may have to be quoted according to shell r `aptly repo import percona stable 'mysql-client (>= 3.6)'` +## PACKAGE DISPLAY FORMAT + +Some aptly commands (`aptly mirror search`, `aptly package search`, ...) support `-format` flag +which allows to customize how search results are printed. Golang templates are used to specify +display format, with all package stanza fields available to template. In addition to package stanza +fields aptly provides: + + * `Key`: + internal aptly package ID, unique for all packages in aptly + (combination of `ShortKey` and `FilesHash`). + + * `FilesHash`: + hash that includes MD5 of all packages files. + + * `ShortKey`: + package ID, which is unique in single list (mirror, repo, snapshot, ...), but not unique + in whole aptly package collection. + +For example, default aptly display format could be presented with the following template: +`{{"{{"}}.Package{{"}}"}}_{{"{{"}}.Version{{"}}"}}_{{"{{"}}.Architecture{{"}}"}}`. To display package name with dependencies: +`{{"{{"}}.Package{{"}}"}} | {{"{{"}}.Depends{{"}}"}}`. More information on Golang template syntax: http://godoc.org/text/template ## GLOBAL OPTIONS @@ -283,12 +314,16 @@ When specified on command line, query may have to be quoted according to shell r {{template "command" findCommand . "serve"}} +{{template "command" findCommand . "api"}} + {{template "command" findCommand . "graph"}} {{template "command" findCommand . "config"}} {{template "command" findCommand . "task"}} +{{template "command" findCommand . "config"}} + ## ENVIRONMENT If environment variable `HTTP_PROXY` is set `aptly` would use its value @@ -309,7 +344,7 @@ to proxy all HTTP requests. ## AUTHORS -Andrey Smirnov (me@smira.ru) +{{authors}} {{end}} diff --git a/src/github.com/smira/aptly/man/gen.go b/src/github.com/smira/aptly/man/gen.go index 0bc9e238..0718940e 100644 --- a/src/github.com/smira/aptly/man/gen.go +++ b/src/github.com/smira/aptly/man/gen.go @@ -5,6 +5,7 @@ import ( "github.com/smira/aptly/cmd" "github.com/smira/commander" "github.com/smira/flag" + "io/ioutil" "log" "os" "os/exec" @@ -43,6 +44,12 @@ func capitalize(s string) string { return strings.Join(parts, " ") } +var authorsS string + +func authors() string { + return authorsS +} + func main() { command := cmd.RootCommand() command.UsageLine = "aptly" @@ -56,9 +63,24 @@ func main() { "findCommand": findCommand, "toUpper": strings.ToUpper, "capitalize": capitalize, + "authors": authors, }) template.Must(templ.ParseFiles(filepath.Join(filepath.Dir(_File), "aptly.1.ronn.tmpl"))) + authorsF, err := os.Open(filepath.Join(filepath.Dir(_File), "..", "AUTHORS")) + if err != nil { + log.Fatal(err) + } + + authorsB, err := ioutil.ReadAll(authorsF) + if err != nil { + log.Fatal(err) + } + + authorsF.Close() + + authorsS = string(authorsB) + output, err := os.Create(filepath.Join(filepath.Dir(_File), "aptly.1.ronn")) if err != nil { log.Fatal(err) diff --git a/src/github.com/smira/aptly/s3/public.go b/src/github.com/smira/aptly/s3/public.go index f0011127..4482ce15 100644 --- a/src/github.com/smira/aptly/s3/public.go +++ b/src/github.com/smira/aptly/s3/public.go @@ -6,6 +6,7 @@ import ( "github.com/mitchellh/goamz/s3" "github.com/smira/aptly/aptly" "github.com/smira/aptly/files" + "net/http" "os" "path/filepath" "strings" @@ -20,6 +21,8 @@ type PublishedStorage struct { storageClass string encryptionMethod string plusWorkaround bool + disableMultiDel bool + pathCache map[string]string } // Check interface @@ -29,7 +32,7 @@ var ( // NewPublishedStorageRaw creates published storage from raw aws credentials func NewPublishedStorageRaw(auth aws.Auth, region aws.Region, bucket, defaultACL, prefix, - storageClass, encryptionMethod string, plusWorkaround bool) (*PublishedStorage, error) { + storageClass, encryptionMethod string, plusWorkaround, disabledMultiDel bool) (*PublishedStorage, error) { if defaultACL == "" { defaultACL = "private" } @@ -44,7 +47,13 @@ func NewPublishedStorageRaw(auth aws.Auth, region aws.Region, bucket, defaultACL prefix: prefix, storageClass: storageClass, encryptionMethod: encryptionMethod, - plusWorkaround: plusWorkaround} + plusWorkaround: plusWorkaround, + disableMultiDel: disabledMultiDel, + } + + result.s3.HTTPClient = func() *http.Client { + return RetryingClient + } result.bucket = result.s3.Bucket(bucket) return result, nil @@ -52,19 +61,33 @@ func NewPublishedStorageRaw(auth aws.Auth, region aws.Region, bucket, defaultACL // NewPublishedStorage creates new instance of PublishedStorage with specified S3 access // keys, region and bucket name -func NewPublishedStorage(accessKey, secretKey, region, bucket, defaultACL, prefix, - storageClass, encryptionMethod string, plusWorkaround bool) (*PublishedStorage, error) { +func NewPublishedStorage(accessKey, secretKey, region, endpoint, bucket, defaultACL, prefix, + storageClass, encryptionMethod string, plusWorkaround, disableMultiDel bool) (*PublishedStorage, error) { auth, err := aws.GetAuth(accessKey, secretKey) if err != nil { return nil, err } - awsRegion, ok := aws.Regions[region] - if !ok { - return nil, fmt.Errorf("unknown region: %#v", region) + var awsRegion aws.Region + + if endpoint == "" { + var ok bool + + awsRegion, ok = aws.Regions[region] + if !ok { + return nil, fmt.Errorf("unknown region: %#v", region) + } + } else { + awsRegion = aws.Region{ + Name: region, + S3Endpoint: endpoint, + S3LocationConstraint: true, + S3LowercaseBucket: true, + } } - return NewPublishedStorageRaw(auth, awsRegion, bucket, defaultACL, prefix, storageClass, encryptionMethod, plusWorkaround) + return NewPublishedStorageRaw(auth, awsRegion, bucket, defaultACL, prefix, storageClass, encryptionMethod, + plusWorkaround, disableMultiDel) } // String @@ -123,6 +146,11 @@ func (storage *PublishedStorage) Remove(path string) error { if err != nil { return fmt.Errorf("error deleting %s from %s: %s", path, storage, err) } + + if storage.plusWorkaround && strings.Index(path, "+") != -1 { + // try to remove workaround version, but don't care about result + _ = storage.Remove(strings.Replace(path, "+", " ", -1)) + } return nil } @@ -130,32 +158,38 @@ func (storage *PublishedStorage) Remove(path string) error { func (storage *PublishedStorage) RemoveDirs(path string, progress aptly.Progress) error { const page = 1000 - filelist, err := storage.Filelist(path) + filelist, _, err := storage.internalFilelist(path, false) if err != nil { return err } - numParts := (len(filelist) + page - 1) / page - - for i := 0; i < numParts; i++ { - var part []string - if i == numParts-1 { - part = filelist[i*page:] - } else { - part = filelist[i*page : (i+1)*page] + if storage.disableMultiDel { + for i := range filelist { + err = storage.bucket.Del(filepath.Join(storage.prefix, path, filelist[i])) + if err != nil { + return fmt.Errorf("error deleting path %s from %s: %s", filelist[i], storage, err) + } } - paths := make([]string, len(part)) + } else { + numParts := (len(filelist) + page - 1) / page - for i := range part { - paths[i] = filepath.Join(storage.prefix, path, part[i]) - } + for i := 0; i < numParts; i++ { + var part []string + if i == numParts-1 { + part = filelist[i*page:] + } else { + part = filelist[i*page : (i+1)*page] + } + paths := make([]string, len(part)) - err = storage.bucket.MultiDel(paths) - if err != nil { - return fmt.Errorf("error deleting multiple paths from %s: %s", storage, err) - } - if err != nil { - return err + for i := range part { + paths[i] = filepath.Join(storage.prefix, path, part[i]) + } + + err = storage.bucket.MultiDel(paths) + if err != nil { + return fmt.Errorf("error deleting multiple paths from %s: %s", storage, err) + } } } @@ -179,17 +213,25 @@ func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourceP poolPath := filepath.Join(storage.prefix, relPath) var ( - dstKey *s3.Key - err error + err error ) - dstKey, err = storage.bucket.GetKey(poolPath) - if err != nil { - if s3err, ok := err.(*s3.Error); !ok || s3err.StatusCode != 404 { - return fmt.Errorf("error getting information about %s from %s: %s", poolPath, storage, err) + if storage.pathCache == nil { + paths, md5s, err := storage.internalFilelist(storage.prefix, true) + if err != nil { + return fmt.Errorf("error caching paths under prefix: %s", err) } - } else { - destinationMD5 := strings.Replace(dstKey.ETag, "\"", "", -1) + + storage.pathCache = make(map[string]string, len(paths)) + + for i := range paths { + storage.pathCache[paths[i]] = md5s[i] + } + } + + destinationMD5, exists := storage.pathCache[relPath] + + if exists { if destinationMD5 == sourceMD5 { return nil } @@ -200,12 +242,23 @@ func (storage *PublishedStorage) LinkFromPool(publishedDirectory string, sourceP } } - return storage.PutFile(relPath, sourcePath) + err = storage.PutFile(relPath, sourcePath) + if err == nil { + storage.pathCache[relPath] = sourceMD5 + } + + return err } // Filelist returns list of files under prefix func (storage *PublishedStorage) Filelist(prefix string) ([]string, error) { - result := []string{} + paths, _, err := storage.internalFilelist(prefix, true) + return paths, err +} + +func (storage *PublishedStorage) internalFilelist(prefix string, hidePlusWorkaround bool) (paths []string, md5s []string, err error) { + paths = make([]string, 0, 1024) + md5s = make([]string, 0, 1024) marker := "" prefix = filepath.Join(storage.prefix, prefix) if prefix != "" { @@ -214,16 +267,23 @@ func (storage *PublishedStorage) Filelist(prefix string) ([]string, error) { for { contents, err := storage.bucket.List(prefix, "", marker, 1000) if err != nil { - return nil, fmt.Errorf("error listing under prefix %s in %s: %s", prefix, storage, err) + return nil, nil, fmt.Errorf("error listing under prefix %s in %s: %s", prefix, storage, err) } lastKey := "" for _, key := range contents.Contents { - if prefix == "" { - result = append(result, key.Key) - } else { - result = append(result, key.Key[len(prefix):]) - } lastKey = key.Key + if storage.plusWorkaround && hidePlusWorkaround && strings.Index(lastKey, " ") != -1 { + // if we use plusWorkaround, we want to hide those duplicates + /// from listing + continue + } + + if prefix == "" { + paths = append(paths, key.Key) + } else { + paths = append(paths, key.Key[len(prefix):]) + } + md5s = append(md5s, strings.Replace(key.ETag, "\"", "", -1)) } if contents.IsTruncated { marker = contents.NextMarker @@ -239,7 +299,7 @@ func (storage *PublishedStorage) Filelist(prefix string) ([]string, error) { } } - return result, nil + return paths, md5s, nil } // RenameFile renames (moves) file diff --git a/src/github.com/smira/aptly/s3/public_test.go b/src/github.com/smira/aptly/s3/public_test.go index 0f6d2221..f19945b8 100644 --- a/src/github.com/smira/aptly/s3/public_test.go +++ b/src/github.com/smira/aptly/s3/public_test.go @@ -25,10 +25,10 @@ func (s *PublishedStorageSuite) SetUpTest(c *C) { c.Assert(s.srv, NotNil) auth, _ := aws.GetAuth("aa", "bb") - s.storage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "", "", "", false) + s.storage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "", "", "", false, true) c.Assert(err, IsNil) - s.prefixedStorage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "lala", "", "", false) + s.prefixedStorage, err = NewPublishedStorageRaw(auth, aws.Region{Name: "test-1", S3Endpoint: s.srv.URL(), S3LocationConstraint: true}, "test", "", "lala", "", "", false, true) c.Assert(err, IsNil) err = s.storage.s3.Bucket("test").PutBucket("private") @@ -40,7 +40,7 @@ func (s *PublishedStorageSuite) TearDownTest(c *C) { } func (s *PublishedStorageSuite) TestNewPublishedStorage(c *C) { - stor, err := NewPublishedStorage("aa", "bbb", "", "", "", "", "", "", false) + stor, err := NewPublishedStorage("aa", "bbb", "", "", "", "", "", "", "", false, false) c.Check(stor, IsNil) c.Check(err, ErrorMatches, "unknown region: .*") } @@ -108,6 +108,33 @@ func (s *PublishedStorageSuite) TestFilelist(c *C) { c.Check(list, DeepEquals, []string{"a", "b", "c"}) } +func (s *PublishedStorageSuite) TestFilelistPlusWorkaround(c *C) { + s.storage.plusWorkaround = true + s.prefixedStorage.plusWorkaround = true + + paths := []string{"a", "b", "c", "testa", "test/a+1", "test/a 1", "lala/a+b", "lala/a b", "lala/c"} + for _, path := range paths { + err := s.storage.bucket.Put(path, []byte("test"), "binary/octet-stream", "private") + c.Check(err, IsNil) + } + + list, err := s.storage.Filelist("") + c.Check(err, IsNil) + c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a+b", "lala/c", "test/a+1", "testa"}) + + list, err = s.storage.Filelist("test") + c.Check(err, IsNil) + c.Check(list, DeepEquals, []string{"a+1"}) + + list, err = s.storage.Filelist("test2") + c.Check(err, IsNil) + c.Check(list, DeepEquals, []string{}) + + list, err = s.prefixedStorage.Filelist("") + c.Check(err, IsNil) + c.Check(list, DeepEquals, []string{"a+b", "c"}) +} + func (s *PublishedStorageSuite) TestRemove(c *C) { err := s.storage.bucket.Put("a/b", []byte("test"), "binary/octet-stream", "private") c.Check(err, IsNil) @@ -119,9 +146,50 @@ func (s *PublishedStorageSuite) TestRemove(c *C) { c.Check(err, ErrorMatches, "The specified key does not exist.") } -func (s *PublishedStorageSuite) TestRemoveDirs(c *C) { - c.Skip("multiple-delete not available in s3test") +func (s *PublishedStorageSuite) TestRemovePlusWorkaround(c *C) { + s.storage.plusWorkaround = true + err := s.storage.bucket.Put("a/b+c", []byte("test"), "binary/octet-stream", "private") + c.Check(err, IsNil) + + err = s.storage.bucket.Put("a/b", []byte("test"), "binary/octet-stream", "private") + c.Check(err, IsNil) + + err = s.storage.Remove("a/b+c") + c.Check(err, IsNil) + + _, err = s.storage.bucket.Get("a/b+c") + c.Check(err, ErrorMatches, "The specified key does not exist.") + + _, err = s.storage.bucket.Get("a/b c") + c.Check(err, ErrorMatches, "The specified key does not exist.") + + err = s.storage.Remove("a/b") + c.Check(err, IsNil) + + _, err = s.storage.bucket.Get("a/b") + c.Check(err, ErrorMatches, "The specified key does not exist.") + +} + +func (s *PublishedStorageSuite) TestRemoveDirs(c *C) { + s.storage.plusWorkaround = true + + paths := []string{"a", "b", "c", "testa", "test/a+1", "test/a 1", "lala/a+b", "lala/a b", "lala/c"} + for _, path := range paths { + err := s.storage.bucket.Put(path, []byte("test"), "binary/octet-stream", "private") + c.Check(err, IsNil) + } + + err := s.storage.RemoveDirs("test", nil) + c.Check(err, IsNil) + + list, err := s.storage.Filelist("") + c.Check(err, IsNil) + c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a+b", "lala/c", "testa"}) +} + +func (s *PublishedStorageSuite) TestRemoveDirsPlusWorkaround(c *C) { paths := []string{"a", "b", "c", "testa", "test/a", "test/b", "lala/a", "lala/b", "lala/c"} for _, path := range paths { err := s.storage.bucket.Put(path, []byte("test"), "binary/octet-stream", "private") @@ -133,8 +201,7 @@ func (s *PublishedStorageSuite) TestRemoveDirs(c *C) { list, err := s.storage.Filelist("") c.Check(err, IsNil) - c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a", "lala/b", "lala/c", "test/a", "test/b", "testa"}) - + c.Check(list, DeepEquals, []string{"a", "b", "c", "lala/a", "lala/b", "lala/c", "testa"}) } func (s *PublishedStorageSuite) TestRenameFile(c *C) { diff --git a/src/github.com/smira/aptly/s3/retry.go b/src/github.com/smira/aptly/s3/retry.go new file mode 100644 index 00000000..91f66d29 --- /dev/null +++ b/src/github.com/smira/aptly/s3/retry.go @@ -0,0 +1,121 @@ +package s3 + +// This was taken from github.com/mitchellh/goamz/amz/client.go: + +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 + 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 + } + return c, nil + }, + DisableKeepAlives: true, + 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{ + DialTimeout: 15 * 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 try == (t.MaxTries - 1) { + 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)))) +} + +// 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/src/github.com/smira/aptly/swift/public_test.go b/src/github.com/smira/aptly/swift/public_test.go index c32175ec..1f1b83b4 100644 --- a/src/github.com/smira/aptly/swift/public_test.go +++ b/src/github.com/smira/aptly/swift/public_test.go @@ -1,21 +1,21 @@ package swift import ( - "github.com/ncw/swift/swifttest" - "github.com/smira/aptly/files" - + "fmt" . "gopkg.in/check.v1" "io/ioutil" + "math/rand" "os" "path/filepath" -) + "time" -const ( - TestAddress = "localhost:5324" - AuthURL = "http://" + TestAddress + "/v1.0" + "github.com/ncw/swift/swifttest" + + "github.com/smira/aptly/files" ) type PublishedStorageSuite struct { + TestAddress, AuthURL string srv *swifttest.SwiftServer storage, prefixedStorage *PublishedStorage } @@ -24,14 +24,20 @@ var _ = Suite(&PublishedStorageSuite{}) func (s *PublishedStorageSuite) SetUpTest(c *C) { var err error - s.srv, err = swifttest.NewSwiftServer(TestAddress) + + rand.Seed(int64(time.Now().Nanosecond())) + + s.TestAddress = fmt.Sprintf("localhost:%d", rand.Intn(10000)+20000) + s.AuthURL = "http://" + s.TestAddress + "/v1.0" + + s.srv, err = swifttest.NewSwiftServer(s.TestAddress) c.Assert(err, IsNil) c.Assert(s.srv, NotNil) - s.storage, err = NewPublishedStorage("swifttest", "swifttest", AuthURL, "", "", "test", "") + s.storage, err = NewPublishedStorage("swifttest", "swifttest", s.AuthURL, "", "", "test", "") c.Assert(err, IsNil) - s.prefixedStorage, err = NewPublishedStorage("swifttest", "swifttest", AuthURL, "", "", "test", "lala") + s.prefixedStorage, err = NewPublishedStorage("swifttest", "swifttest", s.AuthURL, "", "", "test", "lala") c.Assert(err, IsNil) s.storage.conn.ContainerCreate("test", nil) @@ -42,7 +48,7 @@ func (s *PublishedStorageSuite) TearDownTest(c *C) { } func (s *PublishedStorageSuite) TestNewPublishedStorage(c *C) { - stor, err := NewPublishedStorage("swifttest", "swifttest", AuthURL, "", "", "", "") + stor, err := NewPublishedStorage("swifttest", "swifttest", s.AuthURL, "", "", "", "") c.Check(stor, NotNil) c.Check(err, IsNil) } diff --git a/src/github.com/smira/aptly/system/changes/hardlink_0.2.1.dsc b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1.dsc new file mode 100644 index 00000000..8937287c --- /dev/null +++ b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1.dsc @@ -0,0 +1,30 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +Format: 1.0 +Source: hardlink +Binary: hardlink +Architecture: any +Version: 0.2.1 +Maintainer: Julian Andres Klode +Homepage: http://jak-linux.org/projects/hardlink/ +Standards-Version: 3.9.3 +Vcs-Browser: http://git.debian.org/?p=users/jak/hardlink.git;a=summary +Vcs-Git: git://git.debian.org/git/users/jak/hardlink.git +Build-Depends: debhelper (>= 9), pkg-config, libpcre3-dev +Package-List: + hardlink deb utils optional +Checksums-Sha1: + 6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz +Checksums-Sha256: + 4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz +Files: + 8e2caa4d82f228bac08dc9a38bc6edb3 12516 hardlink_0.2.1.tar.gz + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.12 (GNU/Linux) + +iEYEARECAAYFAlUFwywACgkQIdu4nBbbPm2M5wCg0pHD8adE1rY1/DpZ4efRuMXY +MPMAni4xUtyAnwIvkk3MCE2rFrGP3L78 +=5CU1 +-----END PGP SIGNATURE----- diff --git a/src/github.com/smira/aptly/system/changes/hardlink_0.2.1.tar.gz b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1.tar.gz new file mode 100644 index 00000000..560b9811 Binary files /dev/null and b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1.tar.gz differ diff --git a/src/github.com/smira/aptly/system/changes/hardlink_0.2.1_amd64.changes b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1_amd64.changes new file mode 100644 index 00000000..c48899ea --- /dev/null +++ b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1_amd64.changes @@ -0,0 +1,39 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA1 + +Format: 1.8 +Date: Sat, 12 May 2014 12:57:02 +0200 +Source: hardlink +Binary: hardlink +Architecture: source amd64 +Version: 0.2.1 +Distribution: unstable +Urgency: low +Maintainer: Julian Andres Klode +Changed-By: Aptly Tester (don't use it) +Description: + hardlink - Hardlinks multiple copies of the same file +Changes: + hardlink (0.2.1) unstable; urgency=low + . + * Update just to try it out :) +Checksums-Sha1: + ff306b8f923653b78e00c45ebbc6c1c734859cdf 949 hardlink_0.2.1.dsc + 6e95b8cba450343ab4dc01902e521f29fbd87ac2 12516 hardlink_0.2.1.tar.gz + 1ac0e962854dff46f14fa7943746660d3cad1679 12468 hardlink_0.2.1_amd64.deb +Checksums-Sha256: + c0d7458aa2ca3886cd6885f395a289efbc9a396e6765cbbca45f51fde859ea70 949 hardlink_0.2.1.dsc + 4df0adce005526a1f0e1b38171ddb1f017faae9205f5b1c6dfb0fb4207767271 12516 hardlink_0.2.1.tar.gz + 668399580590bf1ffcd9eb161b6e574751e15f71820c6e08245dac7c5111a0ee 12468 hardlink_0.2.1_amd64.deb +Files: + 4efce26825af5842f43961096dd890b3 949 utils optional hardlink_0.2.1.dsc + 8e2caa4d82f228bac08dc9a38bc6edb3 12516 utils optional hardlink_0.2.1.tar.gz + 2081e20b36c47f82811c25841cc0e41b 12468 utils optional hardlink_0.2.1_amd64.deb + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.12 (GNU/Linux) + +iEYEARECAAYFAlUFwywACgkQIdu4nBbbPm1DLACgwW4V8qLQC/QHC/7+t3Iq47Ez +eesAn3ZYLQvLYRw3wPTKVAPI+AW6Fjxi +=hRBo +-----END PGP SIGNATURE----- diff --git a/src/github.com/smira/aptly/system/changes/hardlink_0.2.1_amd64.deb b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1_amd64.deb new file mode 100644 index 00000000..739d2849 Binary files /dev/null and b/src/github.com/smira/aptly/system/changes/hardlink_0.2.1_amd64.deb differ diff --git a/src/github.com/smira/aptly/system/changes/uploaders1.json b/src/github.com/smira/aptly/system/changes/uploaders1.json new file mode 100644 index 00000000..1f5faac8 --- /dev/null +++ b/src/github.com/smira/aptly/system/changes/uploaders1.json @@ -0,0 +1,7 @@ +// no groups, no rules => deny all +{ + "groups": { + }, + "rules": [ + ] +} \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/changes/uploaders2.json b/src/github.com/smira/aptly/system/changes/uploaders2.json new file mode 100644 index 00000000..42f6f16a --- /dev/null +++ b/src/github.com/smira/aptly/system/changes/uploaders2.json @@ -0,0 +1,14 @@ + +{ + "groups": { + "developers": ["21DBB89C16DB3E6D", "37E1C17570096AD1"], + }, + "rules": [ + { "condition": "Source (dangerous) | Source (kernel)", + "deny": ["*"], + }, + { "condition": "Source (hardlink)", + "allow": ["developers", "admins"], + } + ] +} \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/changes/uploaders3.json b/src/github.com/smira/aptly/system/changes/uploaders3.json new file mode 100644 index 00000000..81750b96 --- /dev/null +++ b/src/github.com/smira/aptly/system/changes/uploaders3.json @@ -0,0 +1 @@ +{ \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/changes/uploaders4.json b/src/github.com/smira/aptly/system/changes/uploaders4.json new file mode 100644 index 00000000..82a335b2 --- /dev/null +++ b/src/github.com/smira/aptly/system/changes/uploaders4.json @@ -0,0 +1,14 @@ + +{ + "groups": { + "developers": ["21DBB89C16DB3E6D", "37E1C17570096AD1"], + }, + "rules": [ + { "condition": "Source (dangerous) | Source (kernel)", + "deny": ["*"], + }, + { "condition": "Source (hardlink", + "allow": ["developers", "admins"], + } + ] +} \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/files/debian-archive-keyring.gpg b/src/github.com/smira/aptly/system/files/debian-archive-keyring.gpg index 46d1f0e2..7359335b 100644 Binary files a/src/github.com/smira/aptly/system/files/debian-archive-keyring.gpg and b/src/github.com/smira/aptly/system/files/debian-archive-keyring.gpg differ diff --git a/src/github.com/smira/aptly/system/files/flat.key b/src/github.com/smira/aptly/system/files/flat.key index f40f79eb..47b682e5 100644 --- a/src/github.com/smira/aptly/system/files/flat.key +++ b/src/github.com/smira/aptly/system/files/flat.key @@ -1,19 +1,19 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.5 (GNU/Linux) -mQGiBE9p65cRBACFOL5YS4kW6xieXa98meE+RVu1hfBi1n7ajAy+ZQOfNa2Xb9if -H8WAcwJD4cTZYB19/O/xVxCYf1hnC/T34XGC5PUzMzBDKde86UDqvT4YNHDQA/E1 -I6UUzE0MgLINO4Dt7Mw62koVrlPXklc2Zn83ucZB7YgBzJOIBFUQLghikwCgnubS -n/9lw8Hm8CIsg4nWtHwHGPED/jXIsH7ON3PBx2wIdRsealsx5sPGHQSlq1grRHcN -YT5/glXmVqnexY/+IFhcpjjb3vMMQ5LYq8+bDWGVMQx3GZrJs66rwPbo4kZ92OdC -RTnY/nznJlf5gS86DaFl+NFuO7F1k8ju4CurXXGXPF7nk8cgV6CrYHz1AtNyLVqa -306IA/9j9rdD/MY9SYT16eFMo7C2ieIS0RxxU3q9w0e8EucQKiHWMtjTPJ0Ik0GO -TY5lAPasnD6ZBA15XSiTi2Ck2QoZQZCxdtId/nL7lNG4+vQ8HACNDkxxK4yHJiFa -frMdlWi5cYgAMYzbYPekbhaamDR7Gh4NU7z72QZTPELKyZD/pbRGaG9tZTpEZWVw -RGl2ZXIxOTc1IE9CUyBQcm9qZWN0IDxob21lOkRlZXBEaXZlcjE5NzVAYnVpbGQu -b3BlbnN1c2Uub3JnPohlBBMRAgAmBQJPaeuXAhsDBQkEHrAABgsJCAcDAgQVAggD -BBYCAwECHgECF4AACgkQuCWWGBBIwf+tEgCcDEzTAilZDvOr0OKHHmguuKFXoHMA -ljX7B6nKOYoiHoGpBeOwr8U5ZB6IRgQTEQIABgUCT2nrlwAKCRA7MBG3a51lI7Rt -AJ4mYeomQiHHfd+7c8T0JhbGKUIDlACglHyTlouU5vCpUEHDyLvwrHFylpk= -=b/6f +mQGiBEeWWZoRBADvY6hFi/SwuwZRLbT2yrW/l+/0zsNXusK/s2K6jjA3i5oDWwG+ +wky3ef+9au2qaxd2spt8iq0x5ph8aI/1YEkdFbHe/dfItcc7NAWl2RTworogkz+R +4leJNU3tQJNJQYml33LQyNhgQsmMvmZ6xP4NxJZIrWT9nZxiGexb24uTGwCgkOWV +CpqucQTHnow1ok75gVMRHdkD/3EOtaBAkj5gECBc2WnXk+UzCYBjV1QXmBaLy4sq +vIq0b3ja+zBJzc2mAviWgNuo2h56dYEsBLaQjkEdJKUEGdfiRkDZQjZEPMrT1HZD +L2oYzR4xlwSTqR3dtBzXbLhIvfRUNw1CuNVQG8I+r7aBEje7JAVH8X4poGV3oCBh +faXDA/0a/01gn1d58uSLwDKmBQpUngX/K1U2PchUnJd88DSRqIpzX1Cwk2iu9lJS +ukE9FV2FNb4heKS2HRXyEz/kEONbSC4G1jSzl0keKrc8RwaX2uTolDGqpyOkXSd+ +WHUcnbzQ5MLahLB3QOocrLc0w6wwPKk2fA5F51mckMUgDtdQ2rQ8aG9tZTptb25r +ZXlpcSBPQlMgUHJvamVjdCA8aG9tZTptb25rZXlpcUBidWlsZC5vcGVuc3VzZS5v +cmc+iGYEExECACYFAk/y8O8CGwMFCQx7R1UGCwkIBwMCBBUCCAMEFgIDAQIeAQIX +gAAKCRCooNd/3/r8Q3MZAJ45GODOQT+bFI8Zjq0C93L7oMxptQCgh/lNR+pYmUcT +hb1PQ20qsfV5gJuIRgQTEQIABgUCR5ZZmgAKCRA7MBG3a51lI0jzAJsHZxWi1Db3 +J76+37rmZ/2riTo93QCfS5pFjOdqaRPjbfb6bCHLedhhHlM= +=p7/n -----END PGP PUBLIC KEY BLOCK----- diff --git a/src/github.com/smira/aptly/system/lib.py b/src/github.com/smira/aptly/system/lib.py index b7fccd36..d0240f6a 100644 --- a/src/github.com/smira/aptly/system/lib.py +++ b/src/github.com/smira/aptly/system/lib.py @@ -154,6 +154,7 @@ class BaseTest(object): if not hasattr(command, "__iter__"): params = { 'files': os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files"), + 'changes': os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), 'udebs': os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "udebs"), 'testfiles': os.path.join(os.path.dirname(inspect.getsourcefile(self.__class__)), self.__class__.__name__), 'aptlyroot': os.path.join(os.environ["HOME"], ".aptly"), @@ -235,6 +236,8 @@ class BaseTest(object): self.verify_match(self.get_gold(gold_name), contents, match_prepare=match_prepare) except: if self.captureResults: + if match_prepare is not None: + contents = match_prepare(contents) with open(self.get_gold_filename(gold_name), "w") as f: f.write(contents) else: diff --git a/src/github.com/smira/aptly/system/run.py b/src/github.com/smira/aptly/system/run.py index 1c9ca581..3b1ef70d 100755 --- a/src/github.com/smira/aptly/system/run.py +++ b/src/github.com/smira/aptly/system/run.py @@ -7,6 +7,7 @@ import inspect import fnmatch import sys import traceback +import random from lib import BaseTest from s3_lib import S3Test @@ -98,6 +99,7 @@ def run(include_long_tests=False, capture_results=False, tests=None, filters=Non if __name__ == "__main__": os.chdir(os.path.realpath(os.path.dirname(sys.argv[0]))) + random.seed() include_long_tests = False capture_results = False tests = None diff --git a/src/github.com/smira/aptly/system/t01_version/VersionTest_gold b/src/github.com/smira/aptly/system/t01_version/VersionTest_gold index 1189d3c3..b2b7f2ef 100644 --- a/src/github.com/smira/aptly/system/t01_version/VersionTest_gold +++ b/src/github.com/smira/aptly/system/t01_version/VersionTest_gold @@ -1 +1 @@ -aptly version: 0.9.5 +aptly version: 0.9.6 diff --git a/src/github.com/smira/aptly/system/t03_help/MainHelpTest_gold b/src/github.com/smira/aptly/system/t03_help/MainHelpTest_gold index 0c42fb04..356c4e2f 100644 --- a/src/github.com/smira/aptly/system/t03_help/MainHelpTest_gold +++ b/src/github.com/smira/aptly/system/t03_help/MainHelpTest_gold @@ -13,7 +13,7 @@ package environment to new version. Options: -architectures="": list of architectures to consider during (comma-separated), default to all available -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf) - -dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b' + -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-suggests=false: when processing dependencies, follow Suggests diff --git a/src/github.com/smira/aptly/system/t03_help/MainTest_gold b/src/github.com/smira/aptly/system/t03_help/MainTest_gold index 3339c975..002005ba 100644 --- a/src/github.com/smira/aptly/system/t03_help/MainTest_gold +++ b/src/github.com/smira/aptly/system/t03_help/MainTest_gold @@ -21,7 +21,7 @@ Use "aptly help " for more information about a command. Options: -architectures="": list of architectures to consider during (comma-separated), default to all available -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf) - -dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b' + -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-suggests=false: when processing dependencies, follow Suggests diff --git a/src/github.com/smira/aptly/system/t03_help/MirrorCreateHelpTest_gold b/src/github.com/smira/aptly/system/t03_help/MirrorCreateHelpTest_gold index e404e2d9..07483573 100644 --- a/src/github.com/smira/aptly/system/t03_help/MirrorCreateHelpTest_gold +++ b/src/github.com/smira/aptly/system/t03_help/MirrorCreateHelpTest_gold @@ -15,7 +15,7 @@ Example: Options: -architectures="": list of architectures to consider during (comma-separated), default to all available -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf) - -dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b' + -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-suggests=false: when processing dependencies, follow Suggests diff --git a/src/github.com/smira/aptly/system/t03_help/MirrorCreateTest_gold b/src/github.com/smira/aptly/system/t03_help/MirrorCreateTest_gold index 2aaa8203..7ca699a7 100644 --- a/src/github.com/smira/aptly/system/t03_help/MirrorCreateTest_gold +++ b/src/github.com/smira/aptly/system/t03_help/MirrorCreateTest_gold @@ -6,7 +6,7 @@ aptly mirror create - create new mirror Options: -architectures="": list of architectures to consider during (comma-separated), default to all available -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf) - -dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b' + -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-suggests=false: when processing dependencies, follow Suggests diff --git a/src/github.com/smira/aptly/system/t03_help/MirrorHelpTest_gold b/src/github.com/smira/aptly/system/t03_help/MirrorHelpTest_gold index 6cefc10e..9d62fcca 100644 --- a/src/github.com/smira/aptly/system/t03_help/MirrorHelpTest_gold +++ b/src/github.com/smira/aptly/system/t03_help/MirrorHelpTest_gold @@ -17,7 +17,7 @@ Use "mirror help " for more information about a command. Options: -architectures="": list of architectures to consider during (comma-separated), default to all available -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf) - -dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b' + -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-suggests=false: when processing dependencies, follow Suggests diff --git a/src/github.com/smira/aptly/system/t03_help/MirrorTest_gold b/src/github.com/smira/aptly/system/t03_help/MirrorTest_gold index cf149c99..2c86e735 100644 --- a/src/github.com/smira/aptly/system/t03_help/MirrorTest_gold +++ b/src/github.com/smira/aptly/system/t03_help/MirrorTest_gold @@ -17,7 +17,7 @@ Use "mirror help " for more information about a command. Options: -architectures="": list of architectures to consider during (comma-separated), default to all available -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf) - -dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b' + -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-suggests=false: when processing dependencies, follow Suggests diff --git a/src/github.com/smira/aptly/system/t03_help/WrongFlagTest_gold b/src/github.com/smira/aptly/system/t03_help/WrongFlagTest_gold index 29c7a540..32e018fe 100644 --- a/src/github.com/smira/aptly/system/t03_help/WrongFlagTest_gold +++ b/src/github.com/smira/aptly/system/t03_help/WrongFlagTest_gold @@ -7,7 +7,7 @@ aptly mirror create - create new mirror Options: -architectures="": list of architectures to consider during (comma-separated), default to all available -config="": location of configuration file (default locations are /etc/aptly.conf, ~/.aptly.conf) - -dep-follow-all-variants=false: when processing dependencies, follow a & b if depdency is 'a|b' + -dep-follow-all-variants=false: when processing dependencies, follow a & b if dependency is 'a|b' -dep-follow-recommends=false: when processing dependencies, follow Recommends -dep-follow-source=false: when processing dependencies, follow from binary to Source packages -dep-follow-suggests=false: when processing dependencies, follow Suggests diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror11Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror11Test_mirror_show index 522449e3..66837180 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror11Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror11Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 sparc Codename: squeeze Components: main contrib non-free -Date: Sat, 19 Jul 2014 11:02:06 UTC +Date: Sat, 25 Apr 2015 11:01:14 UTC Description: Debian 6.0.10 Released 19 July 2014 Label: Debian Origin: Debian -Suite: oldstable +Suite: oldoldstable Version: 6.0.10 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror13Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror13Test_mirror_show index 5483fead..b0eb4875 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror13Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror13Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_gold b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_gold index 9022d63a..54cb4be7 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_gold @@ -1,8 +1,8 @@ -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/InRelease... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release.gpg... -gpgv: Signature made Tue May 21 23:01:30 2013 MSK using DSA key ID 1048C1FF -gpgv: Good signature from "home:DeepDiver1975 OBS Project " +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/InRelease... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release.gpg... +gpgv: DSA key ID DFFAFC43 +gpgv: Good signature from "home:monkeyiq OBS Project " -Mirror [mirror14]: http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./ successfully added. +Mirror [mirror14]: http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ ./ successfully added. You can run 'aptly mirror update mirror14' to download repository contents. diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_mirror_show index 8f479d62..b5d02346 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror14Test_mirror_show @@ -1,5 +1,5 @@ Name: mirror14 -Archive Root URL: http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ +Archive Root URL: http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ Distribution: ./ Components: Architectures: @@ -8,9 +8,11 @@ Download .udebs: no Last update: never Information from release file: -Date: Tue May 21 21:01:30 2013 -Description: Open Build Service home:DeepDiver1975 xUbuntu_10.04 +Architectures: i386 amd64 +Archive: Debian_7.0 +Codename: Debian_7.0 +Date: Fri Apr 25 04:32:23 2014 +Description: monkeyiq's Home Project (Debian_7.0) -Label: DeepDiver1975's Home Project (xUbuntu_10.04) -Origin: Open Build Service home:DeepDiver1975 xUbuntu_10.04 -Version: 0.00 +Label: home:monkeyiq +Origin: obs://build.opensuse.org/home:monkeyiq/Debian_7.0 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror17Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror17Test_mirror_show index 32815bb5..eb8846f1 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror17Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror17Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_gold b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_gold index f250a513..e43ad41c 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_gold @@ -1,4 +1,6 @@ Downloading http://security.debian.org/dists/wheezy/updates/InRelease... +gpgv: RSA key ID C857C906 +gpgv: Good signature from "Debian Security Archive Automatic Signing Key (8/jessie) " gpgv: RSA key ID 46925553 gpgv: Good signature from "Debian Archive Automatic Signing Key (7.0/wheezy) " diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_mirror_show index c4425802..71d7d942 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror19Test_mirror_show @@ -15,5 +15,5 @@ Description: Debian 7.0 Security Updates Label: Debian-Security Origin: Debian -Suite: stable +Suite: oldstable Version: 7.0 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror1Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror1Test_mirror_show index f2816c1a..0535ab41 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror1Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror1Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror22Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror22Test_mirror_show index 8b9e103d..d3ed1cd7 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror22Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror22Test_mirror_show @@ -17,5 +17,5 @@ Description: Debian 7.0 Security Updates Label: Debian-Security Origin: Debian -Suite: stable +Suite: oldstable Version: 7.0 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror24Test_gold b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror24Test_gold index 7fc9d2b4..abd444fa 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror24Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror24Test_gold @@ -1,4 +1,6 @@ Downloading http://security.debian.org/dists/wheezy/updates/InRelease... +gpgv: RSA key ID C857C906 +gpgv: Good signature from "Debian Security Archive Automatic Signing Key (8/jessie) " gpgv: RSA key ID 46925553 gpgv: Good signature from "Debian Archive Automatic Signing Key (7.0/wheezy) " diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror25Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror25Test_mirror_show index fccbfcaa..97204d41 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror25Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror25Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror27Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror27Test_mirror_show index 41412dd9..36821d5b 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror27Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror27Test_mirror_show @@ -10,8 +10,8 @@ Last update: never Information from release file: Architectures: amd64 i386 source Codename: wheezy -Components: openmanage openmanage/801 openmanage/740 openmanage/730 -Date: Wed, 22 Oct 2014 18:50:39 UTC +Components: openmanage openmanage/820 openmanage/810 openmanage/801 openmanage/740 openmanage/730 +Date: Mon, 14 Sep 2015 21:24:43 UTC Description: Unofficial Dell OMSA build for Ubuntu Label: Dell OMSA Archive diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror28Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror28Test_mirror_show index bc9cc681..09e9cfed 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror28Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror28Test_mirror_show @@ -10,8 +10,7 @@ Last update: never Information from release file: Architectures: i386 amd64 Codename: dist -Components: mongodb -Date: Wed, 25 Feb 2015 17:35:02 UTC +Components: 10gen Description: mongodb packages Label: mongodb diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror2Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror2Test_mirror_show index c7f66fc1..a361d897 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror2Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror2Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror3Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror3Test_mirror_show index 82d4be81..63e26925 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror3Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror3Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror7Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror7Test_mirror_show index df88e3c3..006426e7 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/CreateMirror7Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/CreateMirror7Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/EditMirror5Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/EditMirror5Test_mirror_show index 8790d809..779097b9 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/EditMirror5Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/EditMirror5Test_mirror_show @@ -15,5 +15,5 @@ Description: Debian 7.0 Security Updates Label: Debian-Security Origin: Debian -Suite: stable +Suite: oldstable Version: 7.0 diff --git a/src/github.com/smira/aptly/system/t04_mirror/EditMirror6Test_mirror_show b/src/github.com/smira/aptly/system/t04_mirror/EditMirror6Test_mirror_show index 09ab3750..4234400c 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/EditMirror6Test_mirror_show +++ b/src/github.com/smira/aptly/system/t04_mirror/EditMirror6Test_mirror_show @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/ListMirror1Test_gold b/src/github.com/smira/aptly/system/t04_mirror/ListMirror1Test_gold index 87670d94..bfb808b8 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/ListMirror1Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/ListMirror1Test_gold @@ -2,6 +2,6 @@ List of mirrors: * [mirror1]: http://mirror.yandex.ru/debian/ wheezy * [mirror2]: http://mirror.yandex.ru/debian/ squeeze [src] * [mirror3]: http://mirror.yandex.ru/debian/ squeeze - * [mirror4]: http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./ + * [mirror4]: http://download.opensuse.org/repositories/Apache:/MirrorBrain/Debian_7.0/ ./ To get more information about mirror, run `aptly mirror show `. diff --git a/src/github.com/smira/aptly/system/t04_mirror/SearchMirror5Test_gold b/src/github.com/smira/aptly/system/t04_mirror/SearchMirror5Test_gold new file mode 100644 index 00000000..b5a49d54 --- /dev/null +++ b/src/github.com/smira/aptly/system/t04_mirror/SearchMirror5Test_gold @@ -0,0 +1,4043 @@ + +aolserver4-dev#4.5.1-15.1 +apache2-prefork-dev#2.2.22-13+deb7u1 +apache2-threaded-dev#2.2.22-13+deb7u1 +apcalc-dev#2.12.4.4-3 +aplus-fsf-dev#4.22.1-6 +aroarfw-dev#0.1~beta4-5 +asterisk-dev#1:1.8.13.1~dfsg1-3+deb7u3 +atfs-dev#1.4pl6-11 +audacious-dev#3.2.4-1 +autotools-dev#20120608.1 +binutils-dev#2.22-8 +biosquid-dev#1.9g+cvs20050121-2 +bitlbee-dev#3.0.5-1.2 +blacs-pvm-dev#1.1-21 +blends-dev#0.6.16.2 +blktap-dev#2.0.90-1 +blt-dev#2.4z-4.2 +boinc-dev#7.0.27+dfsg-5 +boolstuff-dev#0.1.12-3 +cairo-dock-dev#3.0.0-2+deb7u1 +cernlib-base-dev#20061220+dfsg3-2 +cernlib-core-dev#20061220+dfsg3-2 +chipmunk-dev#5.3.4-1 +cimg-dev#1.4.9-2 +clearsilver-dev#0.10.5-1.3 +cli-common-dev#0.8.2 +clinica-dev#0.2.1~dfsg-1 +clisp-dev#1:2.49-8.1 +cluster-glue-dev#1.0.9+hg2665-1 +codeblocks-dev#10.05-2.1 +coinor-libcbc-dev#2.5.0-3 +coinor-libcgl-dev#0.55.0-1.1 +coinor-libclp-dev#1.12.0-2.1 +coinor-libcoinutils-dev#2.6.4-3 +coinor-libdylp-dev#1.6.0-1.1 +coinor-libflopc++-dev#1.0.6-3.1 +coinor-libipopt-dev#3.10.2-1.1 +coinor-libosi-dev#0.103.0-1 +coinor-libsymphony-dev#5.2.4-1.2 +coinor-libvol-dev#1.1.7-1 +collectd-dev#5.1.0-3 +comerr-dev#2.1-1.42.5-1.1 +condor-dev#7.8.2~dfsg.1-1+deb7u1 +config-package-dev#4.13 +connman-dev#1.0-1.1+wheezy1+b1 +console-tools-dev#1:0.2.3dbs-70 +coop-computing-tools-dev#3.5.1-2 +corosync-dev#1.4.2-3 +courier-authlib-dev#0.63.0-6+b1 +crtmpserver-dev#1.0~dfsg-3 +ctapi-dev#1.1 +ctn-dev#3.0.6-13+b2 +cyrus-dev#2.4.16-4+deb7u1 +dcap-dev#2.47.6-2 +dico-dev#2.1-3+b2 +dictionaries-common-dev#1.12.11 +dietlibc-dev#0.33~cvs20120325-4 +dolfin-dev#1.0.0-7 +dovecot-dev#1:2.1.7-7 +dpkg-dev#1.16.12 +drac-dev#1.12-7.2 +drizzle-plugin-dev#1:7.1.36-stable-1 +dssi-dev#1.1.1~dfsg0-1 +e2fslibs-dev#1.42.5-1.1 +emerillon-dev#0.1.90-1 +eog-dev#3.4.2-1+build1 +epiphany-browser-dev#3.4.2-2.1 +erlang-dev#1:15.b.1-dfsg-4+deb7u1 +erlang-esdl-dev#1.2-2 +etl-dev#0.04.15-1 +evolution-data-server-dev#3.4.4-3 +evolution-dev#3.4.4-3 +exim4-dev#4.80-7 +expect-dev#5.45-2 +expeyes-firmware-dev#2.0.0-3 +extremetuxracer-gimp-dev#0.4-5 +falconpl-dev#0.9.6.9-git20120606-2 +fatrat-dev#1.1.3-5 +fcitx-libs-dev#1:4.2.4.1-7 +fenix-dev#0.92a.dfsg1-9 +festival-dev#1:2.1~release-5.1 +fftw-dev#2.1.5-1 +finch-dev#2.10.9-1~deb7u1 +firebird-dev#2.5.2.26540.ds4-1~deb7u1 +flite1-dev#1.4-release-6 +flow-tools-dev#1:0.68-12.1+b1 +fosfat-dev#0.4.0-3 +freeglut3-dev#2.6.0-4 +freetds-dev#0.91-2+deb7u1 +frei0r-plugins-dev#1.1.22git20091109-1.2 +ftgl-dev#2.1.3~rc5-4 +ftplib-dev#3.1-1-9 +gambas3-dev#3.1.1-2+b1 +gap-dev#4r4p12-2 +gauche-dev#0.9.1-5.1 +gcc-4.6-plugin-dev#4.6.3-14 +gcc-4.7-plugin-dev#4.7.2-5 +gcin-dev#2.7.6.1+dfsg-1 +gedit-dev#3.4.2-1 +gem-dev#1:0.93.3-5 +genius-dev#1.0.14-1 +gfxboot-dev#4.5.0-3 +giblib-dev#1.2.4-8 +glabels-dev#3.0.0-3+b1 +glee-dev#5.4.0-1 +gmpc-dev#11.8.16-6 +gnash-dev#0.8.11~git20120629-1+deb7u1 +gnome-control-center-dev#1:3.4.3.1-2 +gnome-settings-daemon-dev#3.4.2+git20121218.7c1322-3+deb7u3 +gnome-video-effects-dev#0.4.0-1 +gnumach-dev#2:1.3.99.dfsg.git20120610-1 +gnunet-dev#0.9.3-7 +gnunet-gtk-dev#0.9.3-1 +gnuradio-dev#3.5.3.2-1 +gosa-dev#2.7.4-4.3~deb7u1 +gpe-ownerinfo-dev#0.28-3 +gpsim-dev#0.26.1-2.1 +graphviz-dev#2.26.3-14+deb7u1 +grass-dev#6.4.2-2 +gridengine-drmaa-dev#6.2u5-7.1 +gromacs-dev#4.5.5-2 +gsettings-desktop-schemas-dev#3.4.2-3 +gthumb-dev#3:3.0.1-2 +guile-1.6-dev#1.6.8-10.3 +guile-1.8-dev#1.8.8+1-8 +guile-2.0-dev#2.0.5+1-3 +guile-cairo-dev#1.4.0-3 +heartbeat-dev#1:3.0.5-3 +heimdal-dev#1.6~git20120403+dfsg1-2 +hime-dev#0.9.9+git20120619+dfsg-1 +hybrid-dev#1:7.2.2.dfsg.2-10 +icedove-dev#10.0.12-1 +inn2-dev#2.5.3-3 +inventor-dev#2.1.5-10-16 +iproute-dev#20120521-3+b3 +iptables-dev#1.4.14-3.1 +irssi-dev#0.8.15-5 +isc-dhcp-dev#4.2.2.dfsg.1-5+deb70u6 +itcl3-dev#3.4.1-1 +itk3-dev#3.3-4 +ivtools-dev#1.2.10a1-1 +kadu-dev#0.11.2-1 +kannel-dev#1.4.3-2+b2 +kde-workspace-dev#4:4.8.4-6 +kdebase-workspace-dev#4:4.8.4-6 +kdelibs5-dev#4:4.8.4-4 +kdemultimedia-dev#4:4.8.4-2 +kdepimlibs5-dev#4:4.8.4-2 +kdevelop-dev#4:4.3.1-3+b1 +kdevplatform-dev#1.3.1-2 +kmymoney-dev#4.6.2-3.2 +konwert-dev#1.8-11.2 +lam4-dev#7.1.4-3 +lesstif2-dev#1:0.95.2-1.1 +lib3ds-dev#1.3.0-6 +lib4store-dev#1.1.4-2 +lib64bz2-dev#1.0.6-4 +lib64expat1-dev#2.1.0-1+deb7u1 +lib64ffi-dev#3.0.10-3 +lib64ncurses5-dev#5.9-10 +lib64readline-gplv2-dev#5.2+dfsg-2~deb7u1 +lib64readline6-dev#6.2+dfsg-0.1 +lib64z1-dev#1:1.2.7.dfsg-13 +liba52-0.7.4-dev#0.7.4-16 +libaa1-dev#1.4p5-40 +libaac-tactics-ocaml-dev#0.2.pl2-7 +libaacs-dev#0.4.0-1 +libaal-dev#1.0.5-5.1 +libabiword-2.9-dev#2.9.2+svn20120603-8 +libaccountsservice-dev#0.6.21-8 +libace-dev#6.0.3+dfsg-0.1 +libace-flreactor-dev#6.0.3+dfsg-0.1 +libace-foxreactor-dev#6.0.3+dfsg-0.1 +libace-htbp-dev#6.0.3+dfsg-0.1 +libace-inet-dev#6.0.3+dfsg-0.1 +libace-inet-ssl-dev#6.0.3+dfsg-0.1 +libace-qtreactor-dev#6.0.3+dfsg-0.1 +libace-rmcast-dev#6.0.3+dfsg-0.1 +libace-ssl-dev#6.0.3+dfsg-0.1 +libace-tkreactor-dev#6.0.3+dfsg-0.1 +libace-tmcast-dev#6.0.3+dfsg-0.1 +libace-xtreactor-dev#6.0.3+dfsg-0.1 +libacexml-dev#6.0.3+dfsg-0.1 +libacl1-dev#2.2.51-8 +libacpi-dev#0.2-4 +libacr38ucontrol-dev#1.7.11-1 +libadasockets4-dev#1.8.10-2 +libaddresses-dev#0.4.7-1+b5 +libaddressview-dev#0.4.7-1+b5 +libadios-dev#1.3-11 +libadminutil-dev#1.1.15-1 +libadns1-dev#1.4-2 +libadolc-dev#2.3.0-1 +libadplug-dev#2.2.1+dfsg3-0.1 +libafflib-dev#3.6.6-1.1+b1 +libafrodite-0.12-dev#0.12.1-3 +libafterimage-dev#2.2.11-7 +libagg-dev#2.5+dfsg1-8 +libagrep-ocaml-dev#1.0-11+b3 +libahven3-dev#2.1-4 +libaiksaurus-1.2-dev#1.2.1+dev-0.12-6.1 +libaiksaurusgtk-1.2-dev#1.2.1+dev-0.12-6.1 +libaio-dev#0.3.109-3 +libakonadi-dev#1.7.2-3 +libalberta2-dev#2.0.1-5 +libaldmb1-dev#1:0.9.3-5.4 +libalglib-dev#2.6.0-6 +libalkimia-dev#4.3.2-1.1 +liballeggl4-dev#2:4.4.2-2.1 +liballegro4.2-dev#2:4.4.2-2.1 +libalog0.4.1-base-dev#0.4.1-2 +libalog0.4.1-full-dev#0.4.1-2 +libalsa-ocaml-dev#0.2.1-1+b1 +libalsaplayer-dev#0.99.80-5.1 +libalure-dev#1.2-6 +libalut-dev#1.1.0-3 +libampsharp-cil-dev#2.0.4-2 +libamu-dev#6.2+rc20110530-3 +libanalitza-dev#4:4.8.4-2 +libanet0.1-dev#0.1-3 +libanjuta-dev#2:3.4.3-1 +libann-dev#1.1.2+doc-3 +libanthy-dev#9100h-16 +libantlr-dev#2.7.7+dfsg-4 +libantlr3c-dev#3.2-2 +libao-dev#1.1.0-2 +libao-ocaml-dev#0.2.0-1+b2 +libaosd-dev#0.2.7-1 +libapache2-mod-perl2-dev#2.0.7-3 +libapertium3-3.1-0-dev#3.1.0-2 +libapm-dev#3.2.2-14 +libapol-dev#3.3.7-3 +libapparmor-dev#2.7.103-4 +libappindicator-dev#0.4.92-2 +libappindicator0.1-cil-dev#0.4.92-2 +libappindicator3-dev#0.4.92-2 +libapq-postgresql3.2.0-dev#3.2.0-2 +libapq3.2.0-dev#3.2.0-1 +libapr-memcache-dev#0.7.0-1 +libapr1-dev#1.4.6-3+deb7u1 +libapreq2-dev#2.13-1+b2 +libapron-dev#0.9.10-5.2 +libapron-ocaml-dev#0.9.10-5.2+b3 +libaprutil1-dev#1.4.1-3 +libapt-pkg-dev#0.9.7.9+deb7u1 +libaqbanking34-dev#5.0.24-3 +libaqsis-dev#1.8.1-3 +libarchive-dev#3.0.4-3+nmu1 +libargtable2-dev#12-1 +libarmadillo-dev#1:3.2.3+dfsg-1 +libarpack++2-dev#2.3-2 +libarpack2-dev#3.1.1-2.1 +libart-2.0-dev#2.3.21-2 +libart2.0-cil-dev#2.24.2-3 +libasio-dev#1.4.1-3.2 +libasis2010-dev#2010-5 +libasm-dev#0.152-1+wheezy1 +libasound2-dev#1.0.25-4 +libaspell-dev#0.60.7~20110707-1 +libass-dev#0.10.0-3 +libassa3.5-5-dev#3.5.1-2 +libassimp-dev#3.0~dfsg-1 +libassuan-dev#2.0.3-1 +libast2-dev#0.7-6+b1 +libasyncns-dev#0.8-4 +libatasmart-dev#0.19-1 +libatd-ocaml-dev#1.0.1-1+b1 +libatdgen-ocaml-dev#1.2.2-1+b1 +libatk-bridge2.0-dev#2.5.3-2 +libatk1.0-dev#2.4.0-2 +libatkmm-1.6-dev#2.22.6-1 +libatlas-base-dev#3.8.4-9+deb7u1 +libatlas-cpp-0.6-dev#0.6.2-3 +libatlas-dev#3.8.4-9+deb7u1 +libatm1-dev#1:2.5.1-1.5 +libatomic-ops-dev#7.2~alpha5+cvs20101124-1+deb7u1 +libatomicparsley-dev#2.1.2-1 +libatspi-dev#1.32.0-2 +libatspi2.0-dev#2.5.3-2 +libattica-dev#0.2.0-1 +libattr1-dev#1:2.4.46-8 +libaubio-dev#0.3.2-4.2+b1 +libaudio-dev#1.9.3-5wheezy1 +libaudiofile-dev#0.3.4-2 +libaudiomask-dev#1.0-2 +libaudit-dev#1:1.7.18-1.1 +libaugeas-dev#0.10.0-1 +libaunit2-dev#1.03-7 +libautotrace-dev#0.31.1-16+b1 +libautounit-dev#0.20.1-4 +libavahi-cil-dev#0.6.19-4.2 +libavahi-client-dev#0.6.31-2 +libavahi-common-dev#0.6.31-2 +libavahi-compat-libdnssd-dev#0.6.31-2 +libavahi-core-dev#0.6.31-2 +libavahi-glib-dev#0.6.31-2 +libavahi-gobject-dev#0.6.31-2 +libavahi-qt4-dev#0.6.31-2 +libavahi-ui-cil-dev#0.6.19-4.2 +libavahi-ui-dev#0.6.31-2 +libavahi-ui-gtk3-dev#0.6.31-2 +libavbin-dev#7-1.3 +libavc1394-dev#0.5.4-2 +libavcodec-dev#6:0.8.10-1 +libavdevice-dev#6:0.8.10-1 +libavfilter-dev#6:0.8.10-1 +libavformat-dev#6:0.8.10-1 +libavifile-0.7-dev#1:0.7.48~20090503.ds-13 +libavl-dev#0.3.5-3 +libavogadro-dev#1.0.3-5 +libavutil-dev#6:0.8.10-1 +libaws2.10.2-dev#2.10.2-4 +libax25-dev#0.0.12-rc2+cvs20120204-2 +libbabl-dev#0.1.10-1 +libball1.4-dev#1.4.1+20111206-4 +libballview1.4-dev#1.4.1+20111206-4 +libbam-dev#0.1.18-1 +libbamf-dev#0.2.118-1 +libbamf3-dev#0.2.118-1 +libbarry-dev#0.18.3-5 +libbatteries-ocaml-dev#1.4.3-1 +libbdd-dev#2.4-8 +libbeecrypt-dev#4.2.1-4 +libbenchmark-ocaml-dev#0.9-2+b3 +libbfb0-dev#0.23-1.1 +libbg1-dev#1.106-1 +libbibutils-dev#4.12-5 +libbin-prot-camlp4-dev#2.0.7-1 +libbind-dev#1:9.8.4.dfsg.P1-6+nmu2+deb7u1 +libbind4-dev#6.0-1 +libbinio-dev#1.4+dfsg1-1 +libbiniou-ocaml-dev#1.0.0-1+b1 +libbio2jack0-dev#0.9-2.1 +libbiococoa-dev#2.2.2-1+b2 +libbiosig-dev#1.3.0-2 +libbisho-common-dev#0.27.2+git20111122.9e68ef3d-1 +libbison-dev#1:2.5.dfsg-2.1 +libbitmask-dev#2.0-2 +libbitstream-dev#1.0-1 +libbitstring-ocaml-dev#2.0.2-3+b1 +libbjack-ocaml-dev#0.1.3-5+b1 +libblacs-mpi-dev#1.1-31 +libblas-dev#1.2.20110419-5 +libbliss-dev#0.72-4 +libblitz0-dev#1:0.9-13 +libblkid-dev#2.20.1-5.3 +libblocksruntime-dev#0.1-1 +libbluedevil-dev#1.9.2-1 +libbluetooth-dev#4.99-2 +libbluray-dev#1:0.2.2-1 +libbml-dev#0.6.1-1 +libbobcat-dev#3.01.00-1+b1 +libbogl-dev#0.1.18-8+b1 +libbognor-regis-dev#0.6.12+git20101007.02c25268-7 +libbonobo2-dev#2.24.3-1 +libbonoboui2-dev#2.24.3-1 +libboo-cil-dev#0.9.5~git20110729.r1.202a430-2 +libboost-all-dev#1.49.0.1 +libboost-chrono-dev#1.49.0.1 +libboost-chrono1.49-dev#1.49.0-3.2 +libboost-date-time-dev#1.49.0.1 +libboost-date-time1.49-dev#1.49.0-3.2 +libboost-dev#1.49.0.1 +libboost-filesystem-dev#1.49.0.1 +libboost-filesystem1.49-dev#1.49.0-3.2 +libboost-graph-dev#1.49.0.1 +libboost-graph-parallel-dev#1.49.0.1 +libboost-graph-parallel1.49-dev#1.49.0-3.2 +libboost-graph1.49-dev#1.49.0-3.2 +libboost-iostreams-dev#1.49.0.1 +libboost-iostreams1.49-dev#1.49.0-3.2 +libboost-locale-dev#1.49.0.1 +libboost-locale1.49-dev#1.49.0-3.2 +libboost-math-dev#1.49.0.1 +libboost-math1.49-dev#1.49.0-3.2 +libboost-mpi-dev#1.49.0.1 +libboost-mpi-python-dev#1.49.0.1 +libboost-mpi-python1.49-dev#1.49.0-3.2 +libboost-mpi1.49-dev#1.49.0-3.2 +libboost-program-options-dev#1.49.0.1 +libboost-program-options1.49-dev#1.49.0-3.2 +libboost-python-dev#1.49.0.1 +libboost-python1.49-dev#1.49.0-3.2 +libboost-random-dev#1.49.0.1 +libboost-random1.49-dev#1.49.0-3.2 +libboost-regex-dev#1.49.0.1 +libboost-regex1.49-dev#1.49.0-3.2 +libboost-serialization-dev#1.49.0.1 +libboost-serialization1.49-dev#1.49.0-3.2 +libboost-signals-dev#1.49.0.1 +libboost-signals1.49-dev#1.49.0-3.2 +libboost-system-dev#1.49.0.1 +libboost-system1.49-dev#1.49.0-3.2 +libboost-test-dev#1.49.0.1 +libboost-test1.49-dev#1.49.0-3.2 +libboost-thread-dev#1.49.0.1 +libboost-thread1.49-dev#1.49.0-3.2 +libboost-timer-dev#1.49.0.1 +libboost-timer1.49-dev#1.49.0-3.2 +libboost-wave-dev#1.49.0.1 +libboost-wave1.49-dev#1.49.0-3.2 +libboost1.49-all-dev#1.49.0-3.2 +libboost1.49-dev#1.49.0-3.2 +libbotan1.10-dev#1.10.5-1 +libbox-dev#2.5-2 +libbox2d-dev#2.0.1+dfsg1-1 +libbpp-core-dev#2.0.3-1 +libbpp-phyl-dev#2.0.3-1 +libbpp-popgen-dev#2.0.3-1 +libbpp-qt-dev#2.0.2-1 +libbpp-raa-dev#2.0.3-1 +libbpp-seq-dev#2.0.3-1 +libbrahe-dev#1.3.2-3 +libbrasero-media3-dev#3.4.1-4 +libbrlapi-dev#4.4-10+deb7u1 +libbs2b-dev#3.1.0+dfsg-2 +libbsd-dev#0.4.2-1 +libbse-dev#0.7.4-5 +libbt-dev#0.70.1-13 +libbtparse-dev#0.63-1 +libbuffy-dev#1.7-1 +libbulletml-dev#0.0.6-5 +libburn-dev#1.2.2-2 +libbuzztard-dev#0.5.0-4 +libbz2-dev#1.0.6-4 +libbz2-ocaml-dev#0.6.0-6+b2 +libc-ares-dev#1.9.1-3 +libc-client2007e-dev#8:2007f~dfsg-2 +libc6-dev#2.13-38+deb7u1 +libcableswig-dev#0.1.0+cvs20111009-1 +libcaca-dev#0.99.beta18-1 +libcairo-ocaml-dev#1:1.2.0-2+b1 +libcairo2-dev#1.12.2-3 +libcairomm-1.0-dev#1.10.0-1 +libcal3d12-dev#0.11.0-4.1 +libcalendar-ocaml-dev#2.03-1+b2 +libcamel1.2-dev#3.4.4-3 +libcameleon-ocaml-dev#1.9.21-2+b1 +libcaml2html-ocaml-dev#1.4.1-3 +libcamlimages-ocaml-dev#1:4.0.1-4+b2 +libcamljava-ocaml-dev#0.3-1+b3 +libcamltemplate-ocaml-dev#1.0.2-1+b2 +libcamomile-ocaml-dev#0.8.4-2 +libcanberra-dev#0.28-6 +libcanberra-gtk-common-dev#0.28-6 +libcanberra-gtk-dev#0.28-6 +libcanberra-gtk3-dev#0.28-6 +libcanlock2-dev#2b-6 +libcanna1g-dev#3.7p3-11 +libcap-dev#1:2.22-1.2 +libcap-ng-dev#0.6.6-2 +libcapi20-dev#1:3.25+dfsg1-3.3~deb7u1 +libcapsinetwork-dev#0.3.0-7 +libcaribou-dev#0.4.4-1 +libcbf-dev#0.7.9.1-3 +libccaudio2-dev#2.0.5-3 +libccfits-dev#2.4-1 +libcconv-dev#0.6.2-1 +libccrtp-dev#2.0.3-4 +libccs-dev#3.0.12-3.2+deb7u2 +libccscript3-dev#1.1.7-2 +libccss-dev#0.5.0-4 +libcdaudio-dev#0.99.12p2-12 +libcdb-dev#0.78 +libcdd-dev#094b.dfsg-4.2 +libcddb2-dev#1.3.2-3 +libcdi-dev#1.5.4+dfsg.1-5 +libcdio-cdda-dev#0.83-4 +libcdio-dev#0.83-4 +libcdio-paranoia-dev#0.83-4 +libcdk5-dev#5.0.20060507-4 +libcdparanoia-dev#3.10.2+debian-10.1 +libcec-dev#1.6.2-1.1 +libcegui-mk2-dev#0.7.6-2+b1 +libcext-dev#6.1.1-2 +libcf-ocaml-dev#0.10-3+b3 +libcfg-dev#1.4.2-3 +libcfitsio3-dev#3.300-2 +libcgal-dev#4.0-5 +libcgic-dev#2.05-3 +libcgicc5-dev#3.2.9-3 +libcgns-dev#3.1.3.4-1+b1 +libcgroup-dev#0.38-1 +libcgsi-gsoap-dev#1.3.5-1 +libchamplain-0.12-dev#0.12.3-1 +libchamplain-gtk-0.12-dev#0.12.3-1 +libcharls-dev#1.0-2 +libchasen-dev#2.4.5-6 +libcheese-dev#3.4.2-2 +libcheese-gtk-dev#3.4.2-2 +libchewing3-dev#0.3.3-4 +libchicken-dev#4.7.0-1 +libchipcard-dev#5.0.3beta-3 +libchise-dev#0.3.0-2+b1 +libchm-dev#2:0.40a-2 +libchromaprint-dev#0.6-2 +libcib1-dev#1.1.7-1 +libcitadel-dev#8.14-1 +libcitygml0-dev#0.14+svn128-1+3p0p1+4 +libck-connector-dev#0.4.5-3.1 +libckyapplet1-dev#1.1.0-12 +libclalsadrv-dev#2.0.0-3 +libclam-dev#1.4.0-5.1 +libclam-qtmonitors-dev#1.4.0-3.1 +libclamav-dev#0.98.1+dfsg-1+deb7u3 +libclang-common-dev#1:3.0-6.2 +libclang-dev#1:3.0-6.2 +libclanlib-dev#1.0~svn3827-3 +libclassad-dev#7.8.2~dfsg.1-1+deb7u1 +libclaw-application-dev#1.7.0-3 +libclaw-configuration-file-dev#1.7.0-3 +libclaw-dev#1.7.0-3 +libclaw-dynamic-library-dev#1.7.0-3 +libclaw-graphic-dev#1.7.0-3 +libclaw-logger-dev#1.7.0-3 +libclaw-net-dev#1.7.0-3 +libclaw-tween-dev#1.7.0-3 +libclaws-mail-dev#3.8.1-2 +libclhep-dev#2.1.2.3-1 +libcli-dev#1.9.6-1 +libclippoly-dev#0.11-3 +libclips-dev#6.24-3 +libcliquer-dev#1.21-1 +libcln-dev#1.3.2-1.2 +libcloog-isl-dev#0.17.0-3 +libcloog-ppl-dev#0.15.11-4 +libclthreads-dev#2.4.0-4 +libclucene-dev#0.9.21b-2+b1 +libclustalo-dev#1.1.0-1 +libcluster-glue-dev#1.0.9+hg2665-1 +libclutter-1.0-dev#1.10.8-2 +libclutter-cil-dev#1.0.0~alpha3~git20090817.r1.349dba6-8 +libclutter-gst-dev#1.5.4-1+build0 +libclutter-gtk-1.0-dev#1.2.0-2 +libclutter-imcontext-0.1-dev#0.1.4-3 +libcluttergesture-dev#0.0.2.1-7 +libclxclient-dev#3.6.1-6 +libcman-dev#3.0.12-3.2+deb7u2 +libcminpack-dev#1.2.2-1 +libcmis-dev#0.1.0-1+b1 +libcmor-dev#2.8.0-2+b1 +libcmph-dev#0.9-1 +libcneartree-dev#3.1.1-1 +libcnf-dev#4.0-2 +libcob1-dev#1.1-1 +libcogl-dev#1.10.2-7 +libcogl-pango-dev#1.10.2-7 +libcoin60-dev#3.1.3-2.2 +libcojets2-dev#20061220+dfsg3-2 +libcollectdclient-dev#5.1.0-3 +libcollection-dev#0.1.3-2 +libcolorblind-dev#0.0.1-1 +libcolord-dev#0.1.21-1 +libcolord-gtk-dev#0.1.21-1 +libcolorhug-dev#0.1.10-1 +libcomedi-dev#0.10.0-3 +libcommoncpp2-dev#1.8.1-5 +libcompfaceg1-dev#1:1.5.2-5 +libconcord-dev#0.24-1.1 +libconfdb-dev#1.4.2-3 +libconfig++-dev#1.4.8-5 +libconfig++8-dev#1.4.8-5 +libconfig-dev#1.4.8-5 +libconfig-file-ocaml-dev#1.1-1 +libconfig8-dev#1.4.8-5 +libconfuse-dev#2.7-4 +libcontactsdb-dev#0.5-8 +libcoq-ocaml-dev#8.3.pl4+dfsg-2 +libcore-ocaml-dev#107.01-5 +libcorelinux-dev#0.4.32-7.3 +libcoroipcc-dev#1.4.2-3 +libcoroipcs-dev#1.4.2-3 +libcorosync-dev#1.4.2-3 +libcos4-dev#4.1.6-2 +libcothreads-ocaml-dev#0.10-3+b3 +libcoyotl-dev#3.1.0-5 +libcpg-dev#1.4.2-3 +libcpl-dev#6.1.1-2 +libcppcutter-dev#1.1.7-1.2 +libcppunit-dev#1.12.1-4 +libcppunit-subunit-dev#0.0.8+bzr176-1 +libcpputest-dev#3.1-2 +libcpufreq-dev#008-1 +libcpuset-dev#1.0-3 +libcqrlib2-dev#1.1.2-1 +libcr-dev#0.8.5-2 +libcrack2-dev#2.8.19-3 +libcreal-ocaml-dev#0.7-6+b3 +libcrmcluster1-dev#1.1.7-1 +libcrmcommon2-dev#1.1.7-1 +libcroco3-dev#0.6.6-2 +libcry-ocaml-dev#0.2.2-1+b1 +libcryptgps-ocaml-dev#0.2.1-7+b3 +libcrypto++-dev#5.6.1-6 +libcryptokit-ocaml-dev#1.5-1 +libcryptsetup-dev#2:1.4.3-4 +libcryptui-dev#3.2.2-1 +libcrystalhd-dev#1:0.0~git20110715.fdd2f19-9 +libcsfml-dev#1.6-1 +libcsnd-dev#1:5.17.11~dfsg-3 +libcsoap-dev#1.1.0-17.1 +libcsound64-dev#1:5.17.11~dfsg-3 +libcsoundac-dev#1:5.17.11~dfsg-3 +libcsv-ocaml-dev#1.2.2-1+b1 +libctapimkt0-dev#1.0.1-1.1 +libctdb-dev#1.12+git20120201-4 +libctemplate-dev#2.2-3 +libctl-dev#3.1.0-5 +libctpl-dev#0.3.3.dfsg-2 +libcuba3-dev#3.0+20111124-2 +libcudf-dev#0.6.2-1 +libcudf-ocaml-dev#0.6.2-1 +libcue-dev#1.4.0-1 +libcunit1-dev#2.1-0.dfsg-10 +libcunit1-ncurses-dev#2.1-0.dfsg-10 +libcups2-dev#1.5.3-5+deb7u1 +libcupscgi1-dev#1.5.3-5+deb7u1 +libcupsdriver1-dev#1.5.3-5+deb7u1 +libcupsfilters-dev#1.0.18-2.1+deb7u1 +libcupsimage2-dev#1.5.3-5+deb7u1 +libcupsmime1-dev#1.5.3-5+deb7u1 +libcupsppdc1-dev#1.5.3-5+deb7u1 +libcupt2-dev#2.5.9 +libcurl-ocaml-dev#0.5.3-2+b1 +libcurl4-gnutls-dev#7.26.0-1+wheezy9 +libcurl4-nss-dev#7.26.0-1+wheezy9 +libcurl4-openssl-dev#7.26.0-1+wheezy9 +libcurses-ocaml-dev#1.0.3-2 +libcutter-dev#1.1.7-1.2 +libcv-dev#2.3.1-11 +libcvaux-dev#2.3.1-11 +libcvc3-dev#2.4.1-4 +libcvector2-dev#1.0.3-1 +libcvm1-dev#0.96-1+b1 +libcw3-dev#3.0.2-1 +libcwidget-dev#0.5.16-3.4 +libcwiid-dev#0.6.00+svn201-3+b1 +libcwnn-dev#1.1.1~a021+cvs20100325-6 +libcxgb3-dev#1.3.1-1 +libcxxtools-dev#2.1.1-1 +libdacs-dev#1.4.27b-2 +libdaemon-dev#0.14-2 +libdancer-xml0-dev#0.8.2.1-3 +libdap-dev#3.11.1-11 +libdapl-dev#2.0.19-1.1 +libdaq-dev#0.6.2-2 +libdar-dev#2.4.5.debian.1-1 +libdatrie-dev#0.2.5-3 +libdawgdic-dev#0.4.3-1 +libdb++-dev#5.1.6 +libdb-dev#5.1.6 +libdb-java-dev#5.1.6 +libdb-sql-dev#5.1.6 +libdb4o-cil-dev#8.0.184.15484+dfsg-2 +libdb5.1++-dev#5.1.29-5 +libdb5.1-dev#5.1.29-5 +libdb5.1-java-dev#5.1.29-5 +libdb5.1-sql-dev#5.1.29-5 +libdb5.1-stl-dev#5.1.29-5 +libdballe-dev#5.18-1 +libdballef-dev#5.18-1 +libdbaudiolib0-dev#0.9.8-6.2 +libdbi-dev#0.8.4-6 +libdbus-1-dev#1.6.8-1+deb7u1 +libdbus-c++-dev#0.9.0-6 +libdbus-glib-1-dev#0.100.2-1 +libdbus-glib1.0-cil-dev#0.5.0-4 +libdbus-ocaml-dev#0.29-1+b3 +libdbus1.0-cil-dev#0.7.0-5 +libdbusada0.2-dev#0.2-2 +libdbusmenu-glib-dev#0.6.2-1 +libdbusmenu-gtk-dev#0.6.2-1 +libdbusmenu-gtk3-dev#0.6.2-1 +libdbusmenu-jsonloader-dev#0.6.2-1 +libdbusmenu-qt-dev#0.9.0-1 +libdc-dev#0.3.24~svn3121-2 +libdc1394-22-dev#2.2.0-2 +libdca-dev#0.0.5-5 +libdcerpc-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcerpc-server-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcmtk2-dev#3.6.0-12 +libdconf-dbus-1-dev#0.12.1-3 +libdconf-dev#0.12.1-3 +libddccontrol-dev#0.4.2-10 +libdds-dev#2.1.2+ddd105-1 +libdebconf-kde-dev#0.2-2 +libdebconfclient0-dev#0.182 +libdebian-installer4-dev#0.87 +libdebug0-dev#0.4.4-1.1 +libdecodeqr-dev#0.9.3-6.2 +libdee-dev#1.0.10-3 +libderiving-ocaml-dev#0.1.1a-3+b1 +libderiving-ocsigen-ocaml-dev#0.3c-1 +libdesktop-agnostic-dev#0.3.92+dfsg-1 +libdessert0.87-dev#0.87.2-1 +libdevhelp-dev#3.4.1-1 +libdevil-dev#1.7.8-6.1+b1 +libdevmapper-dev#2:1.02.74-8 +libdhash-dev#0.1.3-2 +libdiagnostics-dev#0.3.3-1.3 +libdianewcanvas2-dev#0.6.10-5.4 +libdieharder-dev#3.31.1-4 +libdiet-admin2.8-dev#2.8.0-1+b1 +libdiet-client2.8-dev#2.8.0-1+b1 +libdiet-dagda2.8-dev#2.8.0-1+b1 +libdiet-sed2.8-dev#2.8.0-1+b1 +libdime-dev#0.20030921-2 +libdirac-dev#1.0.2-6 +libdirectfb-dev#1.2.10.0-5 +libdisasm-dev#0.23-5 +libdiscid0-dev#0.2.2-3 +libdiscover-dev#2.1.2-5.2 +libdispatch-dev#0~svn197-3.1 +libdisplaymigration0-dev#0.28-10 +libdistorm64-dev#1.7.30-1 +libdivecomputer-dev#0.1.0-3 +libdjconsole-dev#0.1.3-1 +libdjvulibre-dev#3.5.25.3-1 +libdkim-dev#1:1.0.21-3 +libdlm-dev#3.0.12-3.2+deb7u2 +libdlmcontrol-dev#3.0.12-3.2+deb7u2 +libdlrestrictions-dev#0.15.3 +libdm0-dev#2.2.10-1 +libdmalloc-dev#5.5.2-5 +libdmapsharing-3.0-dev#2.9.15-1 +libdmraid-dev#1.0.0.rc16-4.2 +libdmtcpaware-dev#1.2.5-1 +libdmtx-dev#0.7.2-2+build1 +libdmx-dev#1:1.1.2-1+deb7u1 +libdnet-dev#2.60 +libdockapp-dev#1:0.5.0-3 +libdolfin1.0-dev#1.0.0-7 +libdoodle-dev#0.7.0-5 +libdose2-ocaml-dev#1.4.2-4+b3 +libdose3-ocaml-dev#3.0.2-3 +libdotconf-dev#1.0.13-3 +libdpkg-dev#1.16.12 +libdpm-dev#1.8.2-1+b2 +libdrawtk-dev#2.0-2 +libdrizzle-dev#1:7.1.36-stable-1 +libdrizzledmessage-dev#1:7.1.36-stable-1 +libdrm-dev#2.4.40-1~deb7u2 +libdrumstick-dev#0.5.0-3 +libdsdp-dev#5.8-9.1 +libdshconfig1-dev#0.20.13-1 +libdspam7-dev#3.10.1+dfsg-11 +libdssi-ocaml-dev#0.1.0-1+b1 +libdssialsacompat-dev#1.0.8a-1 +libdtools-ocaml-dev#0.3.0-1 +libdts-dev#0.0.5-5 +libdumb1-dev#1:0.9.3-5.4 +libdumbnet-dev#1.12-3.1 +libdune-common-dev#2.2.0-1 +libdune-geometry-dev#2.2.0-1 +libdune-grid-dev#2.2.0-1 +libdune-istl-dev#2.2.0-1 +libdune-localfunctions-dev#2.2.0-1 +libduo-dev#1.8-1 +libduppy-ocaml-dev#0.4.2-1+b2 +libdv4-dev#1.0.0-6 +libdvb-dev#0.5.5.1-5.1 +libdvbcsa-dev#1.1.0-2 +libdvbpsi-dev#0.2.2-1 +libdvdnav-dev#4.2.0+20120524-2 +libdvdread-dev#4.2.0+20120521-2 +libdw-dev#0.152-1+wheezy1 +libdwarf-dev#20120410-2 +libdx4-dev#1:4.4.4-4+b2 +libdxflib-dev#2.2.0.0-8 +libdynamite-dev#0.1.1-2 +libeasy-format-ocaml-dev#1.0.0-1+b2 +libeb16-dev#4.4.3-6 +libebackend1.2-dev#3.4.4-3 +libebml-dev#1.2.2-2 +libebook1.2-dev#3.4.4-3 +libecal1.2-dev#3.4.4-3 +libecasoundc-dev#2.9.0-1 +libecasoundc2.2-dev#2.9.0-1 +libechonest-dev#1.2.1-1 +libecm-dev#6.4.2-1 +libecore-dev#1.2.0-2 +libecpg-dev#9.1.13-0wheezy1 +libecryptfs-dev#99-1 +libedac-dev#0.18-1 +libedata-book1.2-dev#3.4.4-3 +libedata-cal1.2-dev#3.4.4-3 +libedataserver1.2-dev#3.4.4-3 +libedataserverui-3.0-dev#3.4.4-3 +libedbus-dev#1.2.0-1 +libedit-dev#2.11-20080614-5 +libeditline-dev#1.12-6 +libedje-dev#1.2.0-1 +libee-dev#0.4.1-1 +libeegdev-dev#0.2-3 +libeet-dev#1.6.0-1 +libefreet-dev#1.2.0-1 +libegl1-mesa-dev#8.0.5-4+deb7u2 +libeigen2-dev#2.0.17-1 +libeigen3-dev#3.1.0-1 +libeina-dev#1.2.0-2 +libelektra-cpp-dev#0.7.1-1 +libelektra-dev#0.7.1-1 +libelektratools-dev#0.7.1-1 +libelemental-dev#1.2.0-8 +libelementary-dev#0.7.0.55225-1 +libelf-dev#0.152-1+wheezy1 +libelfg0-dev#0.8.13-3 +libeliom-ocaml-dev#2.2.2-1 +libelk0-dev#3.99.8-2 +libelmer-dev#6.1.0.svn.5396.dfsg2-2 +libembryo-dev#1.2.0-1 +libemos-dev#000382+dfsg-2 +libenca-dev#1.13-4 +libenchant-dev#1.6.0-7 +libenet-dev#1.3.3-2 +libepc-dev#0.4.4-1 +libepc-ui-dev#0.4.4-1 +libepr-api2-dev#2.2-2 +libepsilon-dev#0.9.1-2 +libept-dev#1.0.9 +libepub-dev#0.2.1-2+b1 +liberis-1.3-dev#1.3.19-5 +liberuby-dev#1.0.5-2.1 +libescpr-dev#1.1.1-2 +libesd0-dev#0.2.41-10+b1 +libesmtp-dev#1.0.6-1+b1 +libespeak-dev#1.46.02-2 +libestools2.1-dev#1:2.1~release-5 +libestr-dev#0.1.1-2 +libethos-dev#0.2.2-3 +libethos-ui-dev#0.2.2-3 +libetpan-dev#1.0-5 +libetsf-io-dev#1.0.3-4+b1 +libeurodec1-dev#20061220+dfsg3-2 +libev-dev#1:4.11-1 +libev-libevent-dev#1:4.11-1 +libeval0-dev#0.29.6-2 +libevas-dev#1.2.0-2 +libevd-0.1-dev#0.1.20-2 +libevent-dev#2.0.19-stable-3 +libeventdb-dev#0.90-5 +libevince-dev#3.4.0-3.1 +libevocosm-dev#4.0.2-2.1 +libevs-dev#1.4.2-3 +libevtlog-dev#0.2.12-5 +libewf-dev#20100226-1+b1 +libexchangemapi-1.0-dev#3.4.4-1 +libexempi-dev#2.2.0-1 +libexif-dev#0.6.20-3 +libexif-gtk-dev#0.3.5-5 +libexiv2-dev#0.23-1 +libexo-1-dev#0.6.2-5 +libexodusii-dev#5.14.dfsg.1-2+b1 +libexosip2-dev#3.6.0-4 +libexpat-ocaml-dev#0.9.1+debian1-7+b2 +libexpat1-dev#2.1.0-1+deb7u1 +libexpect-ocaml-dev#0.0.2-1+b6 +libexplain-dev#0.52.D002-1 +libextlib-ocaml-dev#1.5.2-1+b1 +libextractor-dev#1:0.6.3-5 +libextractor-java-dev#0.6.0-6 +libexttextcat-dev#3.2.0-2 +libextunix-ocaml-dev#0.0.5-2 +libeztrace-dev#0.7-2-4 +libf2c2-dev#20090411-2 +libfaad-dev#2.7-8 +libfaad-ocaml-dev#0.3.0-1+b1 +libfacile-ocaml-dev#1.1-8+b1 +libfaifa-dev#0.2~svn82-1 +libfakekey-dev#0.1-7 +libfam-dev#2.7.0-17 +libfann-dev#2.1.0~beta~dfsg-8 +libfarstream-0.1-dev#0.1.2-1 +libfastjet-dev#3.0.2+dfsg-2 +libfastjet-fortran-dev#3.0.2+dfsg-2 +libfastjetplugins-dev#3.0.2+dfsg-2 +libfastjettools-dev#3.0.2+dfsg-2 +libfauhdli-dev#20110812-1 +libfcgi-dev#2.4.0-8.1 +libfdt-dev#1.3.0-4 +libfence-dev#3.0.12-3.2+deb7u2 +libffado-dev#2.0.99+svn2171-2 +libffcall1-dev#1.10+cvs20100619-2 +libffi-dev#3.0.10-3 +libffindex0-dev#0.9.6.1-1 +libffmpegthumbnailer-dev#2.0.7-2 +libffms2-dev#2.17-1 +libfftw3-dev#3.3.2-3.1 +libfftw3-mpi-dev#3.3.2-3.1 +libfields-camlp4-dev#107.01-1+b2 +libfileutils-ocaml-dev#0.4.2-1+b2 +libfindlib-ocaml-dev#1.3.1-1 +libfiredns-dev#0.9.12+dfsg-3 +libfirestring-dev#0.9.12-8 +libfishsound1-dev#1.0.0-1.1 +libfiu-dev#0.90-3 +libfixposix-dev#20110316.git47f17f7-1 +libfko0-dev#2.0.0rc2-2+deb7u2 +libflac++-dev#1.2.1-6 +libflac-dev#1.2.1-6 +libflac-ocaml-dev#0.1.1-1 +libflake-dev#0.11-2 +libflann-dev#1.7.1-4 +libflatzebra-dev#0.1.5-4+b1 +libflickrnet-cil-dev#1:2.2.0-4 +libflorist2011-dev#2011-1 +libflowcanvas-dev#0.7.1+dfsg0-0.2 +libfltk1.1-dev#1.1.10-14 +libfltk1.3-dev#1.3.0-8 +libfluidsynth-dev#1.1.5-2 +libfm-dev#0.1.17-2.1 +libfolia1-dev#0.9-2 +libfolks-dev#0.6.9-1+b1 +libfolks-eds-dev#0.6.9-1+b1 +libfolks-telepathy-dev#0.6.9-1+b1 +libfontconfig1-dev#2.9.0-7.1 +libfontenc-dev#1:1.1.1-1 +libfontforge-dev#0.0.20120101+git-2 +libforms-dev#1.0.93sp1-2 +libformsgl-dev#1.0.93sp1-2 +libfox-1.6-dev#1.6.45-1 +libfprint-dev#1:0.4.0-4-gdfff16f-4 +libfreecell-solver-dev#3.12.0-1 +libfreefem++-dev#3.19.1-1 +libfreefem-dev#3.5.8-5 +libfreehdl0-dev#0.0.7-1.1 +libfreeimage-dev#3.15.1-1+b1 +libfreeipmi-dev#1.1.5-3 +libfreenect-dev#1:0.1.2+dfsg-6 +libfreeradius-dev#2.1.12+dfsg-1.2 +libfreerdp-dev#1.0.1-1.1+deb7u3 +libfreetype6-dev#2.4.9-1.1 +libfreexl-dev#1.0.0b-1 +libfribidi-dev#0.19.2-3 +libfs-dev#2:1.0.4-1+deb7u1 +libfso-glib-dev#2012.05.24.1-1.1 +libfsobasics-dev#0.11.0-1.1 +libfsoframework-dev#0.11.0-1.1 +libfsoresource-dev#0.11.0-1.1 +libfsosystem-dev#0.11.0-1 +libfsotransport-dev#0.11.1-2.1 +libfsplib-dev#0.11-2 +libfstrcmp-dev#0.4.D001-1+deb7u1 +libftdi-dev#0.20-1+b1 +libftdipp-dev#0.20-1+b1 +libftgl-dev#2.1.3~rc5-4 +libfuntools-dev#1.4.4-3 +libfuse-dev#2.9.0-2+deb7u1 +libfuzzy-dev#2.7-2 +libfxt-dev#0.2.6-2 +libg15-dev#1.2.7-2 +libg15daemon-client-dev#1.9.5.3-8.2 +libg15render-dev#1.3.0~svn316-2.2 +libg2-dev#0.72-2.1 +libg3d-dev#0.0.8-17 +libga-dev#2.4.7-3 +libgadap-dev#2.0-1 +libgadu-dev#1:1.11.2-1+deb7u1 +libgail-3-dev#3.4.2-7 +libgail-dev#2.24.10-2 +libgalax-ocaml-dev#1.1-10+b3 +libgambc4-dev#4.2.8-1.1 +libgamin-dev#0.1.10-4.1 +libgammu-dev#1.31.90-1+b1 +libganglia1-dev#3.3.8-1+nmu1 +libganv-dev#0~svn4468~dfsg0-1 +libgarcon-1-0-dev#0.1.12-1 +libgarmin-dev#0~svn320-3 +libgatos-dev#0.0.5-19 +libgavl-dev#1.4.0-1 +libgavl-ocaml-dev#0.1.4-1+b1 +libgbm-dev#8.0.5-4+deb7u2 +libgc-dev#1:7.1-9.1 +libgcal-dev#0.9.6-3 +libgccxml-dev#0.9.0+cvs20120420-4 +libgcgi-dev#0.9.5.dfsg-7 +libgcj12-dev#4.6.3-1 +libgcj13-dev#4.7.2-3 +libgck-1-dev#3.4.1-3 +libgconf-bridge-dev#0.1-2.2 +libgconf2-dev#3.2.5-1+build1 +libgconf2.0-cil-dev#2.24.2-3 +libgconfmm-2.6-dev#2.28.0-1 +libgcr-3-dev#3.4.1-3 +libgcroots-dev#0.8.5-2.1 +libgcrypt11-dev#1.5.0-5+deb7u1 +libgctp-dev#1.0-1 +libgd-gd2-noxpm-ocaml-dev#1.0~alpha5-5 +libgd2-noxpm-dev#2.0.36~rc1~dfsg-6.1 +libgd2-xpm-dev#2.0.36~rc1~dfsg-6.1 +libgda-5.0-dev#5.0.3-2 +libgdal-dev#1.9.0-3.1 +libgdal1-dev#1.9.0-3.1 +libgdata-cil-dev#2.1.0.0-1 +libgdata-dev#0.12.0-1 +libgdb-dev#7.4.1+dfsg-0.1 +libgdbm-dev#1.8.3-11 +libgdchart-gd2-noxpm-dev#0.11.5-7+b1 +libgdchart-gd2-xpm-dev#0.11.5-7+b1 +libgdcm2-dev#2.2.0-14.1 +libgdf-dev#0.1.2-2 +libgdict-1.0-dev#3.4.0-2 +libgdk-pixbuf2.0-dev#2.26.1-1 +libgdkcutter-pixbuf-dev#1.1.7-1.2 +libgdl-3-dev#3.4.2-1 +libgdome2-cpp-smart-dev#0.2.6-6+b1 +libgdome2-dev#0.8.1+debian-4.1 +libgdome2-ocaml-dev#0.2.6-6+b1 +libgdu-dev#3.0.2-3 +libgdu-gtk-dev#3.0.2-3 +libgeant321-2-dev#1:3.21.14.dfsg-10 +libgearman-dev#0.33-2 +libgecode-dev#3.7.3-1 +libgeda-dev#1:1.6.2-4.3 +libgee-dev#0.6.4-2 +libgegl-dev#0.2.0-2+nmu1 +libgeier-dev#0.13-1+b1 +libgenders0-dev#1.18-1 +libgenome-1.3-0-dev#1.3.1-3 +libgensec-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libgeoclue-dev#0.12.0-4 +libgeocode-glib-dev#0.99.0-1 +libgeographiclib-dev#1.21-1 +libgeoip-dev#1.4.8+dfsg-3 +libgeomview-dev#1.9.4-3 +libgeos++-dev#3.3.3-1.1 +libgeos-dev#3.3.3-1.1 +libgeotiff-dev#1.3.0+dfsg-3 +libgeotranz3-dev#3.1-2.1 +libges-0.10-dev#0.10.1-2 +libgetdata-dev#0.7.3-6 +libgetfem++-dev#4.1.1+dfsg1-11 +libgetopt++-dev#0.0.2-p22-3 +libgetopt-ocaml-dev#0.0.20040811-10+b3 +libgettext-ocaml-dev#0.3.4-1+b2 +libgexiv2-dev#0.4.1-3 +libgfarm-dev#2.4.1-1.1 +libgflags-dev#2.0-1 +libgfshare-dev#1.0.5-2 +libghc-acid-state-dev#0.6.3-1+b2 +libghc-active-dev#0.1.0.1-2+b2 +libghc-adjunctions-dev#2.4.0.2-1 +libghc-aeson-dev#0.6.0.2-1+b4 +libghc-agda-dev#2.3.0.1-2 +libghc-algebra-dev#2.1.1.2-1 +libghc-alut-dev#2.1.0.2-4+b1 +libghc-ami-dev#0.1-1+b5 +libghc-ansi-terminal-dev#0.5.5-3+b1 +libghc-ansi-wl-pprint-dev#0.6.4-1+b1 +libghc-arrows-dev#0.4.4.0-3+b1 +libghc-asn1-data-dev#0.6.1.3-2+b3 +libghc-attempt-dev#0.4.0-1+b2 +libghc-attoparsec-conduit-dev#0.4.0.1-1 +libghc-attoparsec-dev#0.10.1.1-2+b1 +libghc-attoparsec-enumerator-dev#0.3-3+b3 +libghc-augeas-dev#0.6.1-1 +libghc-authenticate-dev#1.2.1.1-2+b1 +libghc-base-unicode-symbols-dev#0.2.2.3-1+b1 +libghc-base16-bytestring-dev#0.1.1.4-2+b1 +libghc-base64-bytestring-dev#0.1.1.1-2 +libghc-bifunctors-dev#0.1.3.3-1+b1 +libghc-binary-shared-dev#0.8.1-1+b1 +libghc-bindings-dsl-dev#1.0.15-1+b1 +libghc-bindings-gpgme-dev#0.1.4-1 +libghc-bindings-libzip-dev#0.10-2 +libghc-bitarray-dev#0.0.1-2+b1 +libghc-blaze-builder-conduit-dev#0.4.0.2-1 +libghc-blaze-builder-dev#0.3.1.0-1+b2 +libghc-blaze-builder-enumerator-dev#0.2.0.4-1+b1 +libghc-blaze-html-dev#0.4.3.1-3+b2 +libghc-blaze-markup-dev#0.5.1.0-1 +libghc-blaze-textual-dev#0.2.0.6-2+b2 +libghc-bloomfilter-dev#1.2.6.8-1 +libghc-boolean-dev#0.0.1-2+b1 +libghc-boomerang-dev#1.3.1-1 +libghc-brainfuck-dev#0.1-2+b2 +libghc-byteorder-dev#1.0.3-2+b1 +libghc-bytestring-lexing-dev#0.4.0-1+b1 +libghc-bytestring-mmap-dev#0.2.2-2+b1 +libghc-bytestring-nums-dev#0.3.5-2+b1 +libghc-bytestring-show-dev#0.3.5.1-1+b1 +libghc-bzlib-dev#0.5.0.3-2+b1 +libghc-cabal-file-th-dev#0.2.2-1 +libghc-cairo-dev#0.12.3-1+b1 +libghc-case-insensitive-dev#0.4.0.1-2+b2 +libghc-categories-dev#1.0.3-1+b1 +libghc-cautious-file-dev#1.0.1-1 +libghc-cereal-conduit-dev#0.5-1+b1 +libghc-cereal-dev#0.3.5.2-1 +libghc-certificate-dev#1.2.3-2 +libghc-cgi-dev#3001.1.8.2-2+b3 +libghc-chart-dev#0.15-1+b2 +libghc-chell-dev#0.3-1 +libghc-citeproc-hs-dev#0.3.4-1+b4 +libghc-clientsession-dev#0.7.5-3+b1 +libghc-clock-dev#0.2.0.0-2+b1 +libghc-cmdargs-dev#0.9.5-1+b1 +libghc-colour-dev#2.3.3-1+b1 +libghc-comonad-dev#1.1.1.5-1+b1 +libghc-comonad-transformers-dev#2.1.1.1-1+b1 +libghc-comonads-fd-dev#2.1.1.2-1+b1 +libghc-conduit-dev#0.4.2-2 +libghc-configfile-dev#1.0.6-4+b3 +libghc-configurator-dev#0.2.0.0-1+b2 +libghc-contravariant-dev#0.2.0.2-1+b1 +libghc-convertible-dev#1.0.11.0-3+b3 +libghc-cookie-dev#0.4.0-1+b3 +libghc-cpphs-dev#1.13.3-2+b1 +libghc-cprng-aes-dev#0.2.3-3+b4 +libghc-cpu-dev#0.1.1-1 +libghc-criterion-dev#0.6.0.1-3+b4 +libghc-crypto-api-dev#0.10.2-1+b2 +libghc-crypto-conduit-dev#0.3.2-1+b1 +libghc-crypto-dev#4.2.4-1+b1 +libghc-crypto-pubkey-types-dev#0.1.1-1+b3 +libghc-cryptocipher-dev#0.3.5-1+b1 +libghc-cryptohash-dev#0.7.5-1+b2 +libghc-css-text-dev#0.1.1-3+b2 +libghc-csv-conduit-dev#0.2-1 +libghc-csv-dev#0.1.2-2+b3 +libghc-curl-dev#1.3.7-1+b1 +libghc-darcs-dev#2.8.1-1+b1 +libghc-data-accessor-dev#0.2.2.2-1+b1 +libghc-data-accessor-mtl-dev#0.2.0.3-1+b1 +libghc-data-accessor-template-dev#0.2.1.9-1+b2 +libghc-data-binary-ieee754-dev#0.4.2.1-3+b1 +libghc-data-default-dev#0.4.0-1 +libghc-data-inttrie-dev#0.0.7-1+b1 +libghc-data-lens-dev#2.10.0-1+b1 +libghc-data-memocombinators-dev#0.4.3-1+b1 +libghc-dataenc-dev#0.14.0.3-1+b1 +libghc-datetime-dev#0.2.1-3 +libghc-dbus-dev#0.10.3-1 +libghc-debian-dev#3.64-3 +libghc-diagrams-cairo-dev#0.5.0.2-1 +libghc-diagrams-core-dev#0.5.0.1-1+b1 +libghc-diagrams-dev#0.5-2 +libghc-diagrams-lib-dev#0.5-2 +libghc-diff-dev#0.1.3-1+b1 +libghc-digest-dev#0.0.1.0-1+b1 +libghc-dimensional-dev#0.10.1.2-2+b1 +libghc-directory-tree-dev#0.10.0-2+b1 +libghc-distributive-dev#0.2.2-1+b1 +libghc-dlist-dev#0.5-3+b1 +libghc-download-curl-dev#0.1.3-3+b3 +libghc-dpkg-dev#0.0.3-1 +libghc-dyre-dev#0.8.7-1 +libghc-edison-api-dev#1.2.1-18+b1 +libghc-edison-core-dev#1.2.1.3-9+b1 +libghc-edit-distance-dev#0.2.1-2 +libghc-editline-dev#0.2.1.0-5+b1 +libghc-ekg-dev#0.3.1.0-1+b2 +libghc-email-validate-dev#0.2.8-1+b3 +libghc-entropy-dev#0.2.1-2+b1 +libghc-enumerator-dev#0.4.19-1+b1 +libghc-erf-dev#2.0.0.0-2+b1 +libghc-event-list-dev#0.1.0.1-1+b1 +libghc-exception-transformers-dev#0.3.0.2-1+b1 +libghc-executable-path-dev#0.0.3-1+b1 +libghc-explicit-exception-dev#0.1.7-1+b1 +libghc-failure-dev#0.2.0.1-1+b1 +libghc-fast-logger-dev#0.0.2-1+b2 +libghc-fastcgi-dev#3001.0.2.3-3+b3 +libghc-fclabels-dev#1.1.3-1+b1 +libghc-feed-dev#0.3.8-3 +libghc-fgl-dev#5.4.2.4-2+b2 +libghc-file-embed-dev#0.0.4.4-1 +libghc-filemanip-dev#0.3.5.2-2+b2 +libghc-filestore-dev#0.5-1 +libghc-filesystem-conduit-dev#0.4.0-1 +libghc-free-dev#2.1.1.1-1+b1 +libghc-ftphs-dev#1.0.8-1+b3 +libghc-gconf-dev#0.12.1-1+b1 +libghc-gd-dev#3000.7.3-1 +libghc-ghc-events-dev#0.4.0.0-2+b1 +libghc-ghc-mtl-dev#1.0.1.1-1+b3 +libghc-ghc-paths-dev#0.1.0.8-2+b1 +libghc-ghc-syb-utils-dev#0.2.1.0-1+b3 +libghc-gio-dev#0.12.3-1+b1 +libghc-github-dev#0.4.0-2 +libghc-gitit-dev#0.10.0.1-1+b1 +libghc-glade-dev#0.12.1-1+b3 +libghc-glfw-dev#0.5.0.1-1+b1 +libghc-glib-dev#0.12.2-1+b1 +libghc-glut-dev#2.1.2.2-1 +libghc-gnuidn-dev#0.2-2+b2 +libghc-gnutls-dev#0.1.2-1+b1 +libghc-gsasl-dev#0.3.4-1+b1 +libghc-gstreamer-dev#0.12.1-1+b2 +libghc-gtk-dev#0.12.3-1+b2 +libghc-gtkglext-dev#0.12.1-1+b3 +libghc-gtksourceview2-dev#0.12.3-1+b3 +libghc-haddock-dev#2.10.0-1+b2 +libghc-hakyll-dev#3.2.7.2-1+b5 +libghc-hamlet-dev#1.0.1.3-1+b1 +libghc-happstack-dev#7.0.0-1+b1 +libghc-happstack-server-dev#7.0.1-1+b1 +libghc-harp-dev#0.4-3+b1 +libghc-hashable-dev#1.1.2.3-1+b2 +libghc-hashed-storage-dev#0.5.9-2+b2 +libghc-hashmap-dev#1.3.0.1-1+b2 +libghc-hashtables-dev#1.0.1.4-1+b1 +libghc-haskeline-dev#0.6.4.7-1+b1 +libghc-haskell-lexer-dev#1.0-3+b1 +libghc-haskell-src-dev#1.0.1.5-1+b2 +libghc-haskelldb-dev#2.1.1-5+b1 +libghc-haskelldb-hdbc-dev#2.1.0-4 +libghc-haskelldb-hdbc-odbc-dev#2.1.0-3 +libghc-haskelldb-hdbc-postgresql-dev#2.1.0-3 +libghc-haskelldb-hdbc-sqlite3-dev#2.1.0-3 +libghc-haskore-dev#0.2.0.3-2 +libghc-hastache-dev#0.3.3-2+b3 +libghc-haxml-dev#1:1.22.5-2+b2 +libghc-haxr-dev#3000.8.5-1+b3 +libghc-hcard-dev#0.0-2+b2 +libghc-hcwiid-dev#0.0.1-3+b1 +libghc-hdbc-dev#2.3.1.1-1+b3 +libghc-hdbc-odbc-dev#2.2.3.0-5+b3 +libghc-hdbc-postgresql-dev#2.3.2.1-1+b3 +libghc-hdbc-sqlite3-dev#2.3.3.0-1+b3 +libghc-hfuse-dev#0.2.4.1-1 +libghc-highlighting-kate-dev#0.5.1-1 +libghc-hinotify-dev#0.3.2-1+b1 +libghc-hint-dev#0.3.3.4-2+b4 +libghc-hipmunk-dev#5.2.0.8-1+b1 +libghc-hjavascript-dev#0.4.7-3+b1 +libghc-hjscript-dev#0.5.0-3+b2 +libghc-hjsmin-dev#0.1.1-1+b2 +libghc-hlint-dev#1.8.28-1+b3 +libghc-hoauth-dev#0.3.4-1+b1 +libghc-hostname-dev#1.0-4+b1 +libghc-hs-bibutils-dev#4.12-5+b2 +libghc-hs3-dev#0.5.6-2+b4 +libghc-hscolour-dev#1.19-3+b1 +libghc-hscurses-dev#1.4.1.0-1+b2 +libghc-hsemail-dev#1.7.1-2+b3 +libghc-hsh-dev#2.0.3-6+b3 +libghc-hslogger-dev#1.1.4+dfsg1-2+b3 +libghc-hsp-dev#0.6.1-2+b3 +libghc-hspec-dev#1.1.0-1+b1 +libghc-hsql-dev#1.8.1-4 +libghc-hsql-mysql-dev#1.8.1-4+b1 +libghc-hsql-odbc-dev#1.8.1.1-2 +libghc-hsql-postgresql-dev#1.8.1-3 +libghc-hsql-sqlite3-dev#1.8.1-2 +libghc-hssyck-dev#0.50-2+b2 +libghc-hstringtemplate-dev#0.6.8-1 +libghc-hsx-dev#0.9.1-3 +libghc-html-conduit-dev#0.0.1-2 +libghc-html-dev#1.0.1.2-5+b1 +libghc-http-conduit-dev#1.4.1.6-3 +libghc-http-date-dev#0.0.2-1+b2 +libghc-http-dev#1:4000.2.3-1+b2 +libghc-http-types-dev#0.6.11-1 +libghc-hunit-dev#1.2.4.2-2+b1 +libghc-hxt-cache-dev#9.0.2-2+b3 +libghc-hxt-charproperties-dev#9.1.1-2+b1 +libghc-hxt-curl-dev#9.1.1-1+b4 +libghc-hxt-dev#9.2.2-2+b3 +libghc-hxt-http-dev#9.1.4-2+b3 +libghc-hxt-regex-xmlschema-dev#9.0.4-2+b3 +libghc-hxt-relaxng-dev#9.1.4-1+b3 +libghc-hxt-tagsoup-dev#9.1.1-1+b4 +libghc-hxt-unicode-dev#9.0.2-2+b1 +libghc-hxt-xpath-dev#9.1.2-1+b4 +libghc-hxt-xslt-dev#9.1.1-1+b3 +libghc-iconv-dev#0.4.1.0-2+b1 +libghc-ieee754-dev#0.7.3-1+b1 +libghc-ifelse-dev#0.85-4+b1 +libghc-io-choice-dev#0.0.1-1+b3 +libghc-io-storage-dev#0.3-2+b1 +libghc-iospec-dev#0.2.5-1+b2 +libghc-irc-dev#0.5.0.0-1+b3 +libghc-iteratee-dev#0.8.8.2-2+b1 +libghc-ixset-dev#1.0.3-2+b1 +libghc-json-dev#0.5-2+b2 +libghc-keys-dev#2.1.3.2-1+b1 +libghc-knob-dev#0.1.1-1 +libghc-lambdabot-utils-dev#4.2.1-3+b3 +libghc-language-c-dev#0.4.2-2+b2 +libghc-language-haskell-extract-dev#0.2.1-4+b1 +libghc-language-javascript-dev#0.5.4-1+b2 +libghc-largeword-dev#1.0.1-2+b1 +libghc-lazysmallcheck-dev#0.6-1+b1 +libghc-ldap-dev#0.6.6-4.1+b1 +libghc-leksah-server-dev#0.12.0.4-3 +libghc-libtagc-dev#0.12.0-2+b1 +libghc-libxml-sax-dev#0.7.2-2+b1 +libghc-libzip-dev#0.10-1+b2 +libghc-lifted-base-dev#0.1.1-1+b1 +libghc-listlike-dev#3.1.4-1+b1 +libghc-llvm-base-dev#3.0.1.0-1 +libghc-llvm-dev#3.0.1.0-1+b1 +libghc-logict-dev#0.5.0.1-1+b1 +libghc-ltk-dev#0.12.0.0-2+b1 +libghc-maccatcher-dev#2.1.5-2+b3 +libghc-magic-dev#1.0.8-8+b1 +libghc-markov-chain-dev#0.0.3.2-1+b1 +libghc-math-functions-dev#0.1.1.0-2+b2 +libghc-maths-dev#0.4.3-1+b1 +libghc-maybet-dev#0.1.2-3+b2 +libghc-mbox-dev#0.1-2+b1 +libghc-memotrie-dev#0.5-1 +libghc-mersenne-random-dev#1.0.0.1-2+b1 +libghc-midi-dev#0.2.0.1-1+b1 +libghc-mime-mail-dev#0.4.1.1-2+b3 +libghc-missingh-dev#1.1.0.3-6+b3 +libghc-mmap-dev#0.5.7-2+b1 +libghc-monad-control-dev#0.3.1.3-1+b1 +libghc-monad-loops-dev#0.3.2.0-1 +libghc-monad-par-dev#0.1.0.3-2+b1 +libghc-monadcatchio-mtl-dev#0.3.0.4-2+b2 +libghc-monadcatchio-transformers-dev#0.3.0.0-2+b1 +libghc-monadcryptorandom-dev#0.4.1-1+b2 +libghc-monadrandom-dev#0.1.6-2+b2 +libghc-monads-tf-dev#0.1.0.0-1+b2 +libghc-monoid-transformer-dev#0.0.2-3+b1 +libghc-mtl-dev#2.1.1-1 +libghc-mtlparse-dev#0.1.2-2+b2 +libghc-murmur-hash-dev#0.1.0.5-2+b1 +libghc-mwc-random-dev#0.11.0.0-4+b1 +libghc-ncurses-dev#0.2.1-1+b1 +libghc-netwire-dev#3.1.0-2+b5 +libghc-network-conduit-dev#0.4.0.1-2 +libghc-network-dev#2.3.0.13-1+b2 +libghc-network-protocol-xmpp-dev#0.4.3-1 +libghc-newtype-dev#0.2-1 +libghc-non-negative-dev#0.1-2+b1 +libghc-numbers-dev#2009.8.9-2+b1 +libghc-numeric-quest-dev#0.2-1+b1 +libghc-numinstances-dev#1.0-2+b1 +libghc-numtype-dev#1.0-2+b1 +libghc-oeis-dev#0.3.1-2+b3 +libghc-openal-dev#1.3.1.3-4+b1 +libghc-opengl-dev#2.2.3.1-1+b1 +libghc-openpgp-asciiarmor-dev#0.1-1+b2 +libghc-options-dev#0.1.1-1 +libghc-pandoc-dev#1.9.4.2-2 +libghc-pandoc-types-dev#1.9.1-1+b2 +libghc-pango-dev#0.12.2-1+b2 +libghc-parallel-dev#3.2.0.2-2+b1 +libghc-parseargs-dev#0.1.3.2-2+b1 +libghc-parsec2-dev#2.1.0.1-6+b1 +libghc-parsec3-dev#3.1.2-1+b3 +libghc-pastis-dev#0.1.2-2+b3 +libghc-path-pieces-dev#0.1.0-1+b2 +libghc-patience-dev#0.1.1-1 +libghc-pcre-light-dev#0.4-3+b1 +libghc-pem-dev#0.1.1-1+b3 +libghc-persistent-dev#0.9.0.4-2 +libghc-persistent-sqlite-dev#0.9.0.2-2 +libghc-persistent-template-dev#0.9.0.2-1 +libghc-polyparse-dev#1.7-1+b2 +libghc-pool-conduit-dev#0.1.0.2-1 +libghc-postgresql-libpq-dev#0.8.2-1 +libghc-postgresql-simple-dev#0.1.4.3-1 +libghc-pretty-show-dev#1.1.1-4+b1 +libghc-primes-dev#0.2.1.0-2+b1 +libghc-primitive-dev#0.4.1-1+b1 +libghc-psqueue-dev#1.1-2+b1 +libghc-puremd5-dev#2.1.0.3-2+b4 +libghc-pwstore-fast-dev#2.2-2+b4 +libghc-quickcheck1-dev#1.2.0.1-2+b1 +libghc-quickcheck2-dev#2.4.2-1+b1 +libghc-random-dev#1.0.1.1-1+b1 +libghc-random-shuffle-dev#0.0.3-2+b2 +libghc-ranged-sets-dev#0.3.0-2+b1 +libghc-ranges-dev#0.2.4-2+b1 +libghc-reactive-banana-dev#0.6.0.0-1+b3 +libghc-readline-dev#1.0.1.0-3+b1 +libghc-recaptcha-dev#0.1-4+b3 +libghc-regex-base-dev#0.93.2-2+b2 +libghc-regex-compat-dev#0.95.1-2+b1 +libghc-regex-pcre-dev#0.94.2-2+b1 +libghc-regex-posix-dev#0.95.1-2+b1 +libghc-regex-tdfa-dev#1.1.8-2+b1 +libghc-regex-tdfa-utf8-dev#1.0-5+b3 +libghc-regexpr-dev#0.5.4-2+b2 +libghc-representable-functors-dev#2.4.0.2-1+b1 +libghc-representable-tries-dev#2.4.0.2-1 +libghc-resource-pool-dev#0.2.1.0-2+b4 +libghc-resourcet-dev#0.3.2.1-1+b1 +libghc-rsa-dev#1.2.1.0-1+b1 +libghc-safe-dev#0.3.3-1+b1 +libghc-safecopy-dev#0.6.1-1+b1 +libghc-sdl-dev#0.6.3-1+b1 +libghc-sdl-gfx-dev#0.6.0-3+b1 +libghc-sdl-image-dev#0.6.1-3+b1 +libghc-sdl-mixer-dev#0.6.1-3+b1 +libghc-sdl-ttf-dev#0.6.1-3+b1 +libghc-semigroupoids-dev#1.3.1.2-1+b1 +libghc-semigroups-dev#0.8.3.2-1 +libghc-sendfile-dev#0.7.6-1+b2 +libghc-sha-dev#1.5.0.1-1 +libghc-shakespeare-css-dev#1.0.1.2-1+b1 +libghc-shakespeare-dev#1.0.0.2-1+b1 +libghc-shakespeare-i18n-dev#1.0.0.2-1+b1 +libghc-shakespeare-js-dev#1.0.0.2-1+b1 +libghc-shakespeare-text-dev#1.0.0.2-1+b1 +libghc-shellac-dev#0.9.5.1-2+b2 +libghc-show-dev#0.4.1.2-1+b2 +libghc-silently-dev#1.1.4-1+b2 +libghc-simple-sendfile-dev#0.2.3-1+b2 +libghc-simpleea-dev#0.1.1-2+b2 +libghc-simpleirc-dev#0.2.1-2+b3 +libghc-skein-dev#0.1.0.7-2+b1 +libghc-smallcheck-dev#0.6-1+b1 +libghc-smtpclient-dev#1.0.4-3+b3 +libghc-snap-core-dev#0.8.1-1+b4 +libghc-snap-server-dev#0.8.1.1-1 +libghc-socks-dev#0.4.1-1+b4 +libghc-split-dev#0.1.4.2-2 +libghc-src-exts-dev#1.11.1-3+b1 +libghc-statevar-dev#1.0.0.0-2+b1 +libghc-static-hash-dev#0.0.1-3+b2 +libghc-statistics-dev#0.10.1.0-2+b1 +libghc-stm-dev#2.3-1 +libghc-stream-dev#0.4.6-1+b1 +libghc-strict-concurrency-dev#0.2.4.1-2+b1 +libghc-strict-dev#0.3.2-2+b1 +libghc-strptime-dev#1.0.6-1 +libghc-svgcairo-dev#0.12.1-1+b2 +libghc-syb-dev#0.3.6.1-1 +libghc-syb-with-class-dev#0.6.1.3-1+b1 +libghc-syb-with-class-instances-text-dev#0.0.1-3+b2 +libghc-system-fileio-dev#0.3.8-1 +libghc-system-filepath-dev#0.4.6-1+b2 +libghc-tagged-dev#0.4.2.1-1 +libghc-tagsoup-dev#0.12.6-1+b3 +libghc-tagstream-conduit-dev#0.3.2-1 +libghc-tar-dev#0.3.2.0-2+b1 +libghc-template-dev#0.2.0.7-1+b1 +libghc-temporary-dev#1.1.2.3-1+b1 +libghc-terminfo-dev#0.3.2.3-1+b1 +libghc-test-framework-dev#0.6-1+b1 +libghc-test-framework-hunit-dev#0.2.7-1+b3 +libghc-test-framework-quickcheck2-dev#0.2.12.1-1+b1 +libghc-test-framework-th-dev#0.2.2-5 +libghc-test-framework-th-prime-dev#0.0.5-1 +libghc-testpack-dev#2.1.1-1+b2 +libghc-texmath-dev#0.6.0.6-1+b2 +libghc-text-dev#0.11.2.0-1 +libghc-text-icu-dev#0.6.3.4-2+b2 +libghc-tinyurl-dev#0.1.0-2+b3 +libghc-tls-dev#0.9.5-1+b4 +libghc-tls-extra-dev#0.4.6.1-2 +libghc-tokyocabinet-dev#0.0.5-5+b3 +libghc-transformers-base-dev#0.4.1-2+b2 +libghc-transformers-dev#0.3.0.0-1 +libghc-type-level-dev#0.2.4-5 +libghc-uniplate-dev#1.6.7-1+b2 +libghc-unix-bytestring-dev#0.3.5-2+b1 +libghc-unix-compat-dev#0.3.0.1-1+b1 +libghc-unixutils-dev#1.50-1+b1 +libghc-unlambda-dev#0.1-2+b2 +libghc-unordered-containers-dev#0.2.1.0-1 +libghc-uri-dev#0.1.6-1+b2 +libghc-url-dev#2.1.2-4+b1 +libghc-utf8-light-dev#0.4.0.1-2+b1 +libghc-utf8-string-dev#0.3.7-1+b1 +libghc-utility-ht-dev#0.0.5.1-3+b1 +libghc-uuagc-cabal-dev#1.0.2.0-1+b1 +libghc-uuid-dev#1.2.3-2+b4 +libghc-uulib-dev#0.9.14-2 +libghc-vault-dev#0.2.0.0-1+b2 +libghc-vector-algorithms-dev#0.5.4-1+b2 +libghc-vector-dev#0.9.1-2+b1 +libghc-vector-space-dev#0.8.1-1 +libghc-vector-space-points-dev#0.1.1.0-1+b1 +libghc-void-dev#0.5.5.1-2+b1 +libghc-vte-dev#0.12.1-1+b3 +libghc-vty-dev#4.7.0.14-1+b1 +libghc-wai-app-file-cgi-dev#0.5.8-1+b4 +libghc-wai-app-static-dev#1.2.0.3-1+b3 +libghc-wai-dev#1.2.0.2-1+b2 +libghc-wai-extra-dev#1.2.0.4-1 +libghc-wai-logger-dev#0.1.4-1+b6 +libghc-wai-logger-prefork-dev#0.1.3-1+b6 +libghc-wai-test-dev#1.2.0.2-1 +libghc-warp-dev#1.2.1.1-1 +libghc-warp-tls-dev#1.2.0.4-1+b4 +libghc-web-routes-dev#0.25.3-2+b3 +libghc-webkit-dev#0.12.3-2+b1 +libghc-weighted-regexp-dev#0.3.1.1-2+b1 +libghc-x11-dev#1.5.0.1-1+b2 +libghc-x11-xft-dev#0.3.1-1+b3 +libghc-xdg-basedir-dev#0.2.1-2+b1 +libghc-xhtml-dev#3000.2.1-1 +libghc-xml-conduit-dev#0.7.0.2-1 +libghc-xml-dev#1.3.12-1+b2 +libghc-xml-types-dev#0.3.1-2+b2 +libghc-xml2html-dev#0.1.2.3-1 +libghc-xmonad-contrib-dev#0.10-4~deb7u1 +libghc-xmonad-dev#0.10-4+b2 +libghc-xss-sanitize-dev#0.3.2-1+b1 +libghc-yaml-dev#0.7.0.2-1+b2 +libghc-yaml-light-dev#0.1.4-2+b2 +libghc-yesod-auth-dev#1.0.2.1-2+b2 +libghc-yesod-core-dev#1.0.1.2-1+b3 +libghc-yesod-default-dev#1.0.1.1-1+b1 +libghc-yesod-dev#1.0.1.6-2+b3 +libghc-yesod-form-dev#1.0.0.4-1+b1 +libghc-yesod-json-dev#1.0.0.1-1+b3 +libghc-yesod-markdown-dev#0.4.0-1+b3 +libghc-yesod-persistent-dev#1.0.0.1-1+b1 +libghc-yesod-routes-dev#1.0.1.2-1 +libghc-yesod-static-dev#1.0.0.2-1+b3 +libghc-yesod-test-dev#0.2.0.6-1 +libghc-zip-archive-dev#0.1.1.7-3+b2 +libghc-zlib-bindings-dev#0.1.0.1-1 +libghc-zlib-conduit-dev#0.4.0.1-1 +libghc-zlib-dev#0.5.3.3-1+b1 +libghc-zlib-enum-dev#0.2.2.1-1+b1 +libghc6-agda-dev#1:8 +libghc6-alut-dev#1:8 +libghc6-arrows-dev#1:8 +libghc6-binary-dev#1:8 +libghc6-binary-shared-dev#1:8 +libghc6-bzlib-dev#1:8 +libghc6-cairo-dev#1:8 +libghc6-cautious-file-dev#1:8 +libghc6-cgi-dev#1:8 +libghc6-colour-dev#1:8 +libghc6-configfile-dev#1:8 +libghc6-convertible-dev#1:8 +libghc6-cpphs-dev#1:8 +libghc6-criterion-dev#1:8 +libghc6-csv-dev#1:8 +libghc6-curl-dev#1:8 +libghc6-data-accessor-dev#1:8 +libghc6-dataenc-dev#1:8 +libghc6-datetime-dev#1:8 +libghc6-debian-dev#1:8 +libghc6-deepseq-dev#1:8 +libghc6-diagrams-dev#1:8 +libghc6-diff-dev#1:8 +libghc6-digest-dev#1:8 +libghc6-edison-api-dev#1:8 +libghc6-edison-core-dev#1:8 +libghc6-editline-dev#1:8 +libghc6-erf-dev#1:8 +libghc6-event-list-dev#1:8 +libghc6-explicit-exception-dev#1:8 +libghc6-fastcgi-dev#1:8 +libghc6-feed-dev#1:8 +libghc6-fgl-dev#1:8 +libghc6-filemanip-dev#1:8 +libghc6-filestore-dev#1:8 +libghc6-ftphs-dev#1:8 +libghc6-gconf-dev#1:8 +libghc6-ghc-events-dev#1:8 +libghc6-ghc-mtl-dev#1:8 +libghc6-ghc-paths-dev#1:8 +libghc6-gio-dev#1:8 +libghc6-gitit-dev#1:8 +libghc6-glade-dev#1:8 +libghc6-glfw-dev#1:8 +libghc6-glib-dev#1:8 +libghc6-glut-dev#1:8 +libghc6-gstreamer-dev#1:8 +libghc6-gtk-dev#1:8 +libghc6-gtkglext-dev#1:8 +libghc6-gtksourceview2-dev#1:8 +libghc6-haddock-dev#1:8 +libghc6-happstack-dev#1:8 +libghc6-happstack-server-dev#1:8 +libghc6-harp-dev#1:8 +libghc6-hashed-storage-dev#1:8 +libghc6-haskeline-dev#1:8 +libghc6-haskell-lexer-dev#1:8 +libghc6-haskell-src-dev#1:8 +libghc6-haskelldb-dev#1:8 +libghc6-haskelldb-hdbc-dev#1:8 +libghc6-haskelldb-hdbc-odbc-dev#1:8 +libghc6-haskelldb-hdbc-postgresql-dev#1:8 +libghc6-haskelldb-hdbc-sqlite3-dev#1:8 +libghc6-haskore-dev#1:8 +libghc6-haxml-dev#1:8 +libghc6-haxr-dev#1:8 +libghc6-hdbc-dev#1:8 +libghc6-hdbc-odbc-dev#1:8 +libghc6-hdbc-postgresql-dev#1:8 +libghc6-hdbc-sqlite3-dev#1:8 +libghc6-highlighting-kate-dev#1:8 +libghc6-hint-dev#1:8 +libghc6-hjavascript-dev#1:8 +libghc6-hjscript-dev#1:8 +libghc6-hoauth-dev#1:8 +libghc6-hscolour-dev#1:8 +libghc6-hscurses-dev#1:8 +libghc6-hsemail-dev#1:8 +libghc6-hsh-dev#1:8 +libghc6-hslogger-dev#1:8 +libghc6-hsp-dev#1:8 +libghc6-hsql-dev#1:8 +libghc6-hsql-mysql-dev#1:8 +libghc6-hsql-odbc-dev#1:8 +libghc6-hsql-postgresql-dev#1:8 +libghc6-hsql-sqlite3-dev#1:8 +libghc6-hstringtemplate-dev#1:8 +libghc6-hsx-dev#1:8 +libghc6-html-dev#1:8 +libghc6-http-dev#1:8 +libghc6-hunit-dev#1:8 +libghc6-hxt-dev#1:8 +libghc6-ifelse-dev#1:8 +libghc6-irc-dev#1:8 +libghc6-json-dev#1:8 +libghc6-language-c-dev#1:8 +libghc6-lazysmallcheck-dev#1:8 +libghc6-ldap-dev#1:8 +libghc6-leksah-server-dev#1:8 +libghc6-llvm-dev#1:8 +libghc6-ltk-dev#1:8 +libghc6-magic-dev#1:8 +libghc6-markov-chain-dev#1:8 +libghc6-maybet-dev#1:8 +libghc6-midi-dev#1:8 +libghc6-missingh-dev#1:8 +libghc6-mmap-dev#1:8 +libghc6-monadcatchio-mtl-dev#1:8 +libghc6-monoid-transformer-dev#1:8 +libghc6-mtl-dev#1:8 +libghc6-mwc-random-dev#1:8 +libghc6-network-dev#1:8 +libghc6-non-negative-dev#1:8 +libghc6-openal-dev#1:8 +libghc6-opengl-dev#1:8 +libghc6-pandoc-dev#1:8 +libghc6-pango-dev#1:8 +libghc6-parallel-dev#1:8 +libghc6-parsec2-dev#1:8 +libghc6-parsec3-dev#1:8 +libghc6-pcre-light-dev#1:8 +libghc6-polyparse-dev#1:8 +libghc6-pretty-show-dev#1:8 +libghc6-primitive-dev#1:8 +libghc6-quickcheck1-dev#1:8 +libghc6-quickcheck2-dev#1:8 +libghc6-recaptcha-dev#1:8 +libghc6-regex-base-dev#1:8 +libghc6-regex-compat-dev#1:8 +libghc6-regex-posix-dev#1:8 +libghc6-regex-tdfa-dev#1:8 +libghc6-regex-tdfa-utf8-dev#1:8 +libghc6-safe-dev#1:8 +libghc6-sdl-dev#1:8 +libghc6-sdl-gfx-dev#1:8 +libghc6-sdl-image-dev#1:8 +libghc6-sdl-mixer-dev#1:8 +libghc6-sdl-ttf-dev#1:8 +libghc6-sendfile-dev#1:8 +libghc6-sha-dev#1:8 +libghc6-smtpclient-dev#1:8 +libghc6-split-dev#1:8 +libghc6-src-exts-dev#1:8 +libghc6-statistics-dev#1:8 +libghc6-stm-dev#1:8 +libghc6-stream-dev#1:8 +libghc6-strict-concurrency-dev#1:8 +libghc6-svgcairo-dev#1:8 +libghc6-syb-with-class-dev#1:8 +libghc6-syb-with-class-instances-text-dev#1:8 +libghc6-tagsoup-dev#1:8 +libghc6-tar-dev#1:8 +libghc6-terminfo-dev#1:8 +libghc6-testpack-dev#1:8 +libghc6-texmath-dev#1:8 +libghc6-text-dev#1:8 +libghc6-tokyocabinet-dev#1:8 +libghc6-transformers-dev#1:8 +libghc6-type-level-dev#1:8 +libghc6-uniplate-dev#1:8 +libghc6-unix-compat-dev#1:8 +libghc6-unixutils-dev#1:8 +libghc6-url-dev#1:8 +libghc6-utility-ht-dev#1:8 +libghc6-uulib-dev#1:8 +libghc6-vector-algorithms-dev#1:8 +libghc6-vector-dev#1:8 +libghc6-vte-dev#1:8 +libghc6-vty-dev#1:8 +libghc6-webkit-dev#1:8 +libghc6-x11-dev#1:8 +libghc6-x11-xft-dev#1:8 +libghc6-xhtml-dev#1:8 +libghc6-xml-dev#1:8 +libghc6-xmonad-contrib-dev#1:8 +libghc6-xmonad-dev#1:8 +libghc6-zip-archive-dev#1:8 +libghc6-zlib-dev#1:8 +libghemical-dev#3.0.0-2 +libgif-dev#4.1.6-10 +libgiftiio-dev#1.0.9-1 +libgig-dev#3.3.0-2 +libgii1-dev#1:1.0.2-4.1 +libgimp2.0-dev#2.8.2-2+deb7u1 +libginac-dev#1.6.2-1 +libginspx-dev#20050529-3.1 +libgio2.0-cil-dev#2.22.3-2 +libgirara-dev#0.1.2-3 +libgirepository1.0-dev#1.32.1-1 +libgjs-dev#1.32.0-5 +libgkeyfile-cil-dev#0.1-4 +libgksu2-dev#2.0.13~pre1-6 +libgl1-mesa-dev#8.0.5-4+deb7u2 +libgl1-mesa-swx11-dev#8.0.5-4+deb7u2 +libgl2ps-dev#1.3.6-1 +libglade2-dev#1:2.6.4-1 +libglade2.0-cil-dev#2.12.10-5 +libglademm-2.4-dev#2.6.7-2 +libgladeui-1-dev#3.6.7-2.1 +libgladeui-dev#3.12.1-1 +libglbsp-dev#2.24-1 +libglc-dev#0.7.2-5+b1 +libgle3-dev#3.1.0-7 +libgles1-mesa-dev#8.0.5-4+deb7u2 +libgles2-mesa-dev#8.0.5-4+deb7u2 +libglew-dev#1.7.0-3 +libglewmx-dev#1.7.0-3 +libglfw-dev#2.7.2-1 +libglib2.0-cil-dev#2.12.10-5 +libglib2.0-dev#2.33.12+really2.32.4-5 +libglibmm-2.4-dev#2.32.1-1 +libglide2-dev#2002.04.10ds1-7 +libglide3-dev#2002.04.10ds1-7 +libglm-dev#0.9.3.3+dfsg-0.1 +libglobus-authz-callout-error-dev#2.2-1 +libglobus-authz-dev#2.2-1 +libglobus-callout-dev#2.2-1 +libglobus-common-dev#14.7-2 +libglobus-ftp-client-dev#7.3-1 +libglobus-ftp-control-dev#4.4-1 +libglobus-gass-cache-dev#8.1-2 +libglobus-gass-copy-dev#8.4-1 +libglobus-gass-server-ez-dev#4.3-1 +libglobus-gass-transfer-dev#7.2-1 +libglobus-gfork-dev#3.2-1 +libglobus-gram-client-dev#12.4-1 +libglobus-gram-job-manager-callout-error-dev#2.1-2 +libglobus-gram-protocol-dev#11.3-1 +libglobus-gridftp-server-control-dev#2.5-2 +libglobus-gridftp-server-dev#6.10-2 +libglobus-gridmap-callout-error-dev#1.2-2 +libglobus-gsi-callback-dev#4.2-1 +libglobus-gsi-cert-utils-dev#8.3-1 +libglobus-gsi-credential-dev#5.3-1 +libglobus-gsi-openssl-error-dev#2.1-2 +libglobus-gsi-proxy-core-dev#6.2-1 +libglobus-gsi-proxy-ssl-dev#4.1-2 +libglobus-gsi-sysconfig-dev#5.2-1 +libglobus-gss-assist-dev#8.5-1 +libglobus-gssapi-error-dev#4.1-2 +libglobus-gssapi-gsi-dev#10.6-1 +libglobus-io-dev#9.3-1 +libglobus-openssl-module-dev#3.2-1 +libglobus-rls-client-dev#5.2-8 +libglobus-rsl-dev#9.1-2 +libglobus-scheduler-event-generator-dev#4.6-1 +libglobus-usage-dev#3.1-2 +libglobus-xio-dev#3.3-1 +libglobus-xio-gsi-driver-dev#2.3-1 +libglobus-xio-pipe-driver-dev#2.2-1 +libglobus-xio-popen-driver-dev#2.3-1 +libgloox-dev#1.0-1.1 +libglpk-dev#4.45-1 +libglrr-glib-dev#20050529-3.1 +libglrr-gobject-dev#20050529-3.1 +libglrr-gtk-dev#20050529-3.1 +libglrr-widgets-dev#20050529-3.1 +libglu1-mesa-dev#8.0.5-4+deb7u2 +libglui-dev#2.36-4 +libglw1-mesa-dev#8.0.0-1 +libgme-dev#0.5.5-2 +libgmerlin-avdec-dev#1.2.0~dfsg-1+b1 +libgmerlin-dev#1.2.0~dfsg+1-1 +libgmime-2.6-dev#2.6.10-1 +libgmime2.6-cil-dev#2.6.10-1 +libgmlib-dev#1.0.6-1 +libgmm++-dev#4.1.1+dfsg1-11 +libgmp-dev#2:5.0.5+dfsg-2 +libgmp-ocaml-dev#20021123-17+b3 +libgmp3-dev#2:5.0.5+dfsg-2 +libgmpada3-dev#0.0.20120331-1 +libgmt-dev#4.5.7-2 +libgmtk-dev#1.0.6-1 +libgnadecommon2-dev#1.6.2-9 +libgnadeodbc2-dev#1.6.2-9 +libgnadesqlite3-2-dev#1.6.2-9 +libgnatprj4.6-dev#4.6.3-8 +libgnatvsn4.6-dev#4.6.3-8 +libgnelib-dev#0.75+svn20091130-1+b1 +libgnet-dev#2.0.8-2.2 +libgnokii-dev#0.6.30+dfsg-1+b1 +libgnome-bluetooth-dev#3.4.2-1 +libgnome-desktop-3-dev#3.4.2-1 +libgnome-desktop-dev#2.32.1-2 +libgnome-keyring-dev#3.4.1-1 +libgnome-keyring1.0-cil-dev#1.0.0-4 +libgnome-mag-dev#1:0.16.3-1 +libgnome-media-profiles-dev#3.0.0-1 +libgnome-menu-3-dev#3.4.2-5 +libgnome-menu-dev#3.0.1-4 +libgnome-speech-dev#1:0.4.25-5 +libgnome-vfs2.0-cil-dev#2.24.2-3 +libgnome-vfsmm-2.6-dev#2.26.0-1 +libgnome2-dev#2.32.1-3 +libgnome2.0-cil-dev#2.24.2-3 +libgnomeada2.24.1-dev#2.24.1-7 +libgnomecanvas2-dev#2.30.3-1.2 +libgnomecanvasmm-2.6-dev#2.26.0-1 +libgnomecups1.0-dev#0.2.3-5 +libgnomedesktop2.0-cil-dev#2.26.0-8 +libgnomekbd-dev#3.4.0.2-1 +libgnomemm-2.6-dev#2.30.0-1 +libgnomeprint2.2-dev#2.18.8-3 +libgnomeprintui2.2-dev#2.18.6-3 +libgnomeui-dev#2.24.5-2 +libgnomeuimm-2.6-dev#2.28.0-1 +libgnomevfs2-dev#1:2.24.4-2 +libgnuift0-dev#0.1.14-12 +libgnuplot-ocaml-dev#0.8.3-3 +libgnustep-base-dev#1.22.1-4 +libgnustep-dl2-dev#0.12.0-9+nmu1 +libgnustep-gui-dev#0.20.0-3 +libgnutls-dev#2.12.20-8+deb7u1 +libgoa-1.0-dev#3.4.2-2 +libgoffice-0.8-dev#0.8.17-1.2 +libgofigure-dev#0.9.0-1+b2 +libgoocanvas-dev#0.15-1 +libgoocanvasmm-dev#0.15.4-1 +libgoogle-perftools-dev#2.0-2 +libgooglepinyin0-dev#0.1.2-1 +libgpac-dev#0.5.0~dfsg0-1 +libgpds-dev#1.5.1-6 +libgpelaunch-dev#0.14-6 +libgpepimc-dev#0.9-4 +libgpeschedule-dev#0.17-4 +libgpevtype-dev#0.50-6 +libgpewidget-dev#0.117-6 +libgpg-error-dev#1.10-3.1 +libgpgme11-dev#1.2.0-1.4 +libgphoto2-2-dev#2.4.14-2 +libgpiv3-dev#0.6.1-4 +libgpm-dev#1.20.4-6 +libgpod-cil-dev#0.8.2-7 +libgpod-dev#0.8.2-7 +libgpod-nogtk-dev#0.8.2-7 +libgportugol-dev#1.1-2 +libgps-dev#3.6-4+deb7u1 +libgraflib1-dev#20061220+dfsg3-2 +libgrafx11-1-dev#20061220+dfsg3-2 +libgrantlee-dev#0.1.4-1 +libgraphicsmagick++1-dev#1.3.16-1.1 +libgraphicsmagick1-dev#1.3.16-1.1 +libgraphite-dev#1:2.3.1-0.2 +libgraphite2-dev#1.1.3-1 +libgraphviz-dev#2.26.3-14+deb7u1 +libgretl1-dev#1.9.9-1 +libgrib-api-dev#1.9.16-2+b1 +libgrib2c-dev#1.2.2-2+b1 +libgridsite-dev#1.7.16-1 +libgrilo-0.1-dev#0.1.19-1 +libgringotts-dev#1.2.10~pre3-1 +libgrits-dev#0.7-1 +libgrok-dev#1.20110708.1-4 +libgrss-dev#0.5.0-1 +libgs-dev#9.05~dfsg-6.3+deb7u1 +libgsasl7-dev#1.8.0-2 +libgsecuredelete-dev#0.2-1 +libgsf-1-dev#1.14.21-2.1 +libgsf-gnome-1-dev#1.14.21-2.1 +libgsl0-dev#1.15+dfsg.2-2 +libgsm0710-dev#1.2.2-2 +libgsm0710mux-dev#0.11.2-1.1 +libgsm1-dev#1.0.13-4 +libgsmme-dev#1.10-13.2 +libgsnmp0-dev#0.3.0-1.1 +libgsql-dev#0.2.2-1.2+b1 +libgss-dev#1.0.2-1 +libgssdp-1.0-dev#0.12.2.1-2 +libgssglue-dev#0.4-2 +libgst-dev#3.2.4-2 +libgstbuzztard-dev#0.5.0-2+deb7u1 +libgstreamer-ocaml-dev#0.1.0-3+b1 +libgstreamer-plugins-bad0.10-dev#0.10.23-7.1+deb7u1 +libgstreamer-plugins-base0.10-dev#0.10.36-1.1 +libgstreamer0.10-cil-dev#0.9.2-4 +libgstreamer0.10-dev#0.10.36-1.2 +libgstrtspserver-0.10-dev#0.10.8-3 +libgtest-dev#1.6.0-2 +libgtextutils-dev#0.6.2-1 +libgtg-dev#0.2+dfsg-1 +libgtk-3-dev#3.4.2-7 +libgtk-sharp-beans2.0-cil-dev#2.14.1-3 +libgtk-vnc-1.0-dev#0.5.0-3.1 +libgtk-vnc-2.0-dev#0.5.0-3.1 +libgtk2.0-cil-dev#2.12.10-5 +libgtk2.0-dev#2.24.10-2 +libgtkada2.24.1-dev#2.24.1-7 +libgtkdatabox-0.9.1-1-dev#1:0.9.1.1-4 +libgtkgl2.0-dev#2.0.1-2 +libgtkglada2.24.1-dev#2.24.1-7 +libgtkglarea-cil-dev#0.0.17-6 +libgtkglext1-dev#1.2.0-2 +libgtkglextmm-x11-1.2-dev#1.2.0-4.1 +libgtkhex-3-dev#3.4.1-1 +libgtkhotkey-dev#0.2.1-3 +libgtkhtml-4.0-dev#4.4.4-1 +libgtkhtml-editor-3.14-dev#3.32.2-2.1 +libgtkhtml-editor-4.0-dev#4.4.4-1 +libgtkhtml3.14-cil-dev#2.26.0-8 +libgtkhtml3.14-dev#3.32.2-2.1 +libgtkimageview-dev#1.6.4+dfsg-0.1 +libgtkmathview-dev#0.8.0-8 +libgtkmm-2.4-dev#1:2.24.2-1 +libgtkmm-3.0-dev#3.4.2-1 +libgtkpod-dev#2.1.2-1 +libgtksourceview-3.0-dev#3.4.2-1 +libgtksourceview2-cil-dev#2.26.0-8 +libgtksourceview2.0-dev#2.10.4-1 +libgtksourceviewmm-3.0-dev#3.2.0-1 +libgtkspell-3-dev#3.0.0~hg20110814-1 +libgtkspell-dev#2.0.16-1 +libgtop2-dev#2.28.4-3 +libgts-dev#0.7.6+darcs110121-1.1 +libguac-dev#0.6.0-2 +libgucharmap-2-90-dev#1:3.4.1.1-2.1 +libgudev-1.0-dev#175-7.2 +libgudev1.0-cil-dev#0.1-3 +libguess-dev#1.1-1 +libguestfs-dev#1:1.18.1-1+deb7u3 +libguestfs-gobject-dev#1:1.18.1-1+deb7u3 +libguestfs-ocaml-dev#1:1.18.1-1+deb7u3 +libguichan-dev#0.8.2-10+b1 +libgupnp-1.0-dev#0.18.4-1 +libgupnp-av-1.0-dev#0.10.3-1 +libgupnp-dlna-1.0-dev#0.6.6-1 +libgupnp-igd-1.0-dev#0.2.1-2 +libgusb-dev#0.1.3-5 +libgutenprint-dev#5.2.9-1 +libgutenprintui2-dev#5.2.9-1 +libguytools2-dev#2.0.1-1.1 +libgvnc-1.0-dev#0.5.0-3.1 +libgweather-3-dev#3.4.1-1+build1 +libgwenhywfar60-dev#4.3.3-1 +libgwrap-runtime-dev#1.9.14-1.1 +libgwyddion20-dev#2.28-2 +libgxps-dev#0.2.2-2 +libgyoto0-dev#0.0.3-5 +libh323plus-dev#1.24.0~dfsg2-1 +libhaildb-dev#2.3.2-1.2 +libhal-dev#0.5.14-8 +libhal-storage-dev#0.5.14-8 +libhamlib++-dev#1.2.15.1-1 +libhamlib-dev#1.2.15.1-1 +libhandoff-dev#0.1-5 +libhangul-dev#0.1.0-2 +libharminv-dev#1.3.1-9 +libhashkit-dev#1.0.8-1 +libhawknl-dev#1.6.8+dfsg2-1 +libhbaapi-dev#2.2.5-1 +libhbalinux-dev#1.0.14-1 +libhd-dev#16.0-2.2 +libhdate-dev#1.6-1 +libhdf4-alt-dev#4.2r4-13 +libhdf4-dev#4.2r4-13 +libhdf4g-dev#4.2r4-13 +libhdf5-dev#1.8.8-9 +libhdf5-mpi-dev#1.8.8-9 +libhdf5-mpich2-dev#1.8.8-9 +libhdf5-openmpi-dev#1.8.8-9 +libhdf5-serial-dev#1.8.8-9 +libhdfeos-dev#2.17v1.00.dfsg.1-3 +libhdhomerun-dev#20120405-1 +libhe5-hdfeos-dev#5.1.13.dfsg.1-3 +libheartbeat2-dev#1:3.0.5-3 +libhepmc-dev#2.06.09-1 +libhepmcfio-dev#2.06.09-1 +libhepmcinterface8-dev#8.1.65-1 +libherwig59-2-dev#20061220+dfsg3-2 +libhesiod-dev#3.0.2-21 +libhfsp-dev#1.0.4-12 +libhighgui-dev#2.3.1-11 +libhippocanvas-dev#0.3.1-1.1 +libhiredis-dev#0.10.1-7 +libhivex-dev#1.3.6-2 +libhivex-ocaml-dev#1.3.6-2 +libhkl-dev#4.0.3-4 +libhmsbeagle-dev#1.0-6 +libhocr-dev#0.10.17-1+b2 +libhpdf-dev#2.2.1-1 +libhpmud-dev#3.12.6-3.1+deb7u1 +libhsclient-dev#1.1.0-7-g1044a28-1 +libhtmlcxx-dev#0.85-2 +libhtp-dev#0.2.6-2 +libhtsengine-dev#1.06-1 +libhttp-ocaml-dev#0.1.5-1+b2 +libhttrack-dev#3.46.1-1 +libhunspell-dev#1.3.2-4 +libhwloc-dev#1.4.1-4 +libhx-dev#3.12.1-1 +libhyantes-dev#1.3.0-1 +libhyena-cil-dev#0.5-2 +libhyphen-dev#2.8.3-2 +libhypre-dev#2.8.0b-1 +libhz-dev#0.3.16-3 +libi2c-dev#3.1.0-2 +libibcm-dev#1.0.4-1.1 +libibcommon-dev#1.1.2-20090314-1 +libibdm-dev#1.2-OFED-1.4.2-1.3 +libibmad-dev#1.2.3-20090314-1.1 +libibtk-dev#0.0.14-12 +libibumad-dev#1.2.3-20090314-1.1 +libibus-1.0-dev#1.4.1-9+deb7u1 +libibus-qt-dev#1.3.1-2.1 +libibverbs-dev#1.1.6-1 +libical-dev#0.48-2 +libicapapi-dev#1:0.1.6-1.1 +libicc-dev#2.12+argyll1.4.0-8 +libicc-utils-dev#1.6.4-1+b1 +libice-dev#2:1.0.8-2 +libicee-dev#1.2.0-6.1 +libicns-dev#0.8.1-1 +libiconv-hook-dev#0.0.20021209-10 +libics-dev#1.5.2-3 +libicu-dev#4.8.1.1-12+deb7u1 +libid3-3.8.3-dev#3.8.3-15 +libid3tag0-dev#0.15.1b-10 +libident-dev#0.22-3 +libidl-dev#0.8.14-0.2 +libidn11-dev#1.25-2 +libidn2-0-dev#0.8-2 +libido-0.1-dev#0.3.4-1 +libido3-0.1-dev#0.3.4-1 +libidzebra-2.0-dev#2.0.44-3 +libiec16022-dev#0.2.4-1 +libiec61883-dev#1.2.0-0.1 +libieee1284-3-dev#0.2.11-10 +libifp-dev#1.0.0.2-5 +libifstat-dev#1.1-8 +libigraph0-dev#0.5.4-2 +libigstk4-dev#4.4.0-2+b1 +libijs-dev#0.35-8 +libiksemel-dev#1.2-4 +libilmbase-dev#1.0.1-4 +libimdi-dev#1.4.0-8 +libiml-dev#1.0.3-4.2 +libimlib2-dev#1.4.5-1 +libimobiledevice-dev#1.1.1-4 +libindi-dev#0.9.1-2 +libindicate-dev#0.6.92-1 +libindicate-gtk-dev#0.6.92-1 +libindicate-gtk0.1-cil-dev#0.6.92-1 +libindicate-gtk3-dev#0.6.92-1 +libindicate-qt-dev#0.2.5.91-5 +libindicate0.1-cil-dev#0.6.92-1 +libindicator-dev#0.5.0-1 +libindicator-messages-status-provider-dev#0.6.0-1 +libindicator3-dev#0.5.0-1 +libindigo-dev#1.0.0-2 +libinfinity-0.5-dev#0.5.2-6.1 +libini-config-dev#0.1.3-2 +libinifiles-ocaml-dev#1.2-2 +libinnodb-dev#1.0.6.6750-1 +libinotify-ocaml-dev#1.0-1+b3 +libinotifytools0-dev#3.14-1 +libinput-pad-dev#1.0.1-2 +libinsighttoolkit3-dev#3.20.1+git20120521-3 +libinstpatch-dev#1.0.0-3 +libint-dev#1.1.4-1 +libiodbc2-dev#3.52.7-2+deb7u1 +libion-dev#3.0.1~dfsg1-1 +libipa-hbac-dev#1.8.4-2 +libipathverbs-dev#1.2-1 +libipe-dev#7.1.2-1 +libipmiconsole-dev#1.1.5-3 +libipmidetect-dev#1.1.5-3 +libipmimonitoring-dev#1.1.5-3 +libipset-dev#6.12.1-1 +libiptcdata0-dev#1.0.4-3 +libircclient-dev#1.3+dfsg1-3 +libirman-dev#0.4.4-2 +libirrlicht-dev#1.7.3+dfsg1-4 +libisajet758-3-dev#20061220+dfsg3-2 +libiscsi-dev#1.4.0-3 +libisl-dev#0.10-3 +libiso9660-dev#0.83-4 +libisoburn-dev#1.2.2-2 +libisofs-dev#1.2.2-1 +libitl-dev#0.7.0-3 +libitl-gobject-dev#0.2-1 +libitpp-dev#4.2-4 +libitsol-dev#1.0.0-2 +libivykis-dev#0.30.1-2 +libiw-dev#30~pre9-8 +libjack-dev#1:0.121.3+20120418git75e3e20b-2.1 +libjack-jackd2-dev#1.9.8~dfsg.4+20120529git007cdc37-5 +libjalali-dev#0.4.0-1.1 +libjama-dev#1.2.4-2 +libjana-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-ecal-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-gtk-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjansson-dev#2.3.1-2 +libjasper-dev#1.900.1-13 +libjaula-dev#1.4.0-3 +libjavascriptcoregtk-1.0-dev#1.8.1-3.4 +libjavascriptcoregtk-3.0-dev#1.8.1-3.4 +libjbig-dev#2.0-2+deb7u1 +libjbig2dec0-dev#0.11+20120125-1 +libjconv-dev#2.8-6+b1 +libjemalloc-dev#3.0.0-3 +libjim-dev#0.73-3 +libjpeg62-dev#6b1-3 +libjpeg8-dev#8d-1 +libjpgalleg4-dev#2:4.4.2-2.1 +libjs-of-ocaml-dev#1.2-2 +libjson-glib-dev#0.14.2-1 +libjson-spirit-dev#4.04-1+b1 +libjson-static-camlp4-dev#0.9.8-1+b5 +libjson-wheel-ocaml-dev#1.0.6-2+b8 +libjson0-dev#0.10-1.2 +libjsoncpp-dev#0.6.0~rc2-3 +libjte-dev#1.19-1 +libjthread-dev#1.3.1-3 +libjudy-dev#1.0.5-1 +libjuman-dev#5.1-2.1 +libk3b-dev#2.0.2-6 +libkactivities-dev#4:4.8.4-1 +libkakasi2-dev#2.3.5~pre1+cvs20071101-1 +libkal-dev#0.9.0-1 +libkarma-cil-dev#0.1.2-2.3 +libkarma-dev#0.1.2-2.3 +libkate-dev#0.4.1-1 +libkaya-gd-dev#0.4.4-6 +libkaya-gl-dev#0.4.4-6 +libkaya-mysql-dev#0.4.4-6 +libkaya-ncurses-dev#0.4.4-6 +libkaya-ncursesw-dev#0.4.4-6 +libkaya-pgsql-dev#0.4.4-6 +libkaya-sdl-dev#0.4.4-6 +libkaya-sqlite3-dev#0.4.4-6 +libkcddb-dev#4:4.8.4-2 +libkdcraw-dev#4:4.8.4-1 +libkdeedu-dev#4:4.8.4-1 +libkdegames-dev#4:4.8.4-3 +libkdtree++-dev#0.7.0-2 +libkernlib1-dev#20061220+dfsg3-2 +libkexiv2-dev#4:4.8.4-1 +libkeybinder-dev#0.2.2-4 +libkeyutils-dev#1.5.5-3 +libkibi-dev#0.1-1 +libkipi-dev#4:4.8.4-1 +libkiten-dev#4:4.8.4-1 +libklatexformula3-dev#3.2.6-1 +libklibc-dev#2.0.1-3.1 +libkmfl-dev#0.9.8-1 +libkmflcomp-dev#0.9.8-1 +libkml-dev#1.3.0~r863-4.1 +libkmod-dev#9-3 +libkokyu-dev#6.0.3+dfsg-0.1 +libkonq5-dev#4:4.8.4-2 +libkonqsidebarplugin-dev#4:4.8.4-2 +libkopete-dev#4:4.8.4-1+b1 +libkosd2-dev#0.8.1-1 +libkpathsea-dev#2012.20120628-4 +libkqueue-dev#1.0.4-2 +libkrb5-dev#1.10.1+dfsg-5+deb7u1 +libksane-dev#4:4.8.4-1 +libksba-dev#1.2.0-2 +libktoblzcheck1-dev#1.39-1 +libktorrent-dev#1.2.1-1 +libktpcommoninternalsprivate-dev#0.4.0-1 +libkvutils-dev#2.9.0-1 +libkvutils2.2-dev#2.9.0-1 +libkwnn-dev#1.1.1~a021+cvs20100325-6 +libkwwidgets1-dev#1.0.0~cvs20100930-8 +libkxl0-dev#1.1.7-16 +liblablgl-ocaml-dev#1.04-5+b3 +liblablgtk-extras-ocaml-dev#1.0-1+b2 +liblablgtk2-gl-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-gnome-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-ocaml-dev#2.14.2+dfsg-3 +liblablgtkmathview-ocaml-dev#0.7.8-6+b1 +liblablgtksourceview2-ocaml-dev#2.14.2+dfsg-3 +libladr-dev#0.0.200902a-2.1 +libladspa-ocaml-dev#0.1.4-1+b1 +liblapack-dev#3.4.1+dfsg-1+deb70u1 +liblapacke-dev#3.4.1+dfsg-1+deb70u1 +liblas-dev#1.2.1-5+b1 +liblash-compat-dev#1+dfsg0-3 +liblasi-dev#1.1.0-1 +liblasso3-dev#2.3.6-2 +liblastfm-dev#0.4.0~git20090710-2 +liblastfm-ocaml-dev#0.3.0-2+b6 +liblcgdm-dev#1.8.2-1+b2 +liblcms1-dev#1.19.dfsg-1.2 +liblcms2-dev#2.2+git20110628-2.2+deb7u1 +libldap-ocaml-dev#2.1.8-8+b9 +libldap2-dev#2.4.31-1+nmu2 +libldb-dev#1:1.1.6-1 +libldns-dev#1.6.13-1 +libledit-ocaml-dev#2.03-1+b2 +liblensfun-dev#0.2.5-2 +libleptonica-dev#1.69-3.1 +libleveldb-dev#0+20120530.gitdd0d562-1 +liblfc-dev#1.8.2-1+b2 +liblhapdf-dev#5.8.7+repack-1 +liblhasa-dev#0.0.7-2 +liblicense-dev#0.8.1-3 +liblightdm-gobject-dev#1.2.2-4 +liblightdm-qt-dev#1.2.2-4 +liblilv-dev#0.14.2~dfsg0-4 +liblinear-dev#1.8+dfsg-1 +liblinebreak2-dev#2.1-1 +liblink-grammar4-dev#4.7.4-2 +liblinphone-dev#3.5.2-10 +liblip-dev#2.0.0-1.1 +liblircclient-dev#0.9.0~pre1-1 +liblistaller-glib-dev#0.5.5-2 +liblivemedia-dev#2012.05.17-1 +libllvm-2.9-ocaml-dev#2.9+dfsg-7 +libllvm-3.0-ocaml-dev#3.0-10 +libllvm-3.1-ocaml-dev#3.1-1 +libllvm-ocaml-dev#1:3.0-14+nmu2 +liblo-dev#0.26~repack-7 +liblo-ocaml-dev#0.1.0-1+b1 +liblo10k1-dev#1.0.25-2 +libloadpng4-dev#2:4.4.2-2.1 +liblockdev1-dev#1.0.3-1.5 +liblockfile-dev#1.09-5 +liblodo3.0-dev#3.0.2+dfsg-4+b1 +liblog4ada2-dev#1.2-3 +liblog4c-dev#1.2.1-3 +liblog4cplus-dev#1.0.4-1 +liblog4cpp5-dev#1.0-4 +liblog4cxx10-dev#0.10.0-1.2 +liblog4net-cil-dev#1.2.10+dfsg-6 +liblog4shib-dev#1.0.4-1 +liblog4tango4-dev#7.2.6+dfsg-14 +liblogforwarderutils2-dev#2.7-1 +liblognorm-dev#0.3.4-1 +liblogservicecomponentbase2-dev#2.7-1 +liblogservicetoolbase2-dev#2.7-1 +liblogsys-dev#1.4.2-3 +liblogthread-dev#3.0.12-3.2+deb7u2 +libloki-dev#0.1.7-3 +libloudmouth1-dev#1.4.3-9 +liblouis-dev#2.4.1-1 +liblouisutdml-dev#2.2.0-1 +liblouisxml-dev#2.4.0-3 +liblowpan-dev#0.2.2-2.1 +liblpsolve55-dev#5.5.0.13-7 +liblqr-1-0-dev#0.4.1-2 +liblrdf0-dev#0.4.0-5 +liblrm2-dev#1.0.9+hg2665-1 +liblrs-dev#0.42c-1+b1 +liblscp-dev#0.5.6-6 +libltcsmpte-dev#0.4.4-1 +libltdl-dev#2.4.2-1.1 +liblttctl-dev#0.89-05122011-1 +liblttd-dev#0.89-05122011-1 +liblttng-ust-dev#2.0.4-1 +liblttoolbox3-3.1-0-dev#3.1.0-1.1 +liblttvtraceread-2.6-dev#0.12.38-21032011-1+b1 +liblua5.1-0-dev#5.1.5-4 +liblua5.1-apr-dev#0.23.2-1 +liblua5.1-bitop-dev#1.0.2-1 +liblua5.1-cgi-dev#5.1.4+dfsg-2 +liblua5.1-copas-dev#1.1.6-5 +liblua5.1-curl-dev#0.3.0-7 +liblua5.1-cyrussasl-dev#1.0.0-4 +liblua5.1-event-dev#0.4.1-2 +liblua5.1-expat-dev#1.2.0-5+deb7u1 +liblua5.1-filesystem-dev#1.5.0+16+g84f1af5-1 +liblua5.1-leg-dev#0.1.2-8 +liblua5.1-logging-dev#1.2.0-1 +liblua5.1-lpeg-dev#0.10.2-5 +liblua5.1-md5-dev#1.1.2-6 +liblua5.1-oocairo-dev#1.4-1.2 +liblua5.1-oopango-dev#1.1-1 +liblua5.1-orbit-dev#2.2.0+dfsg1-1 +liblua5.1-posix-dev#5.1.19-2 +liblua5.1-rex-onig-dev#2.6.0-2 +liblua5.1-rex-pcre-dev#2.6.0-2 +liblua5.1-rex-posix-dev#2.6.0-2 +liblua5.1-rings-dev#1.2.3-1 +liblua5.1-rrd-dev#1.4.7-2 +liblua5.1-sec-dev#0.4.1-1 +liblua5.1-soap-dev#3.0-3 +liblua5.1-socket-dev#2.0.2-8 +liblua5.1-sql-mysql-dev#2.3.0-1+build0 +liblua5.1-sql-postgres-dev#2.3.0-1+build0 +liblua5.1-sql-sqlite3-dev#2.3.0-1+build0 +liblua5.1-svn-dev#0.4.0-7 +liblua5.1-wsapi-fcgi-dev#1.5-3 +liblua5.1-xmlrpc-dev#1.2.1-5 +liblua5.1-zip-dev#1.2.3-11 +liblua5.2-dev#5.2.1-3 +liblua50-dev#5.0.3-6 +libluabind-dev#0.9.1+dfsg-5 +liblualib50-dev#5.0.3-6 +liblunar-1-dev#2.0.1-2.2 +liblunar-date-dev#2.4.0-1 +liblv2dynparam1-dev#2-5 +liblvm2-dev#2.02.95-8 +liblwipv6-dev#1.5a-2 +liblwt-glib-ocaml-dev#2.3.2-1+b3 +liblwt-ocaml-dev#2.3.2-1+b3 +liblwt-ssl-ocaml-dev#2.3.2-1+b3 +liblz-dev#1.3-2 +liblzma-dev#5.1.1alpha+20120614-2 +liblzo2-dev#2.06-1 +libm17n-dev#1.6.3-2 +libm17n-im-config-dev#0.9.0-3 +libm4ri-dev#0.0.20080521-2 +libmaa-dev#1.3.1-1 +libmad-ocaml-dev#0.4.4-1+b1 +libmad0-dev#0.15.1b-7 +libmadlib-dev#1.3.0-2.1 +libmagic-dev#5.11-2+deb7u3 +libmagic-ocaml-dev#0.7.3-5+b3 +libmagick++-dev#8:6.7.7.10-5+deb7u3 +libmagickcore-dev#8:6.7.7.10-5+deb7u3 +libmagickwand-dev#8:6.7.7.10-5+deb7u3 +libmagics++-dev#2.14.11-4 +libmailutils-dev#1:2.99.97-3 +libmalaga-dev#7.12-4 +libmaloc-dev#0.2-2.3 +libmapi-dev#1:1.0-3 +libmapiadmin-dev#1:1.0-3 +libmapipp-dev#1:1.0-3 +libmapiproxy-dev#1:1.0-3 +libmapistore-dev#1:1.0-3 +libmapnik-dev#2.0.0+ds1-3 +libmapnik2-dev#2.0.0+ds1-3+b4 +libmarble-dev#4:4.8.4-3 +libmarkdown2-dev#2.1.3-3 +libmatchbox-dev#1.9-osso8-3 +libmath++-dev#0.0.4-4 +libmatheval-dev#1.1.8-1 +libmathlib2-dev#20061220+dfsg3-2 +libmatio-dev#1.3.4-4 +libmatrixssl1.8-dev#1.8.8-1 +libmatroska-dev#1.3.0-2 +libmbt0-dev#3.2.8-1 +libmcpp-dev#2.7.2-1.1 +libmcrypt-dev#2.5.8-3.1 +libmcs-dev#0.7.2-2.1 +libmd3-dev#0.1.92-4 +libmdc2-dev#0.10.7-1+b2 +libmdds-dev#0.5.4-1 +libmdsp-dev#0.11-10 +libmeanwhile-dev#1.0.2-4 +libmecab-dev#0.99.3-3 +libmed-dev#3.0.3-3 +libmedc-dev#3.0.3-3 +libmediainfo-dev#0.7.58-1 +libmediastreamer-dev#3.5.2-10 +libmedimport-dev#3.0.3-3 +libmeep-dev#1.1.1-8+deb7u1 +libmeep-lam4-dev#1.1.1-10~deb7u1 +libmeep-mpi-default-dev#1.1.1-10~deb7u1 +libmeep-mpich2-dev#1.1.1-10~deb7u1 +libmeep-openmpi-dev#1.1.1-9~deb7u2 +libmelt-ocaml-dev#1.4.0-1 +libmemcache-dev#1.4.0.rc2-1 +libmemcached-dev#1.0.8-1 +libmemphis-0.2-dev#0.2.3-2 +libmenhir-ocaml-dev#20120123.dfsg-1 +libmenu-cache1-dev#0.3.3-1 +libmercator-0.3-dev#0.3.0-2 +libmeschach-dev#1.2b-13 +libmetacity-dev#1:2.34.3-4 +libmgl-dev#1.11.2-17 +libmhash-dev#0.9.9.9-1.1 +libmicrohttpd-dev#0.9.20-1+deb7u1 +libmigemo-dev#20110227-7 +libmikmatch-ocaml-dev#1.0.4-1+b1 +libmikmod2-dev#3.1.12-5 +libmilter-dev#8.14.4-4 +libmimedir-dev#0.5.1-4 +libmimedir-gnome-dev#0.4.2-5 +libmimelib1-dev#5:1.1.4-2 +libmimetic-dev#0.9.7-3 +libmimic-dev#1.0.4-2.1 +libminc-dev#2.1.10-1+b1 +libming-dev#1:0.4.4-1.1 +libmini18n-dev#0.2.1-1 +libminidjvu-dev#0.8.svn.2010.05.06+dfsg-0.2 +libminiupnpc-dev#1.5-2 +libmission-control-plugins-dev#1:5.12.3-1 +libmkv-dev#0.6.5.1-1 +libmlpcap-ocaml-dev#0.9-16 +libmlpost-ocaml-dev#0.8.1-3 +libmlt++-dev#0.8.0-4 +libmlt-dev#0.8.0-4 +libmlx4-dev#1.0.4-1 +libmm-dev#1.4.2-4 +libmm-ocaml-dev#0.2.0-1+b1 +libmmpong0.9-dev#0.9.1-2.1 +libmms-dev#0.6.2-3 +libmng-dev#1.0.10-3 +libmnl-dev#1.0.3-3 +libmodbus-dev#3.0.3-1 +libmodglue1-dev#1.17-2.1 +libmodplug-dev#1:0.8.8.4-3+deb7u1+git20130828 +libmoe-dev#1.5.8-1 +libmongo-client-dev#0.1.5-1+deb7u1 +libmono-2.0-dev#2.10.8.1-8 +libmono-addins-cil-dev#0.6.2-2 +libmono-addins-gui-cil-dev#0.6.2-2 +libmono-addins-msbuild-cil-dev#0.6.2-2 +libmono-cecil-cil-dev#0.9.5+dfsg-2 +libmono-cecil-flowanalysis-cil-dev#0.1~vcs20110809.r1.b34edf6-2 +libmono-cil-dev#2.10.8.1-8 +libmono-reflection-cil-dev#1.0+git20110407+d2343843-2 +libmono-uia-cil-dev#2.1-4 +libmono-upnp-cil-dev#0.1.2-1 +libmono-zeroconf-cil-dev#0.9.0-4 +libmonogame-cil-dev#2.5.1+dfsg-3 +libmopac7-dev#1.15-5 +libmorph-dev#1:20090926 +libmosquitto0-dev#0.15-2 +libmosquittopp0-dev#0.15-2 +libmount-dev#2.20.1-5.3 +libmowgli-dev#1.0.0-1 +libmozjs-dev#24.4.0esr-1~deb7u2 +libmozjs185-dev#1.8.5-1.0.0+dfsg-4 +libmp3lame-dev#3.99.5+repack1-3 +libmp3lame-ocaml-dev#0.3.1-1+b1 +libmp3splt-dev#0.7.2-2 +libmp4v2-dev#2.0.0~dfsg0-1 +libmpc-dev#0.9-4 +libmpcdec-dev#2:0.1~r459-4 +libmpd-dev#0.20.0-1.1 +libmpdclient-dev#2.3-1 +libmpeg2-4-dev#0.4.1-3 +libmpeg3-dev#1.5.4-5 +libmpfi-dev#1.5.1-1 +libmpfr-dev#3.1.0-5 +libmpg123-dev#1.14.4-1 +libmpich2-dev#1.4.1-4.2 +libmpikmeans-dev#1.5-1+b1 +libmrml1-dev#0.1.14-12 +libmrmpi-dev#1.0~20110620.dfsg-2 +libmrss0-dev#0.19.2-3 +libmsgpack-dev#0.5.7-2 +libmsn-dev#4.2-2 +libmsv-dev#0.0.0-1 +libmtbl-dev#0.2-1 +libmtcp-dev#1.2.5-1 +libmtdev-dev#1.1.2-1 +libmthca-dev#1.0.6-1 +libmtp-dev#1.1.3-35-g0ece104-5 +libmudflap0-4.4-dev#4.4.7-2 +libmudflap0-4.6-dev#4.6.3-14 +libmudflap0-4.7-dev#4.7.2-5 +libmulticobex1-dev#0.23-1.1 +libmumps-dev#4.10.0.dfsg-3 +libmumps-ptscotch-dev#4.10.0.dfsg-3 +libmumps-scotch-dev#4.10.0.dfsg-3 +libmumps-seq-dev#4.10.0.dfsg-3 +libmunge-dev#0.5.10-1 +libmuparser-dev#2.1.0-3 +libmupdf-dev#0.9-2 +libmupen64plus-dev#1.99.5-6 +libmuroar-dev#0.1.8-2 +libmusic-dev#1.0.7-1.2 +libmusicbrainz3-dev#3.0.2-2.1 +libmusicbrainz5-dev#5.0.1-2 +libmutter-dev#3.4.1-5 +libmx-dev#1.4.6-1 +libmxml-dev#2.6-2 +libmyproxy-dev#5.6-1 +libmysql++-dev#3.1.0-2+b1 +libmysql-cil-dev#6.4.3-2 +libmysql-ocaml-dev#1.1.1-1 +libmysqlclient-dev#5.5.35+dfsg-0+wheezy1 +libmysqlcppconn-dev#1.1.0-4+b1 +libmysqld-dev#5.5.35+dfsg-0+wheezy1 +libmythes-dev#2:1.2.2-1 +libnabrit-dev#0.4.1-1 +libnacl-dev#20110221-4 +libnacore-dev#0.4.0-3 +libnanohttp-dev#1.1.0-17.1 +libnatpmp-dev#20110808-3 +libnautilus-extension-dev#3.4.2-1+build1 +libnbio-dev#0.30-1 +libncap-dev#1.9.2-1+b2 +libncbi6-dev#6.1.20120620-2 +libncp-dev#2.2.6-9 +libncurses5-dev#5.9-10 +libncursesada2-dev#5.9.20110404-7 +libncursesw5-dev#5.9-10 +libndesk-dbus-glib1.0-cil-dev#0.4.1-4 +libndesk-dbus1.0-cil-dev#0.6.0-6 +libndr-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libndr-standard-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libnecpp-dev#1.5.0+cvs20101003-2.1 +libneon27-dev#0.29.6-3 +libneon27-gnutls-dev#0.29.6-3 +libnes-dev#1.1.3-1 +libnet1-dev#1.1.4-2.1 +libnet6-1.3-dev#1:1.3.14-1 +libnetcdf-dev#1:4.1.3-6+b1 +libnetcf-dev#0.1.9-2 +libnetclasses-dev#1.06.dfsg-5+b3 +libnetfilter-conntrack-dev#1.0.1-1 +libnetfilter-cttimeout-dev#1.0.0-1 +libnetfilter-log-dev#1.0.0-1 +libnetfilter-queue-dev#0.0.17-1 +libnethttpd-ocaml-dev#3.5.1-1 +libnetpbm10-dev#2:10.0-15+b1 +libnetpbm9-dev#2:10.0-15+b1 +libnetsvcs-dev#6.0.3+dfsg-0.1 +libnewlib-dev#1.18.0-6.2 +libnewmat10-dev#1.10.4-5 +libnewt-dev#0.52.14-11.1 +libnewtonsoft-json-cil-dev#4.5r6-1 +libnexus0-dev#4.2.1-svn1614-1+b2 +libnfnetlink-dev#1.0.0-1.1 +libnfo-dev#1.0.1-1 +libnfs-dev#1.3.0-2 +libnfsidmap-dev#0.25-4 +libnice-dev#0.1.2-1 +libnids-dev#1.23-2 +libnifti-dev#2.0.0-1 +libnih-dbus-dev#1.0.3-4.1 +libnih-dev#1.0.3-4.1 +libnini-cil-dev#1.1.0+dfsg.2-4 +libnjb-dev#2.2.7~dfsg0-3 +libnl-3-dev#3.2.7-4 +libnl-cli-3-dev#3.2.7-4 +libnl-dev#1.1-7 +libnl-genl-3-dev#3.2.7-4 +libnl-nf-3-dev#3.2.7-4 +libnl-route-3-dev#3.2.7-4 +libnm-glib-dev#0.9.4.0-10 +libnm-glib-vpn-dev#0.9.4.0-10 +libnm-gtk-dev#0.9.4.1-5 +libnm-util-dev#0.9.4.0-10 +libnmz7-dev#2.0.21-6 +libnoise-dev#1.0.0+nmu1 +libnotify-cil-dev#0.4.0~r3032-6 +libnotify-dev#0.7.5-1 +libnotmuch-dev#0.13.2-1 +libnova-dev#0.14.0-2 +libnpth0-dev#0.90-2 +libnsbmp0-dev#0.0.1-1.1 +libnsgif0-dev#0.0.1-1.1 +libnspr4-dev#2:4.9.2-1+deb7u1 +libnss3-dev#2:3.14.5-1 +libntfs-dev#2.0.0-1+b1 +libntl-dev#5.5.2-2 +libntlm0-dev#1.2-1 +libntrack-dev#016-1.1 +libntrack-glib-dev#016-1.1 +libntrack-gobject-dev#016-1.1 +libntrack-qt4-dev#016-1.1 +libnuclient-dev#2.4.3-2.2 +libnuma-dev#2.0.8~rc4-1 +libnunit-cil-dev#2.6.0.12051+dfsg-2 +libnussl-dev#2.4.3-2.2 +libnvtt-dev#2.0.8-1+dfsg-2 +libnxcl-dev#0.9-3.1 +libnxml0-dev#0.18.3-4 +libnzb-dev#0.0.20050629-6.1 +liboasis-ocaml-dev#0.2.0-6 +liboasis3-dev#3.3.beta.dfsg.1-8+b1 +liboath-dev#1.12.4-1 +liboauth-dev#0.9.4-3.1 +libobby-0.4-dev#0.4.8-1 +libobexftp0-dev#0.23-1.1 +libobrowser-ocaml-dev#1.1.1+dfsg-1+b9 +libobus-ocaml-dev#1.1.3-1+b8 +libocamlbricks-ocaml-dev#0.50.1-4+b5 +libocamlgraph-ocaml-dev#1.8.2-2 +libocamlgraph-viewer-ocaml-dev#1.8.2-2 +libocamlgsl-ocaml-dev#0.6.0-7+b2 +libocamlnet-gtk2-ocaml-dev#3.5.1-1 +libocamlnet-ocaml-dev#3.5.1-1 +libocamlnet-ssl-ocaml-dev#3.5.1-1 +libocamlodbc-ocaml-dev#2.15-5+b3 +libocamlviz-ocaml-dev#1.01-2+b2 +libocas-dev#0.93-1 +liboce-foundation-dev#0.9.1-3 +liboce-modeling-dev#0.9.1-3 +liboce-ocaf-dev#0.9.1-3 +liboce-ocaf-lite-dev#0.9.1-3 +liboce-visualization-dev#0.9.1-3 +libocpf-dev#1:1.0-3 +libocrad-dev#0.22~rc1-2 +libocsigen-ocaml-dev#1.3.4-2+b12 +libocsigen-xhtml-ocaml-dev#1.3.4-2+b12 +libocsigenserver-ocaml-dev#2.1-1 +liboctave-dev#3.6.2-5+deb7u1 +libode-dev#2:0.11.1-4 +libode-sp-dev#2:0.11.1-4 +libodin-dev#1.8.5-2 +libodn-ocaml-dev#0.0.8-1 +libofa0-dev#0.9.3-5 +libofapi-dev#0git20070620-6 +libofdt-dev#1.3.6-1 +libofetion-dev#2.2.2-1 +libofx-dev#1:0.9.4-2.1 +libogdi3.2-dev#3.2.0~beta2-7 +libogg-dev#1.3.0-4 +libogg-ocaml-dev#0.4.3-1+b1 +liboggkate-dev#0.4.1-1 +liboggplay1-dev#0.2.1~git20091227-1.2 +liboggz2-dev#1.1.1-1 +liboglappth-dev#1.0.0-2 +libogre-1.8-dev#1.8.0+dfsg1-3 +libogre-dev#1.7.4+dfsg1-7 +liboil0.3-dev#0.3.17-2 +libois-dev#1.3.0+dfsg0-5 +libomhacks-dev#0.16-1 +libomnievents-dev#1:2.6.2-2 +libomniorb4-dev#4.1.6-2 +libomnithread3-dev#4.1.6-2 +libomxil-bellagio-dev#0.9.3-1+b1 +libonig-dev#5.9.1-1 +liboobs-1-dev#3.0.0-1 +liboop-dev#1.0-9 +libooptools-dev#2.7-1 +libopal-dev#3.10.4~dfsg-3 +libopenafs-dev#1.6.1-3+deb7u2 +libopenais-dev#1.1.4-4.1 +libopenal-dev#1:1.14-4 +libopenbabel-dev#2.3.1+dfsg-4 +libopenblas-dev#0.1.1-6+deb7u3 +libopencc-dev#0.3.0-3 +libopenconnect-dev#3.20-4 +libopencore-amrnb-dev#0.1.3-2 +libopencore-amrwb-dev#0.1.3-2 +libopencryptoki-dev#2.3.1+dfsg-3 +libopencsg-dev#1.3.2-2 +libopenct1-dev#0.6.20-1.2 +libopencv-calib3d-dev#2.3.1-11 +libopencv-contrib-dev#2.3.1-11 +libopencv-core-dev#2.3.1-11 +libopencv-dev#2.3.1-11 +libopencv-features2d-dev#2.3.1-11 +libopencv-flann-dev#2.3.1-11 +libopencv-gpu-dev#2.3.1-11 +libopencv-highgui-dev#2.3.1-11 +libopencv-imgproc-dev#2.3.1-11 +libopencv-legacy-dev#2.3.1-11 +libopencv-ml-dev#2.3.1-11 +libopencv-objdetect-dev#2.3.1-11 +libopencv-video-dev#2.3.1-11 +libopendkim-dev#2.6.8-4 +libopenexr-dev#1.6.1-6 +libopenhpi-dev#2.14.1-1.2 +libopenigtlink1-dev#1.9.2~svn7468-1 +libopenimageio-dev#1.0.5+dfsg0-1 +libopenipmi-dev#2.0.16-1.3 +libopenjpeg-dev#1.3+dfsg-4.7 +libopenmeeg-dev#2.0.0.dfsg-5 +libopenmpi-dev#1.4.5-1 +libopenobex1-dev#1.5-2 +libopenr2-dev#1.3.2-1.1 +libopenraw-dev#0.0.9-3+b1 +libopenrawgnome-dev#0.0.9-3+b1 +libopenscap-dev#0.8.0-4+b1 +libopenscenegraph-dev#3.0.1-4 +libopenslide-dev#3.2.6-2 +libopensm2-dev#3.2.6-20090317-2.1 +libopenthreads-dev#3.0.1-4 +libopentk-cil-dev#1.0.20101006+dfsg1-1 +libopentoken3-dev#4.0b-3 +libopenturns-dev#1.0-4 +libopenusb-dev#1.1.0-2 +libopenvg1-mesa-dev#8.0.5-4+deb7u2 +libopenvrml-dev#0.18.9-5+deb7u1 +libopenwalnut1-dev#1.2.5-1.1+b1 +liboping-dev#1.6.2-1 +libopkele-dev#2.0.4-5.3 +libopts25-dev#1:5.12-0.1 +libopus-dev#0.9.14+20120615-1+nmu1 +liborange-dev#0.4-2 +liborbit2-dev#1:2.14.19-0.1 +liborc-0.4-dev#1:0.4.16-2 +liborigin-dev#20080225-2.1 +liborigin2-dev#2:20110117-1+b2 +libortp-dev#3.5.2-10 +liboscpack-dev#1.0.2-1 +libosgearth-dev#2.0+dfsg-4+b3 +libosinfo-1.0-dev#0.1.1-1 +libosip2-dev#3.6.0-4 +libosl-dev#0.5.0-1 +libosmesa6-dev#8.0.5-4+deb7u2 +libosmgpsmap-dev#0.7.3-3 +libosmium-dev#0.0~20111213-g7f3500a-3+b2 +libosmpbf-dev#1.2.1-3 +libosp-dev#1.5.2-10 +libosptk3-dev#3.4.2-1+b1 +libossim-dev#1.7.21-4 +libossp-sa-dev#1.2.6-1 +libossp-uuid-dev#1.6.2-1.3 +libostyle-dev#1.4devel1-20.1+b1 +libotcl1-dev#1.14+dfsg-2 +libotf-dev#0.9.12-2 +libotf-trace-dev#1.10.2+dfsg-2 +libotpw-dev#1.3-2 +libotr2-dev#3.2.1-1+deb7u1 +libots-dev#0.5.0-2.1 +libounit-ocaml-dev#1.1.1-1 +libow-dev#2.8p15-1 +libowfat-dev#0.28-6 +libowfat-dietlibc-dev#0.28-6 +libownet-dev#2.8p15-1 +libp11-dev#0.2.8-2 +libp11-kit-dev#0.12-3 +libpackagekit-glib2-dev#0.7.6-3 +libpackagekit-qt2-dev#0.7.6-3 +libpacketdump3-dev#3.0.14-1 +libpacklib-lesstif1-dev#20061220+dfsg3-2 +libpacklib1-dev#20061220+dfsg3-2 +libpacparser-dev#1.3.0-2 +libpam-ocaml-dev#1.1-4+b3 +libpam0g-dev#1.1.3-7.1 +libpanel-applet-4-dev#3.4.2.1-4 +libpango1.0-dev#1.30.0-1 +libpangomm-1.4-dev#2.28.4-1 +libpano13-dev#2.9.18+dfsg-5 +libpantomime1.2-dev#1.2.0~pre3+snap20071004+dfsg-4+b1 +libpaper-dev#1.1.24+nmu2 +libpaps-dev#0.6.8-6 +libpaq-dev#1.0.4-3+b1 +libpar2-0-dev#0.2.1-1 +libpari-dev#2.5.1-2 +libparpack2-dev#3.1.1-2.1 +libparrot-dev#4.0.0-3 +libparser++-dev#0.2.3-2 +libparted0-dev#2.3-12 +libpasswdqc-dev#1.2.0-1 +libpath-utils-dev#0.1.3-2 +libpathfinder-dev#1.1.3-0.4+b1 +libpawlib-lesstif3-dev#1:2.14.04.dfsg.2-8 +libpawlib2-dev#1:2.14.04.dfsg.2-8 +libpcap-dev#1.3.0-1 +libpcap0.8-dev#1.3.0-1 +libpcapnav0-dev#0.8-1 +libpci-dev#1:3.1.9-6 +libpciaccess-dev#0.13.1-2 +libpcl1-dev#1.6-1 +libpcre++-dev#0.9.5-5.1 +libpcre-ocaml-dev#6.2.5-1 +libpcre3-dev#1:8.30-5 +libpcscada2-dev#0.7.1-4 +libpcsclite-dev#1.8.4-1+deb7u1 +libpdflib804-2-dev#20061220+dfsg3-2 +libpe-rules2-dev#1.1.7-1 +libpe-status3-dev#1.1.7-1 +libpeas-dev#1.4.0-2 +libpengine3-dev#1.1.7-1 +libperl-dev#5.14.2-21+deb7u1 +libperl4caml-ocaml-dev#0.9.5-4+b4 +libpetsc3.2-dev#3.2.dfsg-6 +libpfqueue-dev#0.5.6-8 +libpfs-dev#1.8.5-1 +libpgm-dev#5.1.118-1~dfsg-0.1 +libpgocaml-ocaml-dev#1.5-2 +libpgpool-dev#3.1.3-5 +libpgtcl-dev#1:1.5-6 +libphash0-dev#0.9.4-1.2 +libphat-dev#0.4.1-5 +libphobos-4.4-dev#1.063-4.4.7-1 +libphobos2-4.6-dev#0.29.1-4.6.3-2 +libphone-ui-dev#1:0.0.1+git20110825-3 +libphone-utils-dev#0.1+git20110523-2.1 +libphonon-dev#4:4.6.0.0-3 +libphononexperimental-dev#4:4.6.0.0-3 +libphotos202-dev#20061220+dfsg3-2 +libphtools2-dev#20061220+dfsg3-2 +libphysfs-dev#2.0.2-6 +libpiano-dev#2012.05.06-2 +libpigment0.3-dev#0.3.17-1 +libpils2-dev#1.0.9+hg2665-1 +libpinyin0-dev#0.6.91-1 +libpion-common-dev#4.0.7+dfsg-3.1 +libpion-net-dev#4.0.7+dfsg-3.1 +libpipeline-dev#1.2.1-1 +libpisock-dev#0.12.5-5 +libpixman-1-dev#0.26.0-4+deb7u1 +libpkcs11-helper1-dev#1.09-1 +libplayer-dev#2.0.1-2.1 +libplayerc++3.0-dev#3.0.2+dfsg-4+b1 +libplayerc3.0-dev#3.0.2+dfsg-4+b1 +libplayercommon3.0-dev#3.0.2+dfsg-4+b1 +libplayercore3.0-dev#3.0.2+dfsg-4+b1 +libplayerdrivers3.0-dev#3.0.2+dfsg-4+b1 +libplayerinterface3.0-dev#3.0.2+dfsg-4+b1 +libplayerjpeg3.0-dev#3.0.2+dfsg-4+b1 +libplayertcp3.0-dev#3.0.2+dfsg-4+b1 +libplayerwkb3.0-dev#3.0.2+dfsg-4+b1 +libplib-dev#1.8.5-6 +libplist++-dev#1.8-1 +libplist-dev#1.8-1 +libpload-dev#1.4.2-3 +libplot-dev#2.6-3 +libploticus0-dev#2.41-5 +libplotmm-dev#0.1.2-2 +libplplot-ada0-dev#5.9.9-5 +libplplot-dev#5.9.9-5 +libplumb2-dev#1.0.9+hg2665-1 +libplumbgpl2-dev#1.0.9+hg2665-1 +libpmap3.0-dev#3.0.2+dfsg-4+b1 +libpmi0-dev#2.3.4-2+b1 +libpmount-dev#0.0.16 +libpng++-dev#0.2.5-1 +libpng12-dev#1.2.49-1 +libpnglite-dev#0.1.17-1 +libpoco-dev#1.3.6p1-4 +libpodofo-dev#0.9.0-1.1+b1 +libpoker-eval-dev#138.0-1 +libpolarssl-dev#1.2.9-1~deb7u2 +libpoldiff-dev#3.3.7-3 +libpolkit-agent-1-dev#0.105-3 +libpolkit-backend-1-dev#0.105-3 +libpolkit-gobject-1-dev#0.105-3 +libpolkit-qt-1-dev#0.103.0-1 +libpolybori-dev#0.5~rc1-2.2 +libpolylib64-dev#5.22.5-3+dfsg +libpolyml-dev#5.2.1-1.1 +libpolyorb2-dev#2.8~20110207-5.1 +libpomp-dev#1.1+dfsg-2 +libpoppler-cil-dev#0.0.3-2 +libpoppler-cpp-dev#0.18.4-6 +libpoppler-dev#0.18.4-6 +libpoppler-glib-dev#0.18.4-6 +libpoppler-private-dev#0.18.4-6 +libpoppler-qt4-dev#0.18.4-6 +libpopplerkit-dev#0.0.20051227svn-7+b1 +libpopt-dev#1.16-7 +libportaudio-dev#18.1-7.1 +libportaudio-ocaml-dev#0.2.0-1+b1 +libportmidi-dev#1:184-2.1 +libportsmf-dev#0.1~svn20101010-3 +libpostgresql-ocaml-dev#1.18.0-1 +libpostproc-dev#6:0.8.10-1 +libpotrace-dev#1.10-1 +libpowerman0-dev#2.3.5-1 +libppd-dev#2:0.10-7.1 +libppl0.11-dev#0.11.2-8 +libpq-dev#9.1.13-0wheezy1 +libpqxx3-dev#3.1-1.1 +libprelude-dev#1.0.0-9 +libpreludedb-dev#1.0.0-1.1+b2 +libpresage-dev#0.8.8-1 +libpri-dev#1.4.12-2 +libprinterconf-dev#0.5-12 +libprintsys-dev#0.6-13 +libprison-dev#1.0+dfsg-1 +libprocps0-dev#1:3.3.3-3 +libproj-dev#4.7.0-2 +libprojectm-dev#2.1.0+dfsg-1 +libprojectm-qt-dev#2.1.0+dfsg-1 +libprotobuf-c0-dev#0.14-1+b1 +libprotobuf-dev#2.4.1-3 +libprotoc-dev#2.4.1-3 +libproxy-dev#0.3.1-6 +libproxychains-dev#3.1-3 +libpspell-dev#0.60.7~20110707-1 +libpst-dev#0.6.54-4.1 +libpstoedit-dev#3.60-2+b1 +libpstreams-dev#0.7.0-2 +libpt-dev#2.10.4~dfsg-1 +libptexenc-dev#2012.20120628-4 +libpth-dev#2.0.7-16 +libpthread-stubs0-dev#0.3-3 +libpthread-workqueue-dev#0.8.2-1 +libptscotch-dev#5.1.12b.dfsg-1.2 +libpugl-dev#0~svn32+dfsg0-1 +libpulse-dev#2.0-6.1 +libpulse-ocaml-dev#0.1.2-1+b1 +libpuma-dev#1:1.1+svn20120529-2 +libpurelibc-dev#0.4.1-1 +libpurple-dev#2.10.9-1~deb7u1 +libpuzzle-dev#0.9-5 +libpwl-dev#0.11.2-8 +libpxp-ocaml-dev#1.2.2-1+b4 +libpycaml-ocaml-dev#0.82-14+b2 +libpyside-dev#1.1.1-3 +libpythia8-dev#8.1.65-1 +libpythonqt2-dev#2.0.1-1.1 +libqalculate-dev#0.9.7-8 +libqapt-dev#1.3.0-2 +libqb-dev#0.11.1-2 +libqca2-dev#2.0.3-4 +libqd-dev#2.3.11.dfsg-2.1 +libqdaccolib-dev#0.8.2-1 +libqdbm++-dev#1.8.78-2 +libqdbm-dev#1.8.78-2 +libqdjango-dev#0.2.5-2 +libqedje-dev#0.4.0+lgpl-3 +libqfits-dev#6.2.0-5 +libqgis-dev#1.7.4+1.7.5~20120320-1.1+b1 +libqglviewer-qt4-dev#2.3.4-4.2 +libqgpsmm-dev#3.6-4+deb7u1 +libqhull-dev#2009.1-3 +libqimageblitz-dev#1:0.0.6-4 +libqjson-dev#0.7.1-7 +libqmf-dev#0.16-6+deb7u1 +libqmf2-dev#0.16-6+deb7u1 +libqmfconsole2-dev#0.16-6+deb7u1 +libqmfengine1-dev#0.16-6+deb7u1 +libqmmp-dev#0.5.5-1+b1 +libqmmpui-dev#0.5.5-1+b1 +libqoauth-dev#1.0.1-1 +libqof-dev#0.8.6-1 +libqofexpensesobjects-dev#0.1.9-2 +libqpdf-dev#2.3.1-4 +libqpidbroker2-dev#0.16-6+deb7u1 +libqpidclient2-dev#0.16-6+deb7u1 +libqpidcommon2-dev#0.16-6+deb7u1 +libqpidmessaging2-dev#0.16-6+deb7u1 +libqpidtypes1-dev#0.16-6+deb7u1 +libqpol-dev#3.3.7-3 +libqpx-dev#0.7.1.002-5 +libqrencode-dev#3.3.0-2 +libqrupdate-dev#1.1.1-1 +libqsastime-dev#5.9.9-5 +libqscintilla2-dev#2.6.2-2 +libqt4-dev#4:4.8.2+dfsg-11 +libqt4-opengl-dev#4:4.8.2+dfsg-11 +libqt4-private-dev#4:4.8.2+dfsg-11 +libqt4pas-dev#2.5-6 +libqtassistantclient-dev#4.6.3-4 +libqtexengine-dev#0.3-3 +libqtgstreamer-dev#0.10.2-2 +libqtruby4shared-dev#4:4.8.4-1 +libqtwebkit-dev#2.2.1-5 +libquantlib0-dev#1.2-2+b1 +libquantum-dev#1.1.0-3 +libquicktime-dev#2:1.2.4-3 +libquorum-dev#1.4.2-3 +libquvi-dev#0.4.1-1 +libqwt-dev#6.0.0-1.2 +libqwt5-qt4-dev#5.2.2-3 +libqwtplot3d-qt4-dev#0.2.7+svn191-7 +libqxmlrpc-dev#0.0.svn6-2 +libqxmpp-dev#0.4.92-1 +libqxt-dev#0.6.1-6 +libqzeitgeist-dev#0.7.0-1+b1 +libqzion-dev#0.4.0+lgpl-4 +librabbitmq-dev#0.0.1.hg216-1 +libradare2-dev#0.9-3 +libradius1-dev#0.3.2-14 +libradiusclient-ng-dev#0.5.6-1.1 +libranlip-dev#1.0-4.1 +librapi2-dev#0.15-2.1 +libraptor1-dev#1.4.21-7.1 +libraptor2-dev#2.0.8-2 +librarian-dev#0.8.1-5 +librasqal3-dev#0.9.29-1 +librasterlite-dev#1.1~svn11-2 +libraul-dev#0.8.0+dfsg0-0.1+b1 +libraw-dev#0.14.6-2 +libraw1394-dev#2.0.9-1 +librcc-dev#0.2.9-3 +librcd-dev#0.1.13-3 +librdf0-dev#1.0.15-1+b1 +librdkit-dev#201203-3 +librdmacm-dev#1.0.15-1+deb7u1 +librdmawrap2-dev#0.16-6+deb7u1 +libreact-ocaml-dev#0.9.3-1 +libreadline-dev#6.2+dfsg-0.1 +libreadline-gplv2-dev#5.2+dfsg-2~deb7u1 +libreadline6-dev#6.2+dfsg-0.1 +librec-dev#1.5-1 +librecode-dev#3.6-20 +libref-array-dev#0.1.3-2 +libregina3-dev#3.6-2 +libregistry-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libreins-ocaml-dev#0.1a-4+b1 +libreiser4-dev#1.0.7-6.3 +librelp-dev#1.0.0-1 +libremctl-dev#3.2-4 +librenaissance0-dev#0.9.0-4+b3 +libreoffice-dev#1:3.5.4+dfsg2-0+deb7u2 +librep-dev#0.90.2-1.3 +libreplaygain-dev#1.0~r475-1 +libres-ocaml-dev#3.2.0-2+b3 +libresample1-dev#0.1.3-4 +libresid-builder-dev#2.1.1-14 +libresiprocate-1.8-dev#1.8.5-4 +libresiprocate-turn-client-1.8-dev#1.8.5-4 +librest-dev#0.7.12-3 +librest-extras-dev#0.7.12-3 +librhash-cil-dev#1.2.9-8+deb7u1 +librhash-dev#1.2.9-8+deb7u1 +librheolef-dev#6.1-2.1 +librivet-dev#1.8.0-1 +librlog-dev#1.4-2 +libroar-dev#1.0~beta2-3 +libroot-bindings-python-dev#5.34.00-2 +libroot-bindings-ruby-dev#5.34.00-2 +libroot-core-dev#5.34.00-2 +libroot-geom-dev#5.34.00-2 +libroot-graf2d-gpad-dev#5.34.00-2 +libroot-graf2d-graf-dev#5.34.00-2 +libroot-graf2d-postscript-dev#5.34.00-2 +libroot-graf3d-eve-dev#5.34.00-2 +libroot-graf3d-g3d-dev#5.34.00-2 +libroot-graf3d-gl-dev#5.34.00-2 +libroot-gui-dev#5.34.00-2 +libroot-gui-ged-dev#5.34.00-2 +libroot-hist-dev#5.34.00-2 +libroot-hist-spectrum-dev#5.34.00-2 +libroot-html-dev#5.34.00-2 +libroot-io-dev#5.34.00-2 +libroot-io-xmlparser-dev#5.34.00-2 +libroot-math-foam-dev#5.34.00-2 +libroot-math-genvector-dev#5.34.00-2 +libroot-math-mathcore-dev#5.34.00-2 +libroot-math-mathmore-dev#5.34.00-2 +libroot-math-matrix-dev#5.34.00-2 +libroot-math-minuit-dev#5.34.00-2 +libroot-math-mlp-dev#5.34.00-2 +libroot-math-physics-dev#5.34.00-2 +libroot-math-quadp-dev#5.34.00-2 +libroot-math-smatrix-dev#5.34.00-2 +libroot-math-splot-dev#5.34.00-2 +libroot-math-unuran-dev#5.34.00-2 +libroot-misc-memstat-dev#5.34.00-2 +libroot-misc-minicern-dev#5.34.00-2 +libroot-misc-table-dev#5.34.00-2 +libroot-montecarlo-eg-dev#5.34.00-2 +libroot-montecarlo-vmc-dev#5.34.00-2 +libroot-net-auth-dev#5.34.00-2 +libroot-net-bonjour-dev#5.34.00-2 +libroot-net-dev#5.34.00-2 +libroot-net-ldap-dev#5.34.00-2 +libroot-proof-clarens-dev#5.34.00-2 +libroot-proof-dev#5.34.00-2 +libroot-proof-proofplayer-dev#5.34.00-2 +libroot-roofit-dev#5.34.00-2 +libroot-tmva-dev#5.34.00-2 +libroot-tree-dev#5.34.00-2 +libroot-tree-treeplayer-dev#5.34.00-2 +librostlab-blast0-dev#1.0.0-2 +librostlab3-dev#1.0.20-1 +librpcsecgss-dev#0.19-5 +librplay3-dev#3.3.2-14 +librpm-dev#4.10.0-5+deb7u1 +librra-dev#0.14-1.2 +librrd-dev#1.4.7-2 +librsl-dev#1.42-2 +librsskit-dev#0.3-2 +librsvg2-2.0-cil-dev#2.26.0-8 +librsvg2-dev#2.36.1-2 +librsync-dev#0.9.7-9 +librtai-dev#3.8.1-4 +librtas-dev#1.3.6-1 +librtasevent-dev#1.3.6-1 +librtaudio-dev#4.0.10~ds0-2 +librtfcomp-dev#1.1-5+b1 +librtfilter-dev#1.1-4 +librtmidi-dev#1.0.15~ds0-2 +librtmp-dev#2.4+20111222.git4e06e21-1 +librubberband-dev#1.3-1.3 +librudecgi-dev#5.0.0-1 +libruli4-dev#0.33-1.1 +librxp-dev#1.5.0-1 +libs3-dev#2.0-1 +libs3d-dev#0.2.2-8 +libs3dw-dev#0.2.2-8 +libsaamf3-dev#1.1.4-4.1 +libsackpt3-dev#1.1.4-4.1 +libsaclm3-dev#1.1.4-4.1 +libsaevt3-dev#1.1.4-4.1 +libsage-dev#0.2.0-4.1 +libsalck3-dev#1.1.4-4.1 +libsam-dev#1.4.2-3 +libsamba-credentials-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-hostconfig-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-policy-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-util-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamdb-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsaml2-dev#2.4.3-4 +libsampleicc-dev#1.6.4-1+b1 +libsamplerate-ocaml-dev#0.1.1-1+b3 +libsamplerate0-dev#0.1.8-5 +libsamsg4-dev#1.1.4-4.1 +libsane-dev#1.0.22-7.4 +libsane-extras-dev#1.0.22.2 +libsanlock-dev#2.2-2 +libsary-dev#1:1.2.0-2.1 +libsasl2-dev#2.1.25.dfsg1-6+deb7u1 +libsatmr3-dev#1.1.4-4.1 +libsbjson-dev#2.3.2-2 +libsbsms-dev#2.0.1-1 +libsbuf-dev#9.0+ds1-4 +libsbuild-dev#1.6.4-4 +libsc-dev#2.3.1-14 +libscalapack-mpi-dev#1.8.0-9 +libscalapack-pvm-dev#1.8.0-9 +libscalc-dev#0.2.4-1 +libscamperfile0-dev#20111202b-1 +libschroedinger-dev#1.0.11-2 +libschroedinger-ocaml-dev#0.1.0-1+b3 +libscim-dev#1.4.13-5 +libscm-dev#5e5-3.2 +libscotch-dev#5.1.12b.dfsg-1.2 +libscotchmetis-dev#5.1.12b.dfsg-1.2 +libscotchparmetis-dev#5.1.12b.dfsg-1.2 +libsctp-dev#1.0.11+dfsg-2 +libscythestat-dev#1.0.2-1 +libsdl-console-dev#2.1-3 +libsdl-gfx1.2-dev#2.0.23-3 +libsdl-image1.2-dev#1.2.12-2 +libsdl-mixer1.2-dev#1.2.12-3 +libsdl-net1.2-dev#1.2.8-2 +libsdl-ocaml-dev#0.9.0-1 +libsdl-pango-dev#0.1.2-6 +libsdl-sge-dev#030809dfsg-3 +libsdl-sound1.2-dev#1.0.3-6 +libsdl-stretch-dev#0.3.1-3 +libsdl-ttf2.0-dev#2.0.11-2 +libsdl1.2-dev#1.2.15-5 +libsdpa-dev#7.3.8+dfsg-1 +libsearchclient-dev#0.7.7-3 +libseaudit-dev#3.3.7-3 +libseed-gtk3-dev#3.2.0-2 +libsefs-dev#3.3.7-3 +libselinux1-dev#2.1.9-5 +libsemanage1-dev#2.1.6-6 +libsensors-applet-plugin-dev#3.0.0-0.2 +libsensors4-dev#1:3.3.2-2+deb7u1 +libsepol1-dev#2.1.4-3 +libserd-dev#0.14.0~dfsg0-2 +libserf-dev#1.1.0-2 +libsexplib-camlp4-dev#7.0.4-2 +libsexy-dev#0.1.11-2+b1 +libsfml-dev#1.6+dfsg2-2 +libsfst1-1.2-0-dev#1.2.0-1.2 +libsgutils2-dev#1.33-1 +libsha-ocaml-dev#1.7-2+b2 +libshairport-dev#1.2.1~git20120110.aeb4987-2 +libshevek-dev#1.3-1 +libshhmsg1-dev#1.4.1-4.1 +libshhopt1-dev#1.1.7-2.1 +libshiboken-dev#1.1.1-1 +libshibsp-dev#2.4.3+dfsg-5+b1 +libshisa-dev#1.0.1-2 +libshishi-dev#1.0.1-2 +libshout-ocaml-dev#0.2.7-1+b3 +libshout3-dev#2.2.2-8 +libshp-dev#1.2.10-7 +libshr-glib-dev#2011.03.08.2~git20110930-2 +libsidl-dev#1.4.0.dfsg-8.1 +libsidplay1-dev#1.36.59-5 +libsidplay2-dev#2.1.1-14 +libsidplayfp-dev#0.3.5-1 +libsidutils-dev#2.1.1-14 +libsieve2-dev#2.2.6-1.1 +libsigc++-1.2-dev#1.2.7-2 +libsigc++-2.0-dev#2.2.10-0.2 +libsigc++-dev#1.0.4-9.4 +libsigrok0-dev#0.1.0-2 +libsigrokdecode0-dev#0.1.0-2 +libsigsegv-dev#2.9-4 +libsilly-dev#0.1.0-3 +libsilo-dev#4.8-13 +libsimage-dev#1.7.0-1.1+b1 +libsimplelist0-dev#0.3.4-2 +libsipwitch-dev#1.2.4-1 +libsiscone-dev#2.0.5-1 +libsiscone-spherical-dev#2.0.5-1 +libskk-dev#0.0.12-3 +libskstream-0.3-dev#0.3.8-1 +libslang2-dev#2.2.4-15 +libslepc3.2-dev#3.2-p5-1 +libslp-dev#1.2.1-9 +libslurm-dev#2.3.4-2+b1 +libslurmdb-dev#2.3.4-2+b1 +libslv2-dev#0.6.6+dfsg1-2 +libsm-dev#2:1.2.1-2 +libsmbclient-dev#2:3.6.6-6+deb7u3 +libsmbclient-raw-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsmbios-dev#2.0.3.dfsg-1.1 +libsmf-dev#1.3-2 +libsmi2-dev#0.4.8+dfsg2-7 +libsmokekde-dev#4:4.8.4-1 +libsmokeqt4-dev#4:4.8.4-1 +libsmpeg-dev#0.4.5+cvs20030824-5 +libsnacc-dev#1.3.1-1 +libsnack2-dev#2.2.10-dfsg1-12.1 +libsnappy-dev#1.0.5-2 +libsndfile1-dev#1.0.25-5 +libsndobj-dev#2.6.6.1-3 +libsnmp-dev#5.4.3~dfsg-2.8 +libsnmpkit-dev#0.9-16 +libsocialweb-client-dev#0.25.20-2.1 +libsocialweb-dev#0.25.20-2.1 +libsocksd0-dev#1.1.19.dfsg-3+b3 +libsofa-c-dev#2012.03.01-1 +libsofa1-dev#1.0~beta4-7 +libsofia-sip-ua-dev#1.12.11+20110422-1 +libsofia-sip-ua-glib-dev#1.12.11+20110422-1 +libsofthsm-dev#1.3.3-2 +libsoil-dev#1.07~20080707.dfsg-2 +libsombok-dev#2.2.1-1 +libsonic-dev#0.1.17-1.1 +libsope-dev#1.3.16-1 +libsoprano-dev#2.7.6+dfsg.1-2wheezy1 +libsoqt4-dev#1.5.0-2 +libsord-dev#0.8.0~dfsg0-1 +libsoundgen-dev#0.6-4 +libsoundtouch-dev#1.6.0-3 +libsoundtouch-ocaml-dev#0.1.7-1+b1 +libsoup-gnome2.4-dev#2.38.1-3 +libsoup2.4-dev#2.38.1-3 +libsoupcutter-dev#1.1.7-1.2 +libsource-highlight-dev#3.1.6-1.1 +libsox-dev#14.4.0-3 +libsp-gxmlcpp-dev#1.0.20040603-5 +libsp1-dev#1.3.4-1.2.1-47.1+b1 +libspandsp-dev#0.0.6~pre20-3.1 +libsparsehash-dev#1.10-1 +libsparskit-dev#2.0.0-2 +libspatialindex-dev#1.7.0-1 +libspatialite-dev#3.0.0~beta20110817-3+deb7u1 +libspctag-dev#0.2-1 +libspectre-dev#0.2.7-2 +libspectrum-dev#1.0.0-3 +libspeechd-dev#0.7.1-6.2 +libspeex-dev#1.2~rc1-7 +libspeex-ocaml-dev#0.2.0-1+b3 +libspeexdsp-dev#1.2~rc1-7 +libspf2-dev#1.2.9-7 +libsphere-dev#3.2-4 +libspice-client-glib-2.0-dev#0.12-5 +libspice-client-gtk-2.0-dev#0.12-5 +libspice-client-gtk-3.0-dev#0.12-5 +libspice-protocol-dev#0.10.1-1 +libspice-server-dev#0.11.0-1+deb7u1 +libspiro-dev#20071029-2 +libspnav-dev#0.2.2-1 +libspooles-dev#2.2-9 +libsprng2-dev#2.0a-8 +libsqlexpr-ocaml-dev#0.4.1-1+b5 +libsqlheavy-dev#0.1.1-1 +libsqlheavygtk-dev#0.1.1-1 +libsqlite0-dev#2.8.17-7 +libsqlite3-dev#3.7.13-1+deb7u1 +libsqlite3-ocaml-dev#1.6.1-1+b1 +libsquizz-dev#0.99a-2 +libsratom-dev#0.2.0~dfsg0-1 +libsrecord-dev#1.58-1+b1 +libsrf-dev#0.1+dfsg-1 +libsrtp0-dev#1.4.4+20100615~dfsg-2+deb7u1 +libss7-dev#1.0.2-3 +libsscm-dev#0.8.5-2.1 +libssh-dev#0.5.4-1+deb7u1 +libssh2-1-dev#1.4.2-1.1 +libssl-dev#1.0.1e-2+deb7u7 +libssl-ocaml-dev#0.4.6-1 +libsslcommon2-dev#0.16-6+deb7u1 +libssreflect-ocaml-dev#1.3pl4-1 +libsss-sudo-dev#1.8.4-2 +libst-dev#1.9-3 +libstaden-read-dev#1.12.4-1 +libstarlink-ast-dev#7.0.4+dfsg-1 +libstarlink-pal-dev#0.1.0-1 +libstarpu-dev#1.0.1+dfsg-1 +libstartup-notification0-dev#0.12-1 +libstatgrab-dev#0.17-1 +libstdc++6-4.4-dev#4.4.7-2 +libstdc++6-4.6-dev#4.6.3-14 +libstdc++6-4.7-dev#4.7.2-5 +libstemmer-dev#0+svn546-2 +libsteptalk-dev#0.10.0-5+b1 +libstfl-dev#0.22-1+b1 +libstk0-dev#4.4.3-2 +libstlport4.6-dev#4.6.2-7 +libstonith1-dev#1.0.9+hg2665-1 +libstonithd1-dev#1.1.7-1 +libstreamanalyzer-dev#0.7.7-3 +libstreams-dev#0.7.7-3 +libstrigihtmlgui-dev#0.7.7-3 +libstrigiqtdbusclient-dev#0.7.7-3 +libstroke0-dev#0.5.1-6 +libstxxl-dev#1.3.1-4 +libsublime-dev#1.3.1-2 +libsubtitleeditor-dev#0.33.0-1 +libsubunit-dev#0.0.8+bzr176-1 +libsugarext-dev#0.96.1-2 +libsuil-dev#0.6.4~dfsg0-3 +libsuitesparse-dev#1:3.4.0-3 +libsundials-serial-dev#2.5.0-3 +libsunpinyin-dev#2.0.3+git20120607-1 +libsuperlu3-dev#3.0+20070106-3 +libsvga1-dev#1:1.4.3-33 +libsvm-dev#3.12-1 +libsvn-dev#1.6.17dfsg-4+deb7u6 +libsvncpp-dev#0.12.0dfsg-6 +libsvnqt-dev#1.5.5-4.1 +libsvrcore-dev#1:4.0.4-15 +libswami-dev#2.0.0+svn389-2 +libswe-dev#1.77.00.0005-2 +libswiften-dev#2.0~beta1+dev47-1 +libsword-dev#1.6.2+dfsg-5 +libswscale-dev#6:0.8.10-1 +libsx-dev#2.05-3 +libsyfi1.0-dev#1.0.0.dfsg-1 +libsylph-dev#1.1.0-8 +libsymmetrica-dev#2.0-1 +libsynce0-dev#0.15-1.1 +libsyncml-dev#0.5.4-2.1 +libsynfig-dev#0.63.05-1 +libsynopsis0.12-dev#0.12-8 +libsynthesis-dev#3.4.0.16.7-1 +libsysactivity-dev#0.6.4-1 +libsysfs-dev#2.1.0+repack-2 +libsyslog-ng-dev#3.3.5-4 +libsyslog-ocaml-dev#1.4-6+b2 +libsystemd-daemon-dev#44-11+deb7u4 +libsystemd-id128-dev#44-11+deb7u4 +libsystemd-journal-dev#44-11+deb7u4 +libsystemd-login-dev#44-11+deb7u4 +libt1-dev#5.1.2-3.6 +libtacacs+1-dev#4.0.4.19-11 +libtachyon-dev#0.99~b2+dfsg-0.4 +libtag-extras-dev#1.0.1-3 +libtag1-dev#1.7.2-1 +libtagc0-dev#1.7.2-1 +libtagcoll2-dev#2.0.13-1.1 +libtaglib-cil-dev#2.0.4.0-1 +libtaglib-ocaml-dev#0.2.0-1+b1 +libtaktuk-1-dev#3.7.4-1 +libtalloc-dev#2.0.7+git20120207-1 +libtamuanova-dev#0.2-2 +libtango7-dev#7.2.6+dfsg-14 +libtaningia-dev#0.2.2-1 +libtaoframework-devil-cil-dev#2.1.svn20090801-9 +libtaoframework-ffmpeg-cil-dev#2.1.svn20090801-9 +libtaoframework-freeglut-cil-dev#2.1.svn20090801-9 +libtaoframework-freetype-cil-dev#2.1.svn20090801-9 +libtaoframework-ftgl-cil-dev#2.1.svn20090801-9 +libtaoframework-lua-cil-dev#2.1.svn20090801-9 +libtaoframework-ode-cil-dev#2.1.svn20090801-9 +libtaoframework-openal-cil-dev#2.1.svn20090801-9 +libtaoframework-opengl-cil-dev#2.1.svn20090801-9 +libtaoframework-physfs-cil-dev#2.1.svn20090801-9 +libtaoframework-sdl-cil-dev#2.1.svn20090801-9 +libtar-dev#1.2.16-1+deb7u2 +libtarantool-dev#1.4.6+20120629+2158-1 +libtasn1-3-dev#2.13-2 +libtbb-dev#4.0+r233-1 +libtcc-dev#0.9.26~git20120612.ad5f375-6 +libtcd-dev#2.2.2-1 +libtclap-dev#1.2.1-1 +libtclcl1-dev#1.20-6 +libtdb-dev#1.2.10-2 +libtecla1-dev#1.6.1-5 +libteem-dev#1.11.0~svn5226-1 +libtelepathy-farstream-dev#0.4.0-3 +libtelepathy-glib-dev#0.18.2-2 +libtelepathy-logger-dev#0.4.0-1 +libtelepathy-logger-qt4-dev#0.4.0-1 +libtelepathy-qt4-dev#0.9.1-4 +libtelnet-dev#0.21-1 +libtemplates-parser11.6-dev#11.6-2 +libterralib-dev#4.0.0-4 +libtesseract-dev#3.02.01-6 +libtevent-dev#0.9.16-1 +libtext-ocaml-dev#0.5-1+b2 +libtextwrap-dev#0.1-13 +libthai-dev#0.1.18-2 +libtheora-dev#1.1.1+dfsg.1-3.1 +libtheora-ocaml-dev#0.3.0-1+b3 +libthepeg-dev#1.8.0-1 +libthrust-dev#1.6.0-1 +libthunar-vfs-1-dev#1.2.0-3+b1 +libthunarx-2-dev#1.2.3-4+b1 +libticables-dev#1.2.0-2 +libticalcs-dev#1.1.3+dfsg1-1 +libticonv-dev#1.1.0-1.1 +libtidy-dev#20091223cvs-1.2 +libtiff4-dev#3.9.6-11 +libtiff5-alt-dev#4.0.2-6+deb7u2 +libtiff5-dev#4.0.2-6+deb7u2 +libtifiles-dev#1.1.1-1 +libtimbl3-dev#6.4.2-1 +libtimblserver2-dev#1.4-2 +libtinfo-dev#5.9-10 +libtinyxml-dev#2.6.2-1 +libtinyxml2-dev#0~git20120518.1.a2ae54e-1 +libtirpc-dev#0.2.2-5 +libtk-img-dev#1:1.3-release-12 +libtnt-dev#1.2.6-1 +libtntdb-dev#1.2-2+b1 +libtntnet-dev#2.1-2+deb7u1 +libtododb-dev#0.11-3 +libtogl-dev#1.7-12 +libtokyocabinet-dev#1.4.47-2 +libtokyotyrant-dev#1.1.40-4.1+b1 +libtolua++5.1-dev#1.0.93-3 +libtolua-dev#5.2.0-1 +libtomcrypt-dev#1.17-3.2 +libtommath-dev#0.42.0-1 +libtomoe-dev#0.6.0-1.3 +libtonezone-dev#1:2.5.0.1-2 +libtophide-ocaml-dev#1.0.0-3 +libtorch3-dev#3.1-2.1 +libtorque2-dev#2.4.16+dfsg-1+deb7u2 +libtorrent-dev#0.13.2-1 +libtorrent-rasterbar-dev#0.15.10-1+b1 +libtorture-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libtotem-dev#3.0.1-8 +libtotem-pg-dev#1.4.2-3 +libtotem-plparser-dev#3.4.2-1 +libtowitoko-dev#2.0.7-8.3 +libtpl-dev#1.5-2 +libtpm-unseal-dev#1.3.7-1 +libtrace3-dev#3.0.14-1 +libtracker-extract-0.14-dev#0.14.1-3 +libtracker-miner-0.14-dev#0.14.1-3 +libtracker-sparql-0.14-dev#0.14.1-3 +libtransitioner1-dev#1.1.7-1 +libtre-dev#0.8.0-3 +libtreil-dev#1.8-1.1 +libts-dev#1.0-11 +libtse3-dev#0.3.1-4.3 +libtsk-dev#3.2.3-2 +libtspi-dev#0.3.9-3+wheezy1 +libtulip-dev#3.7.0dfsg-4 +libtumbler-1-dev#0.1.25-1+b1 +libtut-dev#0.0.20070706-1 +libtuxcap-dev#1.4.0.dfsg2-2.1 +libtwin-dev#12.04.13.17.57-g130ee5f-2 +libtwofish-dev#0.3-3 +libtwolame-dev#0.3.13-1 +libtxc-dxtn-s2tc-dev#0~git20110809-3 +libtype-conv-camlp4-dev#3.0.4-1 +libtyxml-ocaml-dev#2.1-1 +libuchardet-dev#0.0.1-1 +libucimf-dev#2.3.8-4 +libucl-dev#1.03-5 +libuclmmbase1-dev#1.2.16.0-1 +libucommon-dev#5.2.2-4 +libucto1-dev#0.5.2-2 +libudev-dev#175-7.2 +libudf-dev#0.83-4 +libudt-dev#4.10+dfsg-1 +libudunits2-dev#2.1.23-3 +libuhd-dev#3.4.2-1 +libuim-dev#1:1.8.1-4 +libumlib-dev#0.8.2-1 +libunac1-dev#1.8.0-6 +libunbound-dev#1.4.17-3 +libunicap2-dev#0.9.12-2 +libuninameslist-dev#0.0.20091231-1.1 +libuninum-dev#2.7-1.1 +libunique-3.0-dev#3.0.2-1 +libunique-dev#1.1.6-4 +libunistring-dev#0.9.3-5 +libunittest++-dev#1.4.0-3 +libunshield-dev#0.6-3 +libunwind-setjmp0-dev#0.99-0.3 +libunwind7-dev#0.99-0.3 +libupnp-dev#1:1.6.17-1.2 +libupnp4-dev#1.8.0~svn20100507-1.2 +libupnp6-dev#1:1.6.17-1.2 +libupower-glib-dev#0.9.17-1 +libupsclient1-dev#2.6.4-2.3+deb7u1 +libupse-dev#1.0.0-1 +libuptimed-dev#1:0.3.17-3.1 +liburcu-dev#0.6.7-2 +liburfkill-glib-dev#0.3.0-1 +liburg0-dev#0.8.12-4 +liburiparser-dev#0.7.5-1 +libusb++-dev#2:0.1.12-20+nmu1 +libusb-1.0-0-dev#2:1.0.11-1 +libusb-dev#2:0.1.12-20+nmu1 +libusb-ocaml-dev#1.2.0-2+b7 +libusbip-dev#1.1.1+3.2.17-1 +libusbmuxd-dev#1.0.7-2 +libusbprog-dev#0.2.0-2 +libusbredirhost-dev#0.4.3-2 +libusbredirparser-dev#0.4.3-2 +libusbtc08-dev#1.7.2-1 +libuser1-dev#1:0.56.9.dfsg.1-1.2 +libust-dev#2.0.4-1 +libustr-dev#1.0.4-3 +libutempter-dev#1.1.5-4 +libuu-dev#0.5.20-3.3 +libuuidm-ocaml-dev#0.9.4-1 +libv4l-dev#0.8.8-3 +libv8-dev#3.8.9.20-2 +libv8-i18n-dev#0~0.svn7-3 +libva-dev#1.0.15-4 +libvala-0.14-dev#0.14.2-2 +libvala-0.16-dev#0.16.1-2 +libvaladoc-dev#0.3.2~git20120227-1 +libvalhalla-dev#2.0.0-4+b1 +libvanessa-adt-dev#0.0.9-1 +libvanessa-logger-dev#0.0.10-1.1 +libvanessa-socket-dev#0.0.12-1 +libvarconf-dev#0.6.7-2 +libvarnishapi-dev#3.0.2-2+deb7u1 +libvbr-dev#2.6.8-4 +libvc-dev#003.dfsg.1-12 +libvcdinfo-dev#0.7.24+dfsg-0.1 +libvde-dev#2.3.2-4 +libvdeplug-dev#2.3.2-4 +libvdk2-dev#2.4.0-5.3 +libvdkbuilder2-dev#2.4.0-4.3 +libvdkxdb2-dev#2.4.0-3.4 +libvdpau-dev#0.4.1-7 +libventrilo-dev#1.2.4-1 +libverbiste-dev#0.1.34-1 +libverto-dev#0.2.2-1 +libvformat-dev#1.13-10 +libvia-dev#2.0.4-2 +libvibrant6-dev#6.1.20120620-2 +libview-dev#0.6.6-2.1 +libvigraimpex-dev#1.7.1+dfsg1-3 +libvips-dev#7.28.5-1+deb7u1 +libvirt-dev#0.9.12.3-1 +libvirt-glib-1.0-dev#0.0.8-1 +libvirt-ocaml-dev#0.6.1.2-1 +libvisca-dev#1.0.1-1 +libvisio-dev#0.0.17-1 +libvisual-0.4-dev#0.4.0-5 +libvlc-dev#2.0.3-5 +libvlccore-dev#2.0.3-5 +libvmmlib-dev#1.0-2 +libvncserver-dev#0.9.9+dfsg-1 +libvo-aacenc-dev#0.1.2-1 +libvo-amrwbenc-dev#0.1.2-1 +libvoaacenc-ocaml-dev#0.1.0-1+b1 +libvoikko-dev#3.5-1.1 +libvolpack1-dev#1.0b3-3 +libvorbis-dev#1.3.2-1.3 +libvorbis-ocaml-dev#0.6.1-1+b1 +libvorbisidec-dev#1.0.2+svn18153-0.2 +libvotequorum-dev#1.4.2-3 +libvpb-dev#4.2.55-1 +libvpx-dev#1.1.0-1 +libvrb0-dev#0.5.1-5.1 +libvte-2.90-dev#1:0.32.2-1 +libvte-dev#1:0.28.2-5 +libvte0.16-cil-dev#2.26.0-8 +libvtk5-dev#5.8.0-13+b1 +libvtk5-qt4-dev#5.8.0-13+b1 +libvtkedge-dev#0.2.0~20110819-2 +libvtkgdcm2-dev#2.2.0-14.1 +libvxl1-dev#1.14.0-18 +libwacom-dev#0.6-1 +libwaei-dev#3.4.3-1 +libwaili-dev#19990723-20 +libwavefront-standalone3.0-dev#3.0.2+dfsg-4+b1 +libwavpack-dev#4.60.1-3 +libwayland-dev#0.85.0-2 +libwbclient-dev#2:3.6.6-6+deb7u3 +libwbxml2-dev#0.10.7-1 +libwcstools-dev#3.8.5-1 +libwebauth-dev#4.1.1-2 +libwebcam0-dev#0.2.2-1 +libwebkit-cil-dev#0.3-6 +libwebkit-dev#1.8.1-3.4 +libwebkitgtk-3.0-dev#1.8.1-3.4 +libwebkitgtk-dev#1.8.1-3.4 +libwebp-dev#0.1.3-3+nmu1 +libwebrtc-audio-processing-dev#0.1-2 +libweed-dev#1.6.2~ds1-2 +libwfmath-0.3-dev#0.3.12-3 +libwfut-0.2-dev#0.2.1-2 +libwibble-dev#0.1.28-1.1 +libwildmidi-dev#0.2.3.4-2.1 +libwine-dev#1.4.1-4 +libwings-dev#0.95.3-2 +libwireshark-dev#1.8.2-5wheezy10 +libwiretap-dev#1.8.2-5wheezy10 +libwmf-dev#0.2.8.4-10.3 +libwnck-3-dev#3.4.2-1 +libwnck-dev#2.30.7-1 +libwnck1.0-cil-dev#2.26.0-8 +libwnn-dev#1.1.1~a021+cvs20100325-6 +libwnn6-dev#1.0.0-14.2+b1 +libwpd-dev#0.9.4-3 +libwpg-dev#0.2.1-1 +libwps-dev#0.2.7-1 +libwrap0-dev#7.6.q-24 +libwraster3-dev#0.95.3-2 +libwreport-dev#2.4-1 +libwsutil-dev#1.8.2-5wheezy10 +libwt-dev#3.2.1-2 +libwtdbo-dev#3.2.1-2 +libwtdbofirebird-dev#3.2.1-2 +libwtdbopostgres-dev#3.2.1-2 +libwtdbosqlite-dev#3.2.1-2 +libwtext-dev#3.2.1-2 +libwtfcgi-dev#3.2.1-2 +libwthttp-dev#3.2.1-2 +libwttest-dev#3.2.1-2 +libwv-dev#1.2.9-3 +libwv2-dev#0.4.2.dfsg.2-1~deb7u1 +libwvstreams-dev#4.6.1-5 +libwxbase2.8-dev#2.8.12.1-12 +libwxgtk2.8-dev#2.8.12.1-12 +libwxsmithlib-dev#10.05-2.1 +libwxsmithlib0-dev#10.05-2.1 +libwxsqlite3-2.8-dev#3.0.0.1~dfsg0-2 +libwxsvg-dev#2:1.1.8~dfsg0-2 +libx11-dev#2:1.5.0-1+deb7u1 +libx11-xcb-dev#2:1.5.0-1+deb7u1 +libx264-dev#2:0.123.2189+git35cf912-1 +libx52pro-dev#0.1.1-2.1 +libx86-dev#1.1+ds1-10 +libxalan110-dev#1.10-6 +libxapian-dev#1.2.12-2 +libxatracker-dev#8.0.5-4+deb7u2 +libxau-dev#1:1.0.7-1 +libxaw7-dev#2:1.0.10-2 +libxbae-dev#4.60.4-3 +libxbase2.0-dev#2.0.0-8.5 +libxcb-composite0-dev#1.8.1-2+deb7u1 +libxcb-damage0-dev#1.8.1-2+deb7u1 +libxcb-dpms0-dev#1.8.1-2+deb7u1 +libxcb-dri2-0-dev#1.8.1-2+deb7u1 +libxcb-ewmh-dev#0.3.9-2 +libxcb-glx0-dev#1.8.1-2+deb7u1 +libxcb-icccm4-dev#0.3.9-2 +libxcb-image0-dev#0.3.9-1 +libxcb-keysyms1-dev#0.3.9-1 +libxcb-randr0-dev#1.8.1-2+deb7u1 +libxcb-record0-dev#1.8.1-2+deb7u1 +libxcb-render-util0-dev#0.3.8-1.1 +libxcb-render0-dev#1.8.1-2+deb7u1 +libxcb-res0-dev#1.8.1-2+deb7u1 +libxcb-screensaver0-dev#1.8.1-2+deb7u1 +libxcb-shape0-dev#1.8.1-2+deb7u1 +libxcb-shm0-dev#1.8.1-2+deb7u1 +libxcb-sync0-dev#1.8.1-2+deb7u1 +libxcb-util0-dev#0.3.8-2 +libxcb-xevie0-dev#1.8.1-2+deb7u1 +libxcb-xf86dri0-dev#1.8.1-2+deb7u1 +libxcb-xfixes0-dev#1.8.1-2+deb7u1 +libxcb-xinerama0-dev#1.8.1-2+deb7u1 +libxcb-xprint0-dev#1.8.1-2+deb7u1 +libxcb-xtest0-dev#1.8.1-2+deb7u1 +libxcb-xv0-dev#1.8.1-2+deb7u1 +libxcb-xvmc0-dev#1.8.1-2+deb7u1 +libxcb1-dev#1.8.1-2+deb7u1 +libxcomp-dev#3.5.0.12-1+b1 +libxcomposite-dev#1:0.4.3-2 +libxcp-ocaml-dev#0.5.2-3+b1 +libxcrypt-dev#1:2.4-3 +libxcursor-dev#1:1.1.13-1+deb7u1 +libxdamage-dev#1:1.1.3-2 +libxdb-dev#1.2.0-7.2 +libxdelta2-dev#1.1.3-9 +libxdffileio-dev#0.3-1 +libxdg-basedir-dev#1.1.1-2 +libxdmcp-dev#1:1.1.1-1 +libxdmf-dev#2.1.dfsg.1-5 +libxdo-dev#1:2.20100701.2961-3+deb7u3 +libxen-dev#4.1.4-3+deb7u1 +libxen-ocaml-dev#4.1.4-3+deb7u1 +libxenapi-ocaml-dev#1.3.2-15 +libxenomai-dev#2.6.0-2 +libxerces-c-dev#3.1.1-3 +libxerces-c2-dev#2.8.0+deb1-3 +libxext-dev#2:1.3.1-2+deb7u1 +libxfce4menu-0.1-dev#4.6.2-1 +libxfce4ui-1-dev#4.8.1-1 +libxfce4util-dev#4.8.2-1 +libxfcegui4-dev#4.8.1-5 +libxfconf-0-dev#4.8.1-1 +libxfixes-dev#1:5.0-4+deb7u1 +libxfont-dev#1:1.4.5-3 +libxft-dev#2.3.1-1 +libxi-dev#2:1.6.1-1+deb7u1 +libxine-dev#1.1.21-1+deb7u1 +libxine2-dev#1.2.2-5 +libxinerama-dev#2:1.1.2-1+deb7u1 +libxkbfile-dev#1:1.0.8-1 +libxklavier-dev#5.2.1-1 +libxml++2.6-dev#2.34.2-1 +libxml-light-ocaml-dev#2.2-15 +libxml-security-c-dev#1.6.1-5+deb7u2 +libxml2-dev#2.8.0+dfsg1-7+nmu3 +libxmlada4.1-dev#4.1-2 +libxmlezout2-dev#1.06.1-5 +libxmlm-ocaml-dev#1.1.0-1 +libxmlplaylist-ocaml-dev#0.1.3-1+b2 +libxmlrpc-c++4-dev#1.16.33-3.2 +libxmlrpc-c3-dev#1.16.33-3.2 +libxmlrpc-core-c3-dev#1.16.33-3.2 +libxmlrpc-epi-dev#0.54.2-1 +libxmlrpc-light-ocaml-dev#0.6.1-3+b5 +libxmlsec1-dev#1.2.18-2 +libxmltok1-dev#1.2-3 +libxmltooling-dev#1.4.2-5 +libxmmsclient++-dev#0.8+dfsg-4 +libxmmsclient++-glib-dev#0.8+dfsg-4 +libxmmsclient-dev#0.8+dfsg-4 +libxmmsclient-glib-dev#0.8+dfsg-4 +libxmpi4-dev#2.2.3b8-13 +libxmu-dev#2:1.1.1-1 +libxmuu-dev#2:1.1.1-1 +libxnee-dev#3.13-1 +libxneur-dev#0.15.0-1.1 +libxosd-dev#2.2.14-2 +libxp-dev#1:1.0.1-2+deb7u1 +libxpa-dev#2.1.14-2 +libxplc0.3.13-dev#0.3.13-3 +libxpm-dev#1:3.5.10-1 +libxqdbm-dev#1.8.78-2 +libxqilla-dev#2.3.0-1 +libxr1-dev#1.0-2.1 +libxrandr-dev#2:1.3.2-2+deb7u1 +libxrender-dev#1:0.9.7-1+deb7u1 +libxres-dev#2:1.0.6-1+deb7u1 +libxsettings-client-dev#0.17-6 +libxsettings-dev#0.11-3 +libxslt1-dev#1.1.26-14.1 +libxss-dev#1:1.2.2-1 +libxstr-ocaml-dev#0.2.1-21+b3 +libxstrp4-camlp4-dev#1.8-3 +libxt-dev#1:1.1.3-1+deb7u1 +libxtst-dev#2:1.2.1-1+deb7u1 +libxv-dev#2:1.0.7-1+deb7u1 +libxvidcore-dev#2:1.3.2-9 +libxvmc-dev#2:1.0.7-1+deb7u2 +libxxf86dga-dev#2:1.1.3-2+deb7u1 +libxxf86vm-dev#1:1.1.2-1+deb7u1 +libxy-dev#0.8-1+b1 +libyahoo2-dev#1.0.1-1 +libyajl-dev#2.0.4-2 +libyaml-cpp-dev#0.3.0-1 +libyaml-dev#0.1.4-2+deb7u4 +libyaz4-dev#4.2.30-2 +libyelp-dev#3.4.2-1+b1 +libygl4-dev#4.2e-4 +libykclient-dev#2.6-1 +libykpers-1-dev#1.7.0-1 +libyojson-ocaml-dev#1.0.3-1 +libytnef0-dev#1.5-4 +libyubikey-dev#1.8-1 +libz80ex-dev#1.1.19-3 +libzarith-ocaml-dev#1.1-2 +libzbar-dev#0.10+doc-8 +libzbargtk-dev#0.10+doc-8 +libzbarqt-dev#0.10+doc-8 +libzeep-dev#2.9.0-2 +libzeitgeist-cil-dev#0.8.0.0-4 +libzeitgeist-dev#0.3.18-1 +libzen-dev#0.4.27-2 +libzephyr-dev#3.0.2-2 +libzerg0-dev#1.0.7-3 +libzeroc-ice34-dev#3.4.2-8.2 +libzinnia-dev#0.06-1+b1 +libzip-dev#0.10.1-1.1 +libzip-ocaml-dev#1.04-6+b3 +libzipios++-dev#0.1.5.9+cvs.2007.04.28-5.1 +libzita-alsa-pcmi-dev#0.2.0-1 +libzita-convolver-dev#3.1.0-2 +libzita-resampler-dev#1.1.0-3 +libzlcore-dev#0.12.10dfsg-8 +libzltext-dev#0.12.10dfsg-8 +libzmq-dev#2.2.0+dfsg-2 +libzn-poly-dev#0.8-1.1 +libzookeeper-mt-dev#3.3.5+dfsg1-2 +libzookeeper-st-dev#3.3.5+dfsg1-2 +libzorp-dev#3.9.5-4 +libzorpll-dev#3.9.1.3-1 +libzrtpcpp-dev#2.0.0-3 +libzthread-dev#2.3.2-7 +libzvbi-dev#0.2.33-6 +libzzip-dev#0.13.56-1.1 +licq-dev#1.6.1-3 +linux-libc-dev#3.2.57-3 +lldpad-dev#0.9.44-1 +llvm-2.9-dev#2.9+dfsg-7 +llvm-3.0-dev#3.0-10 +llvm-3.1-dev#3.1-1 +llvm-dev#1:3.0-14+nmu2 +lttv-dev#0.12.38-21032011-1+b1 +lua-apr-dev#0.23.2-1 +lua-bitop-dev#1.0.2-1 +lua-curl-dev#0.3.0-7 +lua-curses-dev#5.1.19-2 +lua-cyrussasl-dev#1.0.0-4 +lua-dbi-mysql-dev#0.5+svn78-4 +lua-dbi-postgresql-dev#0.5+svn78-4 +lua-dbi-sqlite3-dev#0.5+svn78-4 +lua-event-dev#0.4.1-2 +lua-expat-dev#1.2.0-5+deb7u1 +lua-filesystem-dev#1.5.0+16+g84f1af5-1 +lua-iconv-dev#7-1 +lua-ldap-dev#1.1.0-1-geeac494-3 +lua-leg-dev#0.1.2-8 +lua-lgi-dev#0.6.2-1 +lua-lpeg-dev#0.10.2-5 +lua-md5-dev#1.1.2-6 +lua-penlight-dev#1.0.2+htmldoc-2 +lua-posix-dev#5.1.19-2 +lua-rex-onig-dev#2.6.0-2 +lua-rex-pcre-dev#2.6.0-2 +lua-rex-posix-dev#2.6.0-2 +lua-rex-tre-dev#2.6.0-2 +lua-rings-dev#1.2.3-1 +lua-sec-dev#0.4.1-1 +lua-socket-dev#2.0.2-8 +lua-sql-mysql-dev#2.3.0-1+build0 +lua-sql-postgres-dev#2.3.0-1+build0 +lua-sql-sqlite3-dev#2.3.0-1+build0 +lua-svn-dev#0.4.0-7 +lua-wsapi-fcgi-dev#1.5-3 +lua-zip-dev#1.2.3-11 +lua-zlib-dev#0.2-1 +lua5.1-policy-dev#33 +lv2-dev#1.0.0~dfsg2-2 +lxc-dev#0.8.0~rc1-8+deb7u2 +lzma-dev#9.22-2 +manpages-de-dev#1.2-1 +manpages-dev#3.44-1 +manpages-fr-dev#3.44d1p1-1 +manpages-ja-dev#0.5.0.0.20120606-1 +manpages-pl-dev#1:0.3-1 +manpages-pt-dev#20040726-4 +matlab-support-dev#0.0.18 +mdbtools-dev#0.7-1+deb7u1 +med-bio-dev#1.13.2 +med-imaging-dev#1.13.2 +mesa-common-dev#8.0.5-4+deb7u2 +mffm-fftw-dev#1.7-3 +mffm-timecode-dev#1.6-2 +mingw-w64-dev#2.0.3-1 +mingw-w64-i686-dev#2.0.3-1 +mingw-w64-x86-64-dev#2.0.3-1 +minpack-dev#19961126+dfsg1-1 +mongodb-dev#1:2.0.6-1.1 +mpi-default-dev#1.0.1 +muroard-dev#0.1.10-2 +neko-dev#1.8.1-6 +nettle-dev#2.4-3 +network-manager-dev#0.9.4.0-10 +ntfs-3g-dev#1:2012.1.15AR.5-2.1 +ocfs2-tools-dev#1.6.4-1+deb7u1 +ocl-icd-dev#1.3-3 +ocl-icd-opencl-dev#1.3-3 +ocsigen-dev#1.3.4-2 +octave-pkg-dev#1.0.2 +ofono-dev#1.6-2 +okteta-dev#4:4.8.4+dfsg-1 +okular-dev#4:4.8.4-3 +open-vm-tools-dev#2:8.8.0+2012.05.21-724730-1+nmu2 +openais-dev#1.1.4-4.1 +openbox-dev#3.5.0-7 +openchangeserver-dev#1:1.0-3 +oss4-dev#4.2-build2006-2+deb7u1 +pacemaker-dev#1.1.7-1 +packaging-dev#0.4 +paraview-dev#3.14.1-6 +parole-dev#0.2.0.6-1+b1 +parser3-dev#3.4.2-2 +pbs-drmaa-dev#1.0.10-3 +petsc-dev#3.2.dfsg-6 +php5-dev#5.4.4-14+deb7u9 +pidgin-dev#2.10.9-1~deb7u1 +pinball-dev#0.3.1-13.1 +planetpenguin-racer-gimp-dev#0.4-5 +planner-dev#0.14.6-1 +plplot-tcl-dev#5.9.9-5 +plptools-dev#1.0.9-2.4 +plymouth-dev#0.8.5.1-5 +portaudio19-dev#19+svn20111121-1 +postfix-dev#2.9.6-2 +ppl-dev#0.11.2-8 +ppp-dev#2.4.5-5.1 +prayer-templates-dev#1.3.4-dfsg1-1 +proftpd-dev#1.3.4a-5+deb7u1 +pslib-dev#0.4.5-3 +publib-dev#0.40-1 +puredata-dev#0.43.2-5 +pvm-dev#3.4.5-12.5 +pxlib-dev#0.6.5-1 +python-all-dev#2.7.3-4+deb7u1 +python-apt-dev#0.8.8.2 +python-cairo-dev#1.8.8-1 +python-cxx-dev#6.2.4-3 +python-dbus-dev#1.1.1-1 +python-dev#2.7.3-4+deb7u1 +python-egenix-mx-base-dev#3.2.1-1.1 +python-gamera-dev#3.3.3-2 +python-gi-dev#3.2.2-2 +python-gnome2-desktop-dev#2.32.0+dfsg-2 +python-gnome2-dev#2.28.1+dfsg-1 +python-gnome2-extras-dev#2.25.3-12 +python-gobject-2-dev#2.28.6-10 +python-gobject-dev#3.2.2-2 +python-greenlet-dev#0.3.1-2.5 +python-gst0.10-dev#0.10.22-3 +python-gtk2-dev#2.24.0-3 +python-kde4-dev#4:4.8.4-1 +python-ldb-dev#1:1.1.6-1 +python-openturns-dev#1.0-4 +python-pyorbit-dev#2.24.0-6 +python-qt4-dev#4.9.3-4 +python-sip-dev#4.13.3-2 +python-talloc-dev#2.0.7+git20120207-1 +python-webkit-dev#1.1.8-2 +python2.6-dev#2.6.8-1.1 +python2.7-dev#2.7.3-6+deb7u2 +python3-all-dev#3.2.3-6 +python3-cairo-dev#1.10.0+dfsg-2 +python3-cxx-dev#6.2.4-3 +python3-dev#3.2.3-6 +python3-sip-dev#4.13.3-2 +python3.2-dev#3.2.3-7 +qmf-dev#1.0.7~2011w23.2-2.1 +qtmobility-dev#1.2.0-3 +r-base-dev#2.15.1-4 +regina-normal-dev#4.93-1 +resource-agents-dev#1:3.9.2-5+deb7u2 +rhythmbox-dev#2.97-2.1 +rivet-plugins-dev#1.8.0-1 +roarplaylistd-dev#0.1.1-2 +robot-player-dev#3.0.2+dfsg-4 +ruby-dev#1:1.9.3 +ruby-gnome2-dev#1.1.3-2+b1 +ruby1.8-dev#1.8.7.358-7.1+deb7u1 +ruby1.9.1-dev#1.9.3.194-8.1+deb7u2 +rygel-1.0-dev#0.14.3-2+deb7u1 +samba4-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +sbnc-php-dev#1.2-26 +science-astronomy-dev#1.0 +science-dataacquisition-dev#1.0 +science-engineering-dev#1.0 +science-highenergy-physics-dev#1.0 +science-mathematics-dev#1.0 +science-meteorology-dev#1.0 +science-nanoscale-physics-dev#1.0 +science-physics-dev#1.0 +scim-dev#1.4.13-5 +sciplot-dev#1.36-15 +selinux-policy-dev#2:2.20110726-12 +seqan-dev#1.3.1-1 +sfftw-dev#2.1.5-1 +skalibs-dev#0.47-1 +slurm-drmaa-dev#1.0.4-3 +slurm-llnl-basic-plugins-dev#2.3.4-2+b1 +snappea-dev#3.0d3-22 +spl-dev#1.0~pre6-3.1+b1 +sra-toolkit-libs-dev#2.1.7a-1 +ss-dev#2.0-1.42.5-1.1 +stx-btree-dev#0.8.6-1 +styx-dev#1.8.0-1.1 +supercollider-dev#1:3.4.5-1wheezy1 +svdrpservice-dev#0.0.4-14 +sweep-dev#0.9.3-6 +swish-e-dev#2.4.7-3 +syfi-dev#1.0.0.dfsg-1 +system-tools-backends-dev#2.10.2-1 +systemtap-sdt-dev#1.7-1+deb7u1 +tcl-dev#8.5.0-2.1 +tcl-memchan-dev#2.3-2 +tcl-trf-dev#2.1.4-dfsg1-1 +tcl8.4-dev#8.4.19-5 +tcl8.5-dev#8.5.11-2 +tclcl-dev#1.20-6 +tclx8.4-dev#8.4.0-3 +tclxml-dev#3.3~svn11-2 +tdom-dev#0.8.3~20080525-3+nmu2 +tesseract-ocr-dev#3.02.01-6 +tix-dev#8.4.3-4 +tk-dev#8.5.0-2.1 +tk8.4-dev#8.4.19-5 +tk8.5-dev#8.5.11-2 +tqsllib-dev#2.2-5 +trafficserver-dev#3.0.5-1 +tuxpaint-dev#1:0.9.21-1.1 +unagi-dev#0.3.3-2 +unixodbc-dev#2.2.14p2-5 +uthash-dev#1.9.5-1 +uuid-dev#2.20.1-5.3 +vdr-dev#1.7.28-1 +vflib3-dev#3.6.14.dfsg-3+b1 +voms-dev#2.0.8-1 +vstream-client-dev#1.2-6.1 +wcslib-dev#4.13.4-1 +weechat-dev#0.3.8-1+deb7u1 +wireshark-dev#1.8.2-5wheezy10 +witty-dev#3.2.1-2 +wordnet-dev#1:3.0-29 +wzdftpd-dev#0.8.3-6.2 +x11proto-bigreqs-dev#1:1.1.2-1 +x11proto-composite-dev#1:0.4.2-2 +x11proto-core-dev#7.0.23-1 +x11proto-damage-dev#1:1.2.1-2 +x11proto-dmx-dev#1:2.3.1-2 +x11proto-dri2-dev#2.6-2 +x11proto-fixes-dev#1:5.0-2 +x11proto-fonts-dev#2.1.2-1 +x11proto-gl-dev#1.4.15-1 +x11proto-input-dev#2.2-1 +x11proto-kb-dev#1.0.6-2 +x11proto-print-dev#1.0.5-2 +x11proto-randr-dev#1.3.2-2 +x11proto-record-dev#1.14.2-1 +x11proto-render-dev#2:0.11.1-2 +x11proto-resource-dev#1.2.0-3 +x11proto-scrnsaver-dev#1.2.2-1 +x11proto-video-dev#2.3.1-2 +x11proto-xcmisc-dev#1.2.2-1 +x11proto-xext-dev#7.2.1-1 +x11proto-xf86bigfont-dev#1.2.0-3 +x11proto-xf86dga-dev#2.1-3 +x11proto-xf86dri-dev#2.1.1-2 +x11proto-xf86vidmode-dev#2.3.1-2 +x11proto-xinerama-dev#1.2.1-2 +xaw3dg-dev#1.5+E-18.2 +xbmc-eventclients-dev#2:11.0~git20120510.82388d5-1 +xfce4-panel-dev#4.8.6-4 +xfslibs-dev#3.1.7+b1 +xmhtml1-dev#1.1.7-18 +xmms2-dev#0.8+dfsg-4 +xorg-dev#1:7.7+3~deb7u1 +xotcl-dev#1.6.7-2 +xpaint-dev#2.9.1.4-3+b2 +xserver-xorg-dev#2:1.12.4-6+deb7u2 +xserver-xorg-input-evdev-dev#1:2.7.0-1 +xserver-xorg-input-joystick-dev#1:1.6.1-1 +xserver-xorg-input-synaptics-dev#1.6.2-2 +xtrans-dev#1.2.7-1 +xulrunner-dev#24.4.0esr-1~deb7u2 +xutils-dev#1:7.7~1 +xviewg-dev#3.2p1.4-28.1 +yate-dev#4.1.0-1~dfsg-3 +yorick-dev#2.2.02+dfsg-6 +zathura-dev#0.1.2-4 +zlib1g-dev#1:1.2.7.dfsg-13 +znc-dev#0.206-2 +zsh-dev#4.3.17-1 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t04_mirror/ShowMirror1Test_gold b/src/github.com/smira/aptly/system/t04_mirror/ShowMirror1Test_gold index f2816c1a..0535ab41 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/ShowMirror1Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/ShowMirror1Test_gold @@ -11,10 +11,10 @@ Information from release file: Architectures: amd64 armel armhf i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390 s390x sparc Codename: wheezy Components: main contrib non-free -Date: Sat, 10 Jan 2015 11:18:41 UTC -Description: Debian 7.8 Released 10 January 2015 +Date: Sat, 05 Sep 2015 11:44:23 UTC +Description: Debian 7.9 Released 05 September 2015 Label: Debian Origin: Debian -Suite: stable -Version: 7.8 +Suite: oldstable +Version: 7.9 diff --git a/src/github.com/smira/aptly/system/t04_mirror/ShowMirror4Test_gold b/src/github.com/smira/aptly/system/t04_mirror/ShowMirror4Test_gold index 1412be26..3f3f5951 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/ShowMirror4Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/ShowMirror4Test_gold @@ -17,5 +17,5 @@ Description: Debian 7.0 Security Updates Label: Debian-Security Origin: Debian -Suite: stable +Suite: oldstable Version: 7.0 diff --git a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror10Test_gold b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror10Test_gold index e66164f5..e6c447ec 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror10Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror10Test_gold @@ -2,18 +2,18 @@ Applying filter... Building download queue... -Download queue: 2 items (17.38 KiB) +Download queue: 4 items (287.73 KiB) Downloading & parsing package files... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/InRelease... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.bz2... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.gz... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release.gpg... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Sources.bz2... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Sources.gz... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/amd64/libiniparser_3.1-1_amd64.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/i386/libiniparser_3.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/InRelease... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Packages.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release.gpg... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Sources.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/ferrisloki-dev_3.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/ferrisloki1_3.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/ferrisloki-dev_3.0.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/ferrisloki1_3.0.1-1_i386.deb... Mirror `flat-src` has been successfully updated. -Packages filtered: 5 -> 2. -gpgv: Good signature from "home:DeepDiver1975 OBS Project " -gpgv: Signature made Tue May 21 23:01:30 2013 MSK using DSA key ID 1048C1FF \ No newline at end of file +Packages filtered: 8 -> 4. +gpgv: Good signature from "home:monkeyiq OBS Project " +gpgv: DSA key ID DFFAFC43 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror11Test_gold b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror11Test_gold index a00804fe..8f7d11fa 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror11Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror11Test_gold @@ -14,8 +14,10 @@ Downloading ftp://ftp.ru.debian.org/debian/pool/main/s/sysvinit/sysv-rc_2.88dsf- Downloading ftp://ftp.ru.debian.org/debian/pool/main/s/sysvinit/sysvinit-utils_2.88dsf-41+deb7u1_i386.deb... Downloading ftp://ftp.ru.debian.org/debian/pool/main/s/sysvinit/sysvinit_2.88dsf-41+deb7u1_i386.deb... Mirror `wheezy-main` has been successfully updated. -Packages filtered: 36038 -> 5. +Packages filtered: 36033 -> 5. gpgv: Good signature from "Debian Archive Automatic Signing Key (7.0/wheezy) " +gpgv: Good signature from "Debian Archive Automatic Signing Key (8/jessie) " gpgv: Good signature from "Wheezy Stable Release Key " +gpgv: RSA key ID 2B90D010 gpgv: RSA key ID 46925553 gpgv: RSA key ID 65FFB764 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror1Test_gold b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror1Test_gold index fdb2cdcf..1f8901aa 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror1Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror1Test_gold @@ -1,7 +1,7 @@ Building download queue... -Download queue: 42 items (15.95 MiB) +Download queue: 52 items (19.79 MiB) Downloading & parsing package files... Downloading http://repo.varnish-cache.org/debian/dists/wheezy/Release... Downloading http://repo.varnish-cache.org/debian/dists/wheezy/varnish-3.0/binary-amd64/Packages.bz2... @@ -13,6 +13,7 @@ Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agen Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_2.2.1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_3.0.0~wheezy_amd64.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish-agent/varnish-agent_3.0.1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.3-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.3-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.4-1~wheezy_amd64.deb... @@ -21,6 +22,8 @@ Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libv Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.5-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.6-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.6-1~wheezy_i386.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.7-1~wheezy_amd64.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi-dev_3.0.7-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.3-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.3-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.4-1~wheezy_amd64.deb... @@ -29,6 +32,8 @@ Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libv Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.5-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.6-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.6-1~wheezy_i386.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.7-1~wheezy_amd64.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/libvarnishapi1_3.0.7-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.3-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.3-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.4-1~wheezy_amd64.deb... @@ -37,9 +42,12 @@ Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varn Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.5-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.6-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.6-1~wheezy_i386.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.7-1~wheezy_amd64.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-dbg_3.0.7-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-doc_3.0.4-1~wheezy_all.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-doc_3.0.5-1~wheezy_all.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-doc_3.0.6-1~wheezy_all.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish-doc_3.0.7-1~wheezy_all.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.3-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.3-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.4-1~wheezy_amd64.deb... @@ -48,4 +56,6 @@ Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varn Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.5-1~wheezy_i386.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.6-1~wheezy_amd64.deb... Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.6-1~wheezy_i386.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.7-1~wheezy_amd64.deb... +Downloading http://repo.varnish-cache.org/debian/pool/varnish-3.0/v/varnish/varnish_3.0.7-1~wheezy_i386.deb... Mirror `varnish` has been successfully updated. \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror3Test_gold b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror3Test_gold index 87b1b576..4934fde1 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror3Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror3Test_gold @@ -1,6 +1,4 @@ Downloading ${url}dists/hardy/Release... Downloading & parsing package files... -Downloading ${url}dists/hardy/main/binary-amd64/Packages.bz2... -Downloading ${url}dists/hardy/main/binary-amd64/Packages.gz... Downloading ${url}dists/hardy/main/binary-amd64/Packages... ERROR: unable to update: ${url}dists/hardy/main/binary-amd64/Packages: sha256 hash mismatch "494414ded24da13c451b13b424928821351c78fce49f93d9e1b55f102790c206" != "8a21688ae769f2b4ffcaa366409f679d" diff --git a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror5Test_gold b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror5Test_gold index cfa2c961..60eb401a 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror5Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror5Test_gold @@ -1,7 +1,5 @@ Downloading ${url}dists/hardy/Release... Downloading & parsing package files... -Downloading ${url}dists/hardy/main/binary-amd64/Packages.bz2... -Downloading ${url}dists/hardy/main/binary-amd64/Packages.gz... Downloading ${url}dists/hardy/main/binary-amd64/Packages... Building download queue... Download queue: 1 items (30 B) diff --git a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror7Test_gold b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror7Test_gold index 21905956..ba73e87e 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror7Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror7Test_gold @@ -1,17 +1,18 @@ Building download queue... -Download queue: 4 items (58.20 KiB) +Download queue: 6 items (292.29 KiB) Downloading & parsing package files... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/InRelease... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.bz2... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.gz... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release.gpg... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/amd64/libiniparser-dev_3.1-1_amd64.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/amd64/libiniparser_3.1-1_amd64.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/i386/libiniparser-dev_3.1-1_i386.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/i386/libiniparser_3.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/InRelease... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Packages.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release.gpg... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/ferrisloki-dev_3.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/ferrisloki1_3.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/libferris-suite_0.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/ferrisloki-dev_3.0.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/ferrisloki1_3.0.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/libferris-suite_0.0.1-1_i386.deb... Mirror `flat` has been successfully updated. -gpgv: Good signature from "home:DeepDiver1975 OBS Project " -gpgv: Signature made Tue May 21 23:01:30 2013 MSK using DSA key ID 1048C1FF \ No newline at end of file +gpgv: Good signature from "home:monkeyiq OBS Project " +gpgv: DSA key ID DFFAFC43 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror9Test_gold b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror9Test_gold index 626ff9e5..1567852a 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror9Test_gold +++ b/src/github.com/smira/aptly/system/t04_mirror/UpdateMirror9Test_gold @@ -1,22 +1,25 @@ Building download queue... -Download queue: 7 items (97.48 KiB) +Download queue: 12 items (0.73 MiB) Downloading & parsing package files... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/InRelease... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.bz2... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Packages.gz... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Release.gpg... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Sources.bz2... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/Sources.gz... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/amd64/libiniparser-dev_3.1-1_amd64.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/amd64/libiniparser_3.1-1_amd64.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/i386/libiniparser-dev_3.1-1_i386.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/i386/libiniparser_3.1-1_i386.deb... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/libiniparser_3.1-1.diff.gz... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/libiniparser_3.1-1.dsc... -Downloading http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/libiniparser_3.1.orig.tar.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/InRelease... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Packages.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Release.gpg... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/Sources.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/ferrisloki-dev_3.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/ferrisloki1_3.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/amd64/libferris-suite_0.0.1-1_amd64.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ferrisloki_3.0.1-1.diff.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ferrisloki_3.0.1-1.dsc... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ferrisloki_3.0.1.orig.tar.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/ferrisloki-dev_3.0.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/ferrisloki1_3.0.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/i386/libferris-suite_0.0.1-1_i386.deb... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/libferris-suite_0.0.1-1.diff.gz... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/libferris-suite_0.0.1-1.dsc... +Downloading http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/libferris-suite_0.0.1.orig.tar.gz... Mirror `flat-src` has been successfully updated. -gpgv: Good signature from "home:DeepDiver1975 OBS Project " -gpgv: DSA key ID 1048C1FF \ No newline at end of file +gpgv: Good signature from "home:monkeyiq OBS Project " +gpgv: DSA key ID DFFAFC43 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t04_mirror/create.py b/src/github.com/smira/aptly/system/t04_mirror/create.py index 77986642..57b6f29f 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/create.py +++ b/src/github.com/smira/aptly/system/t04_mirror/create.py @@ -153,7 +153,7 @@ class CreateMirror14Test(BaseTest): """ create mirror: flat repository """ - runCmd = "aptly mirror create -keyring=aptlytest.gpg mirror14 http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./" + runCmd = "aptly mirror create -keyring=aptlytest.gpg mirror14 http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ ./" fixtureGpg = True outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s) @@ -166,7 +166,7 @@ class CreateMirror15Test(BaseTest): """ create mirror: flat repository + components """ - runCmd = "aptly mirror create -keyring=aptlytest.gpg mirror14 http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./ main" + runCmd = "aptly mirror create -keyring=aptlytest.gpg mirror14 http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ ./ main" expectedCode = 1 @@ -231,6 +231,7 @@ class CreateMirror20Test(BaseTest): create mirror: using failing HTTP_PROXY """ fixtureGpg = True + outputMatchPrepare = lambda _, s: s.replace('getsockopt: ', '') runCmd = "aptly -architectures='i386' mirror create -keyring=aptlytest.gpg -with-sources mirror20 http://security.debian.org/ wheezy/updates main" environmentOverride = {"HTTP_PROXY": "127.0.0.1:3137"} diff --git a/src/github.com/smira/aptly/system/t04_mirror/list.py b/src/github.com/smira/aptly/system/t04_mirror/list.py index f97759f3..7dd253e2 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/list.py +++ b/src/github.com/smira/aptly/system/t04_mirror/list.py @@ -9,7 +9,7 @@ class ListMirror1Test(BaseTest): "aptly mirror create --ignore-signatures mirror1 http://mirror.yandex.ru/debian/ wheezy", "aptly mirror create -with-sources --ignore-signatures mirror2 http://mirror.yandex.ru/debian/ squeeze contrib", "aptly -architectures=i386 mirror create --ignore-signatures mirror3 http://mirror.yandex.ru/debian/ squeeze non-free", - "aptly mirror create -ignore-signatures mirror4 http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./", + "aptly mirror create -ignore-signatures mirror4 http://download.opensuse.org/repositories/Apache:/MirrorBrain/Debian_7.0/ ./", ] runCmd = "aptly mirror list" diff --git a/src/github.com/smira/aptly/system/t04_mirror/search.py b/src/github.com/smira/aptly/system/t04_mirror/search.py index a887fe29..c18653b9 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/search.py +++ b/src/github.com/smira/aptly/system/t04_mirror/search.py @@ -34,3 +34,12 @@ class SearchMirror4Test(BaseTest): fixtureDB = True outputMatchPrepare = lambda _, s: "\n".join(sorted(s.split("\n"))) runCmd = "aptly mirror search -with-deps wheezy-main 'Name (nginx)'" + + +class SearchMirror5Test(BaseTest): + """ + search mirror: regular search + """ + fixtureDB = True + outputMatchPrepare = lambda _, s: "\n".join(sorted(s.split("\n"))) + runCmd = "aptly mirror search -format='{{.Package}}#{{.Version}}' wheezy-main '$$Architecture (i386), Name (% *-dev)'" diff --git a/src/github.com/smira/aptly/system/t04_mirror/update.py b/src/github.com/smira/aptly/system/t04_mirror/update.py index 5a57aded..0e5d6b2e 100644 --- a/src/github.com/smira/aptly/system/t04_mirror/update.py +++ b/src/github.com/smira/aptly/system/t04_mirror/update.py @@ -90,7 +90,7 @@ class UpdateMirror7Test(BaseTest): """ fixtureGpg = True fixtureCmds = [ - "aptly mirror create --keyring=aptlytest.gpg flat http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./", + "aptly mirror create --keyring=aptlytest.gpg flat http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ ./", ] runCmd = "aptly mirror update --keyring=aptlytest.gpg flat" outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s) @@ -118,7 +118,7 @@ class UpdateMirror9Test(BaseTest): """ fixtureGpg = True fixtureCmds = [ - "aptly mirror create --keyring=aptlytest.gpg -with-sources flat-src http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./", + "aptly mirror create --keyring=aptlytest.gpg -with-sources flat-src http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ ./", ] runCmd = "aptly mirror update --keyring=aptlytest.gpg flat-src" outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s) @@ -133,7 +133,7 @@ class UpdateMirror10Test(BaseTest): """ fixtureGpg = True fixtureCmds = [ - "aptly mirror create -keyring=aptlytest.gpg -with-sources -filter='!(Name (% *-dev)), !($$PackageType (source))' flat-src http://download.opensuse.org/repositories/home:/DeepDiver1975/xUbuntu_10.04/ ./", + "aptly mirror create -keyring=aptlytest.gpg -with-sources -filter='!(Name (% libferris*)), !($$PackageType (source))' flat-src http://download.opensuse.org/repositories/home:/monkeyiq/Debian_7.0/ ./", ] runCmd = "aptly mirror update --keyring=aptlytest.gpg flat-src" outputMatchPrepare = lambda _, s: re.sub(r'Signature made .* using', '', s) diff --git a/src/github.com/smira/aptly/system/t05_snapshot/SearchSnapshot6Test_gold b/src/github.com/smira/aptly/system/t05_snapshot/SearchSnapshot6Test_gold new file mode 100644 index 00000000..b5a49d54 --- /dev/null +++ b/src/github.com/smira/aptly/system/t05_snapshot/SearchSnapshot6Test_gold @@ -0,0 +1,4043 @@ + +aolserver4-dev#4.5.1-15.1 +apache2-prefork-dev#2.2.22-13+deb7u1 +apache2-threaded-dev#2.2.22-13+deb7u1 +apcalc-dev#2.12.4.4-3 +aplus-fsf-dev#4.22.1-6 +aroarfw-dev#0.1~beta4-5 +asterisk-dev#1:1.8.13.1~dfsg1-3+deb7u3 +atfs-dev#1.4pl6-11 +audacious-dev#3.2.4-1 +autotools-dev#20120608.1 +binutils-dev#2.22-8 +biosquid-dev#1.9g+cvs20050121-2 +bitlbee-dev#3.0.5-1.2 +blacs-pvm-dev#1.1-21 +blends-dev#0.6.16.2 +blktap-dev#2.0.90-1 +blt-dev#2.4z-4.2 +boinc-dev#7.0.27+dfsg-5 +boolstuff-dev#0.1.12-3 +cairo-dock-dev#3.0.0-2+deb7u1 +cernlib-base-dev#20061220+dfsg3-2 +cernlib-core-dev#20061220+dfsg3-2 +chipmunk-dev#5.3.4-1 +cimg-dev#1.4.9-2 +clearsilver-dev#0.10.5-1.3 +cli-common-dev#0.8.2 +clinica-dev#0.2.1~dfsg-1 +clisp-dev#1:2.49-8.1 +cluster-glue-dev#1.0.9+hg2665-1 +codeblocks-dev#10.05-2.1 +coinor-libcbc-dev#2.5.0-3 +coinor-libcgl-dev#0.55.0-1.1 +coinor-libclp-dev#1.12.0-2.1 +coinor-libcoinutils-dev#2.6.4-3 +coinor-libdylp-dev#1.6.0-1.1 +coinor-libflopc++-dev#1.0.6-3.1 +coinor-libipopt-dev#3.10.2-1.1 +coinor-libosi-dev#0.103.0-1 +coinor-libsymphony-dev#5.2.4-1.2 +coinor-libvol-dev#1.1.7-1 +collectd-dev#5.1.0-3 +comerr-dev#2.1-1.42.5-1.1 +condor-dev#7.8.2~dfsg.1-1+deb7u1 +config-package-dev#4.13 +connman-dev#1.0-1.1+wheezy1+b1 +console-tools-dev#1:0.2.3dbs-70 +coop-computing-tools-dev#3.5.1-2 +corosync-dev#1.4.2-3 +courier-authlib-dev#0.63.0-6+b1 +crtmpserver-dev#1.0~dfsg-3 +ctapi-dev#1.1 +ctn-dev#3.0.6-13+b2 +cyrus-dev#2.4.16-4+deb7u1 +dcap-dev#2.47.6-2 +dico-dev#2.1-3+b2 +dictionaries-common-dev#1.12.11 +dietlibc-dev#0.33~cvs20120325-4 +dolfin-dev#1.0.0-7 +dovecot-dev#1:2.1.7-7 +dpkg-dev#1.16.12 +drac-dev#1.12-7.2 +drizzle-plugin-dev#1:7.1.36-stable-1 +dssi-dev#1.1.1~dfsg0-1 +e2fslibs-dev#1.42.5-1.1 +emerillon-dev#0.1.90-1 +eog-dev#3.4.2-1+build1 +epiphany-browser-dev#3.4.2-2.1 +erlang-dev#1:15.b.1-dfsg-4+deb7u1 +erlang-esdl-dev#1.2-2 +etl-dev#0.04.15-1 +evolution-data-server-dev#3.4.4-3 +evolution-dev#3.4.4-3 +exim4-dev#4.80-7 +expect-dev#5.45-2 +expeyes-firmware-dev#2.0.0-3 +extremetuxracer-gimp-dev#0.4-5 +falconpl-dev#0.9.6.9-git20120606-2 +fatrat-dev#1.1.3-5 +fcitx-libs-dev#1:4.2.4.1-7 +fenix-dev#0.92a.dfsg1-9 +festival-dev#1:2.1~release-5.1 +fftw-dev#2.1.5-1 +finch-dev#2.10.9-1~deb7u1 +firebird-dev#2.5.2.26540.ds4-1~deb7u1 +flite1-dev#1.4-release-6 +flow-tools-dev#1:0.68-12.1+b1 +fosfat-dev#0.4.0-3 +freeglut3-dev#2.6.0-4 +freetds-dev#0.91-2+deb7u1 +frei0r-plugins-dev#1.1.22git20091109-1.2 +ftgl-dev#2.1.3~rc5-4 +ftplib-dev#3.1-1-9 +gambas3-dev#3.1.1-2+b1 +gap-dev#4r4p12-2 +gauche-dev#0.9.1-5.1 +gcc-4.6-plugin-dev#4.6.3-14 +gcc-4.7-plugin-dev#4.7.2-5 +gcin-dev#2.7.6.1+dfsg-1 +gedit-dev#3.4.2-1 +gem-dev#1:0.93.3-5 +genius-dev#1.0.14-1 +gfxboot-dev#4.5.0-3 +giblib-dev#1.2.4-8 +glabels-dev#3.0.0-3+b1 +glee-dev#5.4.0-1 +gmpc-dev#11.8.16-6 +gnash-dev#0.8.11~git20120629-1+deb7u1 +gnome-control-center-dev#1:3.4.3.1-2 +gnome-settings-daemon-dev#3.4.2+git20121218.7c1322-3+deb7u3 +gnome-video-effects-dev#0.4.0-1 +gnumach-dev#2:1.3.99.dfsg.git20120610-1 +gnunet-dev#0.9.3-7 +gnunet-gtk-dev#0.9.3-1 +gnuradio-dev#3.5.3.2-1 +gosa-dev#2.7.4-4.3~deb7u1 +gpe-ownerinfo-dev#0.28-3 +gpsim-dev#0.26.1-2.1 +graphviz-dev#2.26.3-14+deb7u1 +grass-dev#6.4.2-2 +gridengine-drmaa-dev#6.2u5-7.1 +gromacs-dev#4.5.5-2 +gsettings-desktop-schemas-dev#3.4.2-3 +gthumb-dev#3:3.0.1-2 +guile-1.6-dev#1.6.8-10.3 +guile-1.8-dev#1.8.8+1-8 +guile-2.0-dev#2.0.5+1-3 +guile-cairo-dev#1.4.0-3 +heartbeat-dev#1:3.0.5-3 +heimdal-dev#1.6~git20120403+dfsg1-2 +hime-dev#0.9.9+git20120619+dfsg-1 +hybrid-dev#1:7.2.2.dfsg.2-10 +icedove-dev#10.0.12-1 +inn2-dev#2.5.3-3 +inventor-dev#2.1.5-10-16 +iproute-dev#20120521-3+b3 +iptables-dev#1.4.14-3.1 +irssi-dev#0.8.15-5 +isc-dhcp-dev#4.2.2.dfsg.1-5+deb70u6 +itcl3-dev#3.4.1-1 +itk3-dev#3.3-4 +ivtools-dev#1.2.10a1-1 +kadu-dev#0.11.2-1 +kannel-dev#1.4.3-2+b2 +kde-workspace-dev#4:4.8.4-6 +kdebase-workspace-dev#4:4.8.4-6 +kdelibs5-dev#4:4.8.4-4 +kdemultimedia-dev#4:4.8.4-2 +kdepimlibs5-dev#4:4.8.4-2 +kdevelop-dev#4:4.3.1-3+b1 +kdevplatform-dev#1.3.1-2 +kmymoney-dev#4.6.2-3.2 +konwert-dev#1.8-11.2 +lam4-dev#7.1.4-3 +lesstif2-dev#1:0.95.2-1.1 +lib3ds-dev#1.3.0-6 +lib4store-dev#1.1.4-2 +lib64bz2-dev#1.0.6-4 +lib64expat1-dev#2.1.0-1+deb7u1 +lib64ffi-dev#3.0.10-3 +lib64ncurses5-dev#5.9-10 +lib64readline-gplv2-dev#5.2+dfsg-2~deb7u1 +lib64readline6-dev#6.2+dfsg-0.1 +lib64z1-dev#1:1.2.7.dfsg-13 +liba52-0.7.4-dev#0.7.4-16 +libaa1-dev#1.4p5-40 +libaac-tactics-ocaml-dev#0.2.pl2-7 +libaacs-dev#0.4.0-1 +libaal-dev#1.0.5-5.1 +libabiword-2.9-dev#2.9.2+svn20120603-8 +libaccountsservice-dev#0.6.21-8 +libace-dev#6.0.3+dfsg-0.1 +libace-flreactor-dev#6.0.3+dfsg-0.1 +libace-foxreactor-dev#6.0.3+dfsg-0.1 +libace-htbp-dev#6.0.3+dfsg-0.1 +libace-inet-dev#6.0.3+dfsg-0.1 +libace-inet-ssl-dev#6.0.3+dfsg-0.1 +libace-qtreactor-dev#6.0.3+dfsg-0.1 +libace-rmcast-dev#6.0.3+dfsg-0.1 +libace-ssl-dev#6.0.3+dfsg-0.1 +libace-tkreactor-dev#6.0.3+dfsg-0.1 +libace-tmcast-dev#6.0.3+dfsg-0.1 +libace-xtreactor-dev#6.0.3+dfsg-0.1 +libacexml-dev#6.0.3+dfsg-0.1 +libacl1-dev#2.2.51-8 +libacpi-dev#0.2-4 +libacr38ucontrol-dev#1.7.11-1 +libadasockets4-dev#1.8.10-2 +libaddresses-dev#0.4.7-1+b5 +libaddressview-dev#0.4.7-1+b5 +libadios-dev#1.3-11 +libadminutil-dev#1.1.15-1 +libadns1-dev#1.4-2 +libadolc-dev#2.3.0-1 +libadplug-dev#2.2.1+dfsg3-0.1 +libafflib-dev#3.6.6-1.1+b1 +libafrodite-0.12-dev#0.12.1-3 +libafterimage-dev#2.2.11-7 +libagg-dev#2.5+dfsg1-8 +libagrep-ocaml-dev#1.0-11+b3 +libahven3-dev#2.1-4 +libaiksaurus-1.2-dev#1.2.1+dev-0.12-6.1 +libaiksaurusgtk-1.2-dev#1.2.1+dev-0.12-6.1 +libaio-dev#0.3.109-3 +libakonadi-dev#1.7.2-3 +libalberta2-dev#2.0.1-5 +libaldmb1-dev#1:0.9.3-5.4 +libalglib-dev#2.6.0-6 +libalkimia-dev#4.3.2-1.1 +liballeggl4-dev#2:4.4.2-2.1 +liballegro4.2-dev#2:4.4.2-2.1 +libalog0.4.1-base-dev#0.4.1-2 +libalog0.4.1-full-dev#0.4.1-2 +libalsa-ocaml-dev#0.2.1-1+b1 +libalsaplayer-dev#0.99.80-5.1 +libalure-dev#1.2-6 +libalut-dev#1.1.0-3 +libampsharp-cil-dev#2.0.4-2 +libamu-dev#6.2+rc20110530-3 +libanalitza-dev#4:4.8.4-2 +libanet0.1-dev#0.1-3 +libanjuta-dev#2:3.4.3-1 +libann-dev#1.1.2+doc-3 +libanthy-dev#9100h-16 +libantlr-dev#2.7.7+dfsg-4 +libantlr3c-dev#3.2-2 +libao-dev#1.1.0-2 +libao-ocaml-dev#0.2.0-1+b2 +libaosd-dev#0.2.7-1 +libapache2-mod-perl2-dev#2.0.7-3 +libapertium3-3.1-0-dev#3.1.0-2 +libapm-dev#3.2.2-14 +libapol-dev#3.3.7-3 +libapparmor-dev#2.7.103-4 +libappindicator-dev#0.4.92-2 +libappindicator0.1-cil-dev#0.4.92-2 +libappindicator3-dev#0.4.92-2 +libapq-postgresql3.2.0-dev#3.2.0-2 +libapq3.2.0-dev#3.2.0-1 +libapr-memcache-dev#0.7.0-1 +libapr1-dev#1.4.6-3+deb7u1 +libapreq2-dev#2.13-1+b2 +libapron-dev#0.9.10-5.2 +libapron-ocaml-dev#0.9.10-5.2+b3 +libaprutil1-dev#1.4.1-3 +libapt-pkg-dev#0.9.7.9+deb7u1 +libaqbanking34-dev#5.0.24-3 +libaqsis-dev#1.8.1-3 +libarchive-dev#3.0.4-3+nmu1 +libargtable2-dev#12-1 +libarmadillo-dev#1:3.2.3+dfsg-1 +libarpack++2-dev#2.3-2 +libarpack2-dev#3.1.1-2.1 +libart-2.0-dev#2.3.21-2 +libart2.0-cil-dev#2.24.2-3 +libasio-dev#1.4.1-3.2 +libasis2010-dev#2010-5 +libasm-dev#0.152-1+wheezy1 +libasound2-dev#1.0.25-4 +libaspell-dev#0.60.7~20110707-1 +libass-dev#0.10.0-3 +libassa3.5-5-dev#3.5.1-2 +libassimp-dev#3.0~dfsg-1 +libassuan-dev#2.0.3-1 +libast2-dev#0.7-6+b1 +libasyncns-dev#0.8-4 +libatasmart-dev#0.19-1 +libatd-ocaml-dev#1.0.1-1+b1 +libatdgen-ocaml-dev#1.2.2-1+b1 +libatk-bridge2.0-dev#2.5.3-2 +libatk1.0-dev#2.4.0-2 +libatkmm-1.6-dev#2.22.6-1 +libatlas-base-dev#3.8.4-9+deb7u1 +libatlas-cpp-0.6-dev#0.6.2-3 +libatlas-dev#3.8.4-9+deb7u1 +libatm1-dev#1:2.5.1-1.5 +libatomic-ops-dev#7.2~alpha5+cvs20101124-1+deb7u1 +libatomicparsley-dev#2.1.2-1 +libatspi-dev#1.32.0-2 +libatspi2.0-dev#2.5.3-2 +libattica-dev#0.2.0-1 +libattr1-dev#1:2.4.46-8 +libaubio-dev#0.3.2-4.2+b1 +libaudio-dev#1.9.3-5wheezy1 +libaudiofile-dev#0.3.4-2 +libaudiomask-dev#1.0-2 +libaudit-dev#1:1.7.18-1.1 +libaugeas-dev#0.10.0-1 +libaunit2-dev#1.03-7 +libautotrace-dev#0.31.1-16+b1 +libautounit-dev#0.20.1-4 +libavahi-cil-dev#0.6.19-4.2 +libavahi-client-dev#0.6.31-2 +libavahi-common-dev#0.6.31-2 +libavahi-compat-libdnssd-dev#0.6.31-2 +libavahi-core-dev#0.6.31-2 +libavahi-glib-dev#0.6.31-2 +libavahi-gobject-dev#0.6.31-2 +libavahi-qt4-dev#0.6.31-2 +libavahi-ui-cil-dev#0.6.19-4.2 +libavahi-ui-dev#0.6.31-2 +libavahi-ui-gtk3-dev#0.6.31-2 +libavbin-dev#7-1.3 +libavc1394-dev#0.5.4-2 +libavcodec-dev#6:0.8.10-1 +libavdevice-dev#6:0.8.10-1 +libavfilter-dev#6:0.8.10-1 +libavformat-dev#6:0.8.10-1 +libavifile-0.7-dev#1:0.7.48~20090503.ds-13 +libavl-dev#0.3.5-3 +libavogadro-dev#1.0.3-5 +libavutil-dev#6:0.8.10-1 +libaws2.10.2-dev#2.10.2-4 +libax25-dev#0.0.12-rc2+cvs20120204-2 +libbabl-dev#0.1.10-1 +libball1.4-dev#1.4.1+20111206-4 +libballview1.4-dev#1.4.1+20111206-4 +libbam-dev#0.1.18-1 +libbamf-dev#0.2.118-1 +libbamf3-dev#0.2.118-1 +libbarry-dev#0.18.3-5 +libbatteries-ocaml-dev#1.4.3-1 +libbdd-dev#2.4-8 +libbeecrypt-dev#4.2.1-4 +libbenchmark-ocaml-dev#0.9-2+b3 +libbfb0-dev#0.23-1.1 +libbg1-dev#1.106-1 +libbibutils-dev#4.12-5 +libbin-prot-camlp4-dev#2.0.7-1 +libbind-dev#1:9.8.4.dfsg.P1-6+nmu2+deb7u1 +libbind4-dev#6.0-1 +libbinio-dev#1.4+dfsg1-1 +libbiniou-ocaml-dev#1.0.0-1+b1 +libbio2jack0-dev#0.9-2.1 +libbiococoa-dev#2.2.2-1+b2 +libbiosig-dev#1.3.0-2 +libbisho-common-dev#0.27.2+git20111122.9e68ef3d-1 +libbison-dev#1:2.5.dfsg-2.1 +libbitmask-dev#2.0-2 +libbitstream-dev#1.0-1 +libbitstring-ocaml-dev#2.0.2-3+b1 +libbjack-ocaml-dev#0.1.3-5+b1 +libblacs-mpi-dev#1.1-31 +libblas-dev#1.2.20110419-5 +libbliss-dev#0.72-4 +libblitz0-dev#1:0.9-13 +libblkid-dev#2.20.1-5.3 +libblocksruntime-dev#0.1-1 +libbluedevil-dev#1.9.2-1 +libbluetooth-dev#4.99-2 +libbluray-dev#1:0.2.2-1 +libbml-dev#0.6.1-1 +libbobcat-dev#3.01.00-1+b1 +libbogl-dev#0.1.18-8+b1 +libbognor-regis-dev#0.6.12+git20101007.02c25268-7 +libbonobo2-dev#2.24.3-1 +libbonoboui2-dev#2.24.3-1 +libboo-cil-dev#0.9.5~git20110729.r1.202a430-2 +libboost-all-dev#1.49.0.1 +libboost-chrono-dev#1.49.0.1 +libboost-chrono1.49-dev#1.49.0-3.2 +libboost-date-time-dev#1.49.0.1 +libboost-date-time1.49-dev#1.49.0-3.2 +libboost-dev#1.49.0.1 +libboost-filesystem-dev#1.49.0.1 +libboost-filesystem1.49-dev#1.49.0-3.2 +libboost-graph-dev#1.49.0.1 +libboost-graph-parallel-dev#1.49.0.1 +libboost-graph-parallel1.49-dev#1.49.0-3.2 +libboost-graph1.49-dev#1.49.0-3.2 +libboost-iostreams-dev#1.49.0.1 +libboost-iostreams1.49-dev#1.49.0-3.2 +libboost-locale-dev#1.49.0.1 +libboost-locale1.49-dev#1.49.0-3.2 +libboost-math-dev#1.49.0.1 +libboost-math1.49-dev#1.49.0-3.2 +libboost-mpi-dev#1.49.0.1 +libboost-mpi-python-dev#1.49.0.1 +libboost-mpi-python1.49-dev#1.49.0-3.2 +libboost-mpi1.49-dev#1.49.0-3.2 +libboost-program-options-dev#1.49.0.1 +libboost-program-options1.49-dev#1.49.0-3.2 +libboost-python-dev#1.49.0.1 +libboost-python1.49-dev#1.49.0-3.2 +libboost-random-dev#1.49.0.1 +libboost-random1.49-dev#1.49.0-3.2 +libboost-regex-dev#1.49.0.1 +libboost-regex1.49-dev#1.49.0-3.2 +libboost-serialization-dev#1.49.0.1 +libboost-serialization1.49-dev#1.49.0-3.2 +libboost-signals-dev#1.49.0.1 +libboost-signals1.49-dev#1.49.0-3.2 +libboost-system-dev#1.49.0.1 +libboost-system1.49-dev#1.49.0-3.2 +libboost-test-dev#1.49.0.1 +libboost-test1.49-dev#1.49.0-3.2 +libboost-thread-dev#1.49.0.1 +libboost-thread1.49-dev#1.49.0-3.2 +libboost-timer-dev#1.49.0.1 +libboost-timer1.49-dev#1.49.0-3.2 +libboost-wave-dev#1.49.0.1 +libboost-wave1.49-dev#1.49.0-3.2 +libboost1.49-all-dev#1.49.0-3.2 +libboost1.49-dev#1.49.0-3.2 +libbotan1.10-dev#1.10.5-1 +libbox-dev#2.5-2 +libbox2d-dev#2.0.1+dfsg1-1 +libbpp-core-dev#2.0.3-1 +libbpp-phyl-dev#2.0.3-1 +libbpp-popgen-dev#2.0.3-1 +libbpp-qt-dev#2.0.2-1 +libbpp-raa-dev#2.0.3-1 +libbpp-seq-dev#2.0.3-1 +libbrahe-dev#1.3.2-3 +libbrasero-media3-dev#3.4.1-4 +libbrlapi-dev#4.4-10+deb7u1 +libbs2b-dev#3.1.0+dfsg-2 +libbsd-dev#0.4.2-1 +libbse-dev#0.7.4-5 +libbt-dev#0.70.1-13 +libbtparse-dev#0.63-1 +libbuffy-dev#1.7-1 +libbulletml-dev#0.0.6-5 +libburn-dev#1.2.2-2 +libbuzztard-dev#0.5.0-4 +libbz2-dev#1.0.6-4 +libbz2-ocaml-dev#0.6.0-6+b2 +libc-ares-dev#1.9.1-3 +libc-client2007e-dev#8:2007f~dfsg-2 +libc6-dev#2.13-38+deb7u1 +libcableswig-dev#0.1.0+cvs20111009-1 +libcaca-dev#0.99.beta18-1 +libcairo-ocaml-dev#1:1.2.0-2+b1 +libcairo2-dev#1.12.2-3 +libcairomm-1.0-dev#1.10.0-1 +libcal3d12-dev#0.11.0-4.1 +libcalendar-ocaml-dev#2.03-1+b2 +libcamel1.2-dev#3.4.4-3 +libcameleon-ocaml-dev#1.9.21-2+b1 +libcaml2html-ocaml-dev#1.4.1-3 +libcamlimages-ocaml-dev#1:4.0.1-4+b2 +libcamljava-ocaml-dev#0.3-1+b3 +libcamltemplate-ocaml-dev#1.0.2-1+b2 +libcamomile-ocaml-dev#0.8.4-2 +libcanberra-dev#0.28-6 +libcanberra-gtk-common-dev#0.28-6 +libcanberra-gtk-dev#0.28-6 +libcanberra-gtk3-dev#0.28-6 +libcanlock2-dev#2b-6 +libcanna1g-dev#3.7p3-11 +libcap-dev#1:2.22-1.2 +libcap-ng-dev#0.6.6-2 +libcapi20-dev#1:3.25+dfsg1-3.3~deb7u1 +libcapsinetwork-dev#0.3.0-7 +libcaribou-dev#0.4.4-1 +libcbf-dev#0.7.9.1-3 +libccaudio2-dev#2.0.5-3 +libccfits-dev#2.4-1 +libcconv-dev#0.6.2-1 +libccrtp-dev#2.0.3-4 +libccs-dev#3.0.12-3.2+deb7u2 +libccscript3-dev#1.1.7-2 +libccss-dev#0.5.0-4 +libcdaudio-dev#0.99.12p2-12 +libcdb-dev#0.78 +libcdd-dev#094b.dfsg-4.2 +libcddb2-dev#1.3.2-3 +libcdi-dev#1.5.4+dfsg.1-5 +libcdio-cdda-dev#0.83-4 +libcdio-dev#0.83-4 +libcdio-paranoia-dev#0.83-4 +libcdk5-dev#5.0.20060507-4 +libcdparanoia-dev#3.10.2+debian-10.1 +libcec-dev#1.6.2-1.1 +libcegui-mk2-dev#0.7.6-2+b1 +libcext-dev#6.1.1-2 +libcf-ocaml-dev#0.10-3+b3 +libcfg-dev#1.4.2-3 +libcfitsio3-dev#3.300-2 +libcgal-dev#4.0-5 +libcgic-dev#2.05-3 +libcgicc5-dev#3.2.9-3 +libcgns-dev#3.1.3.4-1+b1 +libcgroup-dev#0.38-1 +libcgsi-gsoap-dev#1.3.5-1 +libchamplain-0.12-dev#0.12.3-1 +libchamplain-gtk-0.12-dev#0.12.3-1 +libcharls-dev#1.0-2 +libchasen-dev#2.4.5-6 +libcheese-dev#3.4.2-2 +libcheese-gtk-dev#3.4.2-2 +libchewing3-dev#0.3.3-4 +libchicken-dev#4.7.0-1 +libchipcard-dev#5.0.3beta-3 +libchise-dev#0.3.0-2+b1 +libchm-dev#2:0.40a-2 +libchromaprint-dev#0.6-2 +libcib1-dev#1.1.7-1 +libcitadel-dev#8.14-1 +libcitygml0-dev#0.14+svn128-1+3p0p1+4 +libck-connector-dev#0.4.5-3.1 +libckyapplet1-dev#1.1.0-12 +libclalsadrv-dev#2.0.0-3 +libclam-dev#1.4.0-5.1 +libclam-qtmonitors-dev#1.4.0-3.1 +libclamav-dev#0.98.1+dfsg-1+deb7u3 +libclang-common-dev#1:3.0-6.2 +libclang-dev#1:3.0-6.2 +libclanlib-dev#1.0~svn3827-3 +libclassad-dev#7.8.2~dfsg.1-1+deb7u1 +libclaw-application-dev#1.7.0-3 +libclaw-configuration-file-dev#1.7.0-3 +libclaw-dev#1.7.0-3 +libclaw-dynamic-library-dev#1.7.0-3 +libclaw-graphic-dev#1.7.0-3 +libclaw-logger-dev#1.7.0-3 +libclaw-net-dev#1.7.0-3 +libclaw-tween-dev#1.7.0-3 +libclaws-mail-dev#3.8.1-2 +libclhep-dev#2.1.2.3-1 +libcli-dev#1.9.6-1 +libclippoly-dev#0.11-3 +libclips-dev#6.24-3 +libcliquer-dev#1.21-1 +libcln-dev#1.3.2-1.2 +libcloog-isl-dev#0.17.0-3 +libcloog-ppl-dev#0.15.11-4 +libclthreads-dev#2.4.0-4 +libclucene-dev#0.9.21b-2+b1 +libclustalo-dev#1.1.0-1 +libcluster-glue-dev#1.0.9+hg2665-1 +libclutter-1.0-dev#1.10.8-2 +libclutter-cil-dev#1.0.0~alpha3~git20090817.r1.349dba6-8 +libclutter-gst-dev#1.5.4-1+build0 +libclutter-gtk-1.0-dev#1.2.0-2 +libclutter-imcontext-0.1-dev#0.1.4-3 +libcluttergesture-dev#0.0.2.1-7 +libclxclient-dev#3.6.1-6 +libcman-dev#3.0.12-3.2+deb7u2 +libcminpack-dev#1.2.2-1 +libcmis-dev#0.1.0-1+b1 +libcmor-dev#2.8.0-2+b1 +libcmph-dev#0.9-1 +libcneartree-dev#3.1.1-1 +libcnf-dev#4.0-2 +libcob1-dev#1.1-1 +libcogl-dev#1.10.2-7 +libcogl-pango-dev#1.10.2-7 +libcoin60-dev#3.1.3-2.2 +libcojets2-dev#20061220+dfsg3-2 +libcollectdclient-dev#5.1.0-3 +libcollection-dev#0.1.3-2 +libcolorblind-dev#0.0.1-1 +libcolord-dev#0.1.21-1 +libcolord-gtk-dev#0.1.21-1 +libcolorhug-dev#0.1.10-1 +libcomedi-dev#0.10.0-3 +libcommoncpp2-dev#1.8.1-5 +libcompfaceg1-dev#1:1.5.2-5 +libconcord-dev#0.24-1.1 +libconfdb-dev#1.4.2-3 +libconfig++-dev#1.4.8-5 +libconfig++8-dev#1.4.8-5 +libconfig-dev#1.4.8-5 +libconfig-file-ocaml-dev#1.1-1 +libconfig8-dev#1.4.8-5 +libconfuse-dev#2.7-4 +libcontactsdb-dev#0.5-8 +libcoq-ocaml-dev#8.3.pl4+dfsg-2 +libcore-ocaml-dev#107.01-5 +libcorelinux-dev#0.4.32-7.3 +libcoroipcc-dev#1.4.2-3 +libcoroipcs-dev#1.4.2-3 +libcorosync-dev#1.4.2-3 +libcos4-dev#4.1.6-2 +libcothreads-ocaml-dev#0.10-3+b3 +libcoyotl-dev#3.1.0-5 +libcpg-dev#1.4.2-3 +libcpl-dev#6.1.1-2 +libcppcutter-dev#1.1.7-1.2 +libcppunit-dev#1.12.1-4 +libcppunit-subunit-dev#0.0.8+bzr176-1 +libcpputest-dev#3.1-2 +libcpufreq-dev#008-1 +libcpuset-dev#1.0-3 +libcqrlib2-dev#1.1.2-1 +libcr-dev#0.8.5-2 +libcrack2-dev#2.8.19-3 +libcreal-ocaml-dev#0.7-6+b3 +libcrmcluster1-dev#1.1.7-1 +libcrmcommon2-dev#1.1.7-1 +libcroco3-dev#0.6.6-2 +libcry-ocaml-dev#0.2.2-1+b1 +libcryptgps-ocaml-dev#0.2.1-7+b3 +libcrypto++-dev#5.6.1-6 +libcryptokit-ocaml-dev#1.5-1 +libcryptsetup-dev#2:1.4.3-4 +libcryptui-dev#3.2.2-1 +libcrystalhd-dev#1:0.0~git20110715.fdd2f19-9 +libcsfml-dev#1.6-1 +libcsnd-dev#1:5.17.11~dfsg-3 +libcsoap-dev#1.1.0-17.1 +libcsound64-dev#1:5.17.11~dfsg-3 +libcsoundac-dev#1:5.17.11~dfsg-3 +libcsv-ocaml-dev#1.2.2-1+b1 +libctapimkt0-dev#1.0.1-1.1 +libctdb-dev#1.12+git20120201-4 +libctemplate-dev#2.2-3 +libctl-dev#3.1.0-5 +libctpl-dev#0.3.3.dfsg-2 +libcuba3-dev#3.0+20111124-2 +libcudf-dev#0.6.2-1 +libcudf-ocaml-dev#0.6.2-1 +libcue-dev#1.4.0-1 +libcunit1-dev#2.1-0.dfsg-10 +libcunit1-ncurses-dev#2.1-0.dfsg-10 +libcups2-dev#1.5.3-5+deb7u1 +libcupscgi1-dev#1.5.3-5+deb7u1 +libcupsdriver1-dev#1.5.3-5+deb7u1 +libcupsfilters-dev#1.0.18-2.1+deb7u1 +libcupsimage2-dev#1.5.3-5+deb7u1 +libcupsmime1-dev#1.5.3-5+deb7u1 +libcupsppdc1-dev#1.5.3-5+deb7u1 +libcupt2-dev#2.5.9 +libcurl-ocaml-dev#0.5.3-2+b1 +libcurl4-gnutls-dev#7.26.0-1+wheezy9 +libcurl4-nss-dev#7.26.0-1+wheezy9 +libcurl4-openssl-dev#7.26.0-1+wheezy9 +libcurses-ocaml-dev#1.0.3-2 +libcutter-dev#1.1.7-1.2 +libcv-dev#2.3.1-11 +libcvaux-dev#2.3.1-11 +libcvc3-dev#2.4.1-4 +libcvector2-dev#1.0.3-1 +libcvm1-dev#0.96-1+b1 +libcw3-dev#3.0.2-1 +libcwidget-dev#0.5.16-3.4 +libcwiid-dev#0.6.00+svn201-3+b1 +libcwnn-dev#1.1.1~a021+cvs20100325-6 +libcxgb3-dev#1.3.1-1 +libcxxtools-dev#2.1.1-1 +libdacs-dev#1.4.27b-2 +libdaemon-dev#0.14-2 +libdancer-xml0-dev#0.8.2.1-3 +libdap-dev#3.11.1-11 +libdapl-dev#2.0.19-1.1 +libdaq-dev#0.6.2-2 +libdar-dev#2.4.5.debian.1-1 +libdatrie-dev#0.2.5-3 +libdawgdic-dev#0.4.3-1 +libdb++-dev#5.1.6 +libdb-dev#5.1.6 +libdb-java-dev#5.1.6 +libdb-sql-dev#5.1.6 +libdb4o-cil-dev#8.0.184.15484+dfsg-2 +libdb5.1++-dev#5.1.29-5 +libdb5.1-dev#5.1.29-5 +libdb5.1-java-dev#5.1.29-5 +libdb5.1-sql-dev#5.1.29-5 +libdb5.1-stl-dev#5.1.29-5 +libdballe-dev#5.18-1 +libdballef-dev#5.18-1 +libdbaudiolib0-dev#0.9.8-6.2 +libdbi-dev#0.8.4-6 +libdbus-1-dev#1.6.8-1+deb7u1 +libdbus-c++-dev#0.9.0-6 +libdbus-glib-1-dev#0.100.2-1 +libdbus-glib1.0-cil-dev#0.5.0-4 +libdbus-ocaml-dev#0.29-1+b3 +libdbus1.0-cil-dev#0.7.0-5 +libdbusada0.2-dev#0.2-2 +libdbusmenu-glib-dev#0.6.2-1 +libdbusmenu-gtk-dev#0.6.2-1 +libdbusmenu-gtk3-dev#0.6.2-1 +libdbusmenu-jsonloader-dev#0.6.2-1 +libdbusmenu-qt-dev#0.9.0-1 +libdc-dev#0.3.24~svn3121-2 +libdc1394-22-dev#2.2.0-2 +libdca-dev#0.0.5-5 +libdcerpc-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcerpc-server-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcmtk2-dev#3.6.0-12 +libdconf-dbus-1-dev#0.12.1-3 +libdconf-dev#0.12.1-3 +libddccontrol-dev#0.4.2-10 +libdds-dev#2.1.2+ddd105-1 +libdebconf-kde-dev#0.2-2 +libdebconfclient0-dev#0.182 +libdebian-installer4-dev#0.87 +libdebug0-dev#0.4.4-1.1 +libdecodeqr-dev#0.9.3-6.2 +libdee-dev#1.0.10-3 +libderiving-ocaml-dev#0.1.1a-3+b1 +libderiving-ocsigen-ocaml-dev#0.3c-1 +libdesktop-agnostic-dev#0.3.92+dfsg-1 +libdessert0.87-dev#0.87.2-1 +libdevhelp-dev#3.4.1-1 +libdevil-dev#1.7.8-6.1+b1 +libdevmapper-dev#2:1.02.74-8 +libdhash-dev#0.1.3-2 +libdiagnostics-dev#0.3.3-1.3 +libdianewcanvas2-dev#0.6.10-5.4 +libdieharder-dev#3.31.1-4 +libdiet-admin2.8-dev#2.8.0-1+b1 +libdiet-client2.8-dev#2.8.0-1+b1 +libdiet-dagda2.8-dev#2.8.0-1+b1 +libdiet-sed2.8-dev#2.8.0-1+b1 +libdime-dev#0.20030921-2 +libdirac-dev#1.0.2-6 +libdirectfb-dev#1.2.10.0-5 +libdisasm-dev#0.23-5 +libdiscid0-dev#0.2.2-3 +libdiscover-dev#2.1.2-5.2 +libdispatch-dev#0~svn197-3.1 +libdisplaymigration0-dev#0.28-10 +libdistorm64-dev#1.7.30-1 +libdivecomputer-dev#0.1.0-3 +libdjconsole-dev#0.1.3-1 +libdjvulibre-dev#3.5.25.3-1 +libdkim-dev#1:1.0.21-3 +libdlm-dev#3.0.12-3.2+deb7u2 +libdlmcontrol-dev#3.0.12-3.2+deb7u2 +libdlrestrictions-dev#0.15.3 +libdm0-dev#2.2.10-1 +libdmalloc-dev#5.5.2-5 +libdmapsharing-3.0-dev#2.9.15-1 +libdmraid-dev#1.0.0.rc16-4.2 +libdmtcpaware-dev#1.2.5-1 +libdmtx-dev#0.7.2-2+build1 +libdmx-dev#1:1.1.2-1+deb7u1 +libdnet-dev#2.60 +libdockapp-dev#1:0.5.0-3 +libdolfin1.0-dev#1.0.0-7 +libdoodle-dev#0.7.0-5 +libdose2-ocaml-dev#1.4.2-4+b3 +libdose3-ocaml-dev#3.0.2-3 +libdotconf-dev#1.0.13-3 +libdpkg-dev#1.16.12 +libdpm-dev#1.8.2-1+b2 +libdrawtk-dev#2.0-2 +libdrizzle-dev#1:7.1.36-stable-1 +libdrizzledmessage-dev#1:7.1.36-stable-1 +libdrm-dev#2.4.40-1~deb7u2 +libdrumstick-dev#0.5.0-3 +libdsdp-dev#5.8-9.1 +libdshconfig1-dev#0.20.13-1 +libdspam7-dev#3.10.1+dfsg-11 +libdssi-ocaml-dev#0.1.0-1+b1 +libdssialsacompat-dev#1.0.8a-1 +libdtools-ocaml-dev#0.3.0-1 +libdts-dev#0.0.5-5 +libdumb1-dev#1:0.9.3-5.4 +libdumbnet-dev#1.12-3.1 +libdune-common-dev#2.2.0-1 +libdune-geometry-dev#2.2.0-1 +libdune-grid-dev#2.2.0-1 +libdune-istl-dev#2.2.0-1 +libdune-localfunctions-dev#2.2.0-1 +libduo-dev#1.8-1 +libduppy-ocaml-dev#0.4.2-1+b2 +libdv4-dev#1.0.0-6 +libdvb-dev#0.5.5.1-5.1 +libdvbcsa-dev#1.1.0-2 +libdvbpsi-dev#0.2.2-1 +libdvdnav-dev#4.2.0+20120524-2 +libdvdread-dev#4.2.0+20120521-2 +libdw-dev#0.152-1+wheezy1 +libdwarf-dev#20120410-2 +libdx4-dev#1:4.4.4-4+b2 +libdxflib-dev#2.2.0.0-8 +libdynamite-dev#0.1.1-2 +libeasy-format-ocaml-dev#1.0.0-1+b2 +libeb16-dev#4.4.3-6 +libebackend1.2-dev#3.4.4-3 +libebml-dev#1.2.2-2 +libebook1.2-dev#3.4.4-3 +libecal1.2-dev#3.4.4-3 +libecasoundc-dev#2.9.0-1 +libecasoundc2.2-dev#2.9.0-1 +libechonest-dev#1.2.1-1 +libecm-dev#6.4.2-1 +libecore-dev#1.2.0-2 +libecpg-dev#9.1.13-0wheezy1 +libecryptfs-dev#99-1 +libedac-dev#0.18-1 +libedata-book1.2-dev#3.4.4-3 +libedata-cal1.2-dev#3.4.4-3 +libedataserver1.2-dev#3.4.4-3 +libedataserverui-3.0-dev#3.4.4-3 +libedbus-dev#1.2.0-1 +libedit-dev#2.11-20080614-5 +libeditline-dev#1.12-6 +libedje-dev#1.2.0-1 +libee-dev#0.4.1-1 +libeegdev-dev#0.2-3 +libeet-dev#1.6.0-1 +libefreet-dev#1.2.0-1 +libegl1-mesa-dev#8.0.5-4+deb7u2 +libeigen2-dev#2.0.17-1 +libeigen3-dev#3.1.0-1 +libeina-dev#1.2.0-2 +libelektra-cpp-dev#0.7.1-1 +libelektra-dev#0.7.1-1 +libelektratools-dev#0.7.1-1 +libelemental-dev#1.2.0-8 +libelementary-dev#0.7.0.55225-1 +libelf-dev#0.152-1+wheezy1 +libelfg0-dev#0.8.13-3 +libeliom-ocaml-dev#2.2.2-1 +libelk0-dev#3.99.8-2 +libelmer-dev#6.1.0.svn.5396.dfsg2-2 +libembryo-dev#1.2.0-1 +libemos-dev#000382+dfsg-2 +libenca-dev#1.13-4 +libenchant-dev#1.6.0-7 +libenet-dev#1.3.3-2 +libepc-dev#0.4.4-1 +libepc-ui-dev#0.4.4-1 +libepr-api2-dev#2.2-2 +libepsilon-dev#0.9.1-2 +libept-dev#1.0.9 +libepub-dev#0.2.1-2+b1 +liberis-1.3-dev#1.3.19-5 +liberuby-dev#1.0.5-2.1 +libescpr-dev#1.1.1-2 +libesd0-dev#0.2.41-10+b1 +libesmtp-dev#1.0.6-1+b1 +libespeak-dev#1.46.02-2 +libestools2.1-dev#1:2.1~release-5 +libestr-dev#0.1.1-2 +libethos-dev#0.2.2-3 +libethos-ui-dev#0.2.2-3 +libetpan-dev#1.0-5 +libetsf-io-dev#1.0.3-4+b1 +libeurodec1-dev#20061220+dfsg3-2 +libev-dev#1:4.11-1 +libev-libevent-dev#1:4.11-1 +libeval0-dev#0.29.6-2 +libevas-dev#1.2.0-2 +libevd-0.1-dev#0.1.20-2 +libevent-dev#2.0.19-stable-3 +libeventdb-dev#0.90-5 +libevince-dev#3.4.0-3.1 +libevocosm-dev#4.0.2-2.1 +libevs-dev#1.4.2-3 +libevtlog-dev#0.2.12-5 +libewf-dev#20100226-1+b1 +libexchangemapi-1.0-dev#3.4.4-1 +libexempi-dev#2.2.0-1 +libexif-dev#0.6.20-3 +libexif-gtk-dev#0.3.5-5 +libexiv2-dev#0.23-1 +libexo-1-dev#0.6.2-5 +libexodusii-dev#5.14.dfsg.1-2+b1 +libexosip2-dev#3.6.0-4 +libexpat-ocaml-dev#0.9.1+debian1-7+b2 +libexpat1-dev#2.1.0-1+deb7u1 +libexpect-ocaml-dev#0.0.2-1+b6 +libexplain-dev#0.52.D002-1 +libextlib-ocaml-dev#1.5.2-1+b1 +libextractor-dev#1:0.6.3-5 +libextractor-java-dev#0.6.0-6 +libexttextcat-dev#3.2.0-2 +libextunix-ocaml-dev#0.0.5-2 +libeztrace-dev#0.7-2-4 +libf2c2-dev#20090411-2 +libfaad-dev#2.7-8 +libfaad-ocaml-dev#0.3.0-1+b1 +libfacile-ocaml-dev#1.1-8+b1 +libfaifa-dev#0.2~svn82-1 +libfakekey-dev#0.1-7 +libfam-dev#2.7.0-17 +libfann-dev#2.1.0~beta~dfsg-8 +libfarstream-0.1-dev#0.1.2-1 +libfastjet-dev#3.0.2+dfsg-2 +libfastjet-fortran-dev#3.0.2+dfsg-2 +libfastjetplugins-dev#3.0.2+dfsg-2 +libfastjettools-dev#3.0.2+dfsg-2 +libfauhdli-dev#20110812-1 +libfcgi-dev#2.4.0-8.1 +libfdt-dev#1.3.0-4 +libfence-dev#3.0.12-3.2+deb7u2 +libffado-dev#2.0.99+svn2171-2 +libffcall1-dev#1.10+cvs20100619-2 +libffi-dev#3.0.10-3 +libffindex0-dev#0.9.6.1-1 +libffmpegthumbnailer-dev#2.0.7-2 +libffms2-dev#2.17-1 +libfftw3-dev#3.3.2-3.1 +libfftw3-mpi-dev#3.3.2-3.1 +libfields-camlp4-dev#107.01-1+b2 +libfileutils-ocaml-dev#0.4.2-1+b2 +libfindlib-ocaml-dev#1.3.1-1 +libfiredns-dev#0.9.12+dfsg-3 +libfirestring-dev#0.9.12-8 +libfishsound1-dev#1.0.0-1.1 +libfiu-dev#0.90-3 +libfixposix-dev#20110316.git47f17f7-1 +libfko0-dev#2.0.0rc2-2+deb7u2 +libflac++-dev#1.2.1-6 +libflac-dev#1.2.1-6 +libflac-ocaml-dev#0.1.1-1 +libflake-dev#0.11-2 +libflann-dev#1.7.1-4 +libflatzebra-dev#0.1.5-4+b1 +libflickrnet-cil-dev#1:2.2.0-4 +libflorist2011-dev#2011-1 +libflowcanvas-dev#0.7.1+dfsg0-0.2 +libfltk1.1-dev#1.1.10-14 +libfltk1.3-dev#1.3.0-8 +libfluidsynth-dev#1.1.5-2 +libfm-dev#0.1.17-2.1 +libfolia1-dev#0.9-2 +libfolks-dev#0.6.9-1+b1 +libfolks-eds-dev#0.6.9-1+b1 +libfolks-telepathy-dev#0.6.9-1+b1 +libfontconfig1-dev#2.9.0-7.1 +libfontenc-dev#1:1.1.1-1 +libfontforge-dev#0.0.20120101+git-2 +libforms-dev#1.0.93sp1-2 +libformsgl-dev#1.0.93sp1-2 +libfox-1.6-dev#1.6.45-1 +libfprint-dev#1:0.4.0-4-gdfff16f-4 +libfreecell-solver-dev#3.12.0-1 +libfreefem++-dev#3.19.1-1 +libfreefem-dev#3.5.8-5 +libfreehdl0-dev#0.0.7-1.1 +libfreeimage-dev#3.15.1-1+b1 +libfreeipmi-dev#1.1.5-3 +libfreenect-dev#1:0.1.2+dfsg-6 +libfreeradius-dev#2.1.12+dfsg-1.2 +libfreerdp-dev#1.0.1-1.1+deb7u3 +libfreetype6-dev#2.4.9-1.1 +libfreexl-dev#1.0.0b-1 +libfribidi-dev#0.19.2-3 +libfs-dev#2:1.0.4-1+deb7u1 +libfso-glib-dev#2012.05.24.1-1.1 +libfsobasics-dev#0.11.0-1.1 +libfsoframework-dev#0.11.0-1.1 +libfsoresource-dev#0.11.0-1.1 +libfsosystem-dev#0.11.0-1 +libfsotransport-dev#0.11.1-2.1 +libfsplib-dev#0.11-2 +libfstrcmp-dev#0.4.D001-1+deb7u1 +libftdi-dev#0.20-1+b1 +libftdipp-dev#0.20-1+b1 +libftgl-dev#2.1.3~rc5-4 +libfuntools-dev#1.4.4-3 +libfuse-dev#2.9.0-2+deb7u1 +libfuzzy-dev#2.7-2 +libfxt-dev#0.2.6-2 +libg15-dev#1.2.7-2 +libg15daemon-client-dev#1.9.5.3-8.2 +libg15render-dev#1.3.0~svn316-2.2 +libg2-dev#0.72-2.1 +libg3d-dev#0.0.8-17 +libga-dev#2.4.7-3 +libgadap-dev#2.0-1 +libgadu-dev#1:1.11.2-1+deb7u1 +libgail-3-dev#3.4.2-7 +libgail-dev#2.24.10-2 +libgalax-ocaml-dev#1.1-10+b3 +libgambc4-dev#4.2.8-1.1 +libgamin-dev#0.1.10-4.1 +libgammu-dev#1.31.90-1+b1 +libganglia1-dev#3.3.8-1+nmu1 +libganv-dev#0~svn4468~dfsg0-1 +libgarcon-1-0-dev#0.1.12-1 +libgarmin-dev#0~svn320-3 +libgatos-dev#0.0.5-19 +libgavl-dev#1.4.0-1 +libgavl-ocaml-dev#0.1.4-1+b1 +libgbm-dev#8.0.5-4+deb7u2 +libgc-dev#1:7.1-9.1 +libgcal-dev#0.9.6-3 +libgccxml-dev#0.9.0+cvs20120420-4 +libgcgi-dev#0.9.5.dfsg-7 +libgcj12-dev#4.6.3-1 +libgcj13-dev#4.7.2-3 +libgck-1-dev#3.4.1-3 +libgconf-bridge-dev#0.1-2.2 +libgconf2-dev#3.2.5-1+build1 +libgconf2.0-cil-dev#2.24.2-3 +libgconfmm-2.6-dev#2.28.0-1 +libgcr-3-dev#3.4.1-3 +libgcroots-dev#0.8.5-2.1 +libgcrypt11-dev#1.5.0-5+deb7u1 +libgctp-dev#1.0-1 +libgd-gd2-noxpm-ocaml-dev#1.0~alpha5-5 +libgd2-noxpm-dev#2.0.36~rc1~dfsg-6.1 +libgd2-xpm-dev#2.0.36~rc1~dfsg-6.1 +libgda-5.0-dev#5.0.3-2 +libgdal-dev#1.9.0-3.1 +libgdal1-dev#1.9.0-3.1 +libgdata-cil-dev#2.1.0.0-1 +libgdata-dev#0.12.0-1 +libgdb-dev#7.4.1+dfsg-0.1 +libgdbm-dev#1.8.3-11 +libgdchart-gd2-noxpm-dev#0.11.5-7+b1 +libgdchart-gd2-xpm-dev#0.11.5-7+b1 +libgdcm2-dev#2.2.0-14.1 +libgdf-dev#0.1.2-2 +libgdict-1.0-dev#3.4.0-2 +libgdk-pixbuf2.0-dev#2.26.1-1 +libgdkcutter-pixbuf-dev#1.1.7-1.2 +libgdl-3-dev#3.4.2-1 +libgdome2-cpp-smart-dev#0.2.6-6+b1 +libgdome2-dev#0.8.1+debian-4.1 +libgdome2-ocaml-dev#0.2.6-6+b1 +libgdu-dev#3.0.2-3 +libgdu-gtk-dev#3.0.2-3 +libgeant321-2-dev#1:3.21.14.dfsg-10 +libgearman-dev#0.33-2 +libgecode-dev#3.7.3-1 +libgeda-dev#1:1.6.2-4.3 +libgee-dev#0.6.4-2 +libgegl-dev#0.2.0-2+nmu1 +libgeier-dev#0.13-1+b1 +libgenders0-dev#1.18-1 +libgenome-1.3-0-dev#1.3.1-3 +libgensec-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libgeoclue-dev#0.12.0-4 +libgeocode-glib-dev#0.99.0-1 +libgeographiclib-dev#1.21-1 +libgeoip-dev#1.4.8+dfsg-3 +libgeomview-dev#1.9.4-3 +libgeos++-dev#3.3.3-1.1 +libgeos-dev#3.3.3-1.1 +libgeotiff-dev#1.3.0+dfsg-3 +libgeotranz3-dev#3.1-2.1 +libges-0.10-dev#0.10.1-2 +libgetdata-dev#0.7.3-6 +libgetfem++-dev#4.1.1+dfsg1-11 +libgetopt++-dev#0.0.2-p22-3 +libgetopt-ocaml-dev#0.0.20040811-10+b3 +libgettext-ocaml-dev#0.3.4-1+b2 +libgexiv2-dev#0.4.1-3 +libgfarm-dev#2.4.1-1.1 +libgflags-dev#2.0-1 +libgfshare-dev#1.0.5-2 +libghc-acid-state-dev#0.6.3-1+b2 +libghc-active-dev#0.1.0.1-2+b2 +libghc-adjunctions-dev#2.4.0.2-1 +libghc-aeson-dev#0.6.0.2-1+b4 +libghc-agda-dev#2.3.0.1-2 +libghc-algebra-dev#2.1.1.2-1 +libghc-alut-dev#2.1.0.2-4+b1 +libghc-ami-dev#0.1-1+b5 +libghc-ansi-terminal-dev#0.5.5-3+b1 +libghc-ansi-wl-pprint-dev#0.6.4-1+b1 +libghc-arrows-dev#0.4.4.0-3+b1 +libghc-asn1-data-dev#0.6.1.3-2+b3 +libghc-attempt-dev#0.4.0-1+b2 +libghc-attoparsec-conduit-dev#0.4.0.1-1 +libghc-attoparsec-dev#0.10.1.1-2+b1 +libghc-attoparsec-enumerator-dev#0.3-3+b3 +libghc-augeas-dev#0.6.1-1 +libghc-authenticate-dev#1.2.1.1-2+b1 +libghc-base-unicode-symbols-dev#0.2.2.3-1+b1 +libghc-base16-bytestring-dev#0.1.1.4-2+b1 +libghc-base64-bytestring-dev#0.1.1.1-2 +libghc-bifunctors-dev#0.1.3.3-1+b1 +libghc-binary-shared-dev#0.8.1-1+b1 +libghc-bindings-dsl-dev#1.0.15-1+b1 +libghc-bindings-gpgme-dev#0.1.4-1 +libghc-bindings-libzip-dev#0.10-2 +libghc-bitarray-dev#0.0.1-2+b1 +libghc-blaze-builder-conduit-dev#0.4.0.2-1 +libghc-blaze-builder-dev#0.3.1.0-1+b2 +libghc-blaze-builder-enumerator-dev#0.2.0.4-1+b1 +libghc-blaze-html-dev#0.4.3.1-3+b2 +libghc-blaze-markup-dev#0.5.1.0-1 +libghc-blaze-textual-dev#0.2.0.6-2+b2 +libghc-bloomfilter-dev#1.2.6.8-1 +libghc-boolean-dev#0.0.1-2+b1 +libghc-boomerang-dev#1.3.1-1 +libghc-brainfuck-dev#0.1-2+b2 +libghc-byteorder-dev#1.0.3-2+b1 +libghc-bytestring-lexing-dev#0.4.0-1+b1 +libghc-bytestring-mmap-dev#0.2.2-2+b1 +libghc-bytestring-nums-dev#0.3.5-2+b1 +libghc-bytestring-show-dev#0.3.5.1-1+b1 +libghc-bzlib-dev#0.5.0.3-2+b1 +libghc-cabal-file-th-dev#0.2.2-1 +libghc-cairo-dev#0.12.3-1+b1 +libghc-case-insensitive-dev#0.4.0.1-2+b2 +libghc-categories-dev#1.0.3-1+b1 +libghc-cautious-file-dev#1.0.1-1 +libghc-cereal-conduit-dev#0.5-1+b1 +libghc-cereal-dev#0.3.5.2-1 +libghc-certificate-dev#1.2.3-2 +libghc-cgi-dev#3001.1.8.2-2+b3 +libghc-chart-dev#0.15-1+b2 +libghc-chell-dev#0.3-1 +libghc-citeproc-hs-dev#0.3.4-1+b4 +libghc-clientsession-dev#0.7.5-3+b1 +libghc-clock-dev#0.2.0.0-2+b1 +libghc-cmdargs-dev#0.9.5-1+b1 +libghc-colour-dev#2.3.3-1+b1 +libghc-comonad-dev#1.1.1.5-1+b1 +libghc-comonad-transformers-dev#2.1.1.1-1+b1 +libghc-comonads-fd-dev#2.1.1.2-1+b1 +libghc-conduit-dev#0.4.2-2 +libghc-configfile-dev#1.0.6-4+b3 +libghc-configurator-dev#0.2.0.0-1+b2 +libghc-contravariant-dev#0.2.0.2-1+b1 +libghc-convertible-dev#1.0.11.0-3+b3 +libghc-cookie-dev#0.4.0-1+b3 +libghc-cpphs-dev#1.13.3-2+b1 +libghc-cprng-aes-dev#0.2.3-3+b4 +libghc-cpu-dev#0.1.1-1 +libghc-criterion-dev#0.6.0.1-3+b4 +libghc-crypto-api-dev#0.10.2-1+b2 +libghc-crypto-conduit-dev#0.3.2-1+b1 +libghc-crypto-dev#4.2.4-1+b1 +libghc-crypto-pubkey-types-dev#0.1.1-1+b3 +libghc-cryptocipher-dev#0.3.5-1+b1 +libghc-cryptohash-dev#0.7.5-1+b2 +libghc-css-text-dev#0.1.1-3+b2 +libghc-csv-conduit-dev#0.2-1 +libghc-csv-dev#0.1.2-2+b3 +libghc-curl-dev#1.3.7-1+b1 +libghc-darcs-dev#2.8.1-1+b1 +libghc-data-accessor-dev#0.2.2.2-1+b1 +libghc-data-accessor-mtl-dev#0.2.0.3-1+b1 +libghc-data-accessor-template-dev#0.2.1.9-1+b2 +libghc-data-binary-ieee754-dev#0.4.2.1-3+b1 +libghc-data-default-dev#0.4.0-1 +libghc-data-inttrie-dev#0.0.7-1+b1 +libghc-data-lens-dev#2.10.0-1+b1 +libghc-data-memocombinators-dev#0.4.3-1+b1 +libghc-dataenc-dev#0.14.0.3-1+b1 +libghc-datetime-dev#0.2.1-3 +libghc-dbus-dev#0.10.3-1 +libghc-debian-dev#3.64-3 +libghc-diagrams-cairo-dev#0.5.0.2-1 +libghc-diagrams-core-dev#0.5.0.1-1+b1 +libghc-diagrams-dev#0.5-2 +libghc-diagrams-lib-dev#0.5-2 +libghc-diff-dev#0.1.3-1+b1 +libghc-digest-dev#0.0.1.0-1+b1 +libghc-dimensional-dev#0.10.1.2-2+b1 +libghc-directory-tree-dev#0.10.0-2+b1 +libghc-distributive-dev#0.2.2-1+b1 +libghc-dlist-dev#0.5-3+b1 +libghc-download-curl-dev#0.1.3-3+b3 +libghc-dpkg-dev#0.0.3-1 +libghc-dyre-dev#0.8.7-1 +libghc-edison-api-dev#1.2.1-18+b1 +libghc-edison-core-dev#1.2.1.3-9+b1 +libghc-edit-distance-dev#0.2.1-2 +libghc-editline-dev#0.2.1.0-5+b1 +libghc-ekg-dev#0.3.1.0-1+b2 +libghc-email-validate-dev#0.2.8-1+b3 +libghc-entropy-dev#0.2.1-2+b1 +libghc-enumerator-dev#0.4.19-1+b1 +libghc-erf-dev#2.0.0.0-2+b1 +libghc-event-list-dev#0.1.0.1-1+b1 +libghc-exception-transformers-dev#0.3.0.2-1+b1 +libghc-executable-path-dev#0.0.3-1+b1 +libghc-explicit-exception-dev#0.1.7-1+b1 +libghc-failure-dev#0.2.0.1-1+b1 +libghc-fast-logger-dev#0.0.2-1+b2 +libghc-fastcgi-dev#3001.0.2.3-3+b3 +libghc-fclabels-dev#1.1.3-1+b1 +libghc-feed-dev#0.3.8-3 +libghc-fgl-dev#5.4.2.4-2+b2 +libghc-file-embed-dev#0.0.4.4-1 +libghc-filemanip-dev#0.3.5.2-2+b2 +libghc-filestore-dev#0.5-1 +libghc-filesystem-conduit-dev#0.4.0-1 +libghc-free-dev#2.1.1.1-1+b1 +libghc-ftphs-dev#1.0.8-1+b3 +libghc-gconf-dev#0.12.1-1+b1 +libghc-gd-dev#3000.7.3-1 +libghc-ghc-events-dev#0.4.0.0-2+b1 +libghc-ghc-mtl-dev#1.0.1.1-1+b3 +libghc-ghc-paths-dev#0.1.0.8-2+b1 +libghc-ghc-syb-utils-dev#0.2.1.0-1+b3 +libghc-gio-dev#0.12.3-1+b1 +libghc-github-dev#0.4.0-2 +libghc-gitit-dev#0.10.0.1-1+b1 +libghc-glade-dev#0.12.1-1+b3 +libghc-glfw-dev#0.5.0.1-1+b1 +libghc-glib-dev#0.12.2-1+b1 +libghc-glut-dev#2.1.2.2-1 +libghc-gnuidn-dev#0.2-2+b2 +libghc-gnutls-dev#0.1.2-1+b1 +libghc-gsasl-dev#0.3.4-1+b1 +libghc-gstreamer-dev#0.12.1-1+b2 +libghc-gtk-dev#0.12.3-1+b2 +libghc-gtkglext-dev#0.12.1-1+b3 +libghc-gtksourceview2-dev#0.12.3-1+b3 +libghc-haddock-dev#2.10.0-1+b2 +libghc-hakyll-dev#3.2.7.2-1+b5 +libghc-hamlet-dev#1.0.1.3-1+b1 +libghc-happstack-dev#7.0.0-1+b1 +libghc-happstack-server-dev#7.0.1-1+b1 +libghc-harp-dev#0.4-3+b1 +libghc-hashable-dev#1.1.2.3-1+b2 +libghc-hashed-storage-dev#0.5.9-2+b2 +libghc-hashmap-dev#1.3.0.1-1+b2 +libghc-hashtables-dev#1.0.1.4-1+b1 +libghc-haskeline-dev#0.6.4.7-1+b1 +libghc-haskell-lexer-dev#1.0-3+b1 +libghc-haskell-src-dev#1.0.1.5-1+b2 +libghc-haskelldb-dev#2.1.1-5+b1 +libghc-haskelldb-hdbc-dev#2.1.0-4 +libghc-haskelldb-hdbc-odbc-dev#2.1.0-3 +libghc-haskelldb-hdbc-postgresql-dev#2.1.0-3 +libghc-haskelldb-hdbc-sqlite3-dev#2.1.0-3 +libghc-haskore-dev#0.2.0.3-2 +libghc-hastache-dev#0.3.3-2+b3 +libghc-haxml-dev#1:1.22.5-2+b2 +libghc-haxr-dev#3000.8.5-1+b3 +libghc-hcard-dev#0.0-2+b2 +libghc-hcwiid-dev#0.0.1-3+b1 +libghc-hdbc-dev#2.3.1.1-1+b3 +libghc-hdbc-odbc-dev#2.2.3.0-5+b3 +libghc-hdbc-postgresql-dev#2.3.2.1-1+b3 +libghc-hdbc-sqlite3-dev#2.3.3.0-1+b3 +libghc-hfuse-dev#0.2.4.1-1 +libghc-highlighting-kate-dev#0.5.1-1 +libghc-hinotify-dev#0.3.2-1+b1 +libghc-hint-dev#0.3.3.4-2+b4 +libghc-hipmunk-dev#5.2.0.8-1+b1 +libghc-hjavascript-dev#0.4.7-3+b1 +libghc-hjscript-dev#0.5.0-3+b2 +libghc-hjsmin-dev#0.1.1-1+b2 +libghc-hlint-dev#1.8.28-1+b3 +libghc-hoauth-dev#0.3.4-1+b1 +libghc-hostname-dev#1.0-4+b1 +libghc-hs-bibutils-dev#4.12-5+b2 +libghc-hs3-dev#0.5.6-2+b4 +libghc-hscolour-dev#1.19-3+b1 +libghc-hscurses-dev#1.4.1.0-1+b2 +libghc-hsemail-dev#1.7.1-2+b3 +libghc-hsh-dev#2.0.3-6+b3 +libghc-hslogger-dev#1.1.4+dfsg1-2+b3 +libghc-hsp-dev#0.6.1-2+b3 +libghc-hspec-dev#1.1.0-1+b1 +libghc-hsql-dev#1.8.1-4 +libghc-hsql-mysql-dev#1.8.1-4+b1 +libghc-hsql-odbc-dev#1.8.1.1-2 +libghc-hsql-postgresql-dev#1.8.1-3 +libghc-hsql-sqlite3-dev#1.8.1-2 +libghc-hssyck-dev#0.50-2+b2 +libghc-hstringtemplate-dev#0.6.8-1 +libghc-hsx-dev#0.9.1-3 +libghc-html-conduit-dev#0.0.1-2 +libghc-html-dev#1.0.1.2-5+b1 +libghc-http-conduit-dev#1.4.1.6-3 +libghc-http-date-dev#0.0.2-1+b2 +libghc-http-dev#1:4000.2.3-1+b2 +libghc-http-types-dev#0.6.11-1 +libghc-hunit-dev#1.2.4.2-2+b1 +libghc-hxt-cache-dev#9.0.2-2+b3 +libghc-hxt-charproperties-dev#9.1.1-2+b1 +libghc-hxt-curl-dev#9.1.1-1+b4 +libghc-hxt-dev#9.2.2-2+b3 +libghc-hxt-http-dev#9.1.4-2+b3 +libghc-hxt-regex-xmlschema-dev#9.0.4-2+b3 +libghc-hxt-relaxng-dev#9.1.4-1+b3 +libghc-hxt-tagsoup-dev#9.1.1-1+b4 +libghc-hxt-unicode-dev#9.0.2-2+b1 +libghc-hxt-xpath-dev#9.1.2-1+b4 +libghc-hxt-xslt-dev#9.1.1-1+b3 +libghc-iconv-dev#0.4.1.0-2+b1 +libghc-ieee754-dev#0.7.3-1+b1 +libghc-ifelse-dev#0.85-4+b1 +libghc-io-choice-dev#0.0.1-1+b3 +libghc-io-storage-dev#0.3-2+b1 +libghc-iospec-dev#0.2.5-1+b2 +libghc-irc-dev#0.5.0.0-1+b3 +libghc-iteratee-dev#0.8.8.2-2+b1 +libghc-ixset-dev#1.0.3-2+b1 +libghc-json-dev#0.5-2+b2 +libghc-keys-dev#2.1.3.2-1+b1 +libghc-knob-dev#0.1.1-1 +libghc-lambdabot-utils-dev#4.2.1-3+b3 +libghc-language-c-dev#0.4.2-2+b2 +libghc-language-haskell-extract-dev#0.2.1-4+b1 +libghc-language-javascript-dev#0.5.4-1+b2 +libghc-largeword-dev#1.0.1-2+b1 +libghc-lazysmallcheck-dev#0.6-1+b1 +libghc-ldap-dev#0.6.6-4.1+b1 +libghc-leksah-server-dev#0.12.0.4-3 +libghc-libtagc-dev#0.12.0-2+b1 +libghc-libxml-sax-dev#0.7.2-2+b1 +libghc-libzip-dev#0.10-1+b2 +libghc-lifted-base-dev#0.1.1-1+b1 +libghc-listlike-dev#3.1.4-1+b1 +libghc-llvm-base-dev#3.0.1.0-1 +libghc-llvm-dev#3.0.1.0-1+b1 +libghc-logict-dev#0.5.0.1-1+b1 +libghc-ltk-dev#0.12.0.0-2+b1 +libghc-maccatcher-dev#2.1.5-2+b3 +libghc-magic-dev#1.0.8-8+b1 +libghc-markov-chain-dev#0.0.3.2-1+b1 +libghc-math-functions-dev#0.1.1.0-2+b2 +libghc-maths-dev#0.4.3-1+b1 +libghc-maybet-dev#0.1.2-3+b2 +libghc-mbox-dev#0.1-2+b1 +libghc-memotrie-dev#0.5-1 +libghc-mersenne-random-dev#1.0.0.1-2+b1 +libghc-midi-dev#0.2.0.1-1+b1 +libghc-mime-mail-dev#0.4.1.1-2+b3 +libghc-missingh-dev#1.1.0.3-6+b3 +libghc-mmap-dev#0.5.7-2+b1 +libghc-monad-control-dev#0.3.1.3-1+b1 +libghc-monad-loops-dev#0.3.2.0-1 +libghc-monad-par-dev#0.1.0.3-2+b1 +libghc-monadcatchio-mtl-dev#0.3.0.4-2+b2 +libghc-monadcatchio-transformers-dev#0.3.0.0-2+b1 +libghc-monadcryptorandom-dev#0.4.1-1+b2 +libghc-monadrandom-dev#0.1.6-2+b2 +libghc-monads-tf-dev#0.1.0.0-1+b2 +libghc-monoid-transformer-dev#0.0.2-3+b1 +libghc-mtl-dev#2.1.1-1 +libghc-mtlparse-dev#0.1.2-2+b2 +libghc-murmur-hash-dev#0.1.0.5-2+b1 +libghc-mwc-random-dev#0.11.0.0-4+b1 +libghc-ncurses-dev#0.2.1-1+b1 +libghc-netwire-dev#3.1.0-2+b5 +libghc-network-conduit-dev#0.4.0.1-2 +libghc-network-dev#2.3.0.13-1+b2 +libghc-network-protocol-xmpp-dev#0.4.3-1 +libghc-newtype-dev#0.2-1 +libghc-non-negative-dev#0.1-2+b1 +libghc-numbers-dev#2009.8.9-2+b1 +libghc-numeric-quest-dev#0.2-1+b1 +libghc-numinstances-dev#1.0-2+b1 +libghc-numtype-dev#1.0-2+b1 +libghc-oeis-dev#0.3.1-2+b3 +libghc-openal-dev#1.3.1.3-4+b1 +libghc-opengl-dev#2.2.3.1-1+b1 +libghc-openpgp-asciiarmor-dev#0.1-1+b2 +libghc-options-dev#0.1.1-1 +libghc-pandoc-dev#1.9.4.2-2 +libghc-pandoc-types-dev#1.9.1-1+b2 +libghc-pango-dev#0.12.2-1+b2 +libghc-parallel-dev#3.2.0.2-2+b1 +libghc-parseargs-dev#0.1.3.2-2+b1 +libghc-parsec2-dev#2.1.0.1-6+b1 +libghc-parsec3-dev#3.1.2-1+b3 +libghc-pastis-dev#0.1.2-2+b3 +libghc-path-pieces-dev#0.1.0-1+b2 +libghc-patience-dev#0.1.1-1 +libghc-pcre-light-dev#0.4-3+b1 +libghc-pem-dev#0.1.1-1+b3 +libghc-persistent-dev#0.9.0.4-2 +libghc-persistent-sqlite-dev#0.9.0.2-2 +libghc-persistent-template-dev#0.9.0.2-1 +libghc-polyparse-dev#1.7-1+b2 +libghc-pool-conduit-dev#0.1.0.2-1 +libghc-postgresql-libpq-dev#0.8.2-1 +libghc-postgresql-simple-dev#0.1.4.3-1 +libghc-pretty-show-dev#1.1.1-4+b1 +libghc-primes-dev#0.2.1.0-2+b1 +libghc-primitive-dev#0.4.1-1+b1 +libghc-psqueue-dev#1.1-2+b1 +libghc-puremd5-dev#2.1.0.3-2+b4 +libghc-pwstore-fast-dev#2.2-2+b4 +libghc-quickcheck1-dev#1.2.0.1-2+b1 +libghc-quickcheck2-dev#2.4.2-1+b1 +libghc-random-dev#1.0.1.1-1+b1 +libghc-random-shuffle-dev#0.0.3-2+b2 +libghc-ranged-sets-dev#0.3.0-2+b1 +libghc-ranges-dev#0.2.4-2+b1 +libghc-reactive-banana-dev#0.6.0.0-1+b3 +libghc-readline-dev#1.0.1.0-3+b1 +libghc-recaptcha-dev#0.1-4+b3 +libghc-regex-base-dev#0.93.2-2+b2 +libghc-regex-compat-dev#0.95.1-2+b1 +libghc-regex-pcre-dev#0.94.2-2+b1 +libghc-regex-posix-dev#0.95.1-2+b1 +libghc-regex-tdfa-dev#1.1.8-2+b1 +libghc-regex-tdfa-utf8-dev#1.0-5+b3 +libghc-regexpr-dev#0.5.4-2+b2 +libghc-representable-functors-dev#2.4.0.2-1+b1 +libghc-representable-tries-dev#2.4.0.2-1 +libghc-resource-pool-dev#0.2.1.0-2+b4 +libghc-resourcet-dev#0.3.2.1-1+b1 +libghc-rsa-dev#1.2.1.0-1+b1 +libghc-safe-dev#0.3.3-1+b1 +libghc-safecopy-dev#0.6.1-1+b1 +libghc-sdl-dev#0.6.3-1+b1 +libghc-sdl-gfx-dev#0.6.0-3+b1 +libghc-sdl-image-dev#0.6.1-3+b1 +libghc-sdl-mixer-dev#0.6.1-3+b1 +libghc-sdl-ttf-dev#0.6.1-3+b1 +libghc-semigroupoids-dev#1.3.1.2-1+b1 +libghc-semigroups-dev#0.8.3.2-1 +libghc-sendfile-dev#0.7.6-1+b2 +libghc-sha-dev#1.5.0.1-1 +libghc-shakespeare-css-dev#1.0.1.2-1+b1 +libghc-shakespeare-dev#1.0.0.2-1+b1 +libghc-shakespeare-i18n-dev#1.0.0.2-1+b1 +libghc-shakespeare-js-dev#1.0.0.2-1+b1 +libghc-shakespeare-text-dev#1.0.0.2-1+b1 +libghc-shellac-dev#0.9.5.1-2+b2 +libghc-show-dev#0.4.1.2-1+b2 +libghc-silently-dev#1.1.4-1+b2 +libghc-simple-sendfile-dev#0.2.3-1+b2 +libghc-simpleea-dev#0.1.1-2+b2 +libghc-simpleirc-dev#0.2.1-2+b3 +libghc-skein-dev#0.1.0.7-2+b1 +libghc-smallcheck-dev#0.6-1+b1 +libghc-smtpclient-dev#1.0.4-3+b3 +libghc-snap-core-dev#0.8.1-1+b4 +libghc-snap-server-dev#0.8.1.1-1 +libghc-socks-dev#0.4.1-1+b4 +libghc-split-dev#0.1.4.2-2 +libghc-src-exts-dev#1.11.1-3+b1 +libghc-statevar-dev#1.0.0.0-2+b1 +libghc-static-hash-dev#0.0.1-3+b2 +libghc-statistics-dev#0.10.1.0-2+b1 +libghc-stm-dev#2.3-1 +libghc-stream-dev#0.4.6-1+b1 +libghc-strict-concurrency-dev#0.2.4.1-2+b1 +libghc-strict-dev#0.3.2-2+b1 +libghc-strptime-dev#1.0.6-1 +libghc-svgcairo-dev#0.12.1-1+b2 +libghc-syb-dev#0.3.6.1-1 +libghc-syb-with-class-dev#0.6.1.3-1+b1 +libghc-syb-with-class-instances-text-dev#0.0.1-3+b2 +libghc-system-fileio-dev#0.3.8-1 +libghc-system-filepath-dev#0.4.6-1+b2 +libghc-tagged-dev#0.4.2.1-1 +libghc-tagsoup-dev#0.12.6-1+b3 +libghc-tagstream-conduit-dev#0.3.2-1 +libghc-tar-dev#0.3.2.0-2+b1 +libghc-template-dev#0.2.0.7-1+b1 +libghc-temporary-dev#1.1.2.3-1+b1 +libghc-terminfo-dev#0.3.2.3-1+b1 +libghc-test-framework-dev#0.6-1+b1 +libghc-test-framework-hunit-dev#0.2.7-1+b3 +libghc-test-framework-quickcheck2-dev#0.2.12.1-1+b1 +libghc-test-framework-th-dev#0.2.2-5 +libghc-test-framework-th-prime-dev#0.0.5-1 +libghc-testpack-dev#2.1.1-1+b2 +libghc-texmath-dev#0.6.0.6-1+b2 +libghc-text-dev#0.11.2.0-1 +libghc-text-icu-dev#0.6.3.4-2+b2 +libghc-tinyurl-dev#0.1.0-2+b3 +libghc-tls-dev#0.9.5-1+b4 +libghc-tls-extra-dev#0.4.6.1-2 +libghc-tokyocabinet-dev#0.0.5-5+b3 +libghc-transformers-base-dev#0.4.1-2+b2 +libghc-transformers-dev#0.3.0.0-1 +libghc-type-level-dev#0.2.4-5 +libghc-uniplate-dev#1.6.7-1+b2 +libghc-unix-bytestring-dev#0.3.5-2+b1 +libghc-unix-compat-dev#0.3.0.1-1+b1 +libghc-unixutils-dev#1.50-1+b1 +libghc-unlambda-dev#0.1-2+b2 +libghc-unordered-containers-dev#0.2.1.0-1 +libghc-uri-dev#0.1.6-1+b2 +libghc-url-dev#2.1.2-4+b1 +libghc-utf8-light-dev#0.4.0.1-2+b1 +libghc-utf8-string-dev#0.3.7-1+b1 +libghc-utility-ht-dev#0.0.5.1-3+b1 +libghc-uuagc-cabal-dev#1.0.2.0-1+b1 +libghc-uuid-dev#1.2.3-2+b4 +libghc-uulib-dev#0.9.14-2 +libghc-vault-dev#0.2.0.0-1+b2 +libghc-vector-algorithms-dev#0.5.4-1+b2 +libghc-vector-dev#0.9.1-2+b1 +libghc-vector-space-dev#0.8.1-1 +libghc-vector-space-points-dev#0.1.1.0-1+b1 +libghc-void-dev#0.5.5.1-2+b1 +libghc-vte-dev#0.12.1-1+b3 +libghc-vty-dev#4.7.0.14-1+b1 +libghc-wai-app-file-cgi-dev#0.5.8-1+b4 +libghc-wai-app-static-dev#1.2.0.3-1+b3 +libghc-wai-dev#1.2.0.2-1+b2 +libghc-wai-extra-dev#1.2.0.4-1 +libghc-wai-logger-dev#0.1.4-1+b6 +libghc-wai-logger-prefork-dev#0.1.3-1+b6 +libghc-wai-test-dev#1.2.0.2-1 +libghc-warp-dev#1.2.1.1-1 +libghc-warp-tls-dev#1.2.0.4-1+b4 +libghc-web-routes-dev#0.25.3-2+b3 +libghc-webkit-dev#0.12.3-2+b1 +libghc-weighted-regexp-dev#0.3.1.1-2+b1 +libghc-x11-dev#1.5.0.1-1+b2 +libghc-x11-xft-dev#0.3.1-1+b3 +libghc-xdg-basedir-dev#0.2.1-2+b1 +libghc-xhtml-dev#3000.2.1-1 +libghc-xml-conduit-dev#0.7.0.2-1 +libghc-xml-dev#1.3.12-1+b2 +libghc-xml-types-dev#0.3.1-2+b2 +libghc-xml2html-dev#0.1.2.3-1 +libghc-xmonad-contrib-dev#0.10-4~deb7u1 +libghc-xmonad-dev#0.10-4+b2 +libghc-xss-sanitize-dev#0.3.2-1+b1 +libghc-yaml-dev#0.7.0.2-1+b2 +libghc-yaml-light-dev#0.1.4-2+b2 +libghc-yesod-auth-dev#1.0.2.1-2+b2 +libghc-yesod-core-dev#1.0.1.2-1+b3 +libghc-yesod-default-dev#1.0.1.1-1+b1 +libghc-yesod-dev#1.0.1.6-2+b3 +libghc-yesod-form-dev#1.0.0.4-1+b1 +libghc-yesod-json-dev#1.0.0.1-1+b3 +libghc-yesod-markdown-dev#0.4.0-1+b3 +libghc-yesod-persistent-dev#1.0.0.1-1+b1 +libghc-yesod-routes-dev#1.0.1.2-1 +libghc-yesod-static-dev#1.0.0.2-1+b3 +libghc-yesod-test-dev#0.2.0.6-1 +libghc-zip-archive-dev#0.1.1.7-3+b2 +libghc-zlib-bindings-dev#0.1.0.1-1 +libghc-zlib-conduit-dev#0.4.0.1-1 +libghc-zlib-dev#0.5.3.3-1+b1 +libghc-zlib-enum-dev#0.2.2.1-1+b1 +libghc6-agda-dev#1:8 +libghc6-alut-dev#1:8 +libghc6-arrows-dev#1:8 +libghc6-binary-dev#1:8 +libghc6-binary-shared-dev#1:8 +libghc6-bzlib-dev#1:8 +libghc6-cairo-dev#1:8 +libghc6-cautious-file-dev#1:8 +libghc6-cgi-dev#1:8 +libghc6-colour-dev#1:8 +libghc6-configfile-dev#1:8 +libghc6-convertible-dev#1:8 +libghc6-cpphs-dev#1:8 +libghc6-criterion-dev#1:8 +libghc6-csv-dev#1:8 +libghc6-curl-dev#1:8 +libghc6-data-accessor-dev#1:8 +libghc6-dataenc-dev#1:8 +libghc6-datetime-dev#1:8 +libghc6-debian-dev#1:8 +libghc6-deepseq-dev#1:8 +libghc6-diagrams-dev#1:8 +libghc6-diff-dev#1:8 +libghc6-digest-dev#1:8 +libghc6-edison-api-dev#1:8 +libghc6-edison-core-dev#1:8 +libghc6-editline-dev#1:8 +libghc6-erf-dev#1:8 +libghc6-event-list-dev#1:8 +libghc6-explicit-exception-dev#1:8 +libghc6-fastcgi-dev#1:8 +libghc6-feed-dev#1:8 +libghc6-fgl-dev#1:8 +libghc6-filemanip-dev#1:8 +libghc6-filestore-dev#1:8 +libghc6-ftphs-dev#1:8 +libghc6-gconf-dev#1:8 +libghc6-ghc-events-dev#1:8 +libghc6-ghc-mtl-dev#1:8 +libghc6-ghc-paths-dev#1:8 +libghc6-gio-dev#1:8 +libghc6-gitit-dev#1:8 +libghc6-glade-dev#1:8 +libghc6-glfw-dev#1:8 +libghc6-glib-dev#1:8 +libghc6-glut-dev#1:8 +libghc6-gstreamer-dev#1:8 +libghc6-gtk-dev#1:8 +libghc6-gtkglext-dev#1:8 +libghc6-gtksourceview2-dev#1:8 +libghc6-haddock-dev#1:8 +libghc6-happstack-dev#1:8 +libghc6-happstack-server-dev#1:8 +libghc6-harp-dev#1:8 +libghc6-hashed-storage-dev#1:8 +libghc6-haskeline-dev#1:8 +libghc6-haskell-lexer-dev#1:8 +libghc6-haskell-src-dev#1:8 +libghc6-haskelldb-dev#1:8 +libghc6-haskelldb-hdbc-dev#1:8 +libghc6-haskelldb-hdbc-odbc-dev#1:8 +libghc6-haskelldb-hdbc-postgresql-dev#1:8 +libghc6-haskelldb-hdbc-sqlite3-dev#1:8 +libghc6-haskore-dev#1:8 +libghc6-haxml-dev#1:8 +libghc6-haxr-dev#1:8 +libghc6-hdbc-dev#1:8 +libghc6-hdbc-odbc-dev#1:8 +libghc6-hdbc-postgresql-dev#1:8 +libghc6-hdbc-sqlite3-dev#1:8 +libghc6-highlighting-kate-dev#1:8 +libghc6-hint-dev#1:8 +libghc6-hjavascript-dev#1:8 +libghc6-hjscript-dev#1:8 +libghc6-hoauth-dev#1:8 +libghc6-hscolour-dev#1:8 +libghc6-hscurses-dev#1:8 +libghc6-hsemail-dev#1:8 +libghc6-hsh-dev#1:8 +libghc6-hslogger-dev#1:8 +libghc6-hsp-dev#1:8 +libghc6-hsql-dev#1:8 +libghc6-hsql-mysql-dev#1:8 +libghc6-hsql-odbc-dev#1:8 +libghc6-hsql-postgresql-dev#1:8 +libghc6-hsql-sqlite3-dev#1:8 +libghc6-hstringtemplate-dev#1:8 +libghc6-hsx-dev#1:8 +libghc6-html-dev#1:8 +libghc6-http-dev#1:8 +libghc6-hunit-dev#1:8 +libghc6-hxt-dev#1:8 +libghc6-ifelse-dev#1:8 +libghc6-irc-dev#1:8 +libghc6-json-dev#1:8 +libghc6-language-c-dev#1:8 +libghc6-lazysmallcheck-dev#1:8 +libghc6-ldap-dev#1:8 +libghc6-leksah-server-dev#1:8 +libghc6-llvm-dev#1:8 +libghc6-ltk-dev#1:8 +libghc6-magic-dev#1:8 +libghc6-markov-chain-dev#1:8 +libghc6-maybet-dev#1:8 +libghc6-midi-dev#1:8 +libghc6-missingh-dev#1:8 +libghc6-mmap-dev#1:8 +libghc6-monadcatchio-mtl-dev#1:8 +libghc6-monoid-transformer-dev#1:8 +libghc6-mtl-dev#1:8 +libghc6-mwc-random-dev#1:8 +libghc6-network-dev#1:8 +libghc6-non-negative-dev#1:8 +libghc6-openal-dev#1:8 +libghc6-opengl-dev#1:8 +libghc6-pandoc-dev#1:8 +libghc6-pango-dev#1:8 +libghc6-parallel-dev#1:8 +libghc6-parsec2-dev#1:8 +libghc6-parsec3-dev#1:8 +libghc6-pcre-light-dev#1:8 +libghc6-polyparse-dev#1:8 +libghc6-pretty-show-dev#1:8 +libghc6-primitive-dev#1:8 +libghc6-quickcheck1-dev#1:8 +libghc6-quickcheck2-dev#1:8 +libghc6-recaptcha-dev#1:8 +libghc6-regex-base-dev#1:8 +libghc6-regex-compat-dev#1:8 +libghc6-regex-posix-dev#1:8 +libghc6-regex-tdfa-dev#1:8 +libghc6-regex-tdfa-utf8-dev#1:8 +libghc6-safe-dev#1:8 +libghc6-sdl-dev#1:8 +libghc6-sdl-gfx-dev#1:8 +libghc6-sdl-image-dev#1:8 +libghc6-sdl-mixer-dev#1:8 +libghc6-sdl-ttf-dev#1:8 +libghc6-sendfile-dev#1:8 +libghc6-sha-dev#1:8 +libghc6-smtpclient-dev#1:8 +libghc6-split-dev#1:8 +libghc6-src-exts-dev#1:8 +libghc6-statistics-dev#1:8 +libghc6-stm-dev#1:8 +libghc6-stream-dev#1:8 +libghc6-strict-concurrency-dev#1:8 +libghc6-svgcairo-dev#1:8 +libghc6-syb-with-class-dev#1:8 +libghc6-syb-with-class-instances-text-dev#1:8 +libghc6-tagsoup-dev#1:8 +libghc6-tar-dev#1:8 +libghc6-terminfo-dev#1:8 +libghc6-testpack-dev#1:8 +libghc6-texmath-dev#1:8 +libghc6-text-dev#1:8 +libghc6-tokyocabinet-dev#1:8 +libghc6-transformers-dev#1:8 +libghc6-type-level-dev#1:8 +libghc6-uniplate-dev#1:8 +libghc6-unix-compat-dev#1:8 +libghc6-unixutils-dev#1:8 +libghc6-url-dev#1:8 +libghc6-utility-ht-dev#1:8 +libghc6-uulib-dev#1:8 +libghc6-vector-algorithms-dev#1:8 +libghc6-vector-dev#1:8 +libghc6-vte-dev#1:8 +libghc6-vty-dev#1:8 +libghc6-webkit-dev#1:8 +libghc6-x11-dev#1:8 +libghc6-x11-xft-dev#1:8 +libghc6-xhtml-dev#1:8 +libghc6-xml-dev#1:8 +libghc6-xmonad-contrib-dev#1:8 +libghc6-xmonad-dev#1:8 +libghc6-zip-archive-dev#1:8 +libghc6-zlib-dev#1:8 +libghemical-dev#3.0.0-2 +libgif-dev#4.1.6-10 +libgiftiio-dev#1.0.9-1 +libgig-dev#3.3.0-2 +libgii1-dev#1:1.0.2-4.1 +libgimp2.0-dev#2.8.2-2+deb7u1 +libginac-dev#1.6.2-1 +libginspx-dev#20050529-3.1 +libgio2.0-cil-dev#2.22.3-2 +libgirara-dev#0.1.2-3 +libgirepository1.0-dev#1.32.1-1 +libgjs-dev#1.32.0-5 +libgkeyfile-cil-dev#0.1-4 +libgksu2-dev#2.0.13~pre1-6 +libgl1-mesa-dev#8.0.5-4+deb7u2 +libgl1-mesa-swx11-dev#8.0.5-4+deb7u2 +libgl2ps-dev#1.3.6-1 +libglade2-dev#1:2.6.4-1 +libglade2.0-cil-dev#2.12.10-5 +libglademm-2.4-dev#2.6.7-2 +libgladeui-1-dev#3.6.7-2.1 +libgladeui-dev#3.12.1-1 +libglbsp-dev#2.24-1 +libglc-dev#0.7.2-5+b1 +libgle3-dev#3.1.0-7 +libgles1-mesa-dev#8.0.5-4+deb7u2 +libgles2-mesa-dev#8.0.5-4+deb7u2 +libglew-dev#1.7.0-3 +libglewmx-dev#1.7.0-3 +libglfw-dev#2.7.2-1 +libglib2.0-cil-dev#2.12.10-5 +libglib2.0-dev#2.33.12+really2.32.4-5 +libglibmm-2.4-dev#2.32.1-1 +libglide2-dev#2002.04.10ds1-7 +libglide3-dev#2002.04.10ds1-7 +libglm-dev#0.9.3.3+dfsg-0.1 +libglobus-authz-callout-error-dev#2.2-1 +libglobus-authz-dev#2.2-1 +libglobus-callout-dev#2.2-1 +libglobus-common-dev#14.7-2 +libglobus-ftp-client-dev#7.3-1 +libglobus-ftp-control-dev#4.4-1 +libglobus-gass-cache-dev#8.1-2 +libglobus-gass-copy-dev#8.4-1 +libglobus-gass-server-ez-dev#4.3-1 +libglobus-gass-transfer-dev#7.2-1 +libglobus-gfork-dev#3.2-1 +libglobus-gram-client-dev#12.4-1 +libglobus-gram-job-manager-callout-error-dev#2.1-2 +libglobus-gram-protocol-dev#11.3-1 +libglobus-gridftp-server-control-dev#2.5-2 +libglobus-gridftp-server-dev#6.10-2 +libglobus-gridmap-callout-error-dev#1.2-2 +libglobus-gsi-callback-dev#4.2-1 +libglobus-gsi-cert-utils-dev#8.3-1 +libglobus-gsi-credential-dev#5.3-1 +libglobus-gsi-openssl-error-dev#2.1-2 +libglobus-gsi-proxy-core-dev#6.2-1 +libglobus-gsi-proxy-ssl-dev#4.1-2 +libglobus-gsi-sysconfig-dev#5.2-1 +libglobus-gss-assist-dev#8.5-1 +libglobus-gssapi-error-dev#4.1-2 +libglobus-gssapi-gsi-dev#10.6-1 +libglobus-io-dev#9.3-1 +libglobus-openssl-module-dev#3.2-1 +libglobus-rls-client-dev#5.2-8 +libglobus-rsl-dev#9.1-2 +libglobus-scheduler-event-generator-dev#4.6-1 +libglobus-usage-dev#3.1-2 +libglobus-xio-dev#3.3-1 +libglobus-xio-gsi-driver-dev#2.3-1 +libglobus-xio-pipe-driver-dev#2.2-1 +libglobus-xio-popen-driver-dev#2.3-1 +libgloox-dev#1.0-1.1 +libglpk-dev#4.45-1 +libglrr-glib-dev#20050529-3.1 +libglrr-gobject-dev#20050529-3.1 +libglrr-gtk-dev#20050529-3.1 +libglrr-widgets-dev#20050529-3.1 +libglu1-mesa-dev#8.0.5-4+deb7u2 +libglui-dev#2.36-4 +libglw1-mesa-dev#8.0.0-1 +libgme-dev#0.5.5-2 +libgmerlin-avdec-dev#1.2.0~dfsg-1+b1 +libgmerlin-dev#1.2.0~dfsg+1-1 +libgmime-2.6-dev#2.6.10-1 +libgmime2.6-cil-dev#2.6.10-1 +libgmlib-dev#1.0.6-1 +libgmm++-dev#4.1.1+dfsg1-11 +libgmp-dev#2:5.0.5+dfsg-2 +libgmp-ocaml-dev#20021123-17+b3 +libgmp3-dev#2:5.0.5+dfsg-2 +libgmpada3-dev#0.0.20120331-1 +libgmt-dev#4.5.7-2 +libgmtk-dev#1.0.6-1 +libgnadecommon2-dev#1.6.2-9 +libgnadeodbc2-dev#1.6.2-9 +libgnadesqlite3-2-dev#1.6.2-9 +libgnatprj4.6-dev#4.6.3-8 +libgnatvsn4.6-dev#4.6.3-8 +libgnelib-dev#0.75+svn20091130-1+b1 +libgnet-dev#2.0.8-2.2 +libgnokii-dev#0.6.30+dfsg-1+b1 +libgnome-bluetooth-dev#3.4.2-1 +libgnome-desktop-3-dev#3.4.2-1 +libgnome-desktop-dev#2.32.1-2 +libgnome-keyring-dev#3.4.1-1 +libgnome-keyring1.0-cil-dev#1.0.0-4 +libgnome-mag-dev#1:0.16.3-1 +libgnome-media-profiles-dev#3.0.0-1 +libgnome-menu-3-dev#3.4.2-5 +libgnome-menu-dev#3.0.1-4 +libgnome-speech-dev#1:0.4.25-5 +libgnome-vfs2.0-cil-dev#2.24.2-3 +libgnome-vfsmm-2.6-dev#2.26.0-1 +libgnome2-dev#2.32.1-3 +libgnome2.0-cil-dev#2.24.2-3 +libgnomeada2.24.1-dev#2.24.1-7 +libgnomecanvas2-dev#2.30.3-1.2 +libgnomecanvasmm-2.6-dev#2.26.0-1 +libgnomecups1.0-dev#0.2.3-5 +libgnomedesktop2.0-cil-dev#2.26.0-8 +libgnomekbd-dev#3.4.0.2-1 +libgnomemm-2.6-dev#2.30.0-1 +libgnomeprint2.2-dev#2.18.8-3 +libgnomeprintui2.2-dev#2.18.6-3 +libgnomeui-dev#2.24.5-2 +libgnomeuimm-2.6-dev#2.28.0-1 +libgnomevfs2-dev#1:2.24.4-2 +libgnuift0-dev#0.1.14-12 +libgnuplot-ocaml-dev#0.8.3-3 +libgnustep-base-dev#1.22.1-4 +libgnustep-dl2-dev#0.12.0-9+nmu1 +libgnustep-gui-dev#0.20.0-3 +libgnutls-dev#2.12.20-8+deb7u1 +libgoa-1.0-dev#3.4.2-2 +libgoffice-0.8-dev#0.8.17-1.2 +libgofigure-dev#0.9.0-1+b2 +libgoocanvas-dev#0.15-1 +libgoocanvasmm-dev#0.15.4-1 +libgoogle-perftools-dev#2.0-2 +libgooglepinyin0-dev#0.1.2-1 +libgpac-dev#0.5.0~dfsg0-1 +libgpds-dev#1.5.1-6 +libgpelaunch-dev#0.14-6 +libgpepimc-dev#0.9-4 +libgpeschedule-dev#0.17-4 +libgpevtype-dev#0.50-6 +libgpewidget-dev#0.117-6 +libgpg-error-dev#1.10-3.1 +libgpgme11-dev#1.2.0-1.4 +libgphoto2-2-dev#2.4.14-2 +libgpiv3-dev#0.6.1-4 +libgpm-dev#1.20.4-6 +libgpod-cil-dev#0.8.2-7 +libgpod-dev#0.8.2-7 +libgpod-nogtk-dev#0.8.2-7 +libgportugol-dev#1.1-2 +libgps-dev#3.6-4+deb7u1 +libgraflib1-dev#20061220+dfsg3-2 +libgrafx11-1-dev#20061220+dfsg3-2 +libgrantlee-dev#0.1.4-1 +libgraphicsmagick++1-dev#1.3.16-1.1 +libgraphicsmagick1-dev#1.3.16-1.1 +libgraphite-dev#1:2.3.1-0.2 +libgraphite2-dev#1.1.3-1 +libgraphviz-dev#2.26.3-14+deb7u1 +libgretl1-dev#1.9.9-1 +libgrib-api-dev#1.9.16-2+b1 +libgrib2c-dev#1.2.2-2+b1 +libgridsite-dev#1.7.16-1 +libgrilo-0.1-dev#0.1.19-1 +libgringotts-dev#1.2.10~pre3-1 +libgrits-dev#0.7-1 +libgrok-dev#1.20110708.1-4 +libgrss-dev#0.5.0-1 +libgs-dev#9.05~dfsg-6.3+deb7u1 +libgsasl7-dev#1.8.0-2 +libgsecuredelete-dev#0.2-1 +libgsf-1-dev#1.14.21-2.1 +libgsf-gnome-1-dev#1.14.21-2.1 +libgsl0-dev#1.15+dfsg.2-2 +libgsm0710-dev#1.2.2-2 +libgsm0710mux-dev#0.11.2-1.1 +libgsm1-dev#1.0.13-4 +libgsmme-dev#1.10-13.2 +libgsnmp0-dev#0.3.0-1.1 +libgsql-dev#0.2.2-1.2+b1 +libgss-dev#1.0.2-1 +libgssdp-1.0-dev#0.12.2.1-2 +libgssglue-dev#0.4-2 +libgst-dev#3.2.4-2 +libgstbuzztard-dev#0.5.0-2+deb7u1 +libgstreamer-ocaml-dev#0.1.0-3+b1 +libgstreamer-plugins-bad0.10-dev#0.10.23-7.1+deb7u1 +libgstreamer-plugins-base0.10-dev#0.10.36-1.1 +libgstreamer0.10-cil-dev#0.9.2-4 +libgstreamer0.10-dev#0.10.36-1.2 +libgstrtspserver-0.10-dev#0.10.8-3 +libgtest-dev#1.6.0-2 +libgtextutils-dev#0.6.2-1 +libgtg-dev#0.2+dfsg-1 +libgtk-3-dev#3.4.2-7 +libgtk-sharp-beans2.0-cil-dev#2.14.1-3 +libgtk-vnc-1.0-dev#0.5.0-3.1 +libgtk-vnc-2.0-dev#0.5.0-3.1 +libgtk2.0-cil-dev#2.12.10-5 +libgtk2.0-dev#2.24.10-2 +libgtkada2.24.1-dev#2.24.1-7 +libgtkdatabox-0.9.1-1-dev#1:0.9.1.1-4 +libgtkgl2.0-dev#2.0.1-2 +libgtkglada2.24.1-dev#2.24.1-7 +libgtkglarea-cil-dev#0.0.17-6 +libgtkglext1-dev#1.2.0-2 +libgtkglextmm-x11-1.2-dev#1.2.0-4.1 +libgtkhex-3-dev#3.4.1-1 +libgtkhotkey-dev#0.2.1-3 +libgtkhtml-4.0-dev#4.4.4-1 +libgtkhtml-editor-3.14-dev#3.32.2-2.1 +libgtkhtml-editor-4.0-dev#4.4.4-1 +libgtkhtml3.14-cil-dev#2.26.0-8 +libgtkhtml3.14-dev#3.32.2-2.1 +libgtkimageview-dev#1.6.4+dfsg-0.1 +libgtkmathview-dev#0.8.0-8 +libgtkmm-2.4-dev#1:2.24.2-1 +libgtkmm-3.0-dev#3.4.2-1 +libgtkpod-dev#2.1.2-1 +libgtksourceview-3.0-dev#3.4.2-1 +libgtksourceview2-cil-dev#2.26.0-8 +libgtksourceview2.0-dev#2.10.4-1 +libgtksourceviewmm-3.0-dev#3.2.0-1 +libgtkspell-3-dev#3.0.0~hg20110814-1 +libgtkspell-dev#2.0.16-1 +libgtop2-dev#2.28.4-3 +libgts-dev#0.7.6+darcs110121-1.1 +libguac-dev#0.6.0-2 +libgucharmap-2-90-dev#1:3.4.1.1-2.1 +libgudev-1.0-dev#175-7.2 +libgudev1.0-cil-dev#0.1-3 +libguess-dev#1.1-1 +libguestfs-dev#1:1.18.1-1+deb7u3 +libguestfs-gobject-dev#1:1.18.1-1+deb7u3 +libguestfs-ocaml-dev#1:1.18.1-1+deb7u3 +libguichan-dev#0.8.2-10+b1 +libgupnp-1.0-dev#0.18.4-1 +libgupnp-av-1.0-dev#0.10.3-1 +libgupnp-dlna-1.0-dev#0.6.6-1 +libgupnp-igd-1.0-dev#0.2.1-2 +libgusb-dev#0.1.3-5 +libgutenprint-dev#5.2.9-1 +libgutenprintui2-dev#5.2.9-1 +libguytools2-dev#2.0.1-1.1 +libgvnc-1.0-dev#0.5.0-3.1 +libgweather-3-dev#3.4.1-1+build1 +libgwenhywfar60-dev#4.3.3-1 +libgwrap-runtime-dev#1.9.14-1.1 +libgwyddion20-dev#2.28-2 +libgxps-dev#0.2.2-2 +libgyoto0-dev#0.0.3-5 +libh323plus-dev#1.24.0~dfsg2-1 +libhaildb-dev#2.3.2-1.2 +libhal-dev#0.5.14-8 +libhal-storage-dev#0.5.14-8 +libhamlib++-dev#1.2.15.1-1 +libhamlib-dev#1.2.15.1-1 +libhandoff-dev#0.1-5 +libhangul-dev#0.1.0-2 +libharminv-dev#1.3.1-9 +libhashkit-dev#1.0.8-1 +libhawknl-dev#1.6.8+dfsg2-1 +libhbaapi-dev#2.2.5-1 +libhbalinux-dev#1.0.14-1 +libhd-dev#16.0-2.2 +libhdate-dev#1.6-1 +libhdf4-alt-dev#4.2r4-13 +libhdf4-dev#4.2r4-13 +libhdf4g-dev#4.2r4-13 +libhdf5-dev#1.8.8-9 +libhdf5-mpi-dev#1.8.8-9 +libhdf5-mpich2-dev#1.8.8-9 +libhdf5-openmpi-dev#1.8.8-9 +libhdf5-serial-dev#1.8.8-9 +libhdfeos-dev#2.17v1.00.dfsg.1-3 +libhdhomerun-dev#20120405-1 +libhe5-hdfeos-dev#5.1.13.dfsg.1-3 +libheartbeat2-dev#1:3.0.5-3 +libhepmc-dev#2.06.09-1 +libhepmcfio-dev#2.06.09-1 +libhepmcinterface8-dev#8.1.65-1 +libherwig59-2-dev#20061220+dfsg3-2 +libhesiod-dev#3.0.2-21 +libhfsp-dev#1.0.4-12 +libhighgui-dev#2.3.1-11 +libhippocanvas-dev#0.3.1-1.1 +libhiredis-dev#0.10.1-7 +libhivex-dev#1.3.6-2 +libhivex-ocaml-dev#1.3.6-2 +libhkl-dev#4.0.3-4 +libhmsbeagle-dev#1.0-6 +libhocr-dev#0.10.17-1+b2 +libhpdf-dev#2.2.1-1 +libhpmud-dev#3.12.6-3.1+deb7u1 +libhsclient-dev#1.1.0-7-g1044a28-1 +libhtmlcxx-dev#0.85-2 +libhtp-dev#0.2.6-2 +libhtsengine-dev#1.06-1 +libhttp-ocaml-dev#0.1.5-1+b2 +libhttrack-dev#3.46.1-1 +libhunspell-dev#1.3.2-4 +libhwloc-dev#1.4.1-4 +libhx-dev#3.12.1-1 +libhyantes-dev#1.3.0-1 +libhyena-cil-dev#0.5-2 +libhyphen-dev#2.8.3-2 +libhypre-dev#2.8.0b-1 +libhz-dev#0.3.16-3 +libi2c-dev#3.1.0-2 +libibcm-dev#1.0.4-1.1 +libibcommon-dev#1.1.2-20090314-1 +libibdm-dev#1.2-OFED-1.4.2-1.3 +libibmad-dev#1.2.3-20090314-1.1 +libibtk-dev#0.0.14-12 +libibumad-dev#1.2.3-20090314-1.1 +libibus-1.0-dev#1.4.1-9+deb7u1 +libibus-qt-dev#1.3.1-2.1 +libibverbs-dev#1.1.6-1 +libical-dev#0.48-2 +libicapapi-dev#1:0.1.6-1.1 +libicc-dev#2.12+argyll1.4.0-8 +libicc-utils-dev#1.6.4-1+b1 +libice-dev#2:1.0.8-2 +libicee-dev#1.2.0-6.1 +libicns-dev#0.8.1-1 +libiconv-hook-dev#0.0.20021209-10 +libics-dev#1.5.2-3 +libicu-dev#4.8.1.1-12+deb7u1 +libid3-3.8.3-dev#3.8.3-15 +libid3tag0-dev#0.15.1b-10 +libident-dev#0.22-3 +libidl-dev#0.8.14-0.2 +libidn11-dev#1.25-2 +libidn2-0-dev#0.8-2 +libido-0.1-dev#0.3.4-1 +libido3-0.1-dev#0.3.4-1 +libidzebra-2.0-dev#2.0.44-3 +libiec16022-dev#0.2.4-1 +libiec61883-dev#1.2.0-0.1 +libieee1284-3-dev#0.2.11-10 +libifp-dev#1.0.0.2-5 +libifstat-dev#1.1-8 +libigraph0-dev#0.5.4-2 +libigstk4-dev#4.4.0-2+b1 +libijs-dev#0.35-8 +libiksemel-dev#1.2-4 +libilmbase-dev#1.0.1-4 +libimdi-dev#1.4.0-8 +libiml-dev#1.0.3-4.2 +libimlib2-dev#1.4.5-1 +libimobiledevice-dev#1.1.1-4 +libindi-dev#0.9.1-2 +libindicate-dev#0.6.92-1 +libindicate-gtk-dev#0.6.92-1 +libindicate-gtk0.1-cil-dev#0.6.92-1 +libindicate-gtk3-dev#0.6.92-1 +libindicate-qt-dev#0.2.5.91-5 +libindicate0.1-cil-dev#0.6.92-1 +libindicator-dev#0.5.0-1 +libindicator-messages-status-provider-dev#0.6.0-1 +libindicator3-dev#0.5.0-1 +libindigo-dev#1.0.0-2 +libinfinity-0.5-dev#0.5.2-6.1 +libini-config-dev#0.1.3-2 +libinifiles-ocaml-dev#1.2-2 +libinnodb-dev#1.0.6.6750-1 +libinotify-ocaml-dev#1.0-1+b3 +libinotifytools0-dev#3.14-1 +libinput-pad-dev#1.0.1-2 +libinsighttoolkit3-dev#3.20.1+git20120521-3 +libinstpatch-dev#1.0.0-3 +libint-dev#1.1.4-1 +libiodbc2-dev#3.52.7-2+deb7u1 +libion-dev#3.0.1~dfsg1-1 +libipa-hbac-dev#1.8.4-2 +libipathverbs-dev#1.2-1 +libipe-dev#7.1.2-1 +libipmiconsole-dev#1.1.5-3 +libipmidetect-dev#1.1.5-3 +libipmimonitoring-dev#1.1.5-3 +libipset-dev#6.12.1-1 +libiptcdata0-dev#1.0.4-3 +libircclient-dev#1.3+dfsg1-3 +libirman-dev#0.4.4-2 +libirrlicht-dev#1.7.3+dfsg1-4 +libisajet758-3-dev#20061220+dfsg3-2 +libiscsi-dev#1.4.0-3 +libisl-dev#0.10-3 +libiso9660-dev#0.83-4 +libisoburn-dev#1.2.2-2 +libisofs-dev#1.2.2-1 +libitl-dev#0.7.0-3 +libitl-gobject-dev#0.2-1 +libitpp-dev#4.2-4 +libitsol-dev#1.0.0-2 +libivykis-dev#0.30.1-2 +libiw-dev#30~pre9-8 +libjack-dev#1:0.121.3+20120418git75e3e20b-2.1 +libjack-jackd2-dev#1.9.8~dfsg.4+20120529git007cdc37-5 +libjalali-dev#0.4.0-1.1 +libjama-dev#1.2.4-2 +libjana-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-ecal-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-gtk-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjansson-dev#2.3.1-2 +libjasper-dev#1.900.1-13 +libjaula-dev#1.4.0-3 +libjavascriptcoregtk-1.0-dev#1.8.1-3.4 +libjavascriptcoregtk-3.0-dev#1.8.1-3.4 +libjbig-dev#2.0-2+deb7u1 +libjbig2dec0-dev#0.11+20120125-1 +libjconv-dev#2.8-6+b1 +libjemalloc-dev#3.0.0-3 +libjim-dev#0.73-3 +libjpeg62-dev#6b1-3 +libjpeg8-dev#8d-1 +libjpgalleg4-dev#2:4.4.2-2.1 +libjs-of-ocaml-dev#1.2-2 +libjson-glib-dev#0.14.2-1 +libjson-spirit-dev#4.04-1+b1 +libjson-static-camlp4-dev#0.9.8-1+b5 +libjson-wheel-ocaml-dev#1.0.6-2+b8 +libjson0-dev#0.10-1.2 +libjsoncpp-dev#0.6.0~rc2-3 +libjte-dev#1.19-1 +libjthread-dev#1.3.1-3 +libjudy-dev#1.0.5-1 +libjuman-dev#5.1-2.1 +libk3b-dev#2.0.2-6 +libkactivities-dev#4:4.8.4-1 +libkakasi2-dev#2.3.5~pre1+cvs20071101-1 +libkal-dev#0.9.0-1 +libkarma-cil-dev#0.1.2-2.3 +libkarma-dev#0.1.2-2.3 +libkate-dev#0.4.1-1 +libkaya-gd-dev#0.4.4-6 +libkaya-gl-dev#0.4.4-6 +libkaya-mysql-dev#0.4.4-6 +libkaya-ncurses-dev#0.4.4-6 +libkaya-ncursesw-dev#0.4.4-6 +libkaya-pgsql-dev#0.4.4-6 +libkaya-sdl-dev#0.4.4-6 +libkaya-sqlite3-dev#0.4.4-6 +libkcddb-dev#4:4.8.4-2 +libkdcraw-dev#4:4.8.4-1 +libkdeedu-dev#4:4.8.4-1 +libkdegames-dev#4:4.8.4-3 +libkdtree++-dev#0.7.0-2 +libkernlib1-dev#20061220+dfsg3-2 +libkexiv2-dev#4:4.8.4-1 +libkeybinder-dev#0.2.2-4 +libkeyutils-dev#1.5.5-3 +libkibi-dev#0.1-1 +libkipi-dev#4:4.8.4-1 +libkiten-dev#4:4.8.4-1 +libklatexformula3-dev#3.2.6-1 +libklibc-dev#2.0.1-3.1 +libkmfl-dev#0.9.8-1 +libkmflcomp-dev#0.9.8-1 +libkml-dev#1.3.0~r863-4.1 +libkmod-dev#9-3 +libkokyu-dev#6.0.3+dfsg-0.1 +libkonq5-dev#4:4.8.4-2 +libkonqsidebarplugin-dev#4:4.8.4-2 +libkopete-dev#4:4.8.4-1+b1 +libkosd2-dev#0.8.1-1 +libkpathsea-dev#2012.20120628-4 +libkqueue-dev#1.0.4-2 +libkrb5-dev#1.10.1+dfsg-5+deb7u1 +libksane-dev#4:4.8.4-1 +libksba-dev#1.2.0-2 +libktoblzcheck1-dev#1.39-1 +libktorrent-dev#1.2.1-1 +libktpcommoninternalsprivate-dev#0.4.0-1 +libkvutils-dev#2.9.0-1 +libkvutils2.2-dev#2.9.0-1 +libkwnn-dev#1.1.1~a021+cvs20100325-6 +libkwwidgets1-dev#1.0.0~cvs20100930-8 +libkxl0-dev#1.1.7-16 +liblablgl-ocaml-dev#1.04-5+b3 +liblablgtk-extras-ocaml-dev#1.0-1+b2 +liblablgtk2-gl-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-gnome-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-ocaml-dev#2.14.2+dfsg-3 +liblablgtkmathview-ocaml-dev#0.7.8-6+b1 +liblablgtksourceview2-ocaml-dev#2.14.2+dfsg-3 +libladr-dev#0.0.200902a-2.1 +libladspa-ocaml-dev#0.1.4-1+b1 +liblapack-dev#3.4.1+dfsg-1+deb70u1 +liblapacke-dev#3.4.1+dfsg-1+deb70u1 +liblas-dev#1.2.1-5+b1 +liblash-compat-dev#1+dfsg0-3 +liblasi-dev#1.1.0-1 +liblasso3-dev#2.3.6-2 +liblastfm-dev#0.4.0~git20090710-2 +liblastfm-ocaml-dev#0.3.0-2+b6 +liblcgdm-dev#1.8.2-1+b2 +liblcms1-dev#1.19.dfsg-1.2 +liblcms2-dev#2.2+git20110628-2.2+deb7u1 +libldap-ocaml-dev#2.1.8-8+b9 +libldap2-dev#2.4.31-1+nmu2 +libldb-dev#1:1.1.6-1 +libldns-dev#1.6.13-1 +libledit-ocaml-dev#2.03-1+b2 +liblensfun-dev#0.2.5-2 +libleptonica-dev#1.69-3.1 +libleveldb-dev#0+20120530.gitdd0d562-1 +liblfc-dev#1.8.2-1+b2 +liblhapdf-dev#5.8.7+repack-1 +liblhasa-dev#0.0.7-2 +liblicense-dev#0.8.1-3 +liblightdm-gobject-dev#1.2.2-4 +liblightdm-qt-dev#1.2.2-4 +liblilv-dev#0.14.2~dfsg0-4 +liblinear-dev#1.8+dfsg-1 +liblinebreak2-dev#2.1-1 +liblink-grammar4-dev#4.7.4-2 +liblinphone-dev#3.5.2-10 +liblip-dev#2.0.0-1.1 +liblircclient-dev#0.9.0~pre1-1 +liblistaller-glib-dev#0.5.5-2 +liblivemedia-dev#2012.05.17-1 +libllvm-2.9-ocaml-dev#2.9+dfsg-7 +libllvm-3.0-ocaml-dev#3.0-10 +libllvm-3.1-ocaml-dev#3.1-1 +libllvm-ocaml-dev#1:3.0-14+nmu2 +liblo-dev#0.26~repack-7 +liblo-ocaml-dev#0.1.0-1+b1 +liblo10k1-dev#1.0.25-2 +libloadpng4-dev#2:4.4.2-2.1 +liblockdev1-dev#1.0.3-1.5 +liblockfile-dev#1.09-5 +liblodo3.0-dev#3.0.2+dfsg-4+b1 +liblog4ada2-dev#1.2-3 +liblog4c-dev#1.2.1-3 +liblog4cplus-dev#1.0.4-1 +liblog4cpp5-dev#1.0-4 +liblog4cxx10-dev#0.10.0-1.2 +liblog4net-cil-dev#1.2.10+dfsg-6 +liblog4shib-dev#1.0.4-1 +liblog4tango4-dev#7.2.6+dfsg-14 +liblogforwarderutils2-dev#2.7-1 +liblognorm-dev#0.3.4-1 +liblogservicecomponentbase2-dev#2.7-1 +liblogservicetoolbase2-dev#2.7-1 +liblogsys-dev#1.4.2-3 +liblogthread-dev#3.0.12-3.2+deb7u2 +libloki-dev#0.1.7-3 +libloudmouth1-dev#1.4.3-9 +liblouis-dev#2.4.1-1 +liblouisutdml-dev#2.2.0-1 +liblouisxml-dev#2.4.0-3 +liblowpan-dev#0.2.2-2.1 +liblpsolve55-dev#5.5.0.13-7 +liblqr-1-0-dev#0.4.1-2 +liblrdf0-dev#0.4.0-5 +liblrm2-dev#1.0.9+hg2665-1 +liblrs-dev#0.42c-1+b1 +liblscp-dev#0.5.6-6 +libltcsmpte-dev#0.4.4-1 +libltdl-dev#2.4.2-1.1 +liblttctl-dev#0.89-05122011-1 +liblttd-dev#0.89-05122011-1 +liblttng-ust-dev#2.0.4-1 +liblttoolbox3-3.1-0-dev#3.1.0-1.1 +liblttvtraceread-2.6-dev#0.12.38-21032011-1+b1 +liblua5.1-0-dev#5.1.5-4 +liblua5.1-apr-dev#0.23.2-1 +liblua5.1-bitop-dev#1.0.2-1 +liblua5.1-cgi-dev#5.1.4+dfsg-2 +liblua5.1-copas-dev#1.1.6-5 +liblua5.1-curl-dev#0.3.0-7 +liblua5.1-cyrussasl-dev#1.0.0-4 +liblua5.1-event-dev#0.4.1-2 +liblua5.1-expat-dev#1.2.0-5+deb7u1 +liblua5.1-filesystem-dev#1.5.0+16+g84f1af5-1 +liblua5.1-leg-dev#0.1.2-8 +liblua5.1-logging-dev#1.2.0-1 +liblua5.1-lpeg-dev#0.10.2-5 +liblua5.1-md5-dev#1.1.2-6 +liblua5.1-oocairo-dev#1.4-1.2 +liblua5.1-oopango-dev#1.1-1 +liblua5.1-orbit-dev#2.2.0+dfsg1-1 +liblua5.1-posix-dev#5.1.19-2 +liblua5.1-rex-onig-dev#2.6.0-2 +liblua5.1-rex-pcre-dev#2.6.0-2 +liblua5.1-rex-posix-dev#2.6.0-2 +liblua5.1-rings-dev#1.2.3-1 +liblua5.1-rrd-dev#1.4.7-2 +liblua5.1-sec-dev#0.4.1-1 +liblua5.1-soap-dev#3.0-3 +liblua5.1-socket-dev#2.0.2-8 +liblua5.1-sql-mysql-dev#2.3.0-1+build0 +liblua5.1-sql-postgres-dev#2.3.0-1+build0 +liblua5.1-sql-sqlite3-dev#2.3.0-1+build0 +liblua5.1-svn-dev#0.4.0-7 +liblua5.1-wsapi-fcgi-dev#1.5-3 +liblua5.1-xmlrpc-dev#1.2.1-5 +liblua5.1-zip-dev#1.2.3-11 +liblua5.2-dev#5.2.1-3 +liblua50-dev#5.0.3-6 +libluabind-dev#0.9.1+dfsg-5 +liblualib50-dev#5.0.3-6 +liblunar-1-dev#2.0.1-2.2 +liblunar-date-dev#2.4.0-1 +liblv2dynparam1-dev#2-5 +liblvm2-dev#2.02.95-8 +liblwipv6-dev#1.5a-2 +liblwt-glib-ocaml-dev#2.3.2-1+b3 +liblwt-ocaml-dev#2.3.2-1+b3 +liblwt-ssl-ocaml-dev#2.3.2-1+b3 +liblz-dev#1.3-2 +liblzma-dev#5.1.1alpha+20120614-2 +liblzo2-dev#2.06-1 +libm17n-dev#1.6.3-2 +libm17n-im-config-dev#0.9.0-3 +libm4ri-dev#0.0.20080521-2 +libmaa-dev#1.3.1-1 +libmad-ocaml-dev#0.4.4-1+b1 +libmad0-dev#0.15.1b-7 +libmadlib-dev#1.3.0-2.1 +libmagic-dev#5.11-2+deb7u3 +libmagic-ocaml-dev#0.7.3-5+b3 +libmagick++-dev#8:6.7.7.10-5+deb7u3 +libmagickcore-dev#8:6.7.7.10-5+deb7u3 +libmagickwand-dev#8:6.7.7.10-5+deb7u3 +libmagics++-dev#2.14.11-4 +libmailutils-dev#1:2.99.97-3 +libmalaga-dev#7.12-4 +libmaloc-dev#0.2-2.3 +libmapi-dev#1:1.0-3 +libmapiadmin-dev#1:1.0-3 +libmapipp-dev#1:1.0-3 +libmapiproxy-dev#1:1.0-3 +libmapistore-dev#1:1.0-3 +libmapnik-dev#2.0.0+ds1-3 +libmapnik2-dev#2.0.0+ds1-3+b4 +libmarble-dev#4:4.8.4-3 +libmarkdown2-dev#2.1.3-3 +libmatchbox-dev#1.9-osso8-3 +libmath++-dev#0.0.4-4 +libmatheval-dev#1.1.8-1 +libmathlib2-dev#20061220+dfsg3-2 +libmatio-dev#1.3.4-4 +libmatrixssl1.8-dev#1.8.8-1 +libmatroska-dev#1.3.0-2 +libmbt0-dev#3.2.8-1 +libmcpp-dev#2.7.2-1.1 +libmcrypt-dev#2.5.8-3.1 +libmcs-dev#0.7.2-2.1 +libmd3-dev#0.1.92-4 +libmdc2-dev#0.10.7-1+b2 +libmdds-dev#0.5.4-1 +libmdsp-dev#0.11-10 +libmeanwhile-dev#1.0.2-4 +libmecab-dev#0.99.3-3 +libmed-dev#3.0.3-3 +libmedc-dev#3.0.3-3 +libmediainfo-dev#0.7.58-1 +libmediastreamer-dev#3.5.2-10 +libmedimport-dev#3.0.3-3 +libmeep-dev#1.1.1-8+deb7u1 +libmeep-lam4-dev#1.1.1-10~deb7u1 +libmeep-mpi-default-dev#1.1.1-10~deb7u1 +libmeep-mpich2-dev#1.1.1-10~deb7u1 +libmeep-openmpi-dev#1.1.1-9~deb7u2 +libmelt-ocaml-dev#1.4.0-1 +libmemcache-dev#1.4.0.rc2-1 +libmemcached-dev#1.0.8-1 +libmemphis-0.2-dev#0.2.3-2 +libmenhir-ocaml-dev#20120123.dfsg-1 +libmenu-cache1-dev#0.3.3-1 +libmercator-0.3-dev#0.3.0-2 +libmeschach-dev#1.2b-13 +libmetacity-dev#1:2.34.3-4 +libmgl-dev#1.11.2-17 +libmhash-dev#0.9.9.9-1.1 +libmicrohttpd-dev#0.9.20-1+deb7u1 +libmigemo-dev#20110227-7 +libmikmatch-ocaml-dev#1.0.4-1+b1 +libmikmod2-dev#3.1.12-5 +libmilter-dev#8.14.4-4 +libmimedir-dev#0.5.1-4 +libmimedir-gnome-dev#0.4.2-5 +libmimelib1-dev#5:1.1.4-2 +libmimetic-dev#0.9.7-3 +libmimic-dev#1.0.4-2.1 +libminc-dev#2.1.10-1+b1 +libming-dev#1:0.4.4-1.1 +libmini18n-dev#0.2.1-1 +libminidjvu-dev#0.8.svn.2010.05.06+dfsg-0.2 +libminiupnpc-dev#1.5-2 +libmission-control-plugins-dev#1:5.12.3-1 +libmkv-dev#0.6.5.1-1 +libmlpcap-ocaml-dev#0.9-16 +libmlpost-ocaml-dev#0.8.1-3 +libmlt++-dev#0.8.0-4 +libmlt-dev#0.8.0-4 +libmlx4-dev#1.0.4-1 +libmm-dev#1.4.2-4 +libmm-ocaml-dev#0.2.0-1+b1 +libmmpong0.9-dev#0.9.1-2.1 +libmms-dev#0.6.2-3 +libmng-dev#1.0.10-3 +libmnl-dev#1.0.3-3 +libmodbus-dev#3.0.3-1 +libmodglue1-dev#1.17-2.1 +libmodplug-dev#1:0.8.8.4-3+deb7u1+git20130828 +libmoe-dev#1.5.8-1 +libmongo-client-dev#0.1.5-1+deb7u1 +libmono-2.0-dev#2.10.8.1-8 +libmono-addins-cil-dev#0.6.2-2 +libmono-addins-gui-cil-dev#0.6.2-2 +libmono-addins-msbuild-cil-dev#0.6.2-2 +libmono-cecil-cil-dev#0.9.5+dfsg-2 +libmono-cecil-flowanalysis-cil-dev#0.1~vcs20110809.r1.b34edf6-2 +libmono-cil-dev#2.10.8.1-8 +libmono-reflection-cil-dev#1.0+git20110407+d2343843-2 +libmono-uia-cil-dev#2.1-4 +libmono-upnp-cil-dev#0.1.2-1 +libmono-zeroconf-cil-dev#0.9.0-4 +libmonogame-cil-dev#2.5.1+dfsg-3 +libmopac7-dev#1.15-5 +libmorph-dev#1:20090926 +libmosquitto0-dev#0.15-2 +libmosquittopp0-dev#0.15-2 +libmount-dev#2.20.1-5.3 +libmowgli-dev#1.0.0-1 +libmozjs-dev#24.4.0esr-1~deb7u2 +libmozjs185-dev#1.8.5-1.0.0+dfsg-4 +libmp3lame-dev#3.99.5+repack1-3 +libmp3lame-ocaml-dev#0.3.1-1+b1 +libmp3splt-dev#0.7.2-2 +libmp4v2-dev#2.0.0~dfsg0-1 +libmpc-dev#0.9-4 +libmpcdec-dev#2:0.1~r459-4 +libmpd-dev#0.20.0-1.1 +libmpdclient-dev#2.3-1 +libmpeg2-4-dev#0.4.1-3 +libmpeg3-dev#1.5.4-5 +libmpfi-dev#1.5.1-1 +libmpfr-dev#3.1.0-5 +libmpg123-dev#1.14.4-1 +libmpich2-dev#1.4.1-4.2 +libmpikmeans-dev#1.5-1+b1 +libmrml1-dev#0.1.14-12 +libmrmpi-dev#1.0~20110620.dfsg-2 +libmrss0-dev#0.19.2-3 +libmsgpack-dev#0.5.7-2 +libmsn-dev#4.2-2 +libmsv-dev#0.0.0-1 +libmtbl-dev#0.2-1 +libmtcp-dev#1.2.5-1 +libmtdev-dev#1.1.2-1 +libmthca-dev#1.0.6-1 +libmtp-dev#1.1.3-35-g0ece104-5 +libmudflap0-4.4-dev#4.4.7-2 +libmudflap0-4.6-dev#4.6.3-14 +libmudflap0-4.7-dev#4.7.2-5 +libmulticobex1-dev#0.23-1.1 +libmumps-dev#4.10.0.dfsg-3 +libmumps-ptscotch-dev#4.10.0.dfsg-3 +libmumps-scotch-dev#4.10.0.dfsg-3 +libmumps-seq-dev#4.10.0.dfsg-3 +libmunge-dev#0.5.10-1 +libmuparser-dev#2.1.0-3 +libmupdf-dev#0.9-2 +libmupen64plus-dev#1.99.5-6 +libmuroar-dev#0.1.8-2 +libmusic-dev#1.0.7-1.2 +libmusicbrainz3-dev#3.0.2-2.1 +libmusicbrainz5-dev#5.0.1-2 +libmutter-dev#3.4.1-5 +libmx-dev#1.4.6-1 +libmxml-dev#2.6-2 +libmyproxy-dev#5.6-1 +libmysql++-dev#3.1.0-2+b1 +libmysql-cil-dev#6.4.3-2 +libmysql-ocaml-dev#1.1.1-1 +libmysqlclient-dev#5.5.35+dfsg-0+wheezy1 +libmysqlcppconn-dev#1.1.0-4+b1 +libmysqld-dev#5.5.35+dfsg-0+wheezy1 +libmythes-dev#2:1.2.2-1 +libnabrit-dev#0.4.1-1 +libnacl-dev#20110221-4 +libnacore-dev#0.4.0-3 +libnanohttp-dev#1.1.0-17.1 +libnatpmp-dev#20110808-3 +libnautilus-extension-dev#3.4.2-1+build1 +libnbio-dev#0.30-1 +libncap-dev#1.9.2-1+b2 +libncbi6-dev#6.1.20120620-2 +libncp-dev#2.2.6-9 +libncurses5-dev#5.9-10 +libncursesada2-dev#5.9.20110404-7 +libncursesw5-dev#5.9-10 +libndesk-dbus-glib1.0-cil-dev#0.4.1-4 +libndesk-dbus1.0-cil-dev#0.6.0-6 +libndr-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libndr-standard-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libnecpp-dev#1.5.0+cvs20101003-2.1 +libneon27-dev#0.29.6-3 +libneon27-gnutls-dev#0.29.6-3 +libnes-dev#1.1.3-1 +libnet1-dev#1.1.4-2.1 +libnet6-1.3-dev#1:1.3.14-1 +libnetcdf-dev#1:4.1.3-6+b1 +libnetcf-dev#0.1.9-2 +libnetclasses-dev#1.06.dfsg-5+b3 +libnetfilter-conntrack-dev#1.0.1-1 +libnetfilter-cttimeout-dev#1.0.0-1 +libnetfilter-log-dev#1.0.0-1 +libnetfilter-queue-dev#0.0.17-1 +libnethttpd-ocaml-dev#3.5.1-1 +libnetpbm10-dev#2:10.0-15+b1 +libnetpbm9-dev#2:10.0-15+b1 +libnetsvcs-dev#6.0.3+dfsg-0.1 +libnewlib-dev#1.18.0-6.2 +libnewmat10-dev#1.10.4-5 +libnewt-dev#0.52.14-11.1 +libnewtonsoft-json-cil-dev#4.5r6-1 +libnexus0-dev#4.2.1-svn1614-1+b2 +libnfnetlink-dev#1.0.0-1.1 +libnfo-dev#1.0.1-1 +libnfs-dev#1.3.0-2 +libnfsidmap-dev#0.25-4 +libnice-dev#0.1.2-1 +libnids-dev#1.23-2 +libnifti-dev#2.0.0-1 +libnih-dbus-dev#1.0.3-4.1 +libnih-dev#1.0.3-4.1 +libnini-cil-dev#1.1.0+dfsg.2-4 +libnjb-dev#2.2.7~dfsg0-3 +libnl-3-dev#3.2.7-4 +libnl-cli-3-dev#3.2.7-4 +libnl-dev#1.1-7 +libnl-genl-3-dev#3.2.7-4 +libnl-nf-3-dev#3.2.7-4 +libnl-route-3-dev#3.2.7-4 +libnm-glib-dev#0.9.4.0-10 +libnm-glib-vpn-dev#0.9.4.0-10 +libnm-gtk-dev#0.9.4.1-5 +libnm-util-dev#0.9.4.0-10 +libnmz7-dev#2.0.21-6 +libnoise-dev#1.0.0+nmu1 +libnotify-cil-dev#0.4.0~r3032-6 +libnotify-dev#0.7.5-1 +libnotmuch-dev#0.13.2-1 +libnova-dev#0.14.0-2 +libnpth0-dev#0.90-2 +libnsbmp0-dev#0.0.1-1.1 +libnsgif0-dev#0.0.1-1.1 +libnspr4-dev#2:4.9.2-1+deb7u1 +libnss3-dev#2:3.14.5-1 +libntfs-dev#2.0.0-1+b1 +libntl-dev#5.5.2-2 +libntlm0-dev#1.2-1 +libntrack-dev#016-1.1 +libntrack-glib-dev#016-1.1 +libntrack-gobject-dev#016-1.1 +libntrack-qt4-dev#016-1.1 +libnuclient-dev#2.4.3-2.2 +libnuma-dev#2.0.8~rc4-1 +libnunit-cil-dev#2.6.0.12051+dfsg-2 +libnussl-dev#2.4.3-2.2 +libnvtt-dev#2.0.8-1+dfsg-2 +libnxcl-dev#0.9-3.1 +libnxml0-dev#0.18.3-4 +libnzb-dev#0.0.20050629-6.1 +liboasis-ocaml-dev#0.2.0-6 +liboasis3-dev#3.3.beta.dfsg.1-8+b1 +liboath-dev#1.12.4-1 +liboauth-dev#0.9.4-3.1 +libobby-0.4-dev#0.4.8-1 +libobexftp0-dev#0.23-1.1 +libobrowser-ocaml-dev#1.1.1+dfsg-1+b9 +libobus-ocaml-dev#1.1.3-1+b8 +libocamlbricks-ocaml-dev#0.50.1-4+b5 +libocamlgraph-ocaml-dev#1.8.2-2 +libocamlgraph-viewer-ocaml-dev#1.8.2-2 +libocamlgsl-ocaml-dev#0.6.0-7+b2 +libocamlnet-gtk2-ocaml-dev#3.5.1-1 +libocamlnet-ocaml-dev#3.5.1-1 +libocamlnet-ssl-ocaml-dev#3.5.1-1 +libocamlodbc-ocaml-dev#2.15-5+b3 +libocamlviz-ocaml-dev#1.01-2+b2 +libocas-dev#0.93-1 +liboce-foundation-dev#0.9.1-3 +liboce-modeling-dev#0.9.1-3 +liboce-ocaf-dev#0.9.1-3 +liboce-ocaf-lite-dev#0.9.1-3 +liboce-visualization-dev#0.9.1-3 +libocpf-dev#1:1.0-3 +libocrad-dev#0.22~rc1-2 +libocsigen-ocaml-dev#1.3.4-2+b12 +libocsigen-xhtml-ocaml-dev#1.3.4-2+b12 +libocsigenserver-ocaml-dev#2.1-1 +liboctave-dev#3.6.2-5+deb7u1 +libode-dev#2:0.11.1-4 +libode-sp-dev#2:0.11.1-4 +libodin-dev#1.8.5-2 +libodn-ocaml-dev#0.0.8-1 +libofa0-dev#0.9.3-5 +libofapi-dev#0git20070620-6 +libofdt-dev#1.3.6-1 +libofetion-dev#2.2.2-1 +libofx-dev#1:0.9.4-2.1 +libogdi3.2-dev#3.2.0~beta2-7 +libogg-dev#1.3.0-4 +libogg-ocaml-dev#0.4.3-1+b1 +liboggkate-dev#0.4.1-1 +liboggplay1-dev#0.2.1~git20091227-1.2 +liboggz2-dev#1.1.1-1 +liboglappth-dev#1.0.0-2 +libogre-1.8-dev#1.8.0+dfsg1-3 +libogre-dev#1.7.4+dfsg1-7 +liboil0.3-dev#0.3.17-2 +libois-dev#1.3.0+dfsg0-5 +libomhacks-dev#0.16-1 +libomnievents-dev#1:2.6.2-2 +libomniorb4-dev#4.1.6-2 +libomnithread3-dev#4.1.6-2 +libomxil-bellagio-dev#0.9.3-1+b1 +libonig-dev#5.9.1-1 +liboobs-1-dev#3.0.0-1 +liboop-dev#1.0-9 +libooptools-dev#2.7-1 +libopal-dev#3.10.4~dfsg-3 +libopenafs-dev#1.6.1-3+deb7u2 +libopenais-dev#1.1.4-4.1 +libopenal-dev#1:1.14-4 +libopenbabel-dev#2.3.1+dfsg-4 +libopenblas-dev#0.1.1-6+deb7u3 +libopencc-dev#0.3.0-3 +libopenconnect-dev#3.20-4 +libopencore-amrnb-dev#0.1.3-2 +libopencore-amrwb-dev#0.1.3-2 +libopencryptoki-dev#2.3.1+dfsg-3 +libopencsg-dev#1.3.2-2 +libopenct1-dev#0.6.20-1.2 +libopencv-calib3d-dev#2.3.1-11 +libopencv-contrib-dev#2.3.1-11 +libopencv-core-dev#2.3.1-11 +libopencv-dev#2.3.1-11 +libopencv-features2d-dev#2.3.1-11 +libopencv-flann-dev#2.3.1-11 +libopencv-gpu-dev#2.3.1-11 +libopencv-highgui-dev#2.3.1-11 +libopencv-imgproc-dev#2.3.1-11 +libopencv-legacy-dev#2.3.1-11 +libopencv-ml-dev#2.3.1-11 +libopencv-objdetect-dev#2.3.1-11 +libopencv-video-dev#2.3.1-11 +libopendkim-dev#2.6.8-4 +libopenexr-dev#1.6.1-6 +libopenhpi-dev#2.14.1-1.2 +libopenigtlink1-dev#1.9.2~svn7468-1 +libopenimageio-dev#1.0.5+dfsg0-1 +libopenipmi-dev#2.0.16-1.3 +libopenjpeg-dev#1.3+dfsg-4.7 +libopenmeeg-dev#2.0.0.dfsg-5 +libopenmpi-dev#1.4.5-1 +libopenobex1-dev#1.5-2 +libopenr2-dev#1.3.2-1.1 +libopenraw-dev#0.0.9-3+b1 +libopenrawgnome-dev#0.0.9-3+b1 +libopenscap-dev#0.8.0-4+b1 +libopenscenegraph-dev#3.0.1-4 +libopenslide-dev#3.2.6-2 +libopensm2-dev#3.2.6-20090317-2.1 +libopenthreads-dev#3.0.1-4 +libopentk-cil-dev#1.0.20101006+dfsg1-1 +libopentoken3-dev#4.0b-3 +libopenturns-dev#1.0-4 +libopenusb-dev#1.1.0-2 +libopenvg1-mesa-dev#8.0.5-4+deb7u2 +libopenvrml-dev#0.18.9-5+deb7u1 +libopenwalnut1-dev#1.2.5-1.1+b1 +liboping-dev#1.6.2-1 +libopkele-dev#2.0.4-5.3 +libopts25-dev#1:5.12-0.1 +libopus-dev#0.9.14+20120615-1+nmu1 +liborange-dev#0.4-2 +liborbit2-dev#1:2.14.19-0.1 +liborc-0.4-dev#1:0.4.16-2 +liborigin-dev#20080225-2.1 +liborigin2-dev#2:20110117-1+b2 +libortp-dev#3.5.2-10 +liboscpack-dev#1.0.2-1 +libosgearth-dev#2.0+dfsg-4+b3 +libosinfo-1.0-dev#0.1.1-1 +libosip2-dev#3.6.0-4 +libosl-dev#0.5.0-1 +libosmesa6-dev#8.0.5-4+deb7u2 +libosmgpsmap-dev#0.7.3-3 +libosmium-dev#0.0~20111213-g7f3500a-3+b2 +libosmpbf-dev#1.2.1-3 +libosp-dev#1.5.2-10 +libosptk3-dev#3.4.2-1+b1 +libossim-dev#1.7.21-4 +libossp-sa-dev#1.2.6-1 +libossp-uuid-dev#1.6.2-1.3 +libostyle-dev#1.4devel1-20.1+b1 +libotcl1-dev#1.14+dfsg-2 +libotf-dev#0.9.12-2 +libotf-trace-dev#1.10.2+dfsg-2 +libotpw-dev#1.3-2 +libotr2-dev#3.2.1-1+deb7u1 +libots-dev#0.5.0-2.1 +libounit-ocaml-dev#1.1.1-1 +libow-dev#2.8p15-1 +libowfat-dev#0.28-6 +libowfat-dietlibc-dev#0.28-6 +libownet-dev#2.8p15-1 +libp11-dev#0.2.8-2 +libp11-kit-dev#0.12-3 +libpackagekit-glib2-dev#0.7.6-3 +libpackagekit-qt2-dev#0.7.6-3 +libpacketdump3-dev#3.0.14-1 +libpacklib-lesstif1-dev#20061220+dfsg3-2 +libpacklib1-dev#20061220+dfsg3-2 +libpacparser-dev#1.3.0-2 +libpam-ocaml-dev#1.1-4+b3 +libpam0g-dev#1.1.3-7.1 +libpanel-applet-4-dev#3.4.2.1-4 +libpango1.0-dev#1.30.0-1 +libpangomm-1.4-dev#2.28.4-1 +libpano13-dev#2.9.18+dfsg-5 +libpantomime1.2-dev#1.2.0~pre3+snap20071004+dfsg-4+b1 +libpaper-dev#1.1.24+nmu2 +libpaps-dev#0.6.8-6 +libpaq-dev#1.0.4-3+b1 +libpar2-0-dev#0.2.1-1 +libpari-dev#2.5.1-2 +libparpack2-dev#3.1.1-2.1 +libparrot-dev#4.0.0-3 +libparser++-dev#0.2.3-2 +libparted0-dev#2.3-12 +libpasswdqc-dev#1.2.0-1 +libpath-utils-dev#0.1.3-2 +libpathfinder-dev#1.1.3-0.4+b1 +libpawlib-lesstif3-dev#1:2.14.04.dfsg.2-8 +libpawlib2-dev#1:2.14.04.dfsg.2-8 +libpcap-dev#1.3.0-1 +libpcap0.8-dev#1.3.0-1 +libpcapnav0-dev#0.8-1 +libpci-dev#1:3.1.9-6 +libpciaccess-dev#0.13.1-2 +libpcl1-dev#1.6-1 +libpcre++-dev#0.9.5-5.1 +libpcre-ocaml-dev#6.2.5-1 +libpcre3-dev#1:8.30-5 +libpcscada2-dev#0.7.1-4 +libpcsclite-dev#1.8.4-1+deb7u1 +libpdflib804-2-dev#20061220+dfsg3-2 +libpe-rules2-dev#1.1.7-1 +libpe-status3-dev#1.1.7-1 +libpeas-dev#1.4.0-2 +libpengine3-dev#1.1.7-1 +libperl-dev#5.14.2-21+deb7u1 +libperl4caml-ocaml-dev#0.9.5-4+b4 +libpetsc3.2-dev#3.2.dfsg-6 +libpfqueue-dev#0.5.6-8 +libpfs-dev#1.8.5-1 +libpgm-dev#5.1.118-1~dfsg-0.1 +libpgocaml-ocaml-dev#1.5-2 +libpgpool-dev#3.1.3-5 +libpgtcl-dev#1:1.5-6 +libphash0-dev#0.9.4-1.2 +libphat-dev#0.4.1-5 +libphobos-4.4-dev#1.063-4.4.7-1 +libphobos2-4.6-dev#0.29.1-4.6.3-2 +libphone-ui-dev#1:0.0.1+git20110825-3 +libphone-utils-dev#0.1+git20110523-2.1 +libphonon-dev#4:4.6.0.0-3 +libphononexperimental-dev#4:4.6.0.0-3 +libphotos202-dev#20061220+dfsg3-2 +libphtools2-dev#20061220+dfsg3-2 +libphysfs-dev#2.0.2-6 +libpiano-dev#2012.05.06-2 +libpigment0.3-dev#0.3.17-1 +libpils2-dev#1.0.9+hg2665-1 +libpinyin0-dev#0.6.91-1 +libpion-common-dev#4.0.7+dfsg-3.1 +libpion-net-dev#4.0.7+dfsg-3.1 +libpipeline-dev#1.2.1-1 +libpisock-dev#0.12.5-5 +libpixman-1-dev#0.26.0-4+deb7u1 +libpkcs11-helper1-dev#1.09-1 +libplayer-dev#2.0.1-2.1 +libplayerc++3.0-dev#3.0.2+dfsg-4+b1 +libplayerc3.0-dev#3.0.2+dfsg-4+b1 +libplayercommon3.0-dev#3.0.2+dfsg-4+b1 +libplayercore3.0-dev#3.0.2+dfsg-4+b1 +libplayerdrivers3.0-dev#3.0.2+dfsg-4+b1 +libplayerinterface3.0-dev#3.0.2+dfsg-4+b1 +libplayerjpeg3.0-dev#3.0.2+dfsg-4+b1 +libplayertcp3.0-dev#3.0.2+dfsg-4+b1 +libplayerwkb3.0-dev#3.0.2+dfsg-4+b1 +libplib-dev#1.8.5-6 +libplist++-dev#1.8-1 +libplist-dev#1.8-1 +libpload-dev#1.4.2-3 +libplot-dev#2.6-3 +libploticus0-dev#2.41-5 +libplotmm-dev#0.1.2-2 +libplplot-ada0-dev#5.9.9-5 +libplplot-dev#5.9.9-5 +libplumb2-dev#1.0.9+hg2665-1 +libplumbgpl2-dev#1.0.9+hg2665-1 +libpmap3.0-dev#3.0.2+dfsg-4+b1 +libpmi0-dev#2.3.4-2+b1 +libpmount-dev#0.0.16 +libpng++-dev#0.2.5-1 +libpng12-dev#1.2.49-1 +libpnglite-dev#0.1.17-1 +libpoco-dev#1.3.6p1-4 +libpodofo-dev#0.9.0-1.1+b1 +libpoker-eval-dev#138.0-1 +libpolarssl-dev#1.2.9-1~deb7u2 +libpoldiff-dev#3.3.7-3 +libpolkit-agent-1-dev#0.105-3 +libpolkit-backend-1-dev#0.105-3 +libpolkit-gobject-1-dev#0.105-3 +libpolkit-qt-1-dev#0.103.0-1 +libpolybori-dev#0.5~rc1-2.2 +libpolylib64-dev#5.22.5-3+dfsg +libpolyml-dev#5.2.1-1.1 +libpolyorb2-dev#2.8~20110207-5.1 +libpomp-dev#1.1+dfsg-2 +libpoppler-cil-dev#0.0.3-2 +libpoppler-cpp-dev#0.18.4-6 +libpoppler-dev#0.18.4-6 +libpoppler-glib-dev#0.18.4-6 +libpoppler-private-dev#0.18.4-6 +libpoppler-qt4-dev#0.18.4-6 +libpopplerkit-dev#0.0.20051227svn-7+b1 +libpopt-dev#1.16-7 +libportaudio-dev#18.1-7.1 +libportaudio-ocaml-dev#0.2.0-1+b1 +libportmidi-dev#1:184-2.1 +libportsmf-dev#0.1~svn20101010-3 +libpostgresql-ocaml-dev#1.18.0-1 +libpostproc-dev#6:0.8.10-1 +libpotrace-dev#1.10-1 +libpowerman0-dev#2.3.5-1 +libppd-dev#2:0.10-7.1 +libppl0.11-dev#0.11.2-8 +libpq-dev#9.1.13-0wheezy1 +libpqxx3-dev#3.1-1.1 +libprelude-dev#1.0.0-9 +libpreludedb-dev#1.0.0-1.1+b2 +libpresage-dev#0.8.8-1 +libpri-dev#1.4.12-2 +libprinterconf-dev#0.5-12 +libprintsys-dev#0.6-13 +libprison-dev#1.0+dfsg-1 +libprocps0-dev#1:3.3.3-3 +libproj-dev#4.7.0-2 +libprojectm-dev#2.1.0+dfsg-1 +libprojectm-qt-dev#2.1.0+dfsg-1 +libprotobuf-c0-dev#0.14-1+b1 +libprotobuf-dev#2.4.1-3 +libprotoc-dev#2.4.1-3 +libproxy-dev#0.3.1-6 +libproxychains-dev#3.1-3 +libpspell-dev#0.60.7~20110707-1 +libpst-dev#0.6.54-4.1 +libpstoedit-dev#3.60-2+b1 +libpstreams-dev#0.7.0-2 +libpt-dev#2.10.4~dfsg-1 +libptexenc-dev#2012.20120628-4 +libpth-dev#2.0.7-16 +libpthread-stubs0-dev#0.3-3 +libpthread-workqueue-dev#0.8.2-1 +libptscotch-dev#5.1.12b.dfsg-1.2 +libpugl-dev#0~svn32+dfsg0-1 +libpulse-dev#2.0-6.1 +libpulse-ocaml-dev#0.1.2-1+b1 +libpuma-dev#1:1.1+svn20120529-2 +libpurelibc-dev#0.4.1-1 +libpurple-dev#2.10.9-1~deb7u1 +libpuzzle-dev#0.9-5 +libpwl-dev#0.11.2-8 +libpxp-ocaml-dev#1.2.2-1+b4 +libpycaml-ocaml-dev#0.82-14+b2 +libpyside-dev#1.1.1-3 +libpythia8-dev#8.1.65-1 +libpythonqt2-dev#2.0.1-1.1 +libqalculate-dev#0.9.7-8 +libqapt-dev#1.3.0-2 +libqb-dev#0.11.1-2 +libqca2-dev#2.0.3-4 +libqd-dev#2.3.11.dfsg-2.1 +libqdaccolib-dev#0.8.2-1 +libqdbm++-dev#1.8.78-2 +libqdbm-dev#1.8.78-2 +libqdjango-dev#0.2.5-2 +libqedje-dev#0.4.0+lgpl-3 +libqfits-dev#6.2.0-5 +libqgis-dev#1.7.4+1.7.5~20120320-1.1+b1 +libqglviewer-qt4-dev#2.3.4-4.2 +libqgpsmm-dev#3.6-4+deb7u1 +libqhull-dev#2009.1-3 +libqimageblitz-dev#1:0.0.6-4 +libqjson-dev#0.7.1-7 +libqmf-dev#0.16-6+deb7u1 +libqmf2-dev#0.16-6+deb7u1 +libqmfconsole2-dev#0.16-6+deb7u1 +libqmfengine1-dev#0.16-6+deb7u1 +libqmmp-dev#0.5.5-1+b1 +libqmmpui-dev#0.5.5-1+b1 +libqoauth-dev#1.0.1-1 +libqof-dev#0.8.6-1 +libqofexpensesobjects-dev#0.1.9-2 +libqpdf-dev#2.3.1-4 +libqpidbroker2-dev#0.16-6+deb7u1 +libqpidclient2-dev#0.16-6+deb7u1 +libqpidcommon2-dev#0.16-6+deb7u1 +libqpidmessaging2-dev#0.16-6+deb7u1 +libqpidtypes1-dev#0.16-6+deb7u1 +libqpol-dev#3.3.7-3 +libqpx-dev#0.7.1.002-5 +libqrencode-dev#3.3.0-2 +libqrupdate-dev#1.1.1-1 +libqsastime-dev#5.9.9-5 +libqscintilla2-dev#2.6.2-2 +libqt4-dev#4:4.8.2+dfsg-11 +libqt4-opengl-dev#4:4.8.2+dfsg-11 +libqt4-private-dev#4:4.8.2+dfsg-11 +libqt4pas-dev#2.5-6 +libqtassistantclient-dev#4.6.3-4 +libqtexengine-dev#0.3-3 +libqtgstreamer-dev#0.10.2-2 +libqtruby4shared-dev#4:4.8.4-1 +libqtwebkit-dev#2.2.1-5 +libquantlib0-dev#1.2-2+b1 +libquantum-dev#1.1.0-3 +libquicktime-dev#2:1.2.4-3 +libquorum-dev#1.4.2-3 +libquvi-dev#0.4.1-1 +libqwt-dev#6.0.0-1.2 +libqwt5-qt4-dev#5.2.2-3 +libqwtplot3d-qt4-dev#0.2.7+svn191-7 +libqxmlrpc-dev#0.0.svn6-2 +libqxmpp-dev#0.4.92-1 +libqxt-dev#0.6.1-6 +libqzeitgeist-dev#0.7.0-1+b1 +libqzion-dev#0.4.0+lgpl-4 +librabbitmq-dev#0.0.1.hg216-1 +libradare2-dev#0.9-3 +libradius1-dev#0.3.2-14 +libradiusclient-ng-dev#0.5.6-1.1 +libranlip-dev#1.0-4.1 +librapi2-dev#0.15-2.1 +libraptor1-dev#1.4.21-7.1 +libraptor2-dev#2.0.8-2 +librarian-dev#0.8.1-5 +librasqal3-dev#0.9.29-1 +librasterlite-dev#1.1~svn11-2 +libraul-dev#0.8.0+dfsg0-0.1+b1 +libraw-dev#0.14.6-2 +libraw1394-dev#2.0.9-1 +librcc-dev#0.2.9-3 +librcd-dev#0.1.13-3 +librdf0-dev#1.0.15-1+b1 +librdkit-dev#201203-3 +librdmacm-dev#1.0.15-1+deb7u1 +librdmawrap2-dev#0.16-6+deb7u1 +libreact-ocaml-dev#0.9.3-1 +libreadline-dev#6.2+dfsg-0.1 +libreadline-gplv2-dev#5.2+dfsg-2~deb7u1 +libreadline6-dev#6.2+dfsg-0.1 +librec-dev#1.5-1 +librecode-dev#3.6-20 +libref-array-dev#0.1.3-2 +libregina3-dev#3.6-2 +libregistry-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libreins-ocaml-dev#0.1a-4+b1 +libreiser4-dev#1.0.7-6.3 +librelp-dev#1.0.0-1 +libremctl-dev#3.2-4 +librenaissance0-dev#0.9.0-4+b3 +libreoffice-dev#1:3.5.4+dfsg2-0+deb7u2 +librep-dev#0.90.2-1.3 +libreplaygain-dev#1.0~r475-1 +libres-ocaml-dev#3.2.0-2+b3 +libresample1-dev#0.1.3-4 +libresid-builder-dev#2.1.1-14 +libresiprocate-1.8-dev#1.8.5-4 +libresiprocate-turn-client-1.8-dev#1.8.5-4 +librest-dev#0.7.12-3 +librest-extras-dev#0.7.12-3 +librhash-cil-dev#1.2.9-8+deb7u1 +librhash-dev#1.2.9-8+deb7u1 +librheolef-dev#6.1-2.1 +librivet-dev#1.8.0-1 +librlog-dev#1.4-2 +libroar-dev#1.0~beta2-3 +libroot-bindings-python-dev#5.34.00-2 +libroot-bindings-ruby-dev#5.34.00-2 +libroot-core-dev#5.34.00-2 +libroot-geom-dev#5.34.00-2 +libroot-graf2d-gpad-dev#5.34.00-2 +libroot-graf2d-graf-dev#5.34.00-2 +libroot-graf2d-postscript-dev#5.34.00-2 +libroot-graf3d-eve-dev#5.34.00-2 +libroot-graf3d-g3d-dev#5.34.00-2 +libroot-graf3d-gl-dev#5.34.00-2 +libroot-gui-dev#5.34.00-2 +libroot-gui-ged-dev#5.34.00-2 +libroot-hist-dev#5.34.00-2 +libroot-hist-spectrum-dev#5.34.00-2 +libroot-html-dev#5.34.00-2 +libroot-io-dev#5.34.00-2 +libroot-io-xmlparser-dev#5.34.00-2 +libroot-math-foam-dev#5.34.00-2 +libroot-math-genvector-dev#5.34.00-2 +libroot-math-mathcore-dev#5.34.00-2 +libroot-math-mathmore-dev#5.34.00-2 +libroot-math-matrix-dev#5.34.00-2 +libroot-math-minuit-dev#5.34.00-2 +libroot-math-mlp-dev#5.34.00-2 +libroot-math-physics-dev#5.34.00-2 +libroot-math-quadp-dev#5.34.00-2 +libroot-math-smatrix-dev#5.34.00-2 +libroot-math-splot-dev#5.34.00-2 +libroot-math-unuran-dev#5.34.00-2 +libroot-misc-memstat-dev#5.34.00-2 +libroot-misc-minicern-dev#5.34.00-2 +libroot-misc-table-dev#5.34.00-2 +libroot-montecarlo-eg-dev#5.34.00-2 +libroot-montecarlo-vmc-dev#5.34.00-2 +libroot-net-auth-dev#5.34.00-2 +libroot-net-bonjour-dev#5.34.00-2 +libroot-net-dev#5.34.00-2 +libroot-net-ldap-dev#5.34.00-2 +libroot-proof-clarens-dev#5.34.00-2 +libroot-proof-dev#5.34.00-2 +libroot-proof-proofplayer-dev#5.34.00-2 +libroot-roofit-dev#5.34.00-2 +libroot-tmva-dev#5.34.00-2 +libroot-tree-dev#5.34.00-2 +libroot-tree-treeplayer-dev#5.34.00-2 +librostlab-blast0-dev#1.0.0-2 +librostlab3-dev#1.0.20-1 +librpcsecgss-dev#0.19-5 +librplay3-dev#3.3.2-14 +librpm-dev#4.10.0-5+deb7u1 +librra-dev#0.14-1.2 +librrd-dev#1.4.7-2 +librsl-dev#1.42-2 +librsskit-dev#0.3-2 +librsvg2-2.0-cil-dev#2.26.0-8 +librsvg2-dev#2.36.1-2 +librsync-dev#0.9.7-9 +librtai-dev#3.8.1-4 +librtas-dev#1.3.6-1 +librtasevent-dev#1.3.6-1 +librtaudio-dev#4.0.10~ds0-2 +librtfcomp-dev#1.1-5+b1 +librtfilter-dev#1.1-4 +librtmidi-dev#1.0.15~ds0-2 +librtmp-dev#2.4+20111222.git4e06e21-1 +librubberband-dev#1.3-1.3 +librudecgi-dev#5.0.0-1 +libruli4-dev#0.33-1.1 +librxp-dev#1.5.0-1 +libs3-dev#2.0-1 +libs3d-dev#0.2.2-8 +libs3dw-dev#0.2.2-8 +libsaamf3-dev#1.1.4-4.1 +libsackpt3-dev#1.1.4-4.1 +libsaclm3-dev#1.1.4-4.1 +libsaevt3-dev#1.1.4-4.1 +libsage-dev#0.2.0-4.1 +libsalck3-dev#1.1.4-4.1 +libsam-dev#1.4.2-3 +libsamba-credentials-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-hostconfig-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-policy-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-util-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamdb-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsaml2-dev#2.4.3-4 +libsampleicc-dev#1.6.4-1+b1 +libsamplerate-ocaml-dev#0.1.1-1+b3 +libsamplerate0-dev#0.1.8-5 +libsamsg4-dev#1.1.4-4.1 +libsane-dev#1.0.22-7.4 +libsane-extras-dev#1.0.22.2 +libsanlock-dev#2.2-2 +libsary-dev#1:1.2.0-2.1 +libsasl2-dev#2.1.25.dfsg1-6+deb7u1 +libsatmr3-dev#1.1.4-4.1 +libsbjson-dev#2.3.2-2 +libsbsms-dev#2.0.1-1 +libsbuf-dev#9.0+ds1-4 +libsbuild-dev#1.6.4-4 +libsc-dev#2.3.1-14 +libscalapack-mpi-dev#1.8.0-9 +libscalapack-pvm-dev#1.8.0-9 +libscalc-dev#0.2.4-1 +libscamperfile0-dev#20111202b-1 +libschroedinger-dev#1.0.11-2 +libschroedinger-ocaml-dev#0.1.0-1+b3 +libscim-dev#1.4.13-5 +libscm-dev#5e5-3.2 +libscotch-dev#5.1.12b.dfsg-1.2 +libscotchmetis-dev#5.1.12b.dfsg-1.2 +libscotchparmetis-dev#5.1.12b.dfsg-1.2 +libsctp-dev#1.0.11+dfsg-2 +libscythestat-dev#1.0.2-1 +libsdl-console-dev#2.1-3 +libsdl-gfx1.2-dev#2.0.23-3 +libsdl-image1.2-dev#1.2.12-2 +libsdl-mixer1.2-dev#1.2.12-3 +libsdl-net1.2-dev#1.2.8-2 +libsdl-ocaml-dev#0.9.0-1 +libsdl-pango-dev#0.1.2-6 +libsdl-sge-dev#030809dfsg-3 +libsdl-sound1.2-dev#1.0.3-6 +libsdl-stretch-dev#0.3.1-3 +libsdl-ttf2.0-dev#2.0.11-2 +libsdl1.2-dev#1.2.15-5 +libsdpa-dev#7.3.8+dfsg-1 +libsearchclient-dev#0.7.7-3 +libseaudit-dev#3.3.7-3 +libseed-gtk3-dev#3.2.0-2 +libsefs-dev#3.3.7-3 +libselinux1-dev#2.1.9-5 +libsemanage1-dev#2.1.6-6 +libsensors-applet-plugin-dev#3.0.0-0.2 +libsensors4-dev#1:3.3.2-2+deb7u1 +libsepol1-dev#2.1.4-3 +libserd-dev#0.14.0~dfsg0-2 +libserf-dev#1.1.0-2 +libsexplib-camlp4-dev#7.0.4-2 +libsexy-dev#0.1.11-2+b1 +libsfml-dev#1.6+dfsg2-2 +libsfst1-1.2-0-dev#1.2.0-1.2 +libsgutils2-dev#1.33-1 +libsha-ocaml-dev#1.7-2+b2 +libshairport-dev#1.2.1~git20120110.aeb4987-2 +libshevek-dev#1.3-1 +libshhmsg1-dev#1.4.1-4.1 +libshhopt1-dev#1.1.7-2.1 +libshiboken-dev#1.1.1-1 +libshibsp-dev#2.4.3+dfsg-5+b1 +libshisa-dev#1.0.1-2 +libshishi-dev#1.0.1-2 +libshout-ocaml-dev#0.2.7-1+b3 +libshout3-dev#2.2.2-8 +libshp-dev#1.2.10-7 +libshr-glib-dev#2011.03.08.2~git20110930-2 +libsidl-dev#1.4.0.dfsg-8.1 +libsidplay1-dev#1.36.59-5 +libsidplay2-dev#2.1.1-14 +libsidplayfp-dev#0.3.5-1 +libsidutils-dev#2.1.1-14 +libsieve2-dev#2.2.6-1.1 +libsigc++-1.2-dev#1.2.7-2 +libsigc++-2.0-dev#2.2.10-0.2 +libsigc++-dev#1.0.4-9.4 +libsigrok0-dev#0.1.0-2 +libsigrokdecode0-dev#0.1.0-2 +libsigsegv-dev#2.9-4 +libsilly-dev#0.1.0-3 +libsilo-dev#4.8-13 +libsimage-dev#1.7.0-1.1+b1 +libsimplelist0-dev#0.3.4-2 +libsipwitch-dev#1.2.4-1 +libsiscone-dev#2.0.5-1 +libsiscone-spherical-dev#2.0.5-1 +libskk-dev#0.0.12-3 +libskstream-0.3-dev#0.3.8-1 +libslang2-dev#2.2.4-15 +libslepc3.2-dev#3.2-p5-1 +libslp-dev#1.2.1-9 +libslurm-dev#2.3.4-2+b1 +libslurmdb-dev#2.3.4-2+b1 +libslv2-dev#0.6.6+dfsg1-2 +libsm-dev#2:1.2.1-2 +libsmbclient-dev#2:3.6.6-6+deb7u3 +libsmbclient-raw-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsmbios-dev#2.0.3.dfsg-1.1 +libsmf-dev#1.3-2 +libsmi2-dev#0.4.8+dfsg2-7 +libsmokekde-dev#4:4.8.4-1 +libsmokeqt4-dev#4:4.8.4-1 +libsmpeg-dev#0.4.5+cvs20030824-5 +libsnacc-dev#1.3.1-1 +libsnack2-dev#2.2.10-dfsg1-12.1 +libsnappy-dev#1.0.5-2 +libsndfile1-dev#1.0.25-5 +libsndobj-dev#2.6.6.1-3 +libsnmp-dev#5.4.3~dfsg-2.8 +libsnmpkit-dev#0.9-16 +libsocialweb-client-dev#0.25.20-2.1 +libsocialweb-dev#0.25.20-2.1 +libsocksd0-dev#1.1.19.dfsg-3+b3 +libsofa-c-dev#2012.03.01-1 +libsofa1-dev#1.0~beta4-7 +libsofia-sip-ua-dev#1.12.11+20110422-1 +libsofia-sip-ua-glib-dev#1.12.11+20110422-1 +libsofthsm-dev#1.3.3-2 +libsoil-dev#1.07~20080707.dfsg-2 +libsombok-dev#2.2.1-1 +libsonic-dev#0.1.17-1.1 +libsope-dev#1.3.16-1 +libsoprano-dev#2.7.6+dfsg.1-2wheezy1 +libsoqt4-dev#1.5.0-2 +libsord-dev#0.8.0~dfsg0-1 +libsoundgen-dev#0.6-4 +libsoundtouch-dev#1.6.0-3 +libsoundtouch-ocaml-dev#0.1.7-1+b1 +libsoup-gnome2.4-dev#2.38.1-3 +libsoup2.4-dev#2.38.1-3 +libsoupcutter-dev#1.1.7-1.2 +libsource-highlight-dev#3.1.6-1.1 +libsox-dev#14.4.0-3 +libsp-gxmlcpp-dev#1.0.20040603-5 +libsp1-dev#1.3.4-1.2.1-47.1+b1 +libspandsp-dev#0.0.6~pre20-3.1 +libsparsehash-dev#1.10-1 +libsparskit-dev#2.0.0-2 +libspatialindex-dev#1.7.0-1 +libspatialite-dev#3.0.0~beta20110817-3+deb7u1 +libspctag-dev#0.2-1 +libspectre-dev#0.2.7-2 +libspectrum-dev#1.0.0-3 +libspeechd-dev#0.7.1-6.2 +libspeex-dev#1.2~rc1-7 +libspeex-ocaml-dev#0.2.0-1+b3 +libspeexdsp-dev#1.2~rc1-7 +libspf2-dev#1.2.9-7 +libsphere-dev#3.2-4 +libspice-client-glib-2.0-dev#0.12-5 +libspice-client-gtk-2.0-dev#0.12-5 +libspice-client-gtk-3.0-dev#0.12-5 +libspice-protocol-dev#0.10.1-1 +libspice-server-dev#0.11.0-1+deb7u1 +libspiro-dev#20071029-2 +libspnav-dev#0.2.2-1 +libspooles-dev#2.2-9 +libsprng2-dev#2.0a-8 +libsqlexpr-ocaml-dev#0.4.1-1+b5 +libsqlheavy-dev#0.1.1-1 +libsqlheavygtk-dev#0.1.1-1 +libsqlite0-dev#2.8.17-7 +libsqlite3-dev#3.7.13-1+deb7u1 +libsqlite3-ocaml-dev#1.6.1-1+b1 +libsquizz-dev#0.99a-2 +libsratom-dev#0.2.0~dfsg0-1 +libsrecord-dev#1.58-1+b1 +libsrf-dev#0.1+dfsg-1 +libsrtp0-dev#1.4.4+20100615~dfsg-2+deb7u1 +libss7-dev#1.0.2-3 +libsscm-dev#0.8.5-2.1 +libssh-dev#0.5.4-1+deb7u1 +libssh2-1-dev#1.4.2-1.1 +libssl-dev#1.0.1e-2+deb7u7 +libssl-ocaml-dev#0.4.6-1 +libsslcommon2-dev#0.16-6+deb7u1 +libssreflect-ocaml-dev#1.3pl4-1 +libsss-sudo-dev#1.8.4-2 +libst-dev#1.9-3 +libstaden-read-dev#1.12.4-1 +libstarlink-ast-dev#7.0.4+dfsg-1 +libstarlink-pal-dev#0.1.0-1 +libstarpu-dev#1.0.1+dfsg-1 +libstartup-notification0-dev#0.12-1 +libstatgrab-dev#0.17-1 +libstdc++6-4.4-dev#4.4.7-2 +libstdc++6-4.6-dev#4.6.3-14 +libstdc++6-4.7-dev#4.7.2-5 +libstemmer-dev#0+svn546-2 +libsteptalk-dev#0.10.0-5+b1 +libstfl-dev#0.22-1+b1 +libstk0-dev#4.4.3-2 +libstlport4.6-dev#4.6.2-7 +libstonith1-dev#1.0.9+hg2665-1 +libstonithd1-dev#1.1.7-1 +libstreamanalyzer-dev#0.7.7-3 +libstreams-dev#0.7.7-3 +libstrigihtmlgui-dev#0.7.7-3 +libstrigiqtdbusclient-dev#0.7.7-3 +libstroke0-dev#0.5.1-6 +libstxxl-dev#1.3.1-4 +libsublime-dev#1.3.1-2 +libsubtitleeditor-dev#0.33.0-1 +libsubunit-dev#0.0.8+bzr176-1 +libsugarext-dev#0.96.1-2 +libsuil-dev#0.6.4~dfsg0-3 +libsuitesparse-dev#1:3.4.0-3 +libsundials-serial-dev#2.5.0-3 +libsunpinyin-dev#2.0.3+git20120607-1 +libsuperlu3-dev#3.0+20070106-3 +libsvga1-dev#1:1.4.3-33 +libsvm-dev#3.12-1 +libsvn-dev#1.6.17dfsg-4+deb7u6 +libsvncpp-dev#0.12.0dfsg-6 +libsvnqt-dev#1.5.5-4.1 +libsvrcore-dev#1:4.0.4-15 +libswami-dev#2.0.0+svn389-2 +libswe-dev#1.77.00.0005-2 +libswiften-dev#2.0~beta1+dev47-1 +libsword-dev#1.6.2+dfsg-5 +libswscale-dev#6:0.8.10-1 +libsx-dev#2.05-3 +libsyfi1.0-dev#1.0.0.dfsg-1 +libsylph-dev#1.1.0-8 +libsymmetrica-dev#2.0-1 +libsynce0-dev#0.15-1.1 +libsyncml-dev#0.5.4-2.1 +libsynfig-dev#0.63.05-1 +libsynopsis0.12-dev#0.12-8 +libsynthesis-dev#3.4.0.16.7-1 +libsysactivity-dev#0.6.4-1 +libsysfs-dev#2.1.0+repack-2 +libsyslog-ng-dev#3.3.5-4 +libsyslog-ocaml-dev#1.4-6+b2 +libsystemd-daemon-dev#44-11+deb7u4 +libsystemd-id128-dev#44-11+deb7u4 +libsystemd-journal-dev#44-11+deb7u4 +libsystemd-login-dev#44-11+deb7u4 +libt1-dev#5.1.2-3.6 +libtacacs+1-dev#4.0.4.19-11 +libtachyon-dev#0.99~b2+dfsg-0.4 +libtag-extras-dev#1.0.1-3 +libtag1-dev#1.7.2-1 +libtagc0-dev#1.7.2-1 +libtagcoll2-dev#2.0.13-1.1 +libtaglib-cil-dev#2.0.4.0-1 +libtaglib-ocaml-dev#0.2.0-1+b1 +libtaktuk-1-dev#3.7.4-1 +libtalloc-dev#2.0.7+git20120207-1 +libtamuanova-dev#0.2-2 +libtango7-dev#7.2.6+dfsg-14 +libtaningia-dev#0.2.2-1 +libtaoframework-devil-cil-dev#2.1.svn20090801-9 +libtaoframework-ffmpeg-cil-dev#2.1.svn20090801-9 +libtaoframework-freeglut-cil-dev#2.1.svn20090801-9 +libtaoframework-freetype-cil-dev#2.1.svn20090801-9 +libtaoframework-ftgl-cil-dev#2.1.svn20090801-9 +libtaoframework-lua-cil-dev#2.1.svn20090801-9 +libtaoframework-ode-cil-dev#2.1.svn20090801-9 +libtaoframework-openal-cil-dev#2.1.svn20090801-9 +libtaoframework-opengl-cil-dev#2.1.svn20090801-9 +libtaoframework-physfs-cil-dev#2.1.svn20090801-9 +libtaoframework-sdl-cil-dev#2.1.svn20090801-9 +libtar-dev#1.2.16-1+deb7u2 +libtarantool-dev#1.4.6+20120629+2158-1 +libtasn1-3-dev#2.13-2 +libtbb-dev#4.0+r233-1 +libtcc-dev#0.9.26~git20120612.ad5f375-6 +libtcd-dev#2.2.2-1 +libtclap-dev#1.2.1-1 +libtclcl1-dev#1.20-6 +libtdb-dev#1.2.10-2 +libtecla1-dev#1.6.1-5 +libteem-dev#1.11.0~svn5226-1 +libtelepathy-farstream-dev#0.4.0-3 +libtelepathy-glib-dev#0.18.2-2 +libtelepathy-logger-dev#0.4.0-1 +libtelepathy-logger-qt4-dev#0.4.0-1 +libtelepathy-qt4-dev#0.9.1-4 +libtelnet-dev#0.21-1 +libtemplates-parser11.6-dev#11.6-2 +libterralib-dev#4.0.0-4 +libtesseract-dev#3.02.01-6 +libtevent-dev#0.9.16-1 +libtext-ocaml-dev#0.5-1+b2 +libtextwrap-dev#0.1-13 +libthai-dev#0.1.18-2 +libtheora-dev#1.1.1+dfsg.1-3.1 +libtheora-ocaml-dev#0.3.0-1+b3 +libthepeg-dev#1.8.0-1 +libthrust-dev#1.6.0-1 +libthunar-vfs-1-dev#1.2.0-3+b1 +libthunarx-2-dev#1.2.3-4+b1 +libticables-dev#1.2.0-2 +libticalcs-dev#1.1.3+dfsg1-1 +libticonv-dev#1.1.0-1.1 +libtidy-dev#20091223cvs-1.2 +libtiff4-dev#3.9.6-11 +libtiff5-alt-dev#4.0.2-6+deb7u2 +libtiff5-dev#4.0.2-6+deb7u2 +libtifiles-dev#1.1.1-1 +libtimbl3-dev#6.4.2-1 +libtimblserver2-dev#1.4-2 +libtinfo-dev#5.9-10 +libtinyxml-dev#2.6.2-1 +libtinyxml2-dev#0~git20120518.1.a2ae54e-1 +libtirpc-dev#0.2.2-5 +libtk-img-dev#1:1.3-release-12 +libtnt-dev#1.2.6-1 +libtntdb-dev#1.2-2+b1 +libtntnet-dev#2.1-2+deb7u1 +libtododb-dev#0.11-3 +libtogl-dev#1.7-12 +libtokyocabinet-dev#1.4.47-2 +libtokyotyrant-dev#1.1.40-4.1+b1 +libtolua++5.1-dev#1.0.93-3 +libtolua-dev#5.2.0-1 +libtomcrypt-dev#1.17-3.2 +libtommath-dev#0.42.0-1 +libtomoe-dev#0.6.0-1.3 +libtonezone-dev#1:2.5.0.1-2 +libtophide-ocaml-dev#1.0.0-3 +libtorch3-dev#3.1-2.1 +libtorque2-dev#2.4.16+dfsg-1+deb7u2 +libtorrent-dev#0.13.2-1 +libtorrent-rasterbar-dev#0.15.10-1+b1 +libtorture-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libtotem-dev#3.0.1-8 +libtotem-pg-dev#1.4.2-3 +libtotem-plparser-dev#3.4.2-1 +libtowitoko-dev#2.0.7-8.3 +libtpl-dev#1.5-2 +libtpm-unseal-dev#1.3.7-1 +libtrace3-dev#3.0.14-1 +libtracker-extract-0.14-dev#0.14.1-3 +libtracker-miner-0.14-dev#0.14.1-3 +libtracker-sparql-0.14-dev#0.14.1-3 +libtransitioner1-dev#1.1.7-1 +libtre-dev#0.8.0-3 +libtreil-dev#1.8-1.1 +libts-dev#1.0-11 +libtse3-dev#0.3.1-4.3 +libtsk-dev#3.2.3-2 +libtspi-dev#0.3.9-3+wheezy1 +libtulip-dev#3.7.0dfsg-4 +libtumbler-1-dev#0.1.25-1+b1 +libtut-dev#0.0.20070706-1 +libtuxcap-dev#1.4.0.dfsg2-2.1 +libtwin-dev#12.04.13.17.57-g130ee5f-2 +libtwofish-dev#0.3-3 +libtwolame-dev#0.3.13-1 +libtxc-dxtn-s2tc-dev#0~git20110809-3 +libtype-conv-camlp4-dev#3.0.4-1 +libtyxml-ocaml-dev#2.1-1 +libuchardet-dev#0.0.1-1 +libucimf-dev#2.3.8-4 +libucl-dev#1.03-5 +libuclmmbase1-dev#1.2.16.0-1 +libucommon-dev#5.2.2-4 +libucto1-dev#0.5.2-2 +libudev-dev#175-7.2 +libudf-dev#0.83-4 +libudt-dev#4.10+dfsg-1 +libudunits2-dev#2.1.23-3 +libuhd-dev#3.4.2-1 +libuim-dev#1:1.8.1-4 +libumlib-dev#0.8.2-1 +libunac1-dev#1.8.0-6 +libunbound-dev#1.4.17-3 +libunicap2-dev#0.9.12-2 +libuninameslist-dev#0.0.20091231-1.1 +libuninum-dev#2.7-1.1 +libunique-3.0-dev#3.0.2-1 +libunique-dev#1.1.6-4 +libunistring-dev#0.9.3-5 +libunittest++-dev#1.4.0-3 +libunshield-dev#0.6-3 +libunwind-setjmp0-dev#0.99-0.3 +libunwind7-dev#0.99-0.3 +libupnp-dev#1:1.6.17-1.2 +libupnp4-dev#1.8.0~svn20100507-1.2 +libupnp6-dev#1:1.6.17-1.2 +libupower-glib-dev#0.9.17-1 +libupsclient1-dev#2.6.4-2.3+deb7u1 +libupse-dev#1.0.0-1 +libuptimed-dev#1:0.3.17-3.1 +liburcu-dev#0.6.7-2 +liburfkill-glib-dev#0.3.0-1 +liburg0-dev#0.8.12-4 +liburiparser-dev#0.7.5-1 +libusb++-dev#2:0.1.12-20+nmu1 +libusb-1.0-0-dev#2:1.0.11-1 +libusb-dev#2:0.1.12-20+nmu1 +libusb-ocaml-dev#1.2.0-2+b7 +libusbip-dev#1.1.1+3.2.17-1 +libusbmuxd-dev#1.0.7-2 +libusbprog-dev#0.2.0-2 +libusbredirhost-dev#0.4.3-2 +libusbredirparser-dev#0.4.3-2 +libusbtc08-dev#1.7.2-1 +libuser1-dev#1:0.56.9.dfsg.1-1.2 +libust-dev#2.0.4-1 +libustr-dev#1.0.4-3 +libutempter-dev#1.1.5-4 +libuu-dev#0.5.20-3.3 +libuuidm-ocaml-dev#0.9.4-1 +libv4l-dev#0.8.8-3 +libv8-dev#3.8.9.20-2 +libv8-i18n-dev#0~0.svn7-3 +libva-dev#1.0.15-4 +libvala-0.14-dev#0.14.2-2 +libvala-0.16-dev#0.16.1-2 +libvaladoc-dev#0.3.2~git20120227-1 +libvalhalla-dev#2.0.0-4+b1 +libvanessa-adt-dev#0.0.9-1 +libvanessa-logger-dev#0.0.10-1.1 +libvanessa-socket-dev#0.0.12-1 +libvarconf-dev#0.6.7-2 +libvarnishapi-dev#3.0.2-2+deb7u1 +libvbr-dev#2.6.8-4 +libvc-dev#003.dfsg.1-12 +libvcdinfo-dev#0.7.24+dfsg-0.1 +libvde-dev#2.3.2-4 +libvdeplug-dev#2.3.2-4 +libvdk2-dev#2.4.0-5.3 +libvdkbuilder2-dev#2.4.0-4.3 +libvdkxdb2-dev#2.4.0-3.4 +libvdpau-dev#0.4.1-7 +libventrilo-dev#1.2.4-1 +libverbiste-dev#0.1.34-1 +libverto-dev#0.2.2-1 +libvformat-dev#1.13-10 +libvia-dev#2.0.4-2 +libvibrant6-dev#6.1.20120620-2 +libview-dev#0.6.6-2.1 +libvigraimpex-dev#1.7.1+dfsg1-3 +libvips-dev#7.28.5-1+deb7u1 +libvirt-dev#0.9.12.3-1 +libvirt-glib-1.0-dev#0.0.8-1 +libvirt-ocaml-dev#0.6.1.2-1 +libvisca-dev#1.0.1-1 +libvisio-dev#0.0.17-1 +libvisual-0.4-dev#0.4.0-5 +libvlc-dev#2.0.3-5 +libvlccore-dev#2.0.3-5 +libvmmlib-dev#1.0-2 +libvncserver-dev#0.9.9+dfsg-1 +libvo-aacenc-dev#0.1.2-1 +libvo-amrwbenc-dev#0.1.2-1 +libvoaacenc-ocaml-dev#0.1.0-1+b1 +libvoikko-dev#3.5-1.1 +libvolpack1-dev#1.0b3-3 +libvorbis-dev#1.3.2-1.3 +libvorbis-ocaml-dev#0.6.1-1+b1 +libvorbisidec-dev#1.0.2+svn18153-0.2 +libvotequorum-dev#1.4.2-3 +libvpb-dev#4.2.55-1 +libvpx-dev#1.1.0-1 +libvrb0-dev#0.5.1-5.1 +libvte-2.90-dev#1:0.32.2-1 +libvte-dev#1:0.28.2-5 +libvte0.16-cil-dev#2.26.0-8 +libvtk5-dev#5.8.0-13+b1 +libvtk5-qt4-dev#5.8.0-13+b1 +libvtkedge-dev#0.2.0~20110819-2 +libvtkgdcm2-dev#2.2.0-14.1 +libvxl1-dev#1.14.0-18 +libwacom-dev#0.6-1 +libwaei-dev#3.4.3-1 +libwaili-dev#19990723-20 +libwavefront-standalone3.0-dev#3.0.2+dfsg-4+b1 +libwavpack-dev#4.60.1-3 +libwayland-dev#0.85.0-2 +libwbclient-dev#2:3.6.6-6+deb7u3 +libwbxml2-dev#0.10.7-1 +libwcstools-dev#3.8.5-1 +libwebauth-dev#4.1.1-2 +libwebcam0-dev#0.2.2-1 +libwebkit-cil-dev#0.3-6 +libwebkit-dev#1.8.1-3.4 +libwebkitgtk-3.0-dev#1.8.1-3.4 +libwebkitgtk-dev#1.8.1-3.4 +libwebp-dev#0.1.3-3+nmu1 +libwebrtc-audio-processing-dev#0.1-2 +libweed-dev#1.6.2~ds1-2 +libwfmath-0.3-dev#0.3.12-3 +libwfut-0.2-dev#0.2.1-2 +libwibble-dev#0.1.28-1.1 +libwildmidi-dev#0.2.3.4-2.1 +libwine-dev#1.4.1-4 +libwings-dev#0.95.3-2 +libwireshark-dev#1.8.2-5wheezy10 +libwiretap-dev#1.8.2-5wheezy10 +libwmf-dev#0.2.8.4-10.3 +libwnck-3-dev#3.4.2-1 +libwnck-dev#2.30.7-1 +libwnck1.0-cil-dev#2.26.0-8 +libwnn-dev#1.1.1~a021+cvs20100325-6 +libwnn6-dev#1.0.0-14.2+b1 +libwpd-dev#0.9.4-3 +libwpg-dev#0.2.1-1 +libwps-dev#0.2.7-1 +libwrap0-dev#7.6.q-24 +libwraster3-dev#0.95.3-2 +libwreport-dev#2.4-1 +libwsutil-dev#1.8.2-5wheezy10 +libwt-dev#3.2.1-2 +libwtdbo-dev#3.2.1-2 +libwtdbofirebird-dev#3.2.1-2 +libwtdbopostgres-dev#3.2.1-2 +libwtdbosqlite-dev#3.2.1-2 +libwtext-dev#3.2.1-2 +libwtfcgi-dev#3.2.1-2 +libwthttp-dev#3.2.1-2 +libwttest-dev#3.2.1-2 +libwv-dev#1.2.9-3 +libwv2-dev#0.4.2.dfsg.2-1~deb7u1 +libwvstreams-dev#4.6.1-5 +libwxbase2.8-dev#2.8.12.1-12 +libwxgtk2.8-dev#2.8.12.1-12 +libwxsmithlib-dev#10.05-2.1 +libwxsmithlib0-dev#10.05-2.1 +libwxsqlite3-2.8-dev#3.0.0.1~dfsg0-2 +libwxsvg-dev#2:1.1.8~dfsg0-2 +libx11-dev#2:1.5.0-1+deb7u1 +libx11-xcb-dev#2:1.5.0-1+deb7u1 +libx264-dev#2:0.123.2189+git35cf912-1 +libx52pro-dev#0.1.1-2.1 +libx86-dev#1.1+ds1-10 +libxalan110-dev#1.10-6 +libxapian-dev#1.2.12-2 +libxatracker-dev#8.0.5-4+deb7u2 +libxau-dev#1:1.0.7-1 +libxaw7-dev#2:1.0.10-2 +libxbae-dev#4.60.4-3 +libxbase2.0-dev#2.0.0-8.5 +libxcb-composite0-dev#1.8.1-2+deb7u1 +libxcb-damage0-dev#1.8.1-2+deb7u1 +libxcb-dpms0-dev#1.8.1-2+deb7u1 +libxcb-dri2-0-dev#1.8.1-2+deb7u1 +libxcb-ewmh-dev#0.3.9-2 +libxcb-glx0-dev#1.8.1-2+deb7u1 +libxcb-icccm4-dev#0.3.9-2 +libxcb-image0-dev#0.3.9-1 +libxcb-keysyms1-dev#0.3.9-1 +libxcb-randr0-dev#1.8.1-2+deb7u1 +libxcb-record0-dev#1.8.1-2+deb7u1 +libxcb-render-util0-dev#0.3.8-1.1 +libxcb-render0-dev#1.8.1-2+deb7u1 +libxcb-res0-dev#1.8.1-2+deb7u1 +libxcb-screensaver0-dev#1.8.1-2+deb7u1 +libxcb-shape0-dev#1.8.1-2+deb7u1 +libxcb-shm0-dev#1.8.1-2+deb7u1 +libxcb-sync0-dev#1.8.1-2+deb7u1 +libxcb-util0-dev#0.3.8-2 +libxcb-xevie0-dev#1.8.1-2+deb7u1 +libxcb-xf86dri0-dev#1.8.1-2+deb7u1 +libxcb-xfixes0-dev#1.8.1-2+deb7u1 +libxcb-xinerama0-dev#1.8.1-2+deb7u1 +libxcb-xprint0-dev#1.8.1-2+deb7u1 +libxcb-xtest0-dev#1.8.1-2+deb7u1 +libxcb-xv0-dev#1.8.1-2+deb7u1 +libxcb-xvmc0-dev#1.8.1-2+deb7u1 +libxcb1-dev#1.8.1-2+deb7u1 +libxcomp-dev#3.5.0.12-1+b1 +libxcomposite-dev#1:0.4.3-2 +libxcp-ocaml-dev#0.5.2-3+b1 +libxcrypt-dev#1:2.4-3 +libxcursor-dev#1:1.1.13-1+deb7u1 +libxdamage-dev#1:1.1.3-2 +libxdb-dev#1.2.0-7.2 +libxdelta2-dev#1.1.3-9 +libxdffileio-dev#0.3-1 +libxdg-basedir-dev#1.1.1-2 +libxdmcp-dev#1:1.1.1-1 +libxdmf-dev#2.1.dfsg.1-5 +libxdo-dev#1:2.20100701.2961-3+deb7u3 +libxen-dev#4.1.4-3+deb7u1 +libxen-ocaml-dev#4.1.4-3+deb7u1 +libxenapi-ocaml-dev#1.3.2-15 +libxenomai-dev#2.6.0-2 +libxerces-c-dev#3.1.1-3 +libxerces-c2-dev#2.8.0+deb1-3 +libxext-dev#2:1.3.1-2+deb7u1 +libxfce4menu-0.1-dev#4.6.2-1 +libxfce4ui-1-dev#4.8.1-1 +libxfce4util-dev#4.8.2-1 +libxfcegui4-dev#4.8.1-5 +libxfconf-0-dev#4.8.1-1 +libxfixes-dev#1:5.0-4+deb7u1 +libxfont-dev#1:1.4.5-3 +libxft-dev#2.3.1-1 +libxi-dev#2:1.6.1-1+deb7u1 +libxine-dev#1.1.21-1+deb7u1 +libxine2-dev#1.2.2-5 +libxinerama-dev#2:1.1.2-1+deb7u1 +libxkbfile-dev#1:1.0.8-1 +libxklavier-dev#5.2.1-1 +libxml++2.6-dev#2.34.2-1 +libxml-light-ocaml-dev#2.2-15 +libxml-security-c-dev#1.6.1-5+deb7u2 +libxml2-dev#2.8.0+dfsg1-7+nmu3 +libxmlada4.1-dev#4.1-2 +libxmlezout2-dev#1.06.1-5 +libxmlm-ocaml-dev#1.1.0-1 +libxmlplaylist-ocaml-dev#0.1.3-1+b2 +libxmlrpc-c++4-dev#1.16.33-3.2 +libxmlrpc-c3-dev#1.16.33-3.2 +libxmlrpc-core-c3-dev#1.16.33-3.2 +libxmlrpc-epi-dev#0.54.2-1 +libxmlrpc-light-ocaml-dev#0.6.1-3+b5 +libxmlsec1-dev#1.2.18-2 +libxmltok1-dev#1.2-3 +libxmltooling-dev#1.4.2-5 +libxmmsclient++-dev#0.8+dfsg-4 +libxmmsclient++-glib-dev#0.8+dfsg-4 +libxmmsclient-dev#0.8+dfsg-4 +libxmmsclient-glib-dev#0.8+dfsg-4 +libxmpi4-dev#2.2.3b8-13 +libxmu-dev#2:1.1.1-1 +libxmuu-dev#2:1.1.1-1 +libxnee-dev#3.13-1 +libxneur-dev#0.15.0-1.1 +libxosd-dev#2.2.14-2 +libxp-dev#1:1.0.1-2+deb7u1 +libxpa-dev#2.1.14-2 +libxplc0.3.13-dev#0.3.13-3 +libxpm-dev#1:3.5.10-1 +libxqdbm-dev#1.8.78-2 +libxqilla-dev#2.3.0-1 +libxr1-dev#1.0-2.1 +libxrandr-dev#2:1.3.2-2+deb7u1 +libxrender-dev#1:0.9.7-1+deb7u1 +libxres-dev#2:1.0.6-1+deb7u1 +libxsettings-client-dev#0.17-6 +libxsettings-dev#0.11-3 +libxslt1-dev#1.1.26-14.1 +libxss-dev#1:1.2.2-1 +libxstr-ocaml-dev#0.2.1-21+b3 +libxstrp4-camlp4-dev#1.8-3 +libxt-dev#1:1.1.3-1+deb7u1 +libxtst-dev#2:1.2.1-1+deb7u1 +libxv-dev#2:1.0.7-1+deb7u1 +libxvidcore-dev#2:1.3.2-9 +libxvmc-dev#2:1.0.7-1+deb7u2 +libxxf86dga-dev#2:1.1.3-2+deb7u1 +libxxf86vm-dev#1:1.1.2-1+deb7u1 +libxy-dev#0.8-1+b1 +libyahoo2-dev#1.0.1-1 +libyajl-dev#2.0.4-2 +libyaml-cpp-dev#0.3.0-1 +libyaml-dev#0.1.4-2+deb7u4 +libyaz4-dev#4.2.30-2 +libyelp-dev#3.4.2-1+b1 +libygl4-dev#4.2e-4 +libykclient-dev#2.6-1 +libykpers-1-dev#1.7.0-1 +libyojson-ocaml-dev#1.0.3-1 +libytnef0-dev#1.5-4 +libyubikey-dev#1.8-1 +libz80ex-dev#1.1.19-3 +libzarith-ocaml-dev#1.1-2 +libzbar-dev#0.10+doc-8 +libzbargtk-dev#0.10+doc-8 +libzbarqt-dev#0.10+doc-8 +libzeep-dev#2.9.0-2 +libzeitgeist-cil-dev#0.8.0.0-4 +libzeitgeist-dev#0.3.18-1 +libzen-dev#0.4.27-2 +libzephyr-dev#3.0.2-2 +libzerg0-dev#1.0.7-3 +libzeroc-ice34-dev#3.4.2-8.2 +libzinnia-dev#0.06-1+b1 +libzip-dev#0.10.1-1.1 +libzip-ocaml-dev#1.04-6+b3 +libzipios++-dev#0.1.5.9+cvs.2007.04.28-5.1 +libzita-alsa-pcmi-dev#0.2.0-1 +libzita-convolver-dev#3.1.0-2 +libzita-resampler-dev#1.1.0-3 +libzlcore-dev#0.12.10dfsg-8 +libzltext-dev#0.12.10dfsg-8 +libzmq-dev#2.2.0+dfsg-2 +libzn-poly-dev#0.8-1.1 +libzookeeper-mt-dev#3.3.5+dfsg1-2 +libzookeeper-st-dev#3.3.5+dfsg1-2 +libzorp-dev#3.9.5-4 +libzorpll-dev#3.9.1.3-1 +libzrtpcpp-dev#2.0.0-3 +libzthread-dev#2.3.2-7 +libzvbi-dev#0.2.33-6 +libzzip-dev#0.13.56-1.1 +licq-dev#1.6.1-3 +linux-libc-dev#3.2.57-3 +lldpad-dev#0.9.44-1 +llvm-2.9-dev#2.9+dfsg-7 +llvm-3.0-dev#3.0-10 +llvm-3.1-dev#3.1-1 +llvm-dev#1:3.0-14+nmu2 +lttv-dev#0.12.38-21032011-1+b1 +lua-apr-dev#0.23.2-1 +lua-bitop-dev#1.0.2-1 +lua-curl-dev#0.3.0-7 +lua-curses-dev#5.1.19-2 +lua-cyrussasl-dev#1.0.0-4 +lua-dbi-mysql-dev#0.5+svn78-4 +lua-dbi-postgresql-dev#0.5+svn78-4 +lua-dbi-sqlite3-dev#0.5+svn78-4 +lua-event-dev#0.4.1-2 +lua-expat-dev#1.2.0-5+deb7u1 +lua-filesystem-dev#1.5.0+16+g84f1af5-1 +lua-iconv-dev#7-1 +lua-ldap-dev#1.1.0-1-geeac494-3 +lua-leg-dev#0.1.2-8 +lua-lgi-dev#0.6.2-1 +lua-lpeg-dev#0.10.2-5 +lua-md5-dev#1.1.2-6 +lua-penlight-dev#1.0.2+htmldoc-2 +lua-posix-dev#5.1.19-2 +lua-rex-onig-dev#2.6.0-2 +lua-rex-pcre-dev#2.6.0-2 +lua-rex-posix-dev#2.6.0-2 +lua-rex-tre-dev#2.6.0-2 +lua-rings-dev#1.2.3-1 +lua-sec-dev#0.4.1-1 +lua-socket-dev#2.0.2-8 +lua-sql-mysql-dev#2.3.0-1+build0 +lua-sql-postgres-dev#2.3.0-1+build0 +lua-sql-sqlite3-dev#2.3.0-1+build0 +lua-svn-dev#0.4.0-7 +lua-wsapi-fcgi-dev#1.5-3 +lua-zip-dev#1.2.3-11 +lua-zlib-dev#0.2-1 +lua5.1-policy-dev#33 +lv2-dev#1.0.0~dfsg2-2 +lxc-dev#0.8.0~rc1-8+deb7u2 +lzma-dev#9.22-2 +manpages-de-dev#1.2-1 +manpages-dev#3.44-1 +manpages-fr-dev#3.44d1p1-1 +manpages-ja-dev#0.5.0.0.20120606-1 +manpages-pl-dev#1:0.3-1 +manpages-pt-dev#20040726-4 +matlab-support-dev#0.0.18 +mdbtools-dev#0.7-1+deb7u1 +med-bio-dev#1.13.2 +med-imaging-dev#1.13.2 +mesa-common-dev#8.0.5-4+deb7u2 +mffm-fftw-dev#1.7-3 +mffm-timecode-dev#1.6-2 +mingw-w64-dev#2.0.3-1 +mingw-w64-i686-dev#2.0.3-1 +mingw-w64-x86-64-dev#2.0.3-1 +minpack-dev#19961126+dfsg1-1 +mongodb-dev#1:2.0.6-1.1 +mpi-default-dev#1.0.1 +muroard-dev#0.1.10-2 +neko-dev#1.8.1-6 +nettle-dev#2.4-3 +network-manager-dev#0.9.4.0-10 +ntfs-3g-dev#1:2012.1.15AR.5-2.1 +ocfs2-tools-dev#1.6.4-1+deb7u1 +ocl-icd-dev#1.3-3 +ocl-icd-opencl-dev#1.3-3 +ocsigen-dev#1.3.4-2 +octave-pkg-dev#1.0.2 +ofono-dev#1.6-2 +okteta-dev#4:4.8.4+dfsg-1 +okular-dev#4:4.8.4-3 +open-vm-tools-dev#2:8.8.0+2012.05.21-724730-1+nmu2 +openais-dev#1.1.4-4.1 +openbox-dev#3.5.0-7 +openchangeserver-dev#1:1.0-3 +oss4-dev#4.2-build2006-2+deb7u1 +pacemaker-dev#1.1.7-1 +packaging-dev#0.4 +paraview-dev#3.14.1-6 +parole-dev#0.2.0.6-1+b1 +parser3-dev#3.4.2-2 +pbs-drmaa-dev#1.0.10-3 +petsc-dev#3.2.dfsg-6 +php5-dev#5.4.4-14+deb7u9 +pidgin-dev#2.10.9-1~deb7u1 +pinball-dev#0.3.1-13.1 +planetpenguin-racer-gimp-dev#0.4-5 +planner-dev#0.14.6-1 +plplot-tcl-dev#5.9.9-5 +plptools-dev#1.0.9-2.4 +plymouth-dev#0.8.5.1-5 +portaudio19-dev#19+svn20111121-1 +postfix-dev#2.9.6-2 +ppl-dev#0.11.2-8 +ppp-dev#2.4.5-5.1 +prayer-templates-dev#1.3.4-dfsg1-1 +proftpd-dev#1.3.4a-5+deb7u1 +pslib-dev#0.4.5-3 +publib-dev#0.40-1 +puredata-dev#0.43.2-5 +pvm-dev#3.4.5-12.5 +pxlib-dev#0.6.5-1 +python-all-dev#2.7.3-4+deb7u1 +python-apt-dev#0.8.8.2 +python-cairo-dev#1.8.8-1 +python-cxx-dev#6.2.4-3 +python-dbus-dev#1.1.1-1 +python-dev#2.7.3-4+deb7u1 +python-egenix-mx-base-dev#3.2.1-1.1 +python-gamera-dev#3.3.3-2 +python-gi-dev#3.2.2-2 +python-gnome2-desktop-dev#2.32.0+dfsg-2 +python-gnome2-dev#2.28.1+dfsg-1 +python-gnome2-extras-dev#2.25.3-12 +python-gobject-2-dev#2.28.6-10 +python-gobject-dev#3.2.2-2 +python-greenlet-dev#0.3.1-2.5 +python-gst0.10-dev#0.10.22-3 +python-gtk2-dev#2.24.0-3 +python-kde4-dev#4:4.8.4-1 +python-ldb-dev#1:1.1.6-1 +python-openturns-dev#1.0-4 +python-pyorbit-dev#2.24.0-6 +python-qt4-dev#4.9.3-4 +python-sip-dev#4.13.3-2 +python-talloc-dev#2.0.7+git20120207-1 +python-webkit-dev#1.1.8-2 +python2.6-dev#2.6.8-1.1 +python2.7-dev#2.7.3-6+deb7u2 +python3-all-dev#3.2.3-6 +python3-cairo-dev#1.10.0+dfsg-2 +python3-cxx-dev#6.2.4-3 +python3-dev#3.2.3-6 +python3-sip-dev#4.13.3-2 +python3.2-dev#3.2.3-7 +qmf-dev#1.0.7~2011w23.2-2.1 +qtmobility-dev#1.2.0-3 +r-base-dev#2.15.1-4 +regina-normal-dev#4.93-1 +resource-agents-dev#1:3.9.2-5+deb7u2 +rhythmbox-dev#2.97-2.1 +rivet-plugins-dev#1.8.0-1 +roarplaylistd-dev#0.1.1-2 +robot-player-dev#3.0.2+dfsg-4 +ruby-dev#1:1.9.3 +ruby-gnome2-dev#1.1.3-2+b1 +ruby1.8-dev#1.8.7.358-7.1+deb7u1 +ruby1.9.1-dev#1.9.3.194-8.1+deb7u2 +rygel-1.0-dev#0.14.3-2+deb7u1 +samba4-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +sbnc-php-dev#1.2-26 +science-astronomy-dev#1.0 +science-dataacquisition-dev#1.0 +science-engineering-dev#1.0 +science-highenergy-physics-dev#1.0 +science-mathematics-dev#1.0 +science-meteorology-dev#1.0 +science-nanoscale-physics-dev#1.0 +science-physics-dev#1.0 +scim-dev#1.4.13-5 +sciplot-dev#1.36-15 +selinux-policy-dev#2:2.20110726-12 +seqan-dev#1.3.1-1 +sfftw-dev#2.1.5-1 +skalibs-dev#0.47-1 +slurm-drmaa-dev#1.0.4-3 +slurm-llnl-basic-plugins-dev#2.3.4-2+b1 +snappea-dev#3.0d3-22 +spl-dev#1.0~pre6-3.1+b1 +sra-toolkit-libs-dev#2.1.7a-1 +ss-dev#2.0-1.42.5-1.1 +stx-btree-dev#0.8.6-1 +styx-dev#1.8.0-1.1 +supercollider-dev#1:3.4.5-1wheezy1 +svdrpservice-dev#0.0.4-14 +sweep-dev#0.9.3-6 +swish-e-dev#2.4.7-3 +syfi-dev#1.0.0.dfsg-1 +system-tools-backends-dev#2.10.2-1 +systemtap-sdt-dev#1.7-1+deb7u1 +tcl-dev#8.5.0-2.1 +tcl-memchan-dev#2.3-2 +tcl-trf-dev#2.1.4-dfsg1-1 +tcl8.4-dev#8.4.19-5 +tcl8.5-dev#8.5.11-2 +tclcl-dev#1.20-6 +tclx8.4-dev#8.4.0-3 +tclxml-dev#3.3~svn11-2 +tdom-dev#0.8.3~20080525-3+nmu2 +tesseract-ocr-dev#3.02.01-6 +tix-dev#8.4.3-4 +tk-dev#8.5.0-2.1 +tk8.4-dev#8.4.19-5 +tk8.5-dev#8.5.11-2 +tqsllib-dev#2.2-5 +trafficserver-dev#3.0.5-1 +tuxpaint-dev#1:0.9.21-1.1 +unagi-dev#0.3.3-2 +unixodbc-dev#2.2.14p2-5 +uthash-dev#1.9.5-1 +uuid-dev#2.20.1-5.3 +vdr-dev#1.7.28-1 +vflib3-dev#3.6.14.dfsg-3+b1 +voms-dev#2.0.8-1 +vstream-client-dev#1.2-6.1 +wcslib-dev#4.13.4-1 +weechat-dev#0.3.8-1+deb7u1 +wireshark-dev#1.8.2-5wheezy10 +witty-dev#3.2.1-2 +wordnet-dev#1:3.0-29 +wzdftpd-dev#0.8.3-6.2 +x11proto-bigreqs-dev#1:1.1.2-1 +x11proto-composite-dev#1:0.4.2-2 +x11proto-core-dev#7.0.23-1 +x11proto-damage-dev#1:1.2.1-2 +x11proto-dmx-dev#1:2.3.1-2 +x11proto-dri2-dev#2.6-2 +x11proto-fixes-dev#1:5.0-2 +x11proto-fonts-dev#2.1.2-1 +x11proto-gl-dev#1.4.15-1 +x11proto-input-dev#2.2-1 +x11proto-kb-dev#1.0.6-2 +x11proto-print-dev#1.0.5-2 +x11proto-randr-dev#1.3.2-2 +x11proto-record-dev#1.14.2-1 +x11proto-render-dev#2:0.11.1-2 +x11proto-resource-dev#1.2.0-3 +x11proto-scrnsaver-dev#1.2.2-1 +x11proto-video-dev#2.3.1-2 +x11proto-xcmisc-dev#1.2.2-1 +x11proto-xext-dev#7.2.1-1 +x11proto-xf86bigfont-dev#1.2.0-3 +x11proto-xf86dga-dev#2.1-3 +x11proto-xf86dri-dev#2.1.1-2 +x11proto-xf86vidmode-dev#2.3.1-2 +x11proto-xinerama-dev#1.2.1-2 +xaw3dg-dev#1.5+E-18.2 +xbmc-eventclients-dev#2:11.0~git20120510.82388d5-1 +xfce4-panel-dev#4.8.6-4 +xfslibs-dev#3.1.7+b1 +xmhtml1-dev#1.1.7-18 +xmms2-dev#0.8+dfsg-4 +xorg-dev#1:7.7+3~deb7u1 +xotcl-dev#1.6.7-2 +xpaint-dev#2.9.1.4-3+b2 +xserver-xorg-dev#2:1.12.4-6+deb7u2 +xserver-xorg-input-evdev-dev#1:2.7.0-1 +xserver-xorg-input-joystick-dev#1:1.6.1-1 +xserver-xorg-input-synaptics-dev#1.6.2-2 +xtrans-dev#1.2.7-1 +xulrunner-dev#24.4.0esr-1~deb7u2 +xutils-dev#1:7.7~1 +xviewg-dev#3.2p1.4-28.1 +yate-dev#4.1.0-1~dfsg-3 +yorick-dev#2.2.02+dfsg-6 +zathura-dev#0.1.2-4 +zlib1g-dev#1:1.2.7.dfsg-13 +znc-dev#0.206-2 +zsh-dev#4.3.17-1 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t05_snapshot/search.py b/src/github.com/smira/aptly/system/t05_snapshot/search.py index 9133b333..aa85546c 100644 --- a/src/github.com/smira/aptly/system/t05_snapshot/search.py +++ b/src/github.com/smira/aptly/system/t05_snapshot/search.py @@ -47,3 +47,13 @@ class SearchSnapshot5Test(BaseTest): fixtureCmds = ["aptly snapshot create wheezy-main from mirror wheezy-main"] runCmd = "aptly snapshot search -with-deps wheezy-main 'Name (no-such-package)'" expectedCode = 1 + + +class SearchSnapshot6Test(BaseTest): + """ + search snapshot: with format + """ + fixtureDB = True + outputMatchPrepare = lambda _, s: "\n".join(sorted(s.split("\n"))) + fixtureCmds = ["aptly snapshot create wheezy-main from mirror wheezy-main"] + runCmd = "aptly snapshot search -format='{{.Package}}#{{.Version}}' wheezy-main '$$Architecture (i386), Name (% *-dev)'" diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishRepo1Test_contents_i386 b/src/github.com/smira/aptly/system/t06_publish/PublishRepo1Test_contents_i386 new file mode 100644 index 00000000..6181be28 --- /dev/null +++ b/src/github.com/smira/aptly/system/t06_publish/PublishRepo1Test_contents_i386 @@ -0,0 +1,3 @@ +FILE LOCATION +usr/share/doc/libboost-program-options-dev/changelog.gz libdevel/libboost-program-options-dev +usr/share/doc/libboost-program-options-dev/copyright libdevel/libboost-program-options-dev diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishRepo1Test_sources b/src/github.com/smira/aptly/system/t06_publish/PublishRepo1Test_sources index 63cdaa3b..225625b7 100644 --- a/src/github.com/smira/aptly/system/t06_publish/PublishRepo1Test_sources +++ b/src/github.com/smira/aptly/system/t06_publish/PublishRepo1Test_sources @@ -1,42 +1,49 @@ -Package: pyspi -Version: 0.6.1-1.3 -Maintainer: Jose Carlos Garcia Sogo -Architecture: any -Homepage: http://people.redhat.com/zcerza/dogtail -Binary: python-at-spi -Directory: pool/main/p/pyspi -Checksums-Sha1: 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz - 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc - 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz -Checksums-Sha256: 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz - d494aaf526f1ec6b02f14c2f81e060a5722d6532ddc760ec16972e45c2625989 1782 pyspi_0.6.1-1.3.dsc - 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz -Format: 1.0 -Standards-Version: 3.7.3 -Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk -Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Files: 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz - b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc - def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz -Package: pyspi -Version: 0.6.1-1.4 -Maintainer: Jose Carlos Garcia Sogo -Architecture: any -Binary: python-at-spi -Format: 1.0 -Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Homepage: http://people.redhat.com/zcerza/dogtail -Standards-Version: 3.7.3 -Directory: pool/main/p/pyspi -Files: 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc + + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz - def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz -Checksums-Sha256: 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz + 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc + 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc + 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz -Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk -Checksums-Sha1: 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc + 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz + 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz - + 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz + b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc + d494aaf526f1ec6b02f14c2f81e060a5722d6532ddc760ec16972e45c2625989 1782 pyspi_0.6.1-1.3.dsc + def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz + def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz +Architecture: any +Architecture: any +Binary: python-at-spi +Binary: python-at-spi +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Checksums-Sha1: +Checksums-Sha1: +Checksums-Sha256: +Checksums-Sha256: +Directory: pool/main/p/pyspi +Directory: pool/main/p/pyspi +Files: +Files: +Format: 1.0 +Format: 1.0 +Homepage: http://people.redhat.com/zcerza/dogtail +Homepage: http://people.redhat.com/zcerza/dogtail +Maintainer: Jose Carlos Garcia Sogo +Maintainer: Jose Carlos Garcia Sogo +Package: pyspi +Package: pyspi +Standards-Version: 3.7.3 +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Version: 0.6.1-1.3 +Version: 0.6.1-1.4 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishRepo28Test_gold b/src/github.com/smira/aptly/system/t06_publish/PublishRepo28Test_gold new file mode 100644 index 00000000..365295fa --- /dev/null +++ b/src/github.com/smira/aptly/system/t06_publish/PublishRepo28Test_gold @@ -0,0 +1,14 @@ +Loading packages... +Generating metadata files and linking package files... +Finalizing metadata files... +Signing file 'Release' with gpg, please enter your passphrase when prompted: +Clearsigning file 'Release' with gpg, please enter your passphrase when prompted: + +Local repo local-repo has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ maverick main + deb-src http://your-server/ maverick main +Don't forget to add your GPG key to apt with apt-key. + +You can also use `aptly serve` to publish your repositories over HTTP quickly. diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot16Test_sources b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot16Test_sources index aaac2603..99b8881d 100644 --- a/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot16Test_sources +++ b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot16Test_sources @@ -1,27 +1,32 @@ -Package: gnuplot -Version: 4.6.1-1~maverick2 -Section: math -Maintainer: Debian Science Team -Architecture: any all -Package-List: gnuplot deb math optional + + + 021df43737184e40b1ef8cef3cbd18b9 2431 gnuplot_4.6.1-1~maverick2.dsc + 103201f00bd80a7408dfb0e0b630eb14 18955 gnuplot_4.6.1-1~maverick2.debian.tar.gz + 1ea21a628223159b0297ae65fe8293afd5aab3c0 4959670 gnuplot_4.6.1.orig.tar.gz + 2dd7bd3ee9abf89a0c2d518dfea56e7cbf01e0c2 18955 gnuplot_4.6.1-1~maverick2.debian.tar.gz + 4c9a06461f402482c30cf94e267eb877 4959670 gnuplot_4.6.1.orig.tar.gz + e1e3ad5ad145cf7909a029a4dba6b9fffb5faabc3bc6b5099a3d6a92c7b5da2c 18955 gnuplot_4.6.1-1~maverick2.debian.tar.gz + f4bf99907d0fea7db90b6e50147f1730b5bde2fbb93d9e58478b6b94409eebc6 4959670 gnuplot_4.6.1.orig.tar.gz + gnuplot deb math optional gnuplot-doc deb doc optional gnuplot-nox deb math optional gnuplot-x11 deb math optional -Dm-Upload-Allowed: yes -Checksums-Sha1: 2dd7bd3ee9abf89a0c2d518dfea56e7cbf01e0c2 18955 gnuplot_4.6.1-1~maverick2.debian.tar.gz - 1ea21a628223159b0297ae65fe8293afd5aab3c0 4959670 gnuplot_4.6.1.orig.tar.gz +Architecture: any all Binary: gnuplot, gnuplot-nox, gnuplot-x11, gnuplot-doc +Build-Depends: debhelper (>= 7), libpng-dev, libx11-dev, libxt-dev, pkg-config, texinfo (>= 4.8), texlive-latex-base, texlive-latex-recommended, texlive-latex-extra, liblua5.1-dev, zlib1g-dev, libgd2-noxpm-dev, quilt, libwxgtk2.8-dev, libcairo2-dev, libpango1.0-dev, libedit-dev, autoconf, automake +Checksums-Sha1: +Checksums-Sha256: Directory: pool/main/g/gnuplot -Vcs-Browser: http://git.debian.org/?p=debian-science/packages/gnuplot.git -Vcs-Git: git://git.debian.org/git/debian-science/packages/gnuplot.git +Dm-Upload-Allowed: yes +Files: Format: 3.0 (quilt) -Files: 103201f00bd80a7408dfb0e0b630eb14 18955 gnuplot_4.6.1-1~maverick2.debian.tar.gz - 021df43737184e40b1ef8cef3cbd18b9 2431 gnuplot_4.6.1-1~maverick2.dsc - 4c9a06461f402482c30cf94e267eb877 4959670 gnuplot_4.6.1.orig.tar.gz Homepage: http://gnuplot.sourceforge.net/ +Maintainer: Debian Science Team +Package-List: +Package: gnuplot +Section: math Standards-Version: 3.8.4 Uploaders: Bradley Smith , Anton Gladky -Checksums-Sha256: e1e3ad5ad145cf7909a029a4dba6b9fffb5faabc3bc6b5099a3d6a92c7b5da2c 18955 gnuplot_4.6.1-1~maverick2.debian.tar.gz - f4bf99907d0fea7db90b6e50147f1730b5bde2fbb93d9e58478b6b94409eebc6 4959670 gnuplot_4.6.1.orig.tar.gz -Build-Depends: debhelper (>= 7), libpng-dev, libx11-dev, libxt-dev, pkg-config, texinfo (>= 4.8), texlive-latex-base, texlive-latex-recommended, texlive-latex-extra, liblua5.1-dev, zlib1g-dev, libgd2-noxpm-dev, quilt, libwxgtk2.8-dev, libcairo2-dev, libpango1.0-dev, libedit-dev, autoconf, automake - +Vcs-Browser: http://git.debian.org/?p=debian-science/packages/gnuplot.git +Vcs-Git: git://git.debian.org/git/debian-science/packages/gnuplot.git +Version: 4.6.1-1~maverick2 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot17Test_sources b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot17Test_sources index 63cdaa3b..225625b7 100644 --- a/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot17Test_sources +++ b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot17Test_sources @@ -1,42 +1,49 @@ -Package: pyspi -Version: 0.6.1-1.3 -Maintainer: Jose Carlos Garcia Sogo -Architecture: any -Homepage: http://people.redhat.com/zcerza/dogtail -Binary: python-at-spi -Directory: pool/main/p/pyspi -Checksums-Sha1: 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz - 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc - 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz -Checksums-Sha256: 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz - d494aaf526f1ec6b02f14c2f81e060a5722d6532ddc760ec16972e45c2625989 1782 pyspi_0.6.1-1.3.dsc - 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz -Format: 1.0 -Standards-Version: 3.7.3 -Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk -Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Files: 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz - b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc - def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz -Package: pyspi -Version: 0.6.1-1.4 -Maintainer: Jose Carlos Garcia Sogo -Architecture: any -Binary: python-at-spi -Format: 1.0 -Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Homepage: http://people.redhat.com/zcerza/dogtail -Standards-Version: 3.7.3 -Directory: pool/main/p/pyspi -Files: 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc + + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz - def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz -Checksums-Sha256: 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz + 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc + 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc + 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz -Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk -Checksums-Sha1: 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc + 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz + 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz - + 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz + b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc + d494aaf526f1ec6b02f14c2f81e060a5722d6532ddc760ec16972e45c2625989 1782 pyspi_0.6.1-1.3.dsc + def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz + def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz +Architecture: any +Architecture: any +Binary: python-at-spi +Binary: python-at-spi +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev +Checksums-Sha1: +Checksums-Sha1: +Checksums-Sha256: +Checksums-Sha256: +Directory: pool/main/p/pyspi +Directory: pool/main/p/pyspi +Files: +Files: +Format: 1.0 +Format: 1.0 +Homepage: http://people.redhat.com/zcerza/dogtail +Homepage: http://people.redhat.com/zcerza/dogtail +Maintainer: Jose Carlos Garcia Sogo +Maintainer: Jose Carlos Garcia Sogo +Package: pyspi +Package: pyspi +Standards-Version: 3.7.3 +Standards-Version: 3.7.3 +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk +Version: 0.6.1-1.3 +Version: 0.6.1-1.4 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot1Test_contents_amd64 b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot1Test_contents_amd64 new file mode 100644 index 00000000..922b5c05 --- /dev/null +++ b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot1Test_contents_amd64 @@ -0,0 +1,751 @@ +FILE LOCATION +usr/bin/gnuplot math/gnuplot-nox,math/gnuplot-x11 +usr/lib/gnuplot/gnuplot_x11 math/gnuplot-x11 +usr/share/doc-base/gnuplot doc/gnuplot-doc +usr/share/doc/gnuplot math/gnuplot +usr/share/doc/gnuplot-doc/changelog.Debian.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/changelog.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/copyright doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/1.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/2.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/3.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/GM1_bonds.r3d.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/GM1_sugar.pdb.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/Makefile.am.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/Makefile.am.in doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/Makefile.in.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/airfoil.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/all.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/animate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/animate2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/approximate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/arrowstyle.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/arrowstyle.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/asciimat.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/autoscale.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/barchart_art.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/battery.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/big_peak.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/binary.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/bivariat.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/bldg.png doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/blutux.rgb.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/borders.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/boxplot.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/candlesticks.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/candlesticks.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/charset.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/circles.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/cities.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/cities.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/clip14in.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/colorscheme.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/colorwheel.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/contours.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/controls.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ctg-y2.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/dashcolor.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/datastrings.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/delaunay-edges.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/demo.edf.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/density.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/dgrid3d.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/discrete.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/electron.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ellipse.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ellipses.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ellipses_style.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/empty-circles.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/energy_circles.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/enhanced_utf8.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/enhancedtext.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/epslatex.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fillbetween.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fillcrvs.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fillstyle.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/finance.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/finance.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fit.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fit3.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fontfile.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fontfile_latex.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/glass.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gnu-valley doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gnuplot.cfg doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gnuplot.rot doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gpdemos.tcl.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/heatmaps.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hemisphr.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hexa.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hidden.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hidden2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histerror.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histograms.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histograms2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histopt.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/Makefile doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/Makefile.canvas doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/Makefile.svg doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/canvas_utf8.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/gnuplot_demo.css doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/index.canvas.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/index.save.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/index.svg doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/mouseable.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/mousebox.template doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/webify.pl doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/webify_canvas.pl.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/webify_svg.pl.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/image.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/image2.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/imageNaN.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/immigration.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/iterate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/kdensity2d.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/key.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/klein.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/labelplot.pdb doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/layout.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/lcdemo.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/lena-keypoints.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/lena.rgb.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/line.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/macros.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/margins.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mgr.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/molecule.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/moli3.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mouselab_1.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mouselab_2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mouselabels.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mousevariables.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multiaxis.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multimsh.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multipalette.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multiplt.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/nearmap.csv.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/optimize.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/orbital_elements.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/orbits.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/param.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pm3d.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pm3dcolors.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pm3dgamma.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pointsize.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/polar.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/poldat.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/prob.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/prob2.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rainbow.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/random-points.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/random.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rectangle.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/reflect.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rgb_variable.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rgb_variable.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rgbalpha.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/running_avg.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/scatter.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/scatter2.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/scatter2.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/silver.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/simple.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/sine.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/singulr.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/smooth.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/sound.par doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/sound2.par doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/soundvel.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/spline.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/srl.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/starmap.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/start.par doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/stat.inc.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/stats.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/steps.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/steps.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/stringvar.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/surface1.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/surface2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/table.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/textcolor.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/textrotate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/tics.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/timedat.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/timedat.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/transparent.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/transparent_solids.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/triangle.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/using.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/using.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/using.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/utf8.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/varcolor.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/vector.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/whale.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world.cor doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/gnuplot.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/gpcard.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/2D_005fprojection_005f_0028set_005fview_005fmap_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/3D_005f_0028surface_0029_005fplots.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Backwards_005fcompatibility.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Batch_002fInteractive_005fOperation.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Binary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Bugs.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Canvas_005fsize.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Command_002dline_002dediting.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Command_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Commands.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Comments.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Concept_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Coordinates.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Copyright.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Datastrings.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Do.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/EllipticE.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/EllipticK.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/EllipticPi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Enhanced_005ftext_005fmode.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Environment.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Expressions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/External_005flibraries.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Fonts.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Function_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Functions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Glossary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Gnuplot_002ddefined_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Introduction.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Local_005fcustomization_005fof_005flinetypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Mouse_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005ffeatures.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005for_005frevised_005fterminal_005fdrivers.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005fplot_005fstyles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005fsmoothing_005falgorithms.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005fsyntax.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005ftime_002fdate_005fhandling.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Openstep_005f_0028next_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Operators.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Options_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Plotting.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Quote_005fMarks.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Random_005fnumber_005fgenerator.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Revised_005fpolar_005faxes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Seeking_002dassistance.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Start_002dup_005f_0028initialization_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Statistical_005fsummary_005fof_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/String_005fconstants_005fand_005fstring_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/String_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Substitution_005fand_005fCommand_005fline_005fmacros.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Substitution_005fof_005fstring_005fvariables_005fas_005fmacros.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Substitution_005fof_005fsystem_005fcommands_005fin_005fbackquotes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Summation.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Syntax.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Terminal_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Terminal_005ftypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Ternary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Time_002fDate_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Unary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/User_002ddefined_005fvariables_005fand_005ffunctions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/VWS.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/While.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/X11_005fmouse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/abs.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/acos.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/acosh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/adjustable_005fparameters.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/aed767.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/aifm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/airy.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/algorithm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/angles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/aqua.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/arg.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/array.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/arrow.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/asin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/asinh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/atan.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/atan2.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/atanh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/automated_005fiteration_005fover_005fmultiple_005fcolumns.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/autoscale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/axes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/background_005fcolor.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/be.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besj0.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besj1.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besy0.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besy1.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/binary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bind.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bind_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bind_005fspace.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/border.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxplot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxplot_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxwidth.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxxyerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cairo_005f_0028pdfcairo.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/call.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/candlesticks.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/canvas.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbdtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cblabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbmtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cd.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ceil.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cgi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cgm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/circle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/circles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clear.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clip.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clipping.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cntrparam.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/color_005fassignment.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/color_005fbox.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/colornames.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/colorspec.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/column.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/columnhead.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/complete_005flist_005fof_005fterminals.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/context.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/contour.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/control.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/control_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/corel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cos.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cosh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cubehelix.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/data.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/data_002dfile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/data_005fstyle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/datafile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/debug.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/decimalsign.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/defined.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/defined_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/deprecated_005foptions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dgrid3d.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dospc.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dots.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/doubleclick.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dumb.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dummy.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dxf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dxy800a.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/eepic.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ellipse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ellipses.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/elliptic_005fintegrals.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/emf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/emxvga.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/encoding.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/endian.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/environment_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/epscairo.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/epson_005f180dpi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/equal_005faxes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/erf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/erfc.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/error_005festimates.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/errorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/errorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/evaluate.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/every.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/example_005fdatafile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/example_005fdatafile_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/excl.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/exists.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/exit.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/exp.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/expint.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fig.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/file.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/filetype.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/filledcurves.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fillsteps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/financebars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fit.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fit_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/floor.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fontpath.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/format.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/format_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/format_005fspecifiers.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fsteps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/function_005fstyle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/functions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/functions_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/functions_005f_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gamma.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gamma_005fcorrection.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gd_005f_0028png.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/general.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ggi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gnuplot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gpic.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gprintf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gprintf_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/grass.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/grid.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/grid_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/help.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hidden3d.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hidden3d_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/histeps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/histograms.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/history.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/historysize.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hp2623a.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hp2648.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hp500c.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hpgl.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hpljii.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hppj.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ibeta.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/if.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/if_002dold.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/igamma.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/imag.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/image.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/image_005ffailsafe.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/imagen.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/impulses.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/index.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/int.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/interpolate.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/inverf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/invnorm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/isosamples.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/iteration.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/iteration_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/key.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/key_005fplacement.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/key_005fsamples.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/keywords.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/known_005flimitations.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/kyo.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/label.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/labels.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lambertw.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/latex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lgamma.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linecolor_005fvariable.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linespoints.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linestyles_005fvs_005flinetypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linetype.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linetypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linux.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/load.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/loadpath.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/locale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/log.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/log10.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/logscale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lower.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lua.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/macintosh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/macros.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mapping.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/margin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/matrix.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mif.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mouse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mouse_005finput.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mouseformat.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mp.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/multi_002dbranch.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/multiplot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mx2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mxtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/my2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mytics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mztics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/newhistogram.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/next.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/norm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/object.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/offsets.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/origin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/output.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/palette.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/parametric.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/parametric_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/parametric_005fmode.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pause.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pbm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pdf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/plot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/plot_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/plotting_005fstyles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pm3d.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/png_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pointintervalbox.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/points.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pointsize.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polar.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polar_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polar_005fmode.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polygon.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/position.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/postscript.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/postscript_005f_005f_0028also_005fencapsulated_005fpostscript_005f_002a_002eeps_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/practical_005fguidelines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/print.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/print_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/psdir.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pstricks.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pwd.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/qms.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/quit.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/raise.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rand.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ranges.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/raxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/real.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/record.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rectangle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/refresh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/regis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/replot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/reread.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/reset.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbalpha.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbcolor_005fvariable.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbformulae.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbimage.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/samples.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/save.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/scanorder.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/scrolling.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_002dshow.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fbinary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fcommentschars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005ffortran.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fmissing.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fnofpe_005ftrap.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fseparator.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005farrow.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fcircle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fellipse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005ffill.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005ffunction.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fincrement.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fline.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005frectangle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sgn.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/shell.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/short_005fintroduction.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sinh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/size.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/skip.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/smooth.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/special_002dfilenames.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/splot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/splot_005fsurfaces.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sprintf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sqrt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/starting_005fvalues.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/statistical_005foverview.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/stats_005f_0028Statistical_005fSummary_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/steps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strftime.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/stringcolumn.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strlen.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strptime.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strstrt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/style.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/substr.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sun.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/surface.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/svg.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/svga.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/system.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/system_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/table.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tan.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tanh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tek40.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tek410x.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/terminal.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/termoption.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/test.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/texdraw.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tgif.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/thru.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ticscale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ticslevel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/time.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/time_002fdate_005fspecifiers.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/timecolumn.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/timefmt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/timestamp.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tips.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/title.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/title_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tkcanvas.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fhour.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fmday.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fmin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fmon.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fsec.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fwday.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fyday.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fyear.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tpic.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/trange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/transparency.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/undefine.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/unixpc.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/unset.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/update.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/urange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/using.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/valid.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/value.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/variables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vectors.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/version.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vgagl.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/view.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/voigt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/volatile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vx384.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/windows.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/with.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/word.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/words.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/wxt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x11.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2data.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2dtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2label.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2mtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2range.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2zeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xdtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xerrorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xlabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xlib.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xmtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xtics_005frangelimited.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xtics_005ftime_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xyerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xyerrorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xyplane.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xzeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2data.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2dtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2label.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2mtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2range.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2zeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ydata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ydtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yerrorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ylabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ymtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ytics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yzeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zdtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zero.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zlabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zmtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zoom.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ztics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zzeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_file.doc.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_fontfile_doc.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_guide.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_symbols.gpi.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/tutorial.dvi.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/tutorial.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-nox/BUGS math/gnuplot-nox +usr/share/doc/gnuplot-nox/FAQ.pdf.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/NEWS.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/README.1ST math/gnuplot-nox +usr/share/doc/gnuplot-nox/README.Debian math/gnuplot-nox +usr/share/doc/gnuplot-nox/README.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/changelog.Debian.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/changelog.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/copyright math/gnuplot-nox +usr/share/doc/gnuplot-x11/changelog.Debian.gz math/gnuplot-x11 +usr/share/doc/gnuplot-x11/changelog.gz math/gnuplot-x11 +usr/share/doc/gnuplot-x11/copyright math/gnuplot-x11 +usr/share/gnuplot/gnuplot.gih math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-1.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-15.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-2.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-9.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/aglfn.txt math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp1250.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp1251.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp437.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp850.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp852.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/koi8r.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/koi8u.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/prologue.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/utf-8.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/app-defaults/Gnuplot math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/colors_default.gp math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/colors_mono.gp math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/colors_podo.gp math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/gnuplotrc math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/README math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/canvasmath.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/canvastext.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_common.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_dashedlines.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_mouse.css math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_mouse.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_svg.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/grid.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/help.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/nextzoom.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/previouszoom.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/textzoom.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/lua/gnuplot-tikz.lua math/gnuplot-nox +usr/share/gnuplot/pm3d/README math/gnuplot-nox +usr/share/gnuplot/pm3d/colorpts-demo.gp math/gnuplot-nox +usr/share/gnuplot/pm3d/colorpts.awk math/gnuplot-nox +usr/share/gnuplot/pm3d/pm3dCompress.awk math/gnuplot-nox +usr/share/gnuplot/pm3d/pm3dConvertToImage.awk math/gnuplot-nox +usr/share/gnuplot/pm3d/pts.dat math/gnuplot-nox +usr/share/info/gnuplot.info.gz doc/gnuplot-doc +usr/share/man/man1/gnuplot.1.gz math/gnuplot-nox,math/gnuplot-x11 +usr/share/menu/gnuplot-nox math/gnuplot-nox diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot1Test_contents_i386 b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot1Test_contents_i386 new file mode 100644 index 00000000..922b5c05 --- /dev/null +++ b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot1Test_contents_i386 @@ -0,0 +1,751 @@ +FILE LOCATION +usr/bin/gnuplot math/gnuplot-nox,math/gnuplot-x11 +usr/lib/gnuplot/gnuplot_x11 math/gnuplot-x11 +usr/share/doc-base/gnuplot doc/gnuplot-doc +usr/share/doc/gnuplot math/gnuplot +usr/share/doc/gnuplot-doc/changelog.Debian.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/changelog.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/copyright doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/1.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/2.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/3.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/GM1_bonds.r3d.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/GM1_sugar.pdb.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/Makefile.am.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/Makefile.am.in doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/Makefile.in.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/airfoil.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/all.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/animate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/animate2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/approximate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/arrowstyle.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/arrowstyle.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/asciimat.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/autoscale.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/barchart_art.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/battery.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/big_peak.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/binary.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/bivariat.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/bldg.png doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/blutux.rgb.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/borders.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/boxplot.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/candlesticks.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/candlesticks.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/charset.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/circles.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/cities.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/cities.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/clip14in.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/colorscheme.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/colorwheel.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/contours.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/controls.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ctg-y2.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/dashcolor.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/datastrings.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/delaunay-edges.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/demo.edf.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/density.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/dgrid3d.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/discrete.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/electron.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ellipse.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ellipses.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/ellipses_style.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/empty-circles.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/energy_circles.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/enhanced_utf8.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/enhancedtext.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/epslatex.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fillbetween.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fillcrvs.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fillstyle.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/finance.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/finance.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fit.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fit3.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fontfile.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/fontfile_latex.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/glass.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gnu-valley doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gnuplot.cfg doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gnuplot.rot doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/gpdemos.tcl.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/heatmaps.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hemisphr.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hexa.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hidden.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/hidden2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histerror.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histograms.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histograms2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/histopt.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/Makefile doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/Makefile.canvas doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/Makefile.svg doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/canvas_utf8.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/gnuplot_demo.css doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/index.canvas.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/index.save.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/index.svg doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/mouseable.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/mousebox.template doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/webify.pl doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/webify_canvas.pl.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/html/webify_svg.pl.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/image.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/image2.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/imageNaN.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/immigration.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/iterate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/kdensity2d.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/key.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/klein.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/labelplot.pdb doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/layout.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/lcdemo.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/lena-keypoints.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/lena.rgb.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/line.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/macros.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/margins.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mgr.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/molecule.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/moli3.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mouselab_1.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mouselab_2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mouselabels.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/mousevariables.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multiaxis.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multimsh.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multipalette.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/multiplt.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/nearmap.csv.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/optimize.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/orbital_elements.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/orbits.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/param.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pm3d.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pm3dcolors.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pm3dgamma.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/pointsize.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/polar.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/poldat.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/prob.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/prob2.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rainbow.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/random-points.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/random.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rectangle.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/reflect.fnc doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rgb_variable.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rgb_variable.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/rgbalpha.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/running_avg.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/scatter.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/scatter2.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/scatter2.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/silver.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/simple.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/sine.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/singulr.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/smooth.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/sound.par doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/sound2.par doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/soundvel.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/spline.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/srl.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/starmap.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/start.par doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/stat.inc.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/stats.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/steps.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/steps.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/stringvar.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/surface1.dem.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/surface2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/table.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/textcolor.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/textrotate.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/tics.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/timedat.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/timedat.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/transparent.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/transparent_solids.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/triangle.dat doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/using.bin doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/using.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/using.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/utf8.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/varcolor.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/vector.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/whale.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world.cor doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world.dat.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/examples/world2.dem doc/gnuplot-doc +usr/share/doc/gnuplot-doc/gnuplot.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/gpcard.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/2D_005fprojection_005f_0028set_005fview_005fmap_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/3D_005f_0028surface_0029_005fplots.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Backwards_005fcompatibility.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Batch_002fInteractive_005fOperation.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Binary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Bugs.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Canvas_005fsize.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Command_002dline_002dediting.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Command_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Commands.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Comments.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Concept_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Coordinates.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Copyright.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Datastrings.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Do.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/EllipticE.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/EllipticK.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/EllipticPi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Enhanced_005ftext_005fmode.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Environment.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Expressions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/External_005flibraries.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Fonts.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Function_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Functions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Glossary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Gnuplot_002ddefined_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Introduction.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Local_005fcustomization_005fof_005flinetypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Mouse_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005ffeatures.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005for_005frevised_005fterminal_005fdrivers.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005fplot_005fstyles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005fsmoothing_005falgorithms.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005fsyntax.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/New_005ftime_002fdate_005fhandling.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Openstep_005f_0028next_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Operators.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Options_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Plotting.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Quote_005fMarks.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Random_005fnumber_005fgenerator.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Revised_005fpolar_005faxes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Seeking_002dassistance.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Start_002dup_005f_0028initialization_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Statistical_005fsummary_005fof_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/String_005fconstants_005fand_005fstring_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/String_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Substitution_005fand_005fCommand_005fline_005fmacros.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Substitution_005fof_005fstring_005fvariables_005fas_005fmacros.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Substitution_005fof_005fsystem_005fcommands_005fin_005fbackquotes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Summation.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Syntax.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Terminal_005fIndex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Terminal_005ftypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Ternary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Time_002fDate_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/Unary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/User_002ddefined_005fvariables_005fand_005ffunctions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/VWS.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/While.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/X11_005fmouse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/abs.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/acos.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/acosh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/adjustable_005fparameters.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/aed767.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/aifm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/airy.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/algorithm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/angles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/aqua.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/arg.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/array.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/arrow.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/asin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/asinh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/atan.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/atan2.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/atanh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/automated_005fiteration_005fover_005fmultiple_005fcolumns.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/autoscale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/axes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/background_005fcolor.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/be.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besj0.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besj1.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besy0.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/besy1.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/binary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bind.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bind_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bind_005fspace.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/bmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/border.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxplot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxplot_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxwidth.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/boxxyerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cairo_005f_0028pdfcairo.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/call.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/candlesticks.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/canvas.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbdtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cblabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbmtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cbtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cd.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ceil.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cgi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cgm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/circle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/circles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clear.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clip.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/clipping.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cntrparam.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/color_005fassignment.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/color_005fbox.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/colornames.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/colorspec.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/column.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/columnhead.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/complete_005flist_005fof_005fterminals.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/context.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/contour.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/control.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/control_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/corel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cos.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cosh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/cubehelix.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/data.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/data_002dfile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/data_005fstyle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/datafile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/debug.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/decimalsign.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/defined.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/defined_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/deprecated_005foptions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dgrid3d.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dospc.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dots.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/doubleclick.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dumb.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dummy.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dxf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/dxy800a.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/eepic.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ellipse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ellipses.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/elliptic_005fintegrals.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/emf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/emxvga.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/encoding.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/endian.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/environment_005fvariables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/epscairo.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/epson_005f180dpi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/equal_005faxes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/erf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/erfc.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/error_005festimates.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/errorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/errorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/evaluate.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/every.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/example_005fdatafile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/example_005fdatafile_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/excl.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/exists.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/exit.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/exp.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/expint.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fig.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/file.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/filetype.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/filledcurves.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fillsteps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/financebars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fit.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fit_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/floor.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fontpath.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/format.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/format_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/format_005fspecifiers.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/fsteps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/function_005fstyle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/functions.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/functions_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/functions_005f_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gamma.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gamma_005fcorrection.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gd_005f_0028png.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/general.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ggi.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gnuplot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gpic.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gprintf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/gprintf_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/grass.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/grid.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/grid_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/help.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hidden3d.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hidden3d_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/histeps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/histograms.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/history.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/historysize.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hp2623a.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hp2648.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hp500c.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hpgl.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hpljii.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/hppj.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ibeta.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/if.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/if_002dold.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/igamma.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/imag.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/image.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/image_005ffailsafe.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/imagen.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/impulses.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/index.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/int.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/interpolate.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/inverf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/invnorm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/isosamples.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/iteration.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/iteration_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/key.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/key_005fplacement.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/key_005fsamples.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/keywords.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/known_005flimitations.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/kyo.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/label.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/labels.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lambertw.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/latex.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lgamma.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linecolor_005fvariable.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linespoints.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linestyles_005fvs_005flinetypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linetype.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linetypes.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/linux.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/load.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/loadpath.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/locale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/log.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/log10.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/logscale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lower.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/lua.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/macintosh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/macros.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mapping.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/margin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/matrix.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mif.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mouse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mouse_005finput.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mouseformat.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mp.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/multi_002dbranch.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/multiplot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mx2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mxtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/my2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mytics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/mztics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/newhistogram.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/next.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/norm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/object.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/offsets.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/origin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/output.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/palette.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/parametric.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/parametric_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/parametric_005fmode.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pause.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pbm.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pdf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/plot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/plot_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/plotting_005fstyles.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pm3d.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/png_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pointintervalbox.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/points.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pointsize.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polar.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polar_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polar_005fmode.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/polygon.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/position.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/postscript.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/postscript_005f_005f_0028also_005fencapsulated_005fpostscript_005f_002a_002eeps_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/practical_005fguidelines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/print.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/print_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/psdir.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pstricks.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/pwd.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/qms.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/quit.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/raise.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rand.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ranges.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/raxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/real.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/record.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rectangle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/refresh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/regis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/replot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/reread.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/reset.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbalpha.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbcolor_005fvariable.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbformulae.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rgbimage.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/rtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/samples.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/save.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/scanorder.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/scrolling.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_002dshow.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fbinary.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fcommentschars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005ffortran.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fmissing.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fnofpe_005ftrap.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fdatafile_005fseparator.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005farrow.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fcircle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fellipse.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005ffill.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005ffunction.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fincrement.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005fline.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/set_005fstyle_005frectangle.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sgn.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/shell.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/short_005fintroduction.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sinh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/size.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/skip.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/smooth.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/special_002dfilenames.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/splot.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/splot_005fsurfaces.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sprintf.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sqrt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/starting_005fvalues.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/statistical_005foverview.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/stats_005f_0028Statistical_005fSummary_0029.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/steps.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strftime.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/stringcolumn.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strlen.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strptime.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/strstrt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/style.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/substr.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/sun.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/surface.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/svg.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/svga.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/system.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/system_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/table.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tan.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tanh.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tek40.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tek410x.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/terminal.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/termoption.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/test.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/texdraw.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tgif.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/thru.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ticscale.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ticslevel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/time.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/time_002fdate_005fspecifiers.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/timecolumn.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/timefmt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/timestamp.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tips.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/title.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/title_005f.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tkcanvas.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fhour.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fmday.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fmin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fmon.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fsec.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fwday.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fyday.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tm_005fyear.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tmargin.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/tpic.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/trange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/transparency.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/undefine.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/unixpc.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/unset.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/update.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/urange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/using.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/valid.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/value.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/variables.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vectors.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/version.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vgagl.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/view.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/voigt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/volatile.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/vx384.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/windows.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/with.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/word.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/words.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/wxt.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x11.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2data.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2dtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2label.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2mtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2range.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/x2zeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xdtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xerrorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xlabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xlib.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xmtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xtics_005frangelimited.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xtics_005ftime_005fdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xyerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xyerrorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xyplane.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/xzeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2data.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2dtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2label.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2mtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2range.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2tics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/y2zeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ydata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ydtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yerrorbars.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yerrorlines.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ylabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ymtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ytics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/yzeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zdata.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zdtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zero.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zlabel.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zmtics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zoom.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zrange.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/ztics.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/html/zzeroaxis.html doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_file.doc.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_fontfile_doc.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_guide.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/ps_symbols.gpi.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/tutorial.dvi.gz doc/gnuplot-doc +usr/share/doc/gnuplot-doc/tutorial.ps.gz doc/gnuplot-doc +usr/share/doc/gnuplot-nox/BUGS math/gnuplot-nox +usr/share/doc/gnuplot-nox/FAQ.pdf.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/NEWS.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/README.1ST math/gnuplot-nox +usr/share/doc/gnuplot-nox/README.Debian math/gnuplot-nox +usr/share/doc/gnuplot-nox/README.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/changelog.Debian.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/changelog.gz math/gnuplot-nox +usr/share/doc/gnuplot-nox/copyright math/gnuplot-nox +usr/share/doc/gnuplot-x11/changelog.Debian.gz math/gnuplot-x11 +usr/share/doc/gnuplot-x11/changelog.gz math/gnuplot-x11 +usr/share/doc/gnuplot-x11/copyright math/gnuplot-x11 +usr/share/gnuplot/gnuplot.gih math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-1.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-15.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-2.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/8859-9.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/aglfn.txt math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp1250.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp1251.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp437.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp850.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/cp852.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/koi8r.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/koi8u.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/prologue.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/PostScript/utf-8.ps math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/app-defaults/Gnuplot math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/colors_default.gp math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/colors_mono.gp math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/colors_podo.gp math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/gnuplotrc math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/README math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/canvasmath.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/canvastext.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_common.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_dashedlines.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_mouse.css math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_mouse.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/gnuplot_svg.js math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/grid.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/help.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/nextzoom.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/previouszoom.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/js/textzoom.png math/gnuplot-nox +usr/share/gnuplot/gnuplot/4.6/lua/gnuplot-tikz.lua math/gnuplot-nox +usr/share/gnuplot/pm3d/README math/gnuplot-nox +usr/share/gnuplot/pm3d/colorpts-demo.gp math/gnuplot-nox +usr/share/gnuplot/pm3d/colorpts.awk math/gnuplot-nox +usr/share/gnuplot/pm3d/pm3dCompress.awk math/gnuplot-nox +usr/share/gnuplot/pm3d/pm3dConvertToImage.awk math/gnuplot-nox +usr/share/gnuplot/pm3d/pts.dat math/gnuplot-nox +usr/share/info/gnuplot.info.gz doc/gnuplot-doc +usr/share/man/man1/gnuplot.1.gz math/gnuplot-nox,math/gnuplot-x11 +usr/share/menu/gnuplot-nox math/gnuplot-nox diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot36Test_gold b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot36Test_gold new file mode 100644 index 00000000..5d4c7ab2 --- /dev/null +++ b/src/github.com/smira/aptly/system/t06_publish/PublishSnapshot36Test_gold @@ -0,0 +1,13 @@ +Loading packages... +Generating metadata files and linking package files... +Finalizing metadata files... +Signing file 'Release' with gpg, please enter your passphrase when prompted: +Clearsigning file 'Release' with gpg, please enter your passphrase when prompted: + +Snapshot snap36 has been successfully published. +Please setup your webserver to serve directory '${HOME}/.aptly/public' with autoindexing. +Now you can add following line to apt sources: + deb http://your-server/ maverick main +Don't forget to add your GPG key to apt with apt-key. + +You can also use `aptly serve` to publish your repositories over HTTP quickly. diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishSwitch13Test_gold b/src/github.com/smira/aptly/system/t06_publish/PublishSwitch13Test_gold new file mode 100644 index 00000000..3369aa06 --- /dev/null +++ b/src/github.com/smira/aptly/system/t06_publish/PublishSwitch13Test_gold @@ -0,0 +1,8 @@ +Loading packages... +Generating metadata files and linking package files... +Finalizing metadata files... +Signing file 'Release' with gpg, please enter your passphrase when prompted: +Clearsigning file 'Release' with gpg, please enter your passphrase when prompted: +Cleaning up prefix "." components main... + +Publish for snapshot ./maverick [amd64, i386] publishes {main: [snap3]: Pulled into 'snap2' with 'snap1' as source, pull request was: 'gnuplot-x11'} has been successfully switched to new snapshot. diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishUpdate11Test_gold b/src/github.com/smira/aptly/system/t06_publish/PublishUpdate11Test_gold new file mode 100644 index 00000000..72e92234 --- /dev/null +++ b/src/github.com/smira/aptly/system/t06_publish/PublishUpdate11Test_gold @@ -0,0 +1,8 @@ +Loading packages... +Generating metadata files and linking package files... +Finalizing metadata files... +Signing file 'Release' with gpg, please enter your passphrase when prompted: +Clearsigning file 'Release' with gpg, please enter your passphrase when prompted: +Cleaning up prefix "." components main... + +Publish for local repo ./maverick [i386, source] publishes {main: [local-repo]} has been successfully updated. diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishUpdate2Test_sources b/src/github.com/smira/aptly/system/t06_publish/PublishUpdate2Test_sources index f1c4cf3c..225625b7 100644 --- a/src/github.com/smira/aptly/system/t06_publish/PublishUpdate2Test_sources +++ b/src/github.com/smira/aptly/system/t06_publish/PublishUpdate2Test_sources @@ -1,11 +1,18 @@ + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz + 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc + 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz + 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc @@ -18,14 +25,14 @@ Binary: python-at-spi Binary: python-at-spi Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Checksums-Sha1: 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc -Checksums-Sha1: 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz -Checksums-Sha256: 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc -Checksums-Sha256: 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz +Checksums-Sha1: +Checksums-Sha1: +Checksums-Sha256: +Checksums-Sha256: Directory: pool/main/p/pyspi Directory: pool/main/p/pyspi -Files: 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz -Files: 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc +Files: +Files: Format: 1.0 Format: 1.0 Homepage: http://people.redhat.com/zcerza/dogtail @@ -39,4 +46,4 @@ Standards-Version: 3.7.3 Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk Version: 0.6.1-1.3 -Version: 0.6.1-1.4 +Version: 0.6.1-1.4 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t06_publish/PublishUpdate7Test_sources b/src/github.com/smira/aptly/system/t06_publish/PublishUpdate7Test_sources index 90f5cac5..225625b7 100644 --- a/src/github.com/smira/aptly/system/t06_publish/PublishUpdate7Test_sources +++ b/src/github.com/smira/aptly/system/t06_publish/PublishUpdate7Test_sources @@ -2,11 +2,17 @@ 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz + 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz + 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc + 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz + 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc @@ -19,14 +25,14 @@ Binary: python-at-spi Binary: python-at-spi Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Checksums-Sha1: 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc -Checksums-Sha1: 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz -Checksums-Sha256: 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc -Checksums-Sha256: 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz +Checksums-Sha1: +Checksums-Sha1: +Checksums-Sha256: +Checksums-Sha256: Directory: pool/main/p/pyspi Directory: pool/main/p/pyspi -Files: 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz -Files: 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc +Files: +Files: Format: 1.0 Format: 1.0 Homepage: http://people.redhat.com/zcerza/dogtail diff --git a/src/github.com/smira/aptly/system/t06_publish/S3Publish1Test_sources b/src/github.com/smira/aptly/system/t06_publish/S3Publish1Test_sources index 7ea3c88c..38a7b07f 100644 --- a/src/github.com/smira/aptly/system/t06_publish/S3Publish1Test_sources +++ b/src/github.com/smira/aptly/system/t06_publish/S3Publish1Test_sources @@ -5,17 +5,20 @@ Architecture: any Binary: python-at-spi Standards-Version: 3.7.3 Format: 1.0 -Files: 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz +Files: + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz -Checksums-Sha1: 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz +Checksums-Sha1: + 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk Homepage: http://people.redhat.com/zcerza/dogtail Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev Directory: pool/main/p/pyspi -Checksums-Sha256: 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz +Checksums-Sha256: + 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz d494aaf526f1ec6b02f14c2f81e060a5722d6532ddc760ec16972e45c2625989 1782 pyspi_0.6.1-1.3.dsc 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz @@ -28,15 +31,18 @@ Standards-Version: 3.7.3 Homepage: http://people.redhat.com/zcerza/dogtail Directory: pool/main/p/pyspi Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Checksums-Sha256: 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc +Checksums-Sha256: + 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz Format: 1.0 -Checksums-Sha1: 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc +Checksums-Sha1: + 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz Binary: python-at-spi -Files: 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc +Files: + 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz diff --git a/src/github.com/smira/aptly/system/t06_publish/SwiftPublish1Test_sources b/src/github.com/smira/aptly/system/t06_publish/SwiftPublish1Test_sources index 7ea3c88c..38a7b07f 100644 --- a/src/github.com/smira/aptly/system/t06_publish/SwiftPublish1Test_sources +++ b/src/github.com/smira/aptly/system/t06_publish/SwiftPublish1Test_sources @@ -5,17 +5,20 @@ Architecture: any Binary: python-at-spi Standards-Version: 3.7.3 Format: 1.0 -Files: 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz +Files: + 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz b72cb94699298a117b7c82641c68b6fd 1782 pyspi_0.6.1-1.3.dsc def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz -Checksums-Sha1: 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz +Checksums-Sha1: + 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 56c8a9b1f4ab636052be8966690998cbe865cd6c 1782 pyspi_0.6.1-1.3.dsc 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz Vcs-Svn: svn://svn.tribulaciones.org/srv/svn/pyspi/trunk Homepage: http://people.redhat.com/zcerza/dogtail Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev Directory: pool/main/p/pyspi -Checksums-Sha256: 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz +Checksums-Sha256: + 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz d494aaf526f1ec6b02f14c2f81e060a5722d6532ddc760ec16972e45c2625989 1782 pyspi_0.6.1-1.3.dsc 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz @@ -28,15 +31,18 @@ Standards-Version: 3.7.3 Homepage: http://people.redhat.com/zcerza/dogtail Directory: pool/main/p/pyspi Build-Depends: debhelper (>= 5), cdbs, libatspi-dev, python-pyrex, python-support (>= 0.4), python-all-dev, libx11-dev -Checksums-Sha256: 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc +Checksums-Sha256: + 289d3aefa970876e9c43686ce2b02f478d7f3ed35a713928464a98d54ae4fca3 893 pyspi-0.6.1-1.3.stripped.dsc 2e770b28df948f3197ed0b679bdea99f3f2bf745e9ddb440c677df9c3aeaee3c 3456 pyspi_0.6.1-1.3.diff.gz 64069ee828c50b1c597d10a3fefbba279f093a4723965388cdd0ac02f029bfb9 29063 pyspi_0.6.1.orig.tar.gz Format: 1.0 -Checksums-Sha1: 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc +Checksums-Sha1: + 5005fbd1f30637edc1d380b30f45db9b79100d07 893 pyspi-0.6.1-1.3.stripped.dsc 95a2468e4bbce730ba286f2211fa41861b9f1d90 3456 pyspi_0.6.1-1.3.diff.gz 9694b80acc171c0a5bc99f707933864edfce555e 29063 pyspi_0.6.1.orig.tar.gz Binary: python-at-spi -Files: 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc +Files: + 2f5bd47cf38852b6fc927a50f98c1448 893 pyspi-0.6.1-1.3.stripped.dsc 22ff26db69b73d3438fdde21ab5ba2f1 3456 pyspi_0.6.1-1.3.diff.gz def336bd566ea688a06ec03db7ccf1f4 29063 pyspi_0.6.1.orig.tar.gz diff --git a/src/github.com/smira/aptly/system/t06_publish/repo.py b/src/github.com/smira/aptly/system/t06_publish/repo.py index b29d4623..d0864bac 100644 --- a/src/github.com/smira/aptly/system/t06_publish/repo.py +++ b/src/github.com/smira/aptly/system/t06_publish/repo.py @@ -1,6 +1,7 @@ import os import hashlib import inspect +import zlib from lib import BaseTest @@ -8,6 +9,13 @@ def strip_processor(output): return "\n".join([l for l in output.split("\n") if not l.startswith(' ') and not l.startswith('Date:')]) +def ungzip_if_required(output): + if output.startswith("\x1f\x8b"): + return zlib.decompress(output, 16+zlib.MAX_WBITS) + + return output + + class PublishRepo1Test(BaseTest): """ publish repo: default @@ -29,6 +37,7 @@ class PublishRepo1Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') @@ -43,6 +52,7 @@ class PublishRepo1Test(BaseTest): self.check_file_contents('public/dists/maverick/Release', 'release', match_prepare=strip_processor) self.check_file_contents('public/dists/maverick/main/source/Sources', 'sources', match_prepare=lambda s: "\n".join(sorted(s.split("\n")))) self.check_file_contents('public/dists/maverick/main/binary-i386/Packages', 'binary', match_prepare=lambda s: "\n".join(sorted(s.split("\n")))) + self.check_file_contents('public/dists/maverick/main/Contents-i386.gz', 'contents_i386', match_prepare=ungzip_if_required) # verify signatures self.run_cmd(["gpg", "--no-auto-check-trustdb", "--keyring", os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "aptly.pub"), @@ -79,7 +89,7 @@ class PublishRepo1Test(BaseTest): if pathsSeen != set(['main/binary-i386/Packages', 'main/binary-i386/Packages.bz2', 'main/binary-i386/Packages.gz', 'main/source/Sources', 'main/source/Sources.gz', 'main/source/Sources.bz2', - 'main/binary-i386/Release', 'main/source/Release']): + 'main/binary-i386/Release', 'main/source/Release', 'main/Contents-i386.gz']): raise Exception("path seen wrong: %r" % (pathsSeen, )) @@ -104,6 +114,7 @@ class PublishRepo2Test(BaseTest): self.check_exists('public/dists/maverick/contrib/binary-i386/Packages') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/contrib/Contents-i386.gz') self.check_exists('public/dists/maverick/contrib/source/Sources') self.check_exists('public/dists/maverick/contrib/source/Sources.gz') self.check_exists('public/dists/maverick/contrib/source/Sources.bz2') @@ -136,6 +147,7 @@ class PublishRepo3Test(BaseTest): self.check_exists('public/dists/maverick/contrib/binary-i386/Packages') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/contrib/Contents-i386.gz') self.check_not_exists('public/dists/maverick/contrib/source/Sources') self.check_not_exists('public/dists/maverick/contrib/source/Sources.gz') self.check_not_exists('public/dists/maverick/contrib/source/Sources.bz2') @@ -168,6 +180,7 @@ class PublishRepo4Test(BaseTest): self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages') self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/ppa/dists/maverick/main/Contents-i386.gz') self.check_exists('public/ppa/dists/maverick/main/source/Sources') self.check_exists('public/ppa/dists/maverick/main/source/Sources.gz') self.check_exists('public/ppa/dists/maverick/main/source/Sources.bz2') @@ -289,6 +302,7 @@ class PublishRepo12Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') @@ -330,6 +344,7 @@ class PublishRepo14Test(BaseTest): self.check_exists('public/dists/maverick/contrib/binary-i386/Packages') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/contrib/Contents-i386.gz') self.check_exists('public/dists/maverick/contrib/source/Sources') self.check_exists('public/dists/maverick/contrib/source/Sources.gz') self.check_exists('public/dists/maverick/contrib/source/Sources.bz2') @@ -471,7 +486,8 @@ class PublishRepo17Test(BaseTest): 'contrib/binary-i386/Packages.bz2', 'contrib/source/Sources', 'contrib/source/Sources.gz', 'contrib/source/Sources.bz2', 'main/source/Release', 'contrib/source/Release', - 'main/binary-i386/Release', 'contrib/binary-i386/Release']): + 'main/binary-i386/Release', 'contrib/binary-i386/Release', + 'main/Contents-i386.gz']): raise Exception("path seen wrong: %r" % (pathsSeen, )) @@ -631,6 +647,12 @@ class PublishRepo27Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') + self.check_exists('public/dists/maverick/main/debian-installer/binary-i386/Release') + self.check_exists('public/dists/maverick/main/debian-installer/binary-i386/Packages') + self.check_exists('public/dists/maverick/main/debian-installer/binary-i386/Packages.gz') + self.check_exists('public/dists/maverick/main/debian-installer/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-udeb-i386.gz') self.check_exists('public/dists/maverick/main/source/Release') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') @@ -646,3 +668,25 @@ class PublishRepo27Test(BaseTest): # verify contents except of sums self.check_file_contents('public/dists/maverick/main/debian-installer/binary-i386/Packages', 'udeb_binary', match_prepare=lambda s: "\n".join(sorted(s.split("\n")))) + + +class PublishRepo28Test(BaseTest): + """ + publish repo: -skip-contents + """ + fixtureCmds = [ + "aptly repo create local-repo", + "aptly repo add local-repo ${files} ${udebs}", + ] + runCmd = "aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick -skip-contents local-repo" + gold_processor = BaseTest.expand_environ + + def check(self): + super(PublishRepo28Test, self).check() + + self.check_exists('public/dists/maverick/Release') + + self.check_exists('public/dists/maverick/main/binary-i386/Release') + self.check_not_exists('public/dists/maverick/main/Contents-i386.gz') + self.check_exists('public/dists/maverick/main/debian-installer/binary-i386/Release') + self.check_not_exists('public/dists/maverick/main/Contents-udeb-i386.gz') diff --git a/src/github.com/smira/aptly/system/t06_publish/snapshot.py b/src/github.com/smira/aptly/system/t06_publish/snapshot.py index 5fac3d25..0132db39 100644 --- a/src/github.com/smira/aptly/system/t06_publish/snapshot.py +++ b/src/github.com/smira/aptly/system/t06_publish/snapshot.py @@ -1,6 +1,7 @@ import os import hashlib import inspect +import zlib from lib import BaseTest @@ -12,6 +13,13 @@ def sorted_processor(output): return "\n".join(sorted(output.split("\n"))) +def ungzip_if_required(output): + if output.startswith("\x1f\x8b"): + return zlib.decompress(output, 16+zlib.MAX_WBITS) + + return output + + class PublishSnapshot1Test(BaseTest): """ publish snapshot: defaults @@ -35,10 +43,12 @@ class PublishSnapshot1Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Release') self.check_exists('public/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-amd64.gz') self.check_not_exists('public/dists/maverick/main/debian-installer/binary-i386/Packages') self.check_not_exists('public/dists/maverick/main/debian-installer/binary-amd64/Packages') @@ -53,6 +63,9 @@ class PublishSnapshot1Test(BaseTest): self.check_file_contents('public/dists/maverick/main/binary-i386/Packages', 'packages_i386', match_prepare=sorted_processor) self.check_file_contents('public/dists/maverick/main/binary-amd64/Packages', 'packages_amd64', match_prepare=sorted_processor) + self.check_file_contents('public/dists/maverick/main/Contents-i386.gz', 'contents_i386', match_prepare=ungzip_if_required) + self.check_file_contents('public/dists/maverick/main/Contents-amd64.gz', 'contents_amd64', match_prepare=ungzip_if_required) + # verify signatures self.run_cmd(["gpg", "--no-auto-check-trustdb", "--keyring", os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "aptly.pub"), "--verify", os.path.join(os.environ["HOME"], ".aptly", 'public/dists/maverick/InRelease')]) @@ -88,7 +101,8 @@ class PublishSnapshot1Test(BaseTest): if pathsSeen != set(['main/binary-amd64/Packages', 'main/binary-i386/Packages', 'main/binary-i386/Packages.gz', 'main/binary-amd64/Packages.gz', 'main/binary-amd64/Packages.bz2', 'main/binary-i386/Packages.bz2', - 'main/binary-amd64/Release', 'main/binary-i386/Release']): + 'main/binary-amd64/Release', 'main/binary-i386/Release', 'main/Contents-amd64.gz', + 'main/Contents-i386.gz']): raise Exception("path seen wrong: %r" % (pathsSeen, )) @@ -114,9 +128,11 @@ class PublishSnapshot2Test(BaseTest): self.check_exists('public/dists/squeeze/main/binary-i386/Packages') self.check_exists('public/dists/squeeze/main/binary-i386/Packages.gz') self.check_exists('public/dists/squeeze/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/squeeze/main/Contents-i386.gz') self.check_exists('public/dists/squeeze/main/binary-amd64/Packages') self.check_exists('public/dists/squeeze/main/binary-amd64/Packages.gz') self.check_exists('public/dists/squeeze/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/squeeze/main/Contents-amd64.gz') self.check_exists('public/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') @@ -146,9 +162,11 @@ class PublishSnapshot3Test(BaseTest): self.check_exists('public/dists/squeeze/contrib/binary-i386/Packages') self.check_exists('public/dists/squeeze/contrib/binary-i386/Packages.gz') self.check_exists('public/dists/squeeze/contrib/binary-i386/Packages.bz2') + self.check_exists('public/dists/squeeze/contrib/Contents-i386.gz') self.check_exists('public/dists/squeeze/contrib/binary-amd64/Packages') self.check_exists('public/dists/squeeze/contrib/binary-amd64/Packages.gz') self.check_exists('public/dists/squeeze/contrib/binary-amd64/Packages.bz2') + self.check_exists('public/dists/squeeze/contrib/Contents-amd64.gz') self.check_exists('public/pool/contrib/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') @@ -178,9 +196,11 @@ class PublishSnapshot4Test(BaseTest): self.check_exists('public/dists/squeeze/main/binary-i386/Packages') self.check_exists('public/dists/squeeze/main/binary-i386/Packages.gz') self.check_exists('public/dists/squeeze/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/squeeze/main/Contents-i386.gz') self.check_not_exists('public/dists/squeeze/main/binary-amd64/Packages') self.check_not_exists('public/dists/squeeze/main/binary-amd64/Packages.gz') self.check_not_exists('public/dists/squeeze/main/binary-amd64/Packages.bz2') + self.check_not_exists('public/dists/squeeze/main/Contents-amd64.gz') self.check_exists('public/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') @@ -211,9 +231,11 @@ class PublishSnapshot5Test(BaseTest): self.check_exists('public/ppa/smira/dists/squeeze/main/binary-i386/Packages') self.check_exists('public/ppa/smira/dists/squeeze/main/binary-i386/Packages.gz') self.check_exists('public/ppa/smira/dists/squeeze/main/binary-i386/Packages.bz2') + self.check_exists('public/ppa/smira/dists/squeeze/main/Contents-i386.gz') self.check_exists('public/ppa/smira/dists/squeeze/main/binary-amd64/Packages') self.check_exists('public/ppa/smira/dists/squeeze/main/binary-amd64/Packages.gz') self.check_exists('public/ppa/smira/dists/squeeze/main/binary-amd64/Packages.bz2') + self.check_exists('public/ppa/smira/dists/squeeze/main/Contents-amd64.gz') self.check_exists('public/ppa/smira/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') @@ -327,9 +349,11 @@ class PublishSnapshot13Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-amd64.gz') # verify contents except of sums self.check_file_contents('public/dists/maverick/Release', 'release', match_prepare=strip_processor) @@ -370,9 +394,11 @@ class PublishSnapshot15Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-amd64.gz') # verify contents except of sums self.check_file_contents('public/dists/maverick/Release', 'release', match_prepare=strip_processor) @@ -400,12 +426,15 @@ class PublishSnapshot16Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-amd64.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') + self.check_not_exists('public/dists/maverick/main/Contents-source.gz') self.check_exists('public/pool/main/g/gnuplot/gnuplot-doc_4.6.1-1~maverick2_all.deb') self.check_exists('public/pool/main/g/gnuplot/gnuplot_4.6.1-1~maverick2.debian.tar.gz') @@ -446,9 +475,11 @@ class PublishSnapshot17Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') + self.check_not_exists('public/dists/maverick/main/Contents-source.gz') self.check_exists('public/pool/main/p/pyspi/pyspi_0.6.1-1.3.dsc') self.check_exists('public/pool/main/p/pyspi/pyspi_0.6.1-1.3.diff.gz') @@ -643,19 +674,24 @@ class PublishSnapshot26Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-amd64.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') + self.check_not_exists('public/dists/maverick/main/Contents-source.gz') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/contrib/Contents-i386.gz') self.check_exists('public/dists/maverick/contrib/binary-amd64/Packages') self.check_exists('public/dists/maverick/contrib/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/contrib/binary-amd64/Packages.bz2') + self.check_not_exists('public/dists/maverick/contrib/Contents-amd64.gz') self.check_exists('public/dists/maverick/contrib/source/Sources') self.check_exists('public/dists/maverick/contrib/source/Sources.gz') self.check_exists('public/dists/maverick/contrib/source/Sources.bz2') @@ -710,7 +746,8 @@ class PublishSnapshot26Test(BaseTest): 'contrib/binary-amd64/Packages.gz', 'contrib/binary-amd64/Packages.bz2', 'contrib/binary-i386/Packages.bz2', 'contrib/source/Sources', 'contrib/source/Sources.gz', 'contrib/source/Sources.bz2', 'main/binary-amd64/Release', 'main/binary-i386/Release', 'main/source/Release', - 'contrib/binary-amd64/Release', 'contrib/binary-i386/Release', 'contrib/source/Release']): + 'contrib/binary-amd64/Release', 'contrib/binary-i386/Release', 'contrib/source/Release', + 'contrib/Contents-i386.gz', 'main/Contents-i386.gz', 'main/Contents-amd64.gz']): raise Exception("path seen wrong: %r" % (pathsSeen, )) @@ -859,18 +896,22 @@ class PublishSnapshot35Test(BaseTest): self.check_exists('public/dists/squeeze/main/binary-i386/Packages') self.check_exists('public/dists/squeeze/main/binary-i386/Packages.gz') self.check_exists('public/dists/squeeze/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/squeeze/main/Contents-i386.gz') self.check_exists('public/dists/squeeze/main/debian-installer/binary-i386/Release') self.check_exists('public/dists/squeeze/main/debian-installer/binary-i386/Packages') self.check_exists('public/dists/squeeze/main/debian-installer/binary-i386/Packages.gz') self.check_exists('public/dists/squeeze/main/debian-installer/binary-i386/Packages.bz2') + self.check_exists('public/dists/squeeze/main/Contents-udeb-i386.gz') self.check_exists('public/dists/squeeze/main/binary-amd64/Release') self.check_exists('public/dists/squeeze/main/binary-amd64/Packages') self.check_exists('public/dists/squeeze/main/binary-amd64/Packages.gz') self.check_exists('public/dists/squeeze/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/squeeze/main/Contents-amd64.gz') self.check_exists('public/dists/squeeze/main/debian-installer/binary-amd64/Release') self.check_exists('public/dists/squeeze/main/debian-installer/binary-amd64/Packages') self.check_exists('public/dists/squeeze/main/debian-installer/binary-amd64/Packages.gz') self.check_exists('public/dists/squeeze/main/debian-installer/binary-amd64/Packages.bz2') + self.check_exists('public/dists/squeeze/main/Contents-udeb-amd64.gz') self.check_not_exists('public/dists/squeeze/main/source/Sources') self.check_not_exists('public/dists/squeeze/main/source/Sources.gz') self.check_not_exists('public/dists/squeeze/main/source/Sources.bz2') @@ -922,7 +963,33 @@ class PublishSnapshot35Test(BaseTest): for ext in ("", ".gz", ".bz2"): pathsExepcted.add("main/%sbinary-%s/Packages%s" % (udeb, arch, ext)) + pathsExepcted.add("main/Contents-%s%s.gz" % ("udeb-" if udeb != "" else "", arch)) + pathsExepcted.add("main/%sbinary-%s/Release" % (udeb, arch)) if pathsSeen != pathsExepcted: raise Exception("path seen wrong: %r != %r" % (pathsSeen, pathsExepcted)) + + +class PublishSnapshot36Test(BaseTest): + """ + publish snapshot: -skip-contents + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap36 from mirror gnuplot-maverick", + ] + runCmd = "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -skip-contents snap36" + gold_processor = BaseTest.expand_environ + + def check(self): + super(PublishSnapshot36Test, self).check() + + self.check_exists('public/dists/maverick/Release') + self.check_exists('public/dists/maverick/Release.gpg') + + self.check_exists('public/dists/maverick/main/binary-i386/Release') + self.check_not_exists('public/dists/maverick/main/Contents-i386.gz') + self.check_exists('public/dists/maverick/main/binary-amd64/Release') + self.check_not_exists('public/dists/maverick/main/Contents-amd64.gz') diff --git a/src/github.com/smira/aptly/system/t06_publish/switch.py b/src/github.com/smira/aptly/system/t06_publish/switch.py index 51bfc82f..6d85f3cc 100644 --- a/src/github.com/smira/aptly/system/t06_publish/switch.py +++ b/src/github.com/smira/aptly/system/t06_publish/switch.py @@ -30,11 +30,14 @@ class PublishSwitch1Test(BaseTest): self.check_exists('public/dists/maverick/Release') self.check_exists('public/dists/maverick/Release.gpg') + self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-amd64.gz') self.check_exists('public/pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_i386.deb') self.check_exists('public/pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_amd64.deb') @@ -80,7 +83,8 @@ class PublishSwitch1Test(BaseTest): if pathsSeen != set(['main/binary-amd64/Packages', 'main/binary-i386/Packages', 'main/binary-i386/Packages.gz', 'main/binary-amd64/Packages.gz', 'main/binary-amd64/Packages.bz2', 'main/binary-i386/Packages.bz2', - 'main/binary-amd64/Release', 'main/binary-i386/Release']): + 'main/binary-amd64/Release', 'main/binary-i386/Release', 'main/Contents-amd64.gz', + 'main/Contents-i386.gz']): raise Exception("path seen wrong: %r" % (pathsSeen, )) @@ -106,11 +110,14 @@ class PublishSwitch2Test(BaseTest): self.check_exists('public/ppa/dists/maverick/Release') self.check_exists('public/ppa/dists/maverick/Release.gpg') + self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages') self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/ppa/dists/maverick/main/Contents-i386.gz') self.check_exists('public/ppa/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/ppa/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/ppa/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/ppa/dists/maverick/main/Contents-amd64.gz') self.check_exists('public/ppa/pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_i386.deb') self.check_exists('public/ppa/pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_amd64.deb') @@ -144,11 +151,14 @@ class PublishSwitch3Test(BaseTest): self.check_exists('public/dists/maverick/Release') self.check_exists('public/dists/maverick/Release.gpg') + self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/main/binary-amd64/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-amd64.gz') self.check_exists('public/pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_i386.deb') self.check_exists('public/pool/main/g/gnuplot/gnuplot-x11_4.6.1-1~maverick2_amd64.deb') @@ -178,8 +188,10 @@ class PublishSwitch4Test(BaseTest): self.check_exists('public/ppa/dists/maverick/Release') self.check_exists('public/ppa/dists/maverick/Release.gpg') + self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages') self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/ppa/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/ppa/dists/maverick/main/Contents-i386.gz') self.check_not_exists('public/ppa/dists/maverick/main/binary-amd64/Packages') self.check_not_exists('public/ppa/dists/maverick/main/binary-amd64/Packages.gz') self.check_not_exists('public/ppa/dists/maverick/main/binary-amd64/Packages.bz2') @@ -260,9 +272,14 @@ class PublishSwitch8Test(BaseTest): self.check_exists('public/dists/maverick/' + component + '/binary-i386/Packages') self.check_exists('public/dists/maverick/' + component + '/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/' + component + '/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/' + component + '/Contents-i386.gz') self.check_exists('public/dists/maverick/' + component + '/binary-amd64/Packages') self.check_exists('public/dists/maverick/' + component + '/binary-amd64/Packages.gz') self.check_exists('public/dists/maverick/' + component + '/binary-amd64/Packages.bz2') + if component == "c": + self.check_not_exists('public/dists/maverick/' + component + '/Contents-amd64.gz') + else: + self.check_exists('public/dists/maverick/' + component + '/Contents-amd64.gz') self.check_exists('public/dists/maverick/' + component + '/source/Sources') self.check_exists('public/dists/maverick/' + component + '/source/Sources.gz') self.check_exists('public/dists/maverick/' + component + '/source/Sources.bz2') @@ -331,7 +348,9 @@ class PublishSwitch8Test(BaseTest): 'c/binary-i386/Packages.gz', 'b/source/Sources.gz', 'b/binary-i386/Packages', 'a/binary-amd64/Release', 'b/binary-amd64/Release', 'c/binary-amd64/Release', 'a/binary-i386/Release', 'b/binary-i386/Release', 'c/binary-i386/Release', - 'a/source/Release', 'b/source/Release', 'c/source/Release']): + 'a/source/Release', 'b/source/Release', 'c/source/Release', + 'b/Contents-amd64.gz', 'c/Contents-i386.gz', 'a/Contents-i386.gz', + 'a/Contents-amd64.gz', 'b/Contents-i386.gz']): raise Exception("path seen wrong: %r" % (pathsSeen, )) @@ -400,3 +419,29 @@ class PublishSwitch12Test(BaseTest): ] runCmd = "aptly publish switch -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -component=a,c maverick snap2 snap1" expectedCode = 1 + + +class PublishSwitch13Test(BaseTest): + """ + publish switch: -skip-contents + """ + fixtureDB = True + fixturePool = True + fixtureCmds = [ + "aptly snapshot create snap1 from mirror gnuplot-maverick", + "aptly snapshot create snap2 empty", + "aptly snapshot pull -no-deps -architectures=i386,amd64 snap2 snap1 snap3 gnuplot-x11", + "aptly publish snapshot -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick -skip-contents snap1", + ] + runCmd = "aptly publish switch -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec maverick snap3" + gold_processor = BaseTest.expand_environ + + def check(self): + super(PublishSwitch13Test, self).check() + + self.check_exists('public/dists/maverick/Release') + + self.check_exists('public/dists/maverick/main/binary-i386/Packages') + self.check_not_exists('public/dists/maverick/main/Contents-i386.gz') + self.check_exists('public/dists/maverick/main/binary-amd64/Packages') + self.check_not_exists('public/dists/maverick/main/Contents-amd64.gz') diff --git a/src/github.com/smira/aptly/system/t06_publish/update.py b/src/github.com/smira/aptly/system/t06_publish/update.py index dd65a6d9..62869dda 100644 --- a/src/github.com/smira/aptly/system/t06_publish/update.py +++ b/src/github.com/smira/aptly/system/t06_publish/update.py @@ -31,6 +31,7 @@ class PublishUpdate1Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') @@ -81,7 +82,7 @@ class PublishUpdate1Test(BaseTest): if pathsSeen != set(['main/binary-i386/Packages', 'main/binary-i386/Packages.bz2', 'main/binary-i386/Packages.gz', 'main/source/Sources', 'main/source/Sources.gz', 'main/source/Sources.bz2', - 'main/binary-i386/Release', 'main/source/Release']): + 'main/binary-i386/Release', 'main/source/Release', 'main/Contents-i386.gz']): raise Exception("path seen wrong: %r" % (pathsSeen, )) @@ -108,6 +109,7 @@ class PublishUpdate2Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') @@ -147,6 +149,7 @@ class PublishUpdate3Test(BaseTest): self.check_exists('public/dists/maverick/main/binary-i386/Packages') self.check_exists('public/dists/maverick/main/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/main/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/main/Contents-i386.gz') self.check_exists('public/dists/maverick/main/source/Sources') self.check_exists('public/dists/maverick/main/source/Sources.gz') self.check_exists('public/dists/maverick/main/source/Sources.bz2') @@ -245,6 +248,7 @@ class PublishUpdate7Test(BaseTest): self.check_exists('public/dists/maverick/contrib/binary-i386/Packages') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.gz') self.check_exists('public/dists/maverick/contrib/binary-i386/Packages.bz2') + self.check_exists('public/dists/maverick/contrib/Contents-i386.gz') self.check_exists('public/dists/maverick/contrib/source/Sources') self.check_exists('public/dists/maverick/contrib/source/Sources.gz') self.check_exists('public/dists/maverick/contrib/source/Sources.bz2') @@ -309,3 +313,27 @@ class PublishUpdate10Test(BaseTest): super(PublishUpdate10Test, self).check() self.check_file_contents("public/pool/main/p/pyspi/pyspi_0.6.1.orig.tar.gz", "file") + + +class PublishUpdate11Test(BaseTest): + """ + publish update: -skip-contents + """ + fixtureCmds = [ + "aptly repo create local-repo", + "aptly repo add local-repo ${files}/", + "aptly publish repo -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -distribution=maverick -skip-contents local-repo", + "aptly repo remove local-repo pyspi" + ] + runCmd = "aptly publish update -keyring=${files}/aptly.pub -secret-keyring=${files}/aptly.sec -skip-contents maverick" + gold_processor = BaseTest.expand_environ + + def check(self): + super(PublishUpdate11Test, self).check() + + self.check_exists('public/dists/maverick/InRelease') + self.check_exists('public/dists/maverick/Release') + self.check_exists('public/dists/maverick/Release.gpg') + + self.check_exists('public/dists/maverick/main/binary-i386/Packages') + self.check_not_exists('public/dists/maverick/main/Contents-i386.gz') diff --git a/src/github.com/smira/aptly/system/t09_repo/CreateRepo4Test_gold b/src/github.com/smira/aptly/system/t09_repo/CreateRepo4Test_gold new file mode 100644 index 00000000..02c678bf --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/CreateRepo4Test_gold @@ -0,0 +1,3 @@ + +Local repo [repo4] successfully added. +You can run 'aptly repo add repo4 ...' to add packages to repository. diff --git a/src/github.com/smira/aptly/system/t09_repo/CreateRepo4Test_repo_show b/src/github.com/smira/aptly/system/t09_repo/CreateRepo4Test_repo_show new file mode 100644 index 00000000..bdee25b7 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/CreateRepo4Test_repo_show @@ -0,0 +1,6 @@ +Name: repo4 +Comment: +Default Distribution: +Default Component: main +Uploaders: {"groups":{"developers":["21DBB89C16DB3E6D","37E1C17570096AD1"]},"rules":[{"condition":"Source (dangerous) | Source (kernel)","allow":null,"deny":["*"]},{"condition":"Source (hardlink)","allow":["developers","admins"],"deny":null}]} +Number of packages: 0 diff --git a/src/github.com/smira/aptly/system/t09_repo/CreateRepo5Test_gold b/src/github.com/smira/aptly/system/t09_repo/CreateRepo5Test_gold new file mode 100644 index 00000000..fdab9a7e --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/CreateRepo5Test_gold @@ -0,0 +1 @@ +ERROR: error loading uploaders file: unexpected EOF diff --git a/src/github.com/smira/aptly/system/t09_repo/CreateRepo6Test_gold b/src/github.com/smira/aptly/system/t09_repo/CreateRepo6Test_gold new file mode 100644 index 00000000..4065f97f --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/CreateRepo6Test_gold @@ -0,0 +1 @@ +ERROR: error loading uploaders file: open /uploaders-not-found.json: no such file or directory diff --git a/src/github.com/smira/aptly/system/t09_repo/EditRepo4Test_gold b/src/github.com/smira/aptly/system/t09_repo/EditRepo4Test_gold new file mode 100644 index 00000000..7f6337c1 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/EditRepo4Test_gold @@ -0,0 +1 @@ +Local repo [repo4] successfully updated. diff --git a/src/github.com/smira/aptly/system/t09_repo/EditRepo4Test_repo_show b/src/github.com/smira/aptly/system/t09_repo/EditRepo4Test_repo_show new file mode 100644 index 00000000..bdee25b7 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/EditRepo4Test_repo_show @@ -0,0 +1,6 @@ +Name: repo4 +Comment: +Default Distribution: +Default Component: main +Uploaders: {"groups":{"developers":["21DBB89C16DB3E6D","37E1C17570096AD1"]},"rules":[{"condition":"Source (dangerous) | Source (kernel)","allow":null,"deny":["*"]},{"condition":"Source (hardlink)","allow":["developers","admins"],"deny":null}]} +Number of packages: 0 diff --git a/src/github.com/smira/aptly/system/t09_repo/EditRepo5Test_gold b/src/github.com/smira/aptly/system/t09_repo/EditRepo5Test_gold new file mode 100644 index 00000000..fdab9a7e --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/EditRepo5Test_gold @@ -0,0 +1 @@ +ERROR: error loading uploaders file: unexpected EOF diff --git a/src/github.com/smira/aptly/system/t09_repo/EditRepo6Test_gold b/src/github.com/smira/aptly/system/t09_repo/EditRepo6Test_gold new file mode 100644 index 00000000..4065f97f --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/EditRepo6Test_gold @@ -0,0 +1 @@ +ERROR: error loading uploaders file: open /uploaders-not-found.json: no such file or directory diff --git a/src/github.com/smira/aptly/system/t09_repo/EditRepo7Test_gold b/src/github.com/smira/aptly/system/t09_repo/EditRepo7Test_gold new file mode 100644 index 00000000..b1b50430 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/EditRepo7Test_gold @@ -0,0 +1 @@ +Local repo [repo7] successfully updated. diff --git a/src/github.com/smira/aptly/system/t09_repo/EditRepo7Test_repo_show b/src/github.com/smira/aptly/system/t09_repo/EditRepo7Test_repo_show new file mode 100644 index 00000000..25d60afb --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/EditRepo7Test_repo_show @@ -0,0 +1,5 @@ +Name: repo7 +Comment: +Default Distribution: +Default Component: main +Number of packages: 0 diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo10Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo10Test_gold new file mode 100644 index 00000000..aad7ca65 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo10Test_gold @@ -0,0 +1,3 @@ +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[+] hardlink_0.2.1_amd64 added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo11Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo11Test_gold new file mode 100644 index 00000000..aad7ca65 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo11Test_gold @@ -0,0 +1,3 @@ +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[+] hardlink_0.2.1_amd64 added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo12Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo12Test_gold new file mode 100644 index 00000000..da4f78d6 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo12Test_gold @@ -0,0 +1,6 @@ +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[!] hardlink_0.2.1_amd64 has been ignored as it doesn't match restriction +[!] Some files were skipped due to errors: + /01/hardlink_0.2.1_amd64.deb +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo13Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo13Test_gold new file mode 100644 index 00000000..0dd38627 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo13Test_gold @@ -0,0 +1,7 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[!] changes file skipped due to uploaders config: hardlink_0.2.1_amd64.changes, keys []utils.GpgKey{"21DBB89C16DB3E6D"}: denied as no rule matches +[!] Some files were skipped due to errors: + /hardlink_0.2.1_amd64.changes +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo14Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo14Test_gold new file mode 100644 index 00000000..58285bb6 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo14Test_gold @@ -0,0 +1,5 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[+] hardlink_0.2.1_amd64 added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo15Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo15Test_gold new file mode 100644 index 00000000..c9305b37 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo15Test_gold @@ -0,0 +1 @@ +ERROR: error loading uploaders file: open /uploaders-404.json: no such file or directory diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo16Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo16Test_gold new file mode 100644 index 00000000..fdab9a7e --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo16Test_gold @@ -0,0 +1 @@ +ERROR: error loading uploaders file: unexpected EOF diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo17Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo17Test_gold new file mode 100644 index 00000000..28471e01 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo17Test_gold @@ -0,0 +1 @@ +ERROR: error parsing query Source (hardlink: parsing failed: unexpected token : expecting ')' diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo18Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo18Test_gold new file mode 100644 index 00000000..58285bb6 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo18Test_gold @@ -0,0 +1,5 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[+] hardlink_0.2.1_amd64 added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo19Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo19Test_gold new file mode 100644 index 00000000..0dd38627 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo19Test_gold @@ -0,0 +1,7 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[!] changes file skipped due to uploaders config: hardlink_0.2.1_amd64.changes, keys []utils.GpgKey{"21DBB89C16DB3E6D"}: denied as no rule matches +[!] Some files were skipped due to errors: + /hardlink_0.2.1_amd64.changes +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo1Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo1Test_gold new file mode 100644 index 00000000..456eb0b5 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo1Test_gold @@ -0,0 +1,5 @@ +gpgv: Signature made Sun Mar 15 20:36:44 2015 MSK using DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[+] hardlink_0.2.1_amd64 added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo1Test_repo_show b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo1Test_repo_show new file mode 100644 index 00000000..6543b523 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo1Test_repo_show @@ -0,0 +1,8 @@ +Name: unstable +Comment: +Default Distribution: +Default Component: main +Number of packages: 2 +Packages: + hardlink_0.2.1_amd64 + hardlink_0.2.1_source diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo2Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo2Test_gold new file mode 100644 index 00000000..a9f191f2 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo2Test_gold @@ -0,0 +1,5 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +Loading repository my-unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[+] hardlink_0.2.1_amd64 added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo2Test_repo_show b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo2Test_repo_show new file mode 100644 index 00000000..ab2503c0 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo2Test_repo_show @@ -0,0 +1,11 @@ +Name: my-unstable +Comment: +Default Distribution: +Default Component: main +Number of packages: 5 +Packages: + hardlink_0.2.1_amd64 + libboost-program-options-dev_1.49.0.1_i386 + hardlink_0.2.1_source + pyspi_0.6.1-1.3_source + pyspi_0.6.1-1.4_source diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo3Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo3Test_gold new file mode 100644 index 00000000..96cda590 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo3Test_gold @@ -0,0 +1 @@ +ERROR: error parsing -repo template: template: repo:1: unexpected "}" in operand; missing space? diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo4Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo4Test_gold new file mode 100644 index 00000000..2fcf3fd4 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo4Test_gold @@ -0,0 +1,5 @@ +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[!] unable to process file hardlink_0.2.1_amd64.changes: local repo with name unstable not found +[!] Some files were skipped due to errors: + /hardlink_0.2.1_amd64.changes +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo5Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo5Test_gold new file mode 100644 index 00000000..58285bb6 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo5Test_gold @@ -0,0 +1,5 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +Loading repository unstable for changes file hardlink_0.2.1_amd64.changes... +[+] hardlink_0.2.1_source added +[+] hardlink_0.2.1_amd64 added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo5Test_repo_show b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo5Test_repo_show new file mode 100644 index 00000000..6543b523 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo5Test_repo_show @@ -0,0 +1,8 @@ +Name: unstable +Comment: +Default Distribution: +Default Component: main +Number of packages: 2 +Packages: + hardlink_0.2.1_amd64 + hardlink_0.2.1_source diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo6Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo6Test_gold new file mode 100644 index 00000000..9c02bfa6 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo6Test_gold @@ -0,0 +1,6 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +[!] unable to process file hardlink_0.2.1_amd64.changes: open /01/hardlink_0.2.1.tar.gz: no such file or directory +[!] Some files were skipped due to errors: + /01/hardlink_0.2.1_amd64.changes +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo7Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo7Test_gold new file mode 100644 index 00000000..2215c9dd --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo7Test_gold @@ -0,0 +1,6 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: Good signature from "Aptly Tester (don't use it) " +[!] unable to process file hardlink_0.2.1_amd64.changes: checksum mismatch MD5: expected 4efce26825af5842f43961096dd890b3 != obtained 7515e9279fc32d0c89db965f4dfdec8c +[!] Some files were skipped due to errors: + /01/hardlink_0.2.1_amd64.changes +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo8Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo8Test_gold new file mode 100644 index 00000000..1f1e0949 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo8Test_gold @@ -0,0 +1,6 @@ +gpgv: DSA key ID 16DB3E6D +gpgv: BAD signature from "Aptly Tester (don't use it) " +[!] unable to process file hardlink_0.2.1_amd64.changes: verification of clearsigned file failed: exit status 1 +[!] Some files were skipped due to errors: + /01/hardlink_0.2.1_amd64.changes +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/IncludeRepo9Test_gold b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo9Test_gold new file mode 100644 index 00000000..13fb221e --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/IncludeRepo9Test_gold @@ -0,0 +1,4 @@ +[!] unable to process file hardlink_0.2.1_amd64.changes: .changes file is not signed and unsigned processing hasn't been enabled +[!] Some files were skipped due to errors: + /01/hardlink_0.2.1_amd64.changes +ERROR: some files failed to be added diff --git a/src/github.com/smira/aptly/system/t09_repo/SearchRepo5Test_gold b/src/github.com/smira/aptly/system/t09_repo/SearchRepo5Test_gold new file mode 100644 index 00000000..b5a49d54 --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/SearchRepo5Test_gold @@ -0,0 +1,4043 @@ + +aolserver4-dev#4.5.1-15.1 +apache2-prefork-dev#2.2.22-13+deb7u1 +apache2-threaded-dev#2.2.22-13+deb7u1 +apcalc-dev#2.12.4.4-3 +aplus-fsf-dev#4.22.1-6 +aroarfw-dev#0.1~beta4-5 +asterisk-dev#1:1.8.13.1~dfsg1-3+deb7u3 +atfs-dev#1.4pl6-11 +audacious-dev#3.2.4-1 +autotools-dev#20120608.1 +binutils-dev#2.22-8 +biosquid-dev#1.9g+cvs20050121-2 +bitlbee-dev#3.0.5-1.2 +blacs-pvm-dev#1.1-21 +blends-dev#0.6.16.2 +blktap-dev#2.0.90-1 +blt-dev#2.4z-4.2 +boinc-dev#7.0.27+dfsg-5 +boolstuff-dev#0.1.12-3 +cairo-dock-dev#3.0.0-2+deb7u1 +cernlib-base-dev#20061220+dfsg3-2 +cernlib-core-dev#20061220+dfsg3-2 +chipmunk-dev#5.3.4-1 +cimg-dev#1.4.9-2 +clearsilver-dev#0.10.5-1.3 +cli-common-dev#0.8.2 +clinica-dev#0.2.1~dfsg-1 +clisp-dev#1:2.49-8.1 +cluster-glue-dev#1.0.9+hg2665-1 +codeblocks-dev#10.05-2.1 +coinor-libcbc-dev#2.5.0-3 +coinor-libcgl-dev#0.55.0-1.1 +coinor-libclp-dev#1.12.0-2.1 +coinor-libcoinutils-dev#2.6.4-3 +coinor-libdylp-dev#1.6.0-1.1 +coinor-libflopc++-dev#1.0.6-3.1 +coinor-libipopt-dev#3.10.2-1.1 +coinor-libosi-dev#0.103.0-1 +coinor-libsymphony-dev#5.2.4-1.2 +coinor-libvol-dev#1.1.7-1 +collectd-dev#5.1.0-3 +comerr-dev#2.1-1.42.5-1.1 +condor-dev#7.8.2~dfsg.1-1+deb7u1 +config-package-dev#4.13 +connman-dev#1.0-1.1+wheezy1+b1 +console-tools-dev#1:0.2.3dbs-70 +coop-computing-tools-dev#3.5.1-2 +corosync-dev#1.4.2-3 +courier-authlib-dev#0.63.0-6+b1 +crtmpserver-dev#1.0~dfsg-3 +ctapi-dev#1.1 +ctn-dev#3.0.6-13+b2 +cyrus-dev#2.4.16-4+deb7u1 +dcap-dev#2.47.6-2 +dico-dev#2.1-3+b2 +dictionaries-common-dev#1.12.11 +dietlibc-dev#0.33~cvs20120325-4 +dolfin-dev#1.0.0-7 +dovecot-dev#1:2.1.7-7 +dpkg-dev#1.16.12 +drac-dev#1.12-7.2 +drizzle-plugin-dev#1:7.1.36-stable-1 +dssi-dev#1.1.1~dfsg0-1 +e2fslibs-dev#1.42.5-1.1 +emerillon-dev#0.1.90-1 +eog-dev#3.4.2-1+build1 +epiphany-browser-dev#3.4.2-2.1 +erlang-dev#1:15.b.1-dfsg-4+deb7u1 +erlang-esdl-dev#1.2-2 +etl-dev#0.04.15-1 +evolution-data-server-dev#3.4.4-3 +evolution-dev#3.4.4-3 +exim4-dev#4.80-7 +expect-dev#5.45-2 +expeyes-firmware-dev#2.0.0-3 +extremetuxracer-gimp-dev#0.4-5 +falconpl-dev#0.9.6.9-git20120606-2 +fatrat-dev#1.1.3-5 +fcitx-libs-dev#1:4.2.4.1-7 +fenix-dev#0.92a.dfsg1-9 +festival-dev#1:2.1~release-5.1 +fftw-dev#2.1.5-1 +finch-dev#2.10.9-1~deb7u1 +firebird-dev#2.5.2.26540.ds4-1~deb7u1 +flite1-dev#1.4-release-6 +flow-tools-dev#1:0.68-12.1+b1 +fosfat-dev#0.4.0-3 +freeglut3-dev#2.6.0-4 +freetds-dev#0.91-2+deb7u1 +frei0r-plugins-dev#1.1.22git20091109-1.2 +ftgl-dev#2.1.3~rc5-4 +ftplib-dev#3.1-1-9 +gambas3-dev#3.1.1-2+b1 +gap-dev#4r4p12-2 +gauche-dev#0.9.1-5.1 +gcc-4.6-plugin-dev#4.6.3-14 +gcc-4.7-plugin-dev#4.7.2-5 +gcin-dev#2.7.6.1+dfsg-1 +gedit-dev#3.4.2-1 +gem-dev#1:0.93.3-5 +genius-dev#1.0.14-1 +gfxboot-dev#4.5.0-3 +giblib-dev#1.2.4-8 +glabels-dev#3.0.0-3+b1 +glee-dev#5.4.0-1 +gmpc-dev#11.8.16-6 +gnash-dev#0.8.11~git20120629-1+deb7u1 +gnome-control-center-dev#1:3.4.3.1-2 +gnome-settings-daemon-dev#3.4.2+git20121218.7c1322-3+deb7u3 +gnome-video-effects-dev#0.4.0-1 +gnumach-dev#2:1.3.99.dfsg.git20120610-1 +gnunet-dev#0.9.3-7 +gnunet-gtk-dev#0.9.3-1 +gnuradio-dev#3.5.3.2-1 +gosa-dev#2.7.4-4.3~deb7u1 +gpe-ownerinfo-dev#0.28-3 +gpsim-dev#0.26.1-2.1 +graphviz-dev#2.26.3-14+deb7u1 +grass-dev#6.4.2-2 +gridengine-drmaa-dev#6.2u5-7.1 +gromacs-dev#4.5.5-2 +gsettings-desktop-schemas-dev#3.4.2-3 +gthumb-dev#3:3.0.1-2 +guile-1.6-dev#1.6.8-10.3 +guile-1.8-dev#1.8.8+1-8 +guile-2.0-dev#2.0.5+1-3 +guile-cairo-dev#1.4.0-3 +heartbeat-dev#1:3.0.5-3 +heimdal-dev#1.6~git20120403+dfsg1-2 +hime-dev#0.9.9+git20120619+dfsg-1 +hybrid-dev#1:7.2.2.dfsg.2-10 +icedove-dev#10.0.12-1 +inn2-dev#2.5.3-3 +inventor-dev#2.1.5-10-16 +iproute-dev#20120521-3+b3 +iptables-dev#1.4.14-3.1 +irssi-dev#0.8.15-5 +isc-dhcp-dev#4.2.2.dfsg.1-5+deb70u6 +itcl3-dev#3.4.1-1 +itk3-dev#3.3-4 +ivtools-dev#1.2.10a1-1 +kadu-dev#0.11.2-1 +kannel-dev#1.4.3-2+b2 +kde-workspace-dev#4:4.8.4-6 +kdebase-workspace-dev#4:4.8.4-6 +kdelibs5-dev#4:4.8.4-4 +kdemultimedia-dev#4:4.8.4-2 +kdepimlibs5-dev#4:4.8.4-2 +kdevelop-dev#4:4.3.1-3+b1 +kdevplatform-dev#1.3.1-2 +kmymoney-dev#4.6.2-3.2 +konwert-dev#1.8-11.2 +lam4-dev#7.1.4-3 +lesstif2-dev#1:0.95.2-1.1 +lib3ds-dev#1.3.0-6 +lib4store-dev#1.1.4-2 +lib64bz2-dev#1.0.6-4 +lib64expat1-dev#2.1.0-1+deb7u1 +lib64ffi-dev#3.0.10-3 +lib64ncurses5-dev#5.9-10 +lib64readline-gplv2-dev#5.2+dfsg-2~deb7u1 +lib64readline6-dev#6.2+dfsg-0.1 +lib64z1-dev#1:1.2.7.dfsg-13 +liba52-0.7.4-dev#0.7.4-16 +libaa1-dev#1.4p5-40 +libaac-tactics-ocaml-dev#0.2.pl2-7 +libaacs-dev#0.4.0-1 +libaal-dev#1.0.5-5.1 +libabiword-2.9-dev#2.9.2+svn20120603-8 +libaccountsservice-dev#0.6.21-8 +libace-dev#6.0.3+dfsg-0.1 +libace-flreactor-dev#6.0.3+dfsg-0.1 +libace-foxreactor-dev#6.0.3+dfsg-0.1 +libace-htbp-dev#6.0.3+dfsg-0.1 +libace-inet-dev#6.0.3+dfsg-0.1 +libace-inet-ssl-dev#6.0.3+dfsg-0.1 +libace-qtreactor-dev#6.0.3+dfsg-0.1 +libace-rmcast-dev#6.0.3+dfsg-0.1 +libace-ssl-dev#6.0.3+dfsg-0.1 +libace-tkreactor-dev#6.0.3+dfsg-0.1 +libace-tmcast-dev#6.0.3+dfsg-0.1 +libace-xtreactor-dev#6.0.3+dfsg-0.1 +libacexml-dev#6.0.3+dfsg-0.1 +libacl1-dev#2.2.51-8 +libacpi-dev#0.2-4 +libacr38ucontrol-dev#1.7.11-1 +libadasockets4-dev#1.8.10-2 +libaddresses-dev#0.4.7-1+b5 +libaddressview-dev#0.4.7-1+b5 +libadios-dev#1.3-11 +libadminutil-dev#1.1.15-1 +libadns1-dev#1.4-2 +libadolc-dev#2.3.0-1 +libadplug-dev#2.2.1+dfsg3-0.1 +libafflib-dev#3.6.6-1.1+b1 +libafrodite-0.12-dev#0.12.1-3 +libafterimage-dev#2.2.11-7 +libagg-dev#2.5+dfsg1-8 +libagrep-ocaml-dev#1.0-11+b3 +libahven3-dev#2.1-4 +libaiksaurus-1.2-dev#1.2.1+dev-0.12-6.1 +libaiksaurusgtk-1.2-dev#1.2.1+dev-0.12-6.1 +libaio-dev#0.3.109-3 +libakonadi-dev#1.7.2-3 +libalberta2-dev#2.0.1-5 +libaldmb1-dev#1:0.9.3-5.4 +libalglib-dev#2.6.0-6 +libalkimia-dev#4.3.2-1.1 +liballeggl4-dev#2:4.4.2-2.1 +liballegro4.2-dev#2:4.4.2-2.1 +libalog0.4.1-base-dev#0.4.1-2 +libalog0.4.1-full-dev#0.4.1-2 +libalsa-ocaml-dev#0.2.1-1+b1 +libalsaplayer-dev#0.99.80-5.1 +libalure-dev#1.2-6 +libalut-dev#1.1.0-3 +libampsharp-cil-dev#2.0.4-2 +libamu-dev#6.2+rc20110530-3 +libanalitza-dev#4:4.8.4-2 +libanet0.1-dev#0.1-3 +libanjuta-dev#2:3.4.3-1 +libann-dev#1.1.2+doc-3 +libanthy-dev#9100h-16 +libantlr-dev#2.7.7+dfsg-4 +libantlr3c-dev#3.2-2 +libao-dev#1.1.0-2 +libao-ocaml-dev#0.2.0-1+b2 +libaosd-dev#0.2.7-1 +libapache2-mod-perl2-dev#2.0.7-3 +libapertium3-3.1-0-dev#3.1.0-2 +libapm-dev#3.2.2-14 +libapol-dev#3.3.7-3 +libapparmor-dev#2.7.103-4 +libappindicator-dev#0.4.92-2 +libappindicator0.1-cil-dev#0.4.92-2 +libappindicator3-dev#0.4.92-2 +libapq-postgresql3.2.0-dev#3.2.0-2 +libapq3.2.0-dev#3.2.0-1 +libapr-memcache-dev#0.7.0-1 +libapr1-dev#1.4.6-3+deb7u1 +libapreq2-dev#2.13-1+b2 +libapron-dev#0.9.10-5.2 +libapron-ocaml-dev#0.9.10-5.2+b3 +libaprutil1-dev#1.4.1-3 +libapt-pkg-dev#0.9.7.9+deb7u1 +libaqbanking34-dev#5.0.24-3 +libaqsis-dev#1.8.1-3 +libarchive-dev#3.0.4-3+nmu1 +libargtable2-dev#12-1 +libarmadillo-dev#1:3.2.3+dfsg-1 +libarpack++2-dev#2.3-2 +libarpack2-dev#3.1.1-2.1 +libart-2.0-dev#2.3.21-2 +libart2.0-cil-dev#2.24.2-3 +libasio-dev#1.4.1-3.2 +libasis2010-dev#2010-5 +libasm-dev#0.152-1+wheezy1 +libasound2-dev#1.0.25-4 +libaspell-dev#0.60.7~20110707-1 +libass-dev#0.10.0-3 +libassa3.5-5-dev#3.5.1-2 +libassimp-dev#3.0~dfsg-1 +libassuan-dev#2.0.3-1 +libast2-dev#0.7-6+b1 +libasyncns-dev#0.8-4 +libatasmart-dev#0.19-1 +libatd-ocaml-dev#1.0.1-1+b1 +libatdgen-ocaml-dev#1.2.2-1+b1 +libatk-bridge2.0-dev#2.5.3-2 +libatk1.0-dev#2.4.0-2 +libatkmm-1.6-dev#2.22.6-1 +libatlas-base-dev#3.8.4-9+deb7u1 +libatlas-cpp-0.6-dev#0.6.2-3 +libatlas-dev#3.8.4-9+deb7u1 +libatm1-dev#1:2.5.1-1.5 +libatomic-ops-dev#7.2~alpha5+cvs20101124-1+deb7u1 +libatomicparsley-dev#2.1.2-1 +libatspi-dev#1.32.0-2 +libatspi2.0-dev#2.5.3-2 +libattica-dev#0.2.0-1 +libattr1-dev#1:2.4.46-8 +libaubio-dev#0.3.2-4.2+b1 +libaudio-dev#1.9.3-5wheezy1 +libaudiofile-dev#0.3.4-2 +libaudiomask-dev#1.0-2 +libaudit-dev#1:1.7.18-1.1 +libaugeas-dev#0.10.0-1 +libaunit2-dev#1.03-7 +libautotrace-dev#0.31.1-16+b1 +libautounit-dev#0.20.1-4 +libavahi-cil-dev#0.6.19-4.2 +libavahi-client-dev#0.6.31-2 +libavahi-common-dev#0.6.31-2 +libavahi-compat-libdnssd-dev#0.6.31-2 +libavahi-core-dev#0.6.31-2 +libavahi-glib-dev#0.6.31-2 +libavahi-gobject-dev#0.6.31-2 +libavahi-qt4-dev#0.6.31-2 +libavahi-ui-cil-dev#0.6.19-4.2 +libavahi-ui-dev#0.6.31-2 +libavahi-ui-gtk3-dev#0.6.31-2 +libavbin-dev#7-1.3 +libavc1394-dev#0.5.4-2 +libavcodec-dev#6:0.8.10-1 +libavdevice-dev#6:0.8.10-1 +libavfilter-dev#6:0.8.10-1 +libavformat-dev#6:0.8.10-1 +libavifile-0.7-dev#1:0.7.48~20090503.ds-13 +libavl-dev#0.3.5-3 +libavogadro-dev#1.0.3-5 +libavutil-dev#6:0.8.10-1 +libaws2.10.2-dev#2.10.2-4 +libax25-dev#0.0.12-rc2+cvs20120204-2 +libbabl-dev#0.1.10-1 +libball1.4-dev#1.4.1+20111206-4 +libballview1.4-dev#1.4.1+20111206-4 +libbam-dev#0.1.18-1 +libbamf-dev#0.2.118-1 +libbamf3-dev#0.2.118-1 +libbarry-dev#0.18.3-5 +libbatteries-ocaml-dev#1.4.3-1 +libbdd-dev#2.4-8 +libbeecrypt-dev#4.2.1-4 +libbenchmark-ocaml-dev#0.9-2+b3 +libbfb0-dev#0.23-1.1 +libbg1-dev#1.106-1 +libbibutils-dev#4.12-5 +libbin-prot-camlp4-dev#2.0.7-1 +libbind-dev#1:9.8.4.dfsg.P1-6+nmu2+deb7u1 +libbind4-dev#6.0-1 +libbinio-dev#1.4+dfsg1-1 +libbiniou-ocaml-dev#1.0.0-1+b1 +libbio2jack0-dev#0.9-2.1 +libbiococoa-dev#2.2.2-1+b2 +libbiosig-dev#1.3.0-2 +libbisho-common-dev#0.27.2+git20111122.9e68ef3d-1 +libbison-dev#1:2.5.dfsg-2.1 +libbitmask-dev#2.0-2 +libbitstream-dev#1.0-1 +libbitstring-ocaml-dev#2.0.2-3+b1 +libbjack-ocaml-dev#0.1.3-5+b1 +libblacs-mpi-dev#1.1-31 +libblas-dev#1.2.20110419-5 +libbliss-dev#0.72-4 +libblitz0-dev#1:0.9-13 +libblkid-dev#2.20.1-5.3 +libblocksruntime-dev#0.1-1 +libbluedevil-dev#1.9.2-1 +libbluetooth-dev#4.99-2 +libbluray-dev#1:0.2.2-1 +libbml-dev#0.6.1-1 +libbobcat-dev#3.01.00-1+b1 +libbogl-dev#0.1.18-8+b1 +libbognor-regis-dev#0.6.12+git20101007.02c25268-7 +libbonobo2-dev#2.24.3-1 +libbonoboui2-dev#2.24.3-1 +libboo-cil-dev#0.9.5~git20110729.r1.202a430-2 +libboost-all-dev#1.49.0.1 +libboost-chrono-dev#1.49.0.1 +libboost-chrono1.49-dev#1.49.0-3.2 +libboost-date-time-dev#1.49.0.1 +libboost-date-time1.49-dev#1.49.0-3.2 +libboost-dev#1.49.0.1 +libboost-filesystem-dev#1.49.0.1 +libboost-filesystem1.49-dev#1.49.0-3.2 +libboost-graph-dev#1.49.0.1 +libboost-graph-parallel-dev#1.49.0.1 +libboost-graph-parallel1.49-dev#1.49.0-3.2 +libboost-graph1.49-dev#1.49.0-3.2 +libboost-iostreams-dev#1.49.0.1 +libboost-iostreams1.49-dev#1.49.0-3.2 +libboost-locale-dev#1.49.0.1 +libboost-locale1.49-dev#1.49.0-3.2 +libboost-math-dev#1.49.0.1 +libboost-math1.49-dev#1.49.0-3.2 +libboost-mpi-dev#1.49.0.1 +libboost-mpi-python-dev#1.49.0.1 +libboost-mpi-python1.49-dev#1.49.0-3.2 +libboost-mpi1.49-dev#1.49.0-3.2 +libboost-program-options-dev#1.49.0.1 +libboost-program-options1.49-dev#1.49.0-3.2 +libboost-python-dev#1.49.0.1 +libboost-python1.49-dev#1.49.0-3.2 +libboost-random-dev#1.49.0.1 +libboost-random1.49-dev#1.49.0-3.2 +libboost-regex-dev#1.49.0.1 +libboost-regex1.49-dev#1.49.0-3.2 +libboost-serialization-dev#1.49.0.1 +libboost-serialization1.49-dev#1.49.0-3.2 +libboost-signals-dev#1.49.0.1 +libboost-signals1.49-dev#1.49.0-3.2 +libboost-system-dev#1.49.0.1 +libboost-system1.49-dev#1.49.0-3.2 +libboost-test-dev#1.49.0.1 +libboost-test1.49-dev#1.49.0-3.2 +libboost-thread-dev#1.49.0.1 +libboost-thread1.49-dev#1.49.0-3.2 +libboost-timer-dev#1.49.0.1 +libboost-timer1.49-dev#1.49.0-3.2 +libboost-wave-dev#1.49.0.1 +libboost-wave1.49-dev#1.49.0-3.2 +libboost1.49-all-dev#1.49.0-3.2 +libboost1.49-dev#1.49.0-3.2 +libbotan1.10-dev#1.10.5-1 +libbox-dev#2.5-2 +libbox2d-dev#2.0.1+dfsg1-1 +libbpp-core-dev#2.0.3-1 +libbpp-phyl-dev#2.0.3-1 +libbpp-popgen-dev#2.0.3-1 +libbpp-qt-dev#2.0.2-1 +libbpp-raa-dev#2.0.3-1 +libbpp-seq-dev#2.0.3-1 +libbrahe-dev#1.3.2-3 +libbrasero-media3-dev#3.4.1-4 +libbrlapi-dev#4.4-10+deb7u1 +libbs2b-dev#3.1.0+dfsg-2 +libbsd-dev#0.4.2-1 +libbse-dev#0.7.4-5 +libbt-dev#0.70.1-13 +libbtparse-dev#0.63-1 +libbuffy-dev#1.7-1 +libbulletml-dev#0.0.6-5 +libburn-dev#1.2.2-2 +libbuzztard-dev#0.5.0-4 +libbz2-dev#1.0.6-4 +libbz2-ocaml-dev#0.6.0-6+b2 +libc-ares-dev#1.9.1-3 +libc-client2007e-dev#8:2007f~dfsg-2 +libc6-dev#2.13-38+deb7u1 +libcableswig-dev#0.1.0+cvs20111009-1 +libcaca-dev#0.99.beta18-1 +libcairo-ocaml-dev#1:1.2.0-2+b1 +libcairo2-dev#1.12.2-3 +libcairomm-1.0-dev#1.10.0-1 +libcal3d12-dev#0.11.0-4.1 +libcalendar-ocaml-dev#2.03-1+b2 +libcamel1.2-dev#3.4.4-3 +libcameleon-ocaml-dev#1.9.21-2+b1 +libcaml2html-ocaml-dev#1.4.1-3 +libcamlimages-ocaml-dev#1:4.0.1-4+b2 +libcamljava-ocaml-dev#0.3-1+b3 +libcamltemplate-ocaml-dev#1.0.2-1+b2 +libcamomile-ocaml-dev#0.8.4-2 +libcanberra-dev#0.28-6 +libcanberra-gtk-common-dev#0.28-6 +libcanberra-gtk-dev#0.28-6 +libcanberra-gtk3-dev#0.28-6 +libcanlock2-dev#2b-6 +libcanna1g-dev#3.7p3-11 +libcap-dev#1:2.22-1.2 +libcap-ng-dev#0.6.6-2 +libcapi20-dev#1:3.25+dfsg1-3.3~deb7u1 +libcapsinetwork-dev#0.3.0-7 +libcaribou-dev#0.4.4-1 +libcbf-dev#0.7.9.1-3 +libccaudio2-dev#2.0.5-3 +libccfits-dev#2.4-1 +libcconv-dev#0.6.2-1 +libccrtp-dev#2.0.3-4 +libccs-dev#3.0.12-3.2+deb7u2 +libccscript3-dev#1.1.7-2 +libccss-dev#0.5.0-4 +libcdaudio-dev#0.99.12p2-12 +libcdb-dev#0.78 +libcdd-dev#094b.dfsg-4.2 +libcddb2-dev#1.3.2-3 +libcdi-dev#1.5.4+dfsg.1-5 +libcdio-cdda-dev#0.83-4 +libcdio-dev#0.83-4 +libcdio-paranoia-dev#0.83-4 +libcdk5-dev#5.0.20060507-4 +libcdparanoia-dev#3.10.2+debian-10.1 +libcec-dev#1.6.2-1.1 +libcegui-mk2-dev#0.7.6-2+b1 +libcext-dev#6.1.1-2 +libcf-ocaml-dev#0.10-3+b3 +libcfg-dev#1.4.2-3 +libcfitsio3-dev#3.300-2 +libcgal-dev#4.0-5 +libcgic-dev#2.05-3 +libcgicc5-dev#3.2.9-3 +libcgns-dev#3.1.3.4-1+b1 +libcgroup-dev#0.38-1 +libcgsi-gsoap-dev#1.3.5-1 +libchamplain-0.12-dev#0.12.3-1 +libchamplain-gtk-0.12-dev#0.12.3-1 +libcharls-dev#1.0-2 +libchasen-dev#2.4.5-6 +libcheese-dev#3.4.2-2 +libcheese-gtk-dev#3.4.2-2 +libchewing3-dev#0.3.3-4 +libchicken-dev#4.7.0-1 +libchipcard-dev#5.0.3beta-3 +libchise-dev#0.3.0-2+b1 +libchm-dev#2:0.40a-2 +libchromaprint-dev#0.6-2 +libcib1-dev#1.1.7-1 +libcitadel-dev#8.14-1 +libcitygml0-dev#0.14+svn128-1+3p0p1+4 +libck-connector-dev#0.4.5-3.1 +libckyapplet1-dev#1.1.0-12 +libclalsadrv-dev#2.0.0-3 +libclam-dev#1.4.0-5.1 +libclam-qtmonitors-dev#1.4.0-3.1 +libclamav-dev#0.98.1+dfsg-1+deb7u3 +libclang-common-dev#1:3.0-6.2 +libclang-dev#1:3.0-6.2 +libclanlib-dev#1.0~svn3827-3 +libclassad-dev#7.8.2~dfsg.1-1+deb7u1 +libclaw-application-dev#1.7.0-3 +libclaw-configuration-file-dev#1.7.0-3 +libclaw-dev#1.7.0-3 +libclaw-dynamic-library-dev#1.7.0-3 +libclaw-graphic-dev#1.7.0-3 +libclaw-logger-dev#1.7.0-3 +libclaw-net-dev#1.7.0-3 +libclaw-tween-dev#1.7.0-3 +libclaws-mail-dev#3.8.1-2 +libclhep-dev#2.1.2.3-1 +libcli-dev#1.9.6-1 +libclippoly-dev#0.11-3 +libclips-dev#6.24-3 +libcliquer-dev#1.21-1 +libcln-dev#1.3.2-1.2 +libcloog-isl-dev#0.17.0-3 +libcloog-ppl-dev#0.15.11-4 +libclthreads-dev#2.4.0-4 +libclucene-dev#0.9.21b-2+b1 +libclustalo-dev#1.1.0-1 +libcluster-glue-dev#1.0.9+hg2665-1 +libclutter-1.0-dev#1.10.8-2 +libclutter-cil-dev#1.0.0~alpha3~git20090817.r1.349dba6-8 +libclutter-gst-dev#1.5.4-1+build0 +libclutter-gtk-1.0-dev#1.2.0-2 +libclutter-imcontext-0.1-dev#0.1.4-3 +libcluttergesture-dev#0.0.2.1-7 +libclxclient-dev#3.6.1-6 +libcman-dev#3.0.12-3.2+deb7u2 +libcminpack-dev#1.2.2-1 +libcmis-dev#0.1.0-1+b1 +libcmor-dev#2.8.0-2+b1 +libcmph-dev#0.9-1 +libcneartree-dev#3.1.1-1 +libcnf-dev#4.0-2 +libcob1-dev#1.1-1 +libcogl-dev#1.10.2-7 +libcogl-pango-dev#1.10.2-7 +libcoin60-dev#3.1.3-2.2 +libcojets2-dev#20061220+dfsg3-2 +libcollectdclient-dev#5.1.0-3 +libcollection-dev#0.1.3-2 +libcolorblind-dev#0.0.1-1 +libcolord-dev#0.1.21-1 +libcolord-gtk-dev#0.1.21-1 +libcolorhug-dev#0.1.10-1 +libcomedi-dev#0.10.0-3 +libcommoncpp2-dev#1.8.1-5 +libcompfaceg1-dev#1:1.5.2-5 +libconcord-dev#0.24-1.1 +libconfdb-dev#1.4.2-3 +libconfig++-dev#1.4.8-5 +libconfig++8-dev#1.4.8-5 +libconfig-dev#1.4.8-5 +libconfig-file-ocaml-dev#1.1-1 +libconfig8-dev#1.4.8-5 +libconfuse-dev#2.7-4 +libcontactsdb-dev#0.5-8 +libcoq-ocaml-dev#8.3.pl4+dfsg-2 +libcore-ocaml-dev#107.01-5 +libcorelinux-dev#0.4.32-7.3 +libcoroipcc-dev#1.4.2-3 +libcoroipcs-dev#1.4.2-3 +libcorosync-dev#1.4.2-3 +libcos4-dev#4.1.6-2 +libcothreads-ocaml-dev#0.10-3+b3 +libcoyotl-dev#3.1.0-5 +libcpg-dev#1.4.2-3 +libcpl-dev#6.1.1-2 +libcppcutter-dev#1.1.7-1.2 +libcppunit-dev#1.12.1-4 +libcppunit-subunit-dev#0.0.8+bzr176-1 +libcpputest-dev#3.1-2 +libcpufreq-dev#008-1 +libcpuset-dev#1.0-3 +libcqrlib2-dev#1.1.2-1 +libcr-dev#0.8.5-2 +libcrack2-dev#2.8.19-3 +libcreal-ocaml-dev#0.7-6+b3 +libcrmcluster1-dev#1.1.7-1 +libcrmcommon2-dev#1.1.7-1 +libcroco3-dev#0.6.6-2 +libcry-ocaml-dev#0.2.2-1+b1 +libcryptgps-ocaml-dev#0.2.1-7+b3 +libcrypto++-dev#5.6.1-6 +libcryptokit-ocaml-dev#1.5-1 +libcryptsetup-dev#2:1.4.3-4 +libcryptui-dev#3.2.2-1 +libcrystalhd-dev#1:0.0~git20110715.fdd2f19-9 +libcsfml-dev#1.6-1 +libcsnd-dev#1:5.17.11~dfsg-3 +libcsoap-dev#1.1.0-17.1 +libcsound64-dev#1:5.17.11~dfsg-3 +libcsoundac-dev#1:5.17.11~dfsg-3 +libcsv-ocaml-dev#1.2.2-1+b1 +libctapimkt0-dev#1.0.1-1.1 +libctdb-dev#1.12+git20120201-4 +libctemplate-dev#2.2-3 +libctl-dev#3.1.0-5 +libctpl-dev#0.3.3.dfsg-2 +libcuba3-dev#3.0+20111124-2 +libcudf-dev#0.6.2-1 +libcudf-ocaml-dev#0.6.2-1 +libcue-dev#1.4.0-1 +libcunit1-dev#2.1-0.dfsg-10 +libcunit1-ncurses-dev#2.1-0.dfsg-10 +libcups2-dev#1.5.3-5+deb7u1 +libcupscgi1-dev#1.5.3-5+deb7u1 +libcupsdriver1-dev#1.5.3-5+deb7u1 +libcupsfilters-dev#1.0.18-2.1+deb7u1 +libcupsimage2-dev#1.5.3-5+deb7u1 +libcupsmime1-dev#1.5.3-5+deb7u1 +libcupsppdc1-dev#1.5.3-5+deb7u1 +libcupt2-dev#2.5.9 +libcurl-ocaml-dev#0.5.3-2+b1 +libcurl4-gnutls-dev#7.26.0-1+wheezy9 +libcurl4-nss-dev#7.26.0-1+wheezy9 +libcurl4-openssl-dev#7.26.0-1+wheezy9 +libcurses-ocaml-dev#1.0.3-2 +libcutter-dev#1.1.7-1.2 +libcv-dev#2.3.1-11 +libcvaux-dev#2.3.1-11 +libcvc3-dev#2.4.1-4 +libcvector2-dev#1.0.3-1 +libcvm1-dev#0.96-1+b1 +libcw3-dev#3.0.2-1 +libcwidget-dev#0.5.16-3.4 +libcwiid-dev#0.6.00+svn201-3+b1 +libcwnn-dev#1.1.1~a021+cvs20100325-6 +libcxgb3-dev#1.3.1-1 +libcxxtools-dev#2.1.1-1 +libdacs-dev#1.4.27b-2 +libdaemon-dev#0.14-2 +libdancer-xml0-dev#0.8.2.1-3 +libdap-dev#3.11.1-11 +libdapl-dev#2.0.19-1.1 +libdaq-dev#0.6.2-2 +libdar-dev#2.4.5.debian.1-1 +libdatrie-dev#0.2.5-3 +libdawgdic-dev#0.4.3-1 +libdb++-dev#5.1.6 +libdb-dev#5.1.6 +libdb-java-dev#5.1.6 +libdb-sql-dev#5.1.6 +libdb4o-cil-dev#8.0.184.15484+dfsg-2 +libdb5.1++-dev#5.1.29-5 +libdb5.1-dev#5.1.29-5 +libdb5.1-java-dev#5.1.29-5 +libdb5.1-sql-dev#5.1.29-5 +libdb5.1-stl-dev#5.1.29-5 +libdballe-dev#5.18-1 +libdballef-dev#5.18-1 +libdbaudiolib0-dev#0.9.8-6.2 +libdbi-dev#0.8.4-6 +libdbus-1-dev#1.6.8-1+deb7u1 +libdbus-c++-dev#0.9.0-6 +libdbus-glib-1-dev#0.100.2-1 +libdbus-glib1.0-cil-dev#0.5.0-4 +libdbus-ocaml-dev#0.29-1+b3 +libdbus1.0-cil-dev#0.7.0-5 +libdbusada0.2-dev#0.2-2 +libdbusmenu-glib-dev#0.6.2-1 +libdbusmenu-gtk-dev#0.6.2-1 +libdbusmenu-gtk3-dev#0.6.2-1 +libdbusmenu-jsonloader-dev#0.6.2-1 +libdbusmenu-qt-dev#0.9.0-1 +libdc-dev#0.3.24~svn3121-2 +libdc1394-22-dev#2.2.0-2 +libdca-dev#0.0.5-5 +libdcerpc-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcerpc-server-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcmtk2-dev#3.6.0-12 +libdconf-dbus-1-dev#0.12.1-3 +libdconf-dev#0.12.1-3 +libddccontrol-dev#0.4.2-10 +libdds-dev#2.1.2+ddd105-1 +libdebconf-kde-dev#0.2-2 +libdebconfclient0-dev#0.182 +libdebian-installer4-dev#0.87 +libdebug0-dev#0.4.4-1.1 +libdecodeqr-dev#0.9.3-6.2 +libdee-dev#1.0.10-3 +libderiving-ocaml-dev#0.1.1a-3+b1 +libderiving-ocsigen-ocaml-dev#0.3c-1 +libdesktop-agnostic-dev#0.3.92+dfsg-1 +libdessert0.87-dev#0.87.2-1 +libdevhelp-dev#3.4.1-1 +libdevil-dev#1.7.8-6.1+b1 +libdevmapper-dev#2:1.02.74-8 +libdhash-dev#0.1.3-2 +libdiagnostics-dev#0.3.3-1.3 +libdianewcanvas2-dev#0.6.10-5.4 +libdieharder-dev#3.31.1-4 +libdiet-admin2.8-dev#2.8.0-1+b1 +libdiet-client2.8-dev#2.8.0-1+b1 +libdiet-dagda2.8-dev#2.8.0-1+b1 +libdiet-sed2.8-dev#2.8.0-1+b1 +libdime-dev#0.20030921-2 +libdirac-dev#1.0.2-6 +libdirectfb-dev#1.2.10.0-5 +libdisasm-dev#0.23-5 +libdiscid0-dev#0.2.2-3 +libdiscover-dev#2.1.2-5.2 +libdispatch-dev#0~svn197-3.1 +libdisplaymigration0-dev#0.28-10 +libdistorm64-dev#1.7.30-1 +libdivecomputer-dev#0.1.0-3 +libdjconsole-dev#0.1.3-1 +libdjvulibre-dev#3.5.25.3-1 +libdkim-dev#1:1.0.21-3 +libdlm-dev#3.0.12-3.2+deb7u2 +libdlmcontrol-dev#3.0.12-3.2+deb7u2 +libdlrestrictions-dev#0.15.3 +libdm0-dev#2.2.10-1 +libdmalloc-dev#5.5.2-5 +libdmapsharing-3.0-dev#2.9.15-1 +libdmraid-dev#1.0.0.rc16-4.2 +libdmtcpaware-dev#1.2.5-1 +libdmtx-dev#0.7.2-2+build1 +libdmx-dev#1:1.1.2-1+deb7u1 +libdnet-dev#2.60 +libdockapp-dev#1:0.5.0-3 +libdolfin1.0-dev#1.0.0-7 +libdoodle-dev#0.7.0-5 +libdose2-ocaml-dev#1.4.2-4+b3 +libdose3-ocaml-dev#3.0.2-3 +libdotconf-dev#1.0.13-3 +libdpkg-dev#1.16.12 +libdpm-dev#1.8.2-1+b2 +libdrawtk-dev#2.0-2 +libdrizzle-dev#1:7.1.36-stable-1 +libdrizzledmessage-dev#1:7.1.36-stable-1 +libdrm-dev#2.4.40-1~deb7u2 +libdrumstick-dev#0.5.0-3 +libdsdp-dev#5.8-9.1 +libdshconfig1-dev#0.20.13-1 +libdspam7-dev#3.10.1+dfsg-11 +libdssi-ocaml-dev#0.1.0-1+b1 +libdssialsacompat-dev#1.0.8a-1 +libdtools-ocaml-dev#0.3.0-1 +libdts-dev#0.0.5-5 +libdumb1-dev#1:0.9.3-5.4 +libdumbnet-dev#1.12-3.1 +libdune-common-dev#2.2.0-1 +libdune-geometry-dev#2.2.0-1 +libdune-grid-dev#2.2.0-1 +libdune-istl-dev#2.2.0-1 +libdune-localfunctions-dev#2.2.0-1 +libduo-dev#1.8-1 +libduppy-ocaml-dev#0.4.2-1+b2 +libdv4-dev#1.0.0-6 +libdvb-dev#0.5.5.1-5.1 +libdvbcsa-dev#1.1.0-2 +libdvbpsi-dev#0.2.2-1 +libdvdnav-dev#4.2.0+20120524-2 +libdvdread-dev#4.2.0+20120521-2 +libdw-dev#0.152-1+wheezy1 +libdwarf-dev#20120410-2 +libdx4-dev#1:4.4.4-4+b2 +libdxflib-dev#2.2.0.0-8 +libdynamite-dev#0.1.1-2 +libeasy-format-ocaml-dev#1.0.0-1+b2 +libeb16-dev#4.4.3-6 +libebackend1.2-dev#3.4.4-3 +libebml-dev#1.2.2-2 +libebook1.2-dev#3.4.4-3 +libecal1.2-dev#3.4.4-3 +libecasoundc-dev#2.9.0-1 +libecasoundc2.2-dev#2.9.0-1 +libechonest-dev#1.2.1-1 +libecm-dev#6.4.2-1 +libecore-dev#1.2.0-2 +libecpg-dev#9.1.13-0wheezy1 +libecryptfs-dev#99-1 +libedac-dev#0.18-1 +libedata-book1.2-dev#3.4.4-3 +libedata-cal1.2-dev#3.4.4-3 +libedataserver1.2-dev#3.4.4-3 +libedataserverui-3.0-dev#3.4.4-3 +libedbus-dev#1.2.0-1 +libedit-dev#2.11-20080614-5 +libeditline-dev#1.12-6 +libedje-dev#1.2.0-1 +libee-dev#0.4.1-1 +libeegdev-dev#0.2-3 +libeet-dev#1.6.0-1 +libefreet-dev#1.2.0-1 +libegl1-mesa-dev#8.0.5-4+deb7u2 +libeigen2-dev#2.0.17-1 +libeigen3-dev#3.1.0-1 +libeina-dev#1.2.0-2 +libelektra-cpp-dev#0.7.1-1 +libelektra-dev#0.7.1-1 +libelektratools-dev#0.7.1-1 +libelemental-dev#1.2.0-8 +libelementary-dev#0.7.0.55225-1 +libelf-dev#0.152-1+wheezy1 +libelfg0-dev#0.8.13-3 +libeliom-ocaml-dev#2.2.2-1 +libelk0-dev#3.99.8-2 +libelmer-dev#6.1.0.svn.5396.dfsg2-2 +libembryo-dev#1.2.0-1 +libemos-dev#000382+dfsg-2 +libenca-dev#1.13-4 +libenchant-dev#1.6.0-7 +libenet-dev#1.3.3-2 +libepc-dev#0.4.4-1 +libepc-ui-dev#0.4.4-1 +libepr-api2-dev#2.2-2 +libepsilon-dev#0.9.1-2 +libept-dev#1.0.9 +libepub-dev#0.2.1-2+b1 +liberis-1.3-dev#1.3.19-5 +liberuby-dev#1.0.5-2.1 +libescpr-dev#1.1.1-2 +libesd0-dev#0.2.41-10+b1 +libesmtp-dev#1.0.6-1+b1 +libespeak-dev#1.46.02-2 +libestools2.1-dev#1:2.1~release-5 +libestr-dev#0.1.1-2 +libethos-dev#0.2.2-3 +libethos-ui-dev#0.2.2-3 +libetpan-dev#1.0-5 +libetsf-io-dev#1.0.3-4+b1 +libeurodec1-dev#20061220+dfsg3-2 +libev-dev#1:4.11-1 +libev-libevent-dev#1:4.11-1 +libeval0-dev#0.29.6-2 +libevas-dev#1.2.0-2 +libevd-0.1-dev#0.1.20-2 +libevent-dev#2.0.19-stable-3 +libeventdb-dev#0.90-5 +libevince-dev#3.4.0-3.1 +libevocosm-dev#4.0.2-2.1 +libevs-dev#1.4.2-3 +libevtlog-dev#0.2.12-5 +libewf-dev#20100226-1+b1 +libexchangemapi-1.0-dev#3.4.4-1 +libexempi-dev#2.2.0-1 +libexif-dev#0.6.20-3 +libexif-gtk-dev#0.3.5-5 +libexiv2-dev#0.23-1 +libexo-1-dev#0.6.2-5 +libexodusii-dev#5.14.dfsg.1-2+b1 +libexosip2-dev#3.6.0-4 +libexpat-ocaml-dev#0.9.1+debian1-7+b2 +libexpat1-dev#2.1.0-1+deb7u1 +libexpect-ocaml-dev#0.0.2-1+b6 +libexplain-dev#0.52.D002-1 +libextlib-ocaml-dev#1.5.2-1+b1 +libextractor-dev#1:0.6.3-5 +libextractor-java-dev#0.6.0-6 +libexttextcat-dev#3.2.0-2 +libextunix-ocaml-dev#0.0.5-2 +libeztrace-dev#0.7-2-4 +libf2c2-dev#20090411-2 +libfaad-dev#2.7-8 +libfaad-ocaml-dev#0.3.0-1+b1 +libfacile-ocaml-dev#1.1-8+b1 +libfaifa-dev#0.2~svn82-1 +libfakekey-dev#0.1-7 +libfam-dev#2.7.0-17 +libfann-dev#2.1.0~beta~dfsg-8 +libfarstream-0.1-dev#0.1.2-1 +libfastjet-dev#3.0.2+dfsg-2 +libfastjet-fortran-dev#3.0.2+dfsg-2 +libfastjetplugins-dev#3.0.2+dfsg-2 +libfastjettools-dev#3.0.2+dfsg-2 +libfauhdli-dev#20110812-1 +libfcgi-dev#2.4.0-8.1 +libfdt-dev#1.3.0-4 +libfence-dev#3.0.12-3.2+deb7u2 +libffado-dev#2.0.99+svn2171-2 +libffcall1-dev#1.10+cvs20100619-2 +libffi-dev#3.0.10-3 +libffindex0-dev#0.9.6.1-1 +libffmpegthumbnailer-dev#2.0.7-2 +libffms2-dev#2.17-1 +libfftw3-dev#3.3.2-3.1 +libfftw3-mpi-dev#3.3.2-3.1 +libfields-camlp4-dev#107.01-1+b2 +libfileutils-ocaml-dev#0.4.2-1+b2 +libfindlib-ocaml-dev#1.3.1-1 +libfiredns-dev#0.9.12+dfsg-3 +libfirestring-dev#0.9.12-8 +libfishsound1-dev#1.0.0-1.1 +libfiu-dev#0.90-3 +libfixposix-dev#20110316.git47f17f7-1 +libfko0-dev#2.0.0rc2-2+deb7u2 +libflac++-dev#1.2.1-6 +libflac-dev#1.2.1-6 +libflac-ocaml-dev#0.1.1-1 +libflake-dev#0.11-2 +libflann-dev#1.7.1-4 +libflatzebra-dev#0.1.5-4+b1 +libflickrnet-cil-dev#1:2.2.0-4 +libflorist2011-dev#2011-1 +libflowcanvas-dev#0.7.1+dfsg0-0.2 +libfltk1.1-dev#1.1.10-14 +libfltk1.3-dev#1.3.0-8 +libfluidsynth-dev#1.1.5-2 +libfm-dev#0.1.17-2.1 +libfolia1-dev#0.9-2 +libfolks-dev#0.6.9-1+b1 +libfolks-eds-dev#0.6.9-1+b1 +libfolks-telepathy-dev#0.6.9-1+b1 +libfontconfig1-dev#2.9.0-7.1 +libfontenc-dev#1:1.1.1-1 +libfontforge-dev#0.0.20120101+git-2 +libforms-dev#1.0.93sp1-2 +libformsgl-dev#1.0.93sp1-2 +libfox-1.6-dev#1.6.45-1 +libfprint-dev#1:0.4.0-4-gdfff16f-4 +libfreecell-solver-dev#3.12.0-1 +libfreefem++-dev#3.19.1-1 +libfreefem-dev#3.5.8-5 +libfreehdl0-dev#0.0.7-1.1 +libfreeimage-dev#3.15.1-1+b1 +libfreeipmi-dev#1.1.5-3 +libfreenect-dev#1:0.1.2+dfsg-6 +libfreeradius-dev#2.1.12+dfsg-1.2 +libfreerdp-dev#1.0.1-1.1+deb7u3 +libfreetype6-dev#2.4.9-1.1 +libfreexl-dev#1.0.0b-1 +libfribidi-dev#0.19.2-3 +libfs-dev#2:1.0.4-1+deb7u1 +libfso-glib-dev#2012.05.24.1-1.1 +libfsobasics-dev#0.11.0-1.1 +libfsoframework-dev#0.11.0-1.1 +libfsoresource-dev#0.11.0-1.1 +libfsosystem-dev#0.11.0-1 +libfsotransport-dev#0.11.1-2.1 +libfsplib-dev#0.11-2 +libfstrcmp-dev#0.4.D001-1+deb7u1 +libftdi-dev#0.20-1+b1 +libftdipp-dev#0.20-1+b1 +libftgl-dev#2.1.3~rc5-4 +libfuntools-dev#1.4.4-3 +libfuse-dev#2.9.0-2+deb7u1 +libfuzzy-dev#2.7-2 +libfxt-dev#0.2.6-2 +libg15-dev#1.2.7-2 +libg15daemon-client-dev#1.9.5.3-8.2 +libg15render-dev#1.3.0~svn316-2.2 +libg2-dev#0.72-2.1 +libg3d-dev#0.0.8-17 +libga-dev#2.4.7-3 +libgadap-dev#2.0-1 +libgadu-dev#1:1.11.2-1+deb7u1 +libgail-3-dev#3.4.2-7 +libgail-dev#2.24.10-2 +libgalax-ocaml-dev#1.1-10+b3 +libgambc4-dev#4.2.8-1.1 +libgamin-dev#0.1.10-4.1 +libgammu-dev#1.31.90-1+b1 +libganglia1-dev#3.3.8-1+nmu1 +libganv-dev#0~svn4468~dfsg0-1 +libgarcon-1-0-dev#0.1.12-1 +libgarmin-dev#0~svn320-3 +libgatos-dev#0.0.5-19 +libgavl-dev#1.4.0-1 +libgavl-ocaml-dev#0.1.4-1+b1 +libgbm-dev#8.0.5-4+deb7u2 +libgc-dev#1:7.1-9.1 +libgcal-dev#0.9.6-3 +libgccxml-dev#0.9.0+cvs20120420-4 +libgcgi-dev#0.9.5.dfsg-7 +libgcj12-dev#4.6.3-1 +libgcj13-dev#4.7.2-3 +libgck-1-dev#3.4.1-3 +libgconf-bridge-dev#0.1-2.2 +libgconf2-dev#3.2.5-1+build1 +libgconf2.0-cil-dev#2.24.2-3 +libgconfmm-2.6-dev#2.28.0-1 +libgcr-3-dev#3.4.1-3 +libgcroots-dev#0.8.5-2.1 +libgcrypt11-dev#1.5.0-5+deb7u1 +libgctp-dev#1.0-1 +libgd-gd2-noxpm-ocaml-dev#1.0~alpha5-5 +libgd2-noxpm-dev#2.0.36~rc1~dfsg-6.1 +libgd2-xpm-dev#2.0.36~rc1~dfsg-6.1 +libgda-5.0-dev#5.0.3-2 +libgdal-dev#1.9.0-3.1 +libgdal1-dev#1.9.0-3.1 +libgdata-cil-dev#2.1.0.0-1 +libgdata-dev#0.12.0-1 +libgdb-dev#7.4.1+dfsg-0.1 +libgdbm-dev#1.8.3-11 +libgdchart-gd2-noxpm-dev#0.11.5-7+b1 +libgdchart-gd2-xpm-dev#0.11.5-7+b1 +libgdcm2-dev#2.2.0-14.1 +libgdf-dev#0.1.2-2 +libgdict-1.0-dev#3.4.0-2 +libgdk-pixbuf2.0-dev#2.26.1-1 +libgdkcutter-pixbuf-dev#1.1.7-1.2 +libgdl-3-dev#3.4.2-1 +libgdome2-cpp-smart-dev#0.2.6-6+b1 +libgdome2-dev#0.8.1+debian-4.1 +libgdome2-ocaml-dev#0.2.6-6+b1 +libgdu-dev#3.0.2-3 +libgdu-gtk-dev#3.0.2-3 +libgeant321-2-dev#1:3.21.14.dfsg-10 +libgearman-dev#0.33-2 +libgecode-dev#3.7.3-1 +libgeda-dev#1:1.6.2-4.3 +libgee-dev#0.6.4-2 +libgegl-dev#0.2.0-2+nmu1 +libgeier-dev#0.13-1+b1 +libgenders0-dev#1.18-1 +libgenome-1.3-0-dev#1.3.1-3 +libgensec-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libgeoclue-dev#0.12.0-4 +libgeocode-glib-dev#0.99.0-1 +libgeographiclib-dev#1.21-1 +libgeoip-dev#1.4.8+dfsg-3 +libgeomview-dev#1.9.4-3 +libgeos++-dev#3.3.3-1.1 +libgeos-dev#3.3.3-1.1 +libgeotiff-dev#1.3.0+dfsg-3 +libgeotranz3-dev#3.1-2.1 +libges-0.10-dev#0.10.1-2 +libgetdata-dev#0.7.3-6 +libgetfem++-dev#4.1.1+dfsg1-11 +libgetopt++-dev#0.0.2-p22-3 +libgetopt-ocaml-dev#0.0.20040811-10+b3 +libgettext-ocaml-dev#0.3.4-1+b2 +libgexiv2-dev#0.4.1-3 +libgfarm-dev#2.4.1-1.1 +libgflags-dev#2.0-1 +libgfshare-dev#1.0.5-2 +libghc-acid-state-dev#0.6.3-1+b2 +libghc-active-dev#0.1.0.1-2+b2 +libghc-adjunctions-dev#2.4.0.2-1 +libghc-aeson-dev#0.6.0.2-1+b4 +libghc-agda-dev#2.3.0.1-2 +libghc-algebra-dev#2.1.1.2-1 +libghc-alut-dev#2.1.0.2-4+b1 +libghc-ami-dev#0.1-1+b5 +libghc-ansi-terminal-dev#0.5.5-3+b1 +libghc-ansi-wl-pprint-dev#0.6.4-1+b1 +libghc-arrows-dev#0.4.4.0-3+b1 +libghc-asn1-data-dev#0.6.1.3-2+b3 +libghc-attempt-dev#0.4.0-1+b2 +libghc-attoparsec-conduit-dev#0.4.0.1-1 +libghc-attoparsec-dev#0.10.1.1-2+b1 +libghc-attoparsec-enumerator-dev#0.3-3+b3 +libghc-augeas-dev#0.6.1-1 +libghc-authenticate-dev#1.2.1.1-2+b1 +libghc-base-unicode-symbols-dev#0.2.2.3-1+b1 +libghc-base16-bytestring-dev#0.1.1.4-2+b1 +libghc-base64-bytestring-dev#0.1.1.1-2 +libghc-bifunctors-dev#0.1.3.3-1+b1 +libghc-binary-shared-dev#0.8.1-1+b1 +libghc-bindings-dsl-dev#1.0.15-1+b1 +libghc-bindings-gpgme-dev#0.1.4-1 +libghc-bindings-libzip-dev#0.10-2 +libghc-bitarray-dev#0.0.1-2+b1 +libghc-blaze-builder-conduit-dev#0.4.0.2-1 +libghc-blaze-builder-dev#0.3.1.0-1+b2 +libghc-blaze-builder-enumerator-dev#0.2.0.4-1+b1 +libghc-blaze-html-dev#0.4.3.1-3+b2 +libghc-blaze-markup-dev#0.5.1.0-1 +libghc-blaze-textual-dev#0.2.0.6-2+b2 +libghc-bloomfilter-dev#1.2.6.8-1 +libghc-boolean-dev#0.0.1-2+b1 +libghc-boomerang-dev#1.3.1-1 +libghc-brainfuck-dev#0.1-2+b2 +libghc-byteorder-dev#1.0.3-2+b1 +libghc-bytestring-lexing-dev#0.4.0-1+b1 +libghc-bytestring-mmap-dev#0.2.2-2+b1 +libghc-bytestring-nums-dev#0.3.5-2+b1 +libghc-bytestring-show-dev#0.3.5.1-1+b1 +libghc-bzlib-dev#0.5.0.3-2+b1 +libghc-cabal-file-th-dev#0.2.2-1 +libghc-cairo-dev#0.12.3-1+b1 +libghc-case-insensitive-dev#0.4.0.1-2+b2 +libghc-categories-dev#1.0.3-1+b1 +libghc-cautious-file-dev#1.0.1-1 +libghc-cereal-conduit-dev#0.5-1+b1 +libghc-cereal-dev#0.3.5.2-1 +libghc-certificate-dev#1.2.3-2 +libghc-cgi-dev#3001.1.8.2-2+b3 +libghc-chart-dev#0.15-1+b2 +libghc-chell-dev#0.3-1 +libghc-citeproc-hs-dev#0.3.4-1+b4 +libghc-clientsession-dev#0.7.5-3+b1 +libghc-clock-dev#0.2.0.0-2+b1 +libghc-cmdargs-dev#0.9.5-1+b1 +libghc-colour-dev#2.3.3-1+b1 +libghc-comonad-dev#1.1.1.5-1+b1 +libghc-comonad-transformers-dev#2.1.1.1-1+b1 +libghc-comonads-fd-dev#2.1.1.2-1+b1 +libghc-conduit-dev#0.4.2-2 +libghc-configfile-dev#1.0.6-4+b3 +libghc-configurator-dev#0.2.0.0-1+b2 +libghc-contravariant-dev#0.2.0.2-1+b1 +libghc-convertible-dev#1.0.11.0-3+b3 +libghc-cookie-dev#0.4.0-1+b3 +libghc-cpphs-dev#1.13.3-2+b1 +libghc-cprng-aes-dev#0.2.3-3+b4 +libghc-cpu-dev#0.1.1-1 +libghc-criterion-dev#0.6.0.1-3+b4 +libghc-crypto-api-dev#0.10.2-1+b2 +libghc-crypto-conduit-dev#0.3.2-1+b1 +libghc-crypto-dev#4.2.4-1+b1 +libghc-crypto-pubkey-types-dev#0.1.1-1+b3 +libghc-cryptocipher-dev#0.3.5-1+b1 +libghc-cryptohash-dev#0.7.5-1+b2 +libghc-css-text-dev#0.1.1-3+b2 +libghc-csv-conduit-dev#0.2-1 +libghc-csv-dev#0.1.2-2+b3 +libghc-curl-dev#1.3.7-1+b1 +libghc-darcs-dev#2.8.1-1+b1 +libghc-data-accessor-dev#0.2.2.2-1+b1 +libghc-data-accessor-mtl-dev#0.2.0.3-1+b1 +libghc-data-accessor-template-dev#0.2.1.9-1+b2 +libghc-data-binary-ieee754-dev#0.4.2.1-3+b1 +libghc-data-default-dev#0.4.0-1 +libghc-data-inttrie-dev#0.0.7-1+b1 +libghc-data-lens-dev#2.10.0-1+b1 +libghc-data-memocombinators-dev#0.4.3-1+b1 +libghc-dataenc-dev#0.14.0.3-1+b1 +libghc-datetime-dev#0.2.1-3 +libghc-dbus-dev#0.10.3-1 +libghc-debian-dev#3.64-3 +libghc-diagrams-cairo-dev#0.5.0.2-1 +libghc-diagrams-core-dev#0.5.0.1-1+b1 +libghc-diagrams-dev#0.5-2 +libghc-diagrams-lib-dev#0.5-2 +libghc-diff-dev#0.1.3-1+b1 +libghc-digest-dev#0.0.1.0-1+b1 +libghc-dimensional-dev#0.10.1.2-2+b1 +libghc-directory-tree-dev#0.10.0-2+b1 +libghc-distributive-dev#0.2.2-1+b1 +libghc-dlist-dev#0.5-3+b1 +libghc-download-curl-dev#0.1.3-3+b3 +libghc-dpkg-dev#0.0.3-1 +libghc-dyre-dev#0.8.7-1 +libghc-edison-api-dev#1.2.1-18+b1 +libghc-edison-core-dev#1.2.1.3-9+b1 +libghc-edit-distance-dev#0.2.1-2 +libghc-editline-dev#0.2.1.0-5+b1 +libghc-ekg-dev#0.3.1.0-1+b2 +libghc-email-validate-dev#0.2.8-1+b3 +libghc-entropy-dev#0.2.1-2+b1 +libghc-enumerator-dev#0.4.19-1+b1 +libghc-erf-dev#2.0.0.0-2+b1 +libghc-event-list-dev#0.1.0.1-1+b1 +libghc-exception-transformers-dev#0.3.0.2-1+b1 +libghc-executable-path-dev#0.0.3-1+b1 +libghc-explicit-exception-dev#0.1.7-1+b1 +libghc-failure-dev#0.2.0.1-1+b1 +libghc-fast-logger-dev#0.0.2-1+b2 +libghc-fastcgi-dev#3001.0.2.3-3+b3 +libghc-fclabels-dev#1.1.3-1+b1 +libghc-feed-dev#0.3.8-3 +libghc-fgl-dev#5.4.2.4-2+b2 +libghc-file-embed-dev#0.0.4.4-1 +libghc-filemanip-dev#0.3.5.2-2+b2 +libghc-filestore-dev#0.5-1 +libghc-filesystem-conduit-dev#0.4.0-1 +libghc-free-dev#2.1.1.1-1+b1 +libghc-ftphs-dev#1.0.8-1+b3 +libghc-gconf-dev#0.12.1-1+b1 +libghc-gd-dev#3000.7.3-1 +libghc-ghc-events-dev#0.4.0.0-2+b1 +libghc-ghc-mtl-dev#1.0.1.1-1+b3 +libghc-ghc-paths-dev#0.1.0.8-2+b1 +libghc-ghc-syb-utils-dev#0.2.1.0-1+b3 +libghc-gio-dev#0.12.3-1+b1 +libghc-github-dev#0.4.0-2 +libghc-gitit-dev#0.10.0.1-1+b1 +libghc-glade-dev#0.12.1-1+b3 +libghc-glfw-dev#0.5.0.1-1+b1 +libghc-glib-dev#0.12.2-1+b1 +libghc-glut-dev#2.1.2.2-1 +libghc-gnuidn-dev#0.2-2+b2 +libghc-gnutls-dev#0.1.2-1+b1 +libghc-gsasl-dev#0.3.4-1+b1 +libghc-gstreamer-dev#0.12.1-1+b2 +libghc-gtk-dev#0.12.3-1+b2 +libghc-gtkglext-dev#0.12.1-1+b3 +libghc-gtksourceview2-dev#0.12.3-1+b3 +libghc-haddock-dev#2.10.0-1+b2 +libghc-hakyll-dev#3.2.7.2-1+b5 +libghc-hamlet-dev#1.0.1.3-1+b1 +libghc-happstack-dev#7.0.0-1+b1 +libghc-happstack-server-dev#7.0.1-1+b1 +libghc-harp-dev#0.4-3+b1 +libghc-hashable-dev#1.1.2.3-1+b2 +libghc-hashed-storage-dev#0.5.9-2+b2 +libghc-hashmap-dev#1.3.0.1-1+b2 +libghc-hashtables-dev#1.0.1.4-1+b1 +libghc-haskeline-dev#0.6.4.7-1+b1 +libghc-haskell-lexer-dev#1.0-3+b1 +libghc-haskell-src-dev#1.0.1.5-1+b2 +libghc-haskelldb-dev#2.1.1-5+b1 +libghc-haskelldb-hdbc-dev#2.1.0-4 +libghc-haskelldb-hdbc-odbc-dev#2.1.0-3 +libghc-haskelldb-hdbc-postgresql-dev#2.1.0-3 +libghc-haskelldb-hdbc-sqlite3-dev#2.1.0-3 +libghc-haskore-dev#0.2.0.3-2 +libghc-hastache-dev#0.3.3-2+b3 +libghc-haxml-dev#1:1.22.5-2+b2 +libghc-haxr-dev#3000.8.5-1+b3 +libghc-hcard-dev#0.0-2+b2 +libghc-hcwiid-dev#0.0.1-3+b1 +libghc-hdbc-dev#2.3.1.1-1+b3 +libghc-hdbc-odbc-dev#2.2.3.0-5+b3 +libghc-hdbc-postgresql-dev#2.3.2.1-1+b3 +libghc-hdbc-sqlite3-dev#2.3.3.0-1+b3 +libghc-hfuse-dev#0.2.4.1-1 +libghc-highlighting-kate-dev#0.5.1-1 +libghc-hinotify-dev#0.3.2-1+b1 +libghc-hint-dev#0.3.3.4-2+b4 +libghc-hipmunk-dev#5.2.0.8-1+b1 +libghc-hjavascript-dev#0.4.7-3+b1 +libghc-hjscript-dev#0.5.0-3+b2 +libghc-hjsmin-dev#0.1.1-1+b2 +libghc-hlint-dev#1.8.28-1+b3 +libghc-hoauth-dev#0.3.4-1+b1 +libghc-hostname-dev#1.0-4+b1 +libghc-hs-bibutils-dev#4.12-5+b2 +libghc-hs3-dev#0.5.6-2+b4 +libghc-hscolour-dev#1.19-3+b1 +libghc-hscurses-dev#1.4.1.0-1+b2 +libghc-hsemail-dev#1.7.1-2+b3 +libghc-hsh-dev#2.0.3-6+b3 +libghc-hslogger-dev#1.1.4+dfsg1-2+b3 +libghc-hsp-dev#0.6.1-2+b3 +libghc-hspec-dev#1.1.0-1+b1 +libghc-hsql-dev#1.8.1-4 +libghc-hsql-mysql-dev#1.8.1-4+b1 +libghc-hsql-odbc-dev#1.8.1.1-2 +libghc-hsql-postgresql-dev#1.8.1-3 +libghc-hsql-sqlite3-dev#1.8.1-2 +libghc-hssyck-dev#0.50-2+b2 +libghc-hstringtemplate-dev#0.6.8-1 +libghc-hsx-dev#0.9.1-3 +libghc-html-conduit-dev#0.0.1-2 +libghc-html-dev#1.0.1.2-5+b1 +libghc-http-conduit-dev#1.4.1.6-3 +libghc-http-date-dev#0.0.2-1+b2 +libghc-http-dev#1:4000.2.3-1+b2 +libghc-http-types-dev#0.6.11-1 +libghc-hunit-dev#1.2.4.2-2+b1 +libghc-hxt-cache-dev#9.0.2-2+b3 +libghc-hxt-charproperties-dev#9.1.1-2+b1 +libghc-hxt-curl-dev#9.1.1-1+b4 +libghc-hxt-dev#9.2.2-2+b3 +libghc-hxt-http-dev#9.1.4-2+b3 +libghc-hxt-regex-xmlschema-dev#9.0.4-2+b3 +libghc-hxt-relaxng-dev#9.1.4-1+b3 +libghc-hxt-tagsoup-dev#9.1.1-1+b4 +libghc-hxt-unicode-dev#9.0.2-2+b1 +libghc-hxt-xpath-dev#9.1.2-1+b4 +libghc-hxt-xslt-dev#9.1.1-1+b3 +libghc-iconv-dev#0.4.1.0-2+b1 +libghc-ieee754-dev#0.7.3-1+b1 +libghc-ifelse-dev#0.85-4+b1 +libghc-io-choice-dev#0.0.1-1+b3 +libghc-io-storage-dev#0.3-2+b1 +libghc-iospec-dev#0.2.5-1+b2 +libghc-irc-dev#0.5.0.0-1+b3 +libghc-iteratee-dev#0.8.8.2-2+b1 +libghc-ixset-dev#1.0.3-2+b1 +libghc-json-dev#0.5-2+b2 +libghc-keys-dev#2.1.3.2-1+b1 +libghc-knob-dev#0.1.1-1 +libghc-lambdabot-utils-dev#4.2.1-3+b3 +libghc-language-c-dev#0.4.2-2+b2 +libghc-language-haskell-extract-dev#0.2.1-4+b1 +libghc-language-javascript-dev#0.5.4-1+b2 +libghc-largeword-dev#1.0.1-2+b1 +libghc-lazysmallcheck-dev#0.6-1+b1 +libghc-ldap-dev#0.6.6-4.1+b1 +libghc-leksah-server-dev#0.12.0.4-3 +libghc-libtagc-dev#0.12.0-2+b1 +libghc-libxml-sax-dev#0.7.2-2+b1 +libghc-libzip-dev#0.10-1+b2 +libghc-lifted-base-dev#0.1.1-1+b1 +libghc-listlike-dev#3.1.4-1+b1 +libghc-llvm-base-dev#3.0.1.0-1 +libghc-llvm-dev#3.0.1.0-1+b1 +libghc-logict-dev#0.5.0.1-1+b1 +libghc-ltk-dev#0.12.0.0-2+b1 +libghc-maccatcher-dev#2.1.5-2+b3 +libghc-magic-dev#1.0.8-8+b1 +libghc-markov-chain-dev#0.0.3.2-1+b1 +libghc-math-functions-dev#0.1.1.0-2+b2 +libghc-maths-dev#0.4.3-1+b1 +libghc-maybet-dev#0.1.2-3+b2 +libghc-mbox-dev#0.1-2+b1 +libghc-memotrie-dev#0.5-1 +libghc-mersenne-random-dev#1.0.0.1-2+b1 +libghc-midi-dev#0.2.0.1-1+b1 +libghc-mime-mail-dev#0.4.1.1-2+b3 +libghc-missingh-dev#1.1.0.3-6+b3 +libghc-mmap-dev#0.5.7-2+b1 +libghc-monad-control-dev#0.3.1.3-1+b1 +libghc-monad-loops-dev#0.3.2.0-1 +libghc-monad-par-dev#0.1.0.3-2+b1 +libghc-monadcatchio-mtl-dev#0.3.0.4-2+b2 +libghc-monadcatchio-transformers-dev#0.3.0.0-2+b1 +libghc-monadcryptorandom-dev#0.4.1-1+b2 +libghc-monadrandom-dev#0.1.6-2+b2 +libghc-monads-tf-dev#0.1.0.0-1+b2 +libghc-monoid-transformer-dev#0.0.2-3+b1 +libghc-mtl-dev#2.1.1-1 +libghc-mtlparse-dev#0.1.2-2+b2 +libghc-murmur-hash-dev#0.1.0.5-2+b1 +libghc-mwc-random-dev#0.11.0.0-4+b1 +libghc-ncurses-dev#0.2.1-1+b1 +libghc-netwire-dev#3.1.0-2+b5 +libghc-network-conduit-dev#0.4.0.1-2 +libghc-network-dev#2.3.0.13-1+b2 +libghc-network-protocol-xmpp-dev#0.4.3-1 +libghc-newtype-dev#0.2-1 +libghc-non-negative-dev#0.1-2+b1 +libghc-numbers-dev#2009.8.9-2+b1 +libghc-numeric-quest-dev#0.2-1+b1 +libghc-numinstances-dev#1.0-2+b1 +libghc-numtype-dev#1.0-2+b1 +libghc-oeis-dev#0.3.1-2+b3 +libghc-openal-dev#1.3.1.3-4+b1 +libghc-opengl-dev#2.2.3.1-1+b1 +libghc-openpgp-asciiarmor-dev#0.1-1+b2 +libghc-options-dev#0.1.1-1 +libghc-pandoc-dev#1.9.4.2-2 +libghc-pandoc-types-dev#1.9.1-1+b2 +libghc-pango-dev#0.12.2-1+b2 +libghc-parallel-dev#3.2.0.2-2+b1 +libghc-parseargs-dev#0.1.3.2-2+b1 +libghc-parsec2-dev#2.1.0.1-6+b1 +libghc-parsec3-dev#3.1.2-1+b3 +libghc-pastis-dev#0.1.2-2+b3 +libghc-path-pieces-dev#0.1.0-1+b2 +libghc-patience-dev#0.1.1-1 +libghc-pcre-light-dev#0.4-3+b1 +libghc-pem-dev#0.1.1-1+b3 +libghc-persistent-dev#0.9.0.4-2 +libghc-persistent-sqlite-dev#0.9.0.2-2 +libghc-persistent-template-dev#0.9.0.2-1 +libghc-polyparse-dev#1.7-1+b2 +libghc-pool-conduit-dev#0.1.0.2-1 +libghc-postgresql-libpq-dev#0.8.2-1 +libghc-postgresql-simple-dev#0.1.4.3-1 +libghc-pretty-show-dev#1.1.1-4+b1 +libghc-primes-dev#0.2.1.0-2+b1 +libghc-primitive-dev#0.4.1-1+b1 +libghc-psqueue-dev#1.1-2+b1 +libghc-puremd5-dev#2.1.0.3-2+b4 +libghc-pwstore-fast-dev#2.2-2+b4 +libghc-quickcheck1-dev#1.2.0.1-2+b1 +libghc-quickcheck2-dev#2.4.2-1+b1 +libghc-random-dev#1.0.1.1-1+b1 +libghc-random-shuffle-dev#0.0.3-2+b2 +libghc-ranged-sets-dev#0.3.0-2+b1 +libghc-ranges-dev#0.2.4-2+b1 +libghc-reactive-banana-dev#0.6.0.0-1+b3 +libghc-readline-dev#1.0.1.0-3+b1 +libghc-recaptcha-dev#0.1-4+b3 +libghc-regex-base-dev#0.93.2-2+b2 +libghc-regex-compat-dev#0.95.1-2+b1 +libghc-regex-pcre-dev#0.94.2-2+b1 +libghc-regex-posix-dev#0.95.1-2+b1 +libghc-regex-tdfa-dev#1.1.8-2+b1 +libghc-regex-tdfa-utf8-dev#1.0-5+b3 +libghc-regexpr-dev#0.5.4-2+b2 +libghc-representable-functors-dev#2.4.0.2-1+b1 +libghc-representable-tries-dev#2.4.0.2-1 +libghc-resource-pool-dev#0.2.1.0-2+b4 +libghc-resourcet-dev#0.3.2.1-1+b1 +libghc-rsa-dev#1.2.1.0-1+b1 +libghc-safe-dev#0.3.3-1+b1 +libghc-safecopy-dev#0.6.1-1+b1 +libghc-sdl-dev#0.6.3-1+b1 +libghc-sdl-gfx-dev#0.6.0-3+b1 +libghc-sdl-image-dev#0.6.1-3+b1 +libghc-sdl-mixer-dev#0.6.1-3+b1 +libghc-sdl-ttf-dev#0.6.1-3+b1 +libghc-semigroupoids-dev#1.3.1.2-1+b1 +libghc-semigroups-dev#0.8.3.2-1 +libghc-sendfile-dev#0.7.6-1+b2 +libghc-sha-dev#1.5.0.1-1 +libghc-shakespeare-css-dev#1.0.1.2-1+b1 +libghc-shakespeare-dev#1.0.0.2-1+b1 +libghc-shakespeare-i18n-dev#1.0.0.2-1+b1 +libghc-shakespeare-js-dev#1.0.0.2-1+b1 +libghc-shakespeare-text-dev#1.0.0.2-1+b1 +libghc-shellac-dev#0.9.5.1-2+b2 +libghc-show-dev#0.4.1.2-1+b2 +libghc-silently-dev#1.1.4-1+b2 +libghc-simple-sendfile-dev#0.2.3-1+b2 +libghc-simpleea-dev#0.1.1-2+b2 +libghc-simpleirc-dev#0.2.1-2+b3 +libghc-skein-dev#0.1.0.7-2+b1 +libghc-smallcheck-dev#0.6-1+b1 +libghc-smtpclient-dev#1.0.4-3+b3 +libghc-snap-core-dev#0.8.1-1+b4 +libghc-snap-server-dev#0.8.1.1-1 +libghc-socks-dev#0.4.1-1+b4 +libghc-split-dev#0.1.4.2-2 +libghc-src-exts-dev#1.11.1-3+b1 +libghc-statevar-dev#1.0.0.0-2+b1 +libghc-static-hash-dev#0.0.1-3+b2 +libghc-statistics-dev#0.10.1.0-2+b1 +libghc-stm-dev#2.3-1 +libghc-stream-dev#0.4.6-1+b1 +libghc-strict-concurrency-dev#0.2.4.1-2+b1 +libghc-strict-dev#0.3.2-2+b1 +libghc-strptime-dev#1.0.6-1 +libghc-svgcairo-dev#0.12.1-1+b2 +libghc-syb-dev#0.3.6.1-1 +libghc-syb-with-class-dev#0.6.1.3-1+b1 +libghc-syb-with-class-instances-text-dev#0.0.1-3+b2 +libghc-system-fileio-dev#0.3.8-1 +libghc-system-filepath-dev#0.4.6-1+b2 +libghc-tagged-dev#0.4.2.1-1 +libghc-tagsoup-dev#0.12.6-1+b3 +libghc-tagstream-conduit-dev#0.3.2-1 +libghc-tar-dev#0.3.2.0-2+b1 +libghc-template-dev#0.2.0.7-1+b1 +libghc-temporary-dev#1.1.2.3-1+b1 +libghc-terminfo-dev#0.3.2.3-1+b1 +libghc-test-framework-dev#0.6-1+b1 +libghc-test-framework-hunit-dev#0.2.7-1+b3 +libghc-test-framework-quickcheck2-dev#0.2.12.1-1+b1 +libghc-test-framework-th-dev#0.2.2-5 +libghc-test-framework-th-prime-dev#0.0.5-1 +libghc-testpack-dev#2.1.1-1+b2 +libghc-texmath-dev#0.6.0.6-1+b2 +libghc-text-dev#0.11.2.0-1 +libghc-text-icu-dev#0.6.3.4-2+b2 +libghc-tinyurl-dev#0.1.0-2+b3 +libghc-tls-dev#0.9.5-1+b4 +libghc-tls-extra-dev#0.4.6.1-2 +libghc-tokyocabinet-dev#0.0.5-5+b3 +libghc-transformers-base-dev#0.4.1-2+b2 +libghc-transformers-dev#0.3.0.0-1 +libghc-type-level-dev#0.2.4-5 +libghc-uniplate-dev#1.6.7-1+b2 +libghc-unix-bytestring-dev#0.3.5-2+b1 +libghc-unix-compat-dev#0.3.0.1-1+b1 +libghc-unixutils-dev#1.50-1+b1 +libghc-unlambda-dev#0.1-2+b2 +libghc-unordered-containers-dev#0.2.1.0-1 +libghc-uri-dev#0.1.6-1+b2 +libghc-url-dev#2.1.2-4+b1 +libghc-utf8-light-dev#0.4.0.1-2+b1 +libghc-utf8-string-dev#0.3.7-1+b1 +libghc-utility-ht-dev#0.0.5.1-3+b1 +libghc-uuagc-cabal-dev#1.0.2.0-1+b1 +libghc-uuid-dev#1.2.3-2+b4 +libghc-uulib-dev#0.9.14-2 +libghc-vault-dev#0.2.0.0-1+b2 +libghc-vector-algorithms-dev#0.5.4-1+b2 +libghc-vector-dev#0.9.1-2+b1 +libghc-vector-space-dev#0.8.1-1 +libghc-vector-space-points-dev#0.1.1.0-1+b1 +libghc-void-dev#0.5.5.1-2+b1 +libghc-vte-dev#0.12.1-1+b3 +libghc-vty-dev#4.7.0.14-1+b1 +libghc-wai-app-file-cgi-dev#0.5.8-1+b4 +libghc-wai-app-static-dev#1.2.0.3-1+b3 +libghc-wai-dev#1.2.0.2-1+b2 +libghc-wai-extra-dev#1.2.0.4-1 +libghc-wai-logger-dev#0.1.4-1+b6 +libghc-wai-logger-prefork-dev#0.1.3-1+b6 +libghc-wai-test-dev#1.2.0.2-1 +libghc-warp-dev#1.2.1.1-1 +libghc-warp-tls-dev#1.2.0.4-1+b4 +libghc-web-routes-dev#0.25.3-2+b3 +libghc-webkit-dev#0.12.3-2+b1 +libghc-weighted-regexp-dev#0.3.1.1-2+b1 +libghc-x11-dev#1.5.0.1-1+b2 +libghc-x11-xft-dev#0.3.1-1+b3 +libghc-xdg-basedir-dev#0.2.1-2+b1 +libghc-xhtml-dev#3000.2.1-1 +libghc-xml-conduit-dev#0.7.0.2-1 +libghc-xml-dev#1.3.12-1+b2 +libghc-xml-types-dev#0.3.1-2+b2 +libghc-xml2html-dev#0.1.2.3-1 +libghc-xmonad-contrib-dev#0.10-4~deb7u1 +libghc-xmonad-dev#0.10-4+b2 +libghc-xss-sanitize-dev#0.3.2-1+b1 +libghc-yaml-dev#0.7.0.2-1+b2 +libghc-yaml-light-dev#0.1.4-2+b2 +libghc-yesod-auth-dev#1.0.2.1-2+b2 +libghc-yesod-core-dev#1.0.1.2-1+b3 +libghc-yesod-default-dev#1.0.1.1-1+b1 +libghc-yesod-dev#1.0.1.6-2+b3 +libghc-yesod-form-dev#1.0.0.4-1+b1 +libghc-yesod-json-dev#1.0.0.1-1+b3 +libghc-yesod-markdown-dev#0.4.0-1+b3 +libghc-yesod-persistent-dev#1.0.0.1-1+b1 +libghc-yesod-routes-dev#1.0.1.2-1 +libghc-yesod-static-dev#1.0.0.2-1+b3 +libghc-yesod-test-dev#0.2.0.6-1 +libghc-zip-archive-dev#0.1.1.7-3+b2 +libghc-zlib-bindings-dev#0.1.0.1-1 +libghc-zlib-conduit-dev#0.4.0.1-1 +libghc-zlib-dev#0.5.3.3-1+b1 +libghc-zlib-enum-dev#0.2.2.1-1+b1 +libghc6-agda-dev#1:8 +libghc6-alut-dev#1:8 +libghc6-arrows-dev#1:8 +libghc6-binary-dev#1:8 +libghc6-binary-shared-dev#1:8 +libghc6-bzlib-dev#1:8 +libghc6-cairo-dev#1:8 +libghc6-cautious-file-dev#1:8 +libghc6-cgi-dev#1:8 +libghc6-colour-dev#1:8 +libghc6-configfile-dev#1:8 +libghc6-convertible-dev#1:8 +libghc6-cpphs-dev#1:8 +libghc6-criterion-dev#1:8 +libghc6-csv-dev#1:8 +libghc6-curl-dev#1:8 +libghc6-data-accessor-dev#1:8 +libghc6-dataenc-dev#1:8 +libghc6-datetime-dev#1:8 +libghc6-debian-dev#1:8 +libghc6-deepseq-dev#1:8 +libghc6-diagrams-dev#1:8 +libghc6-diff-dev#1:8 +libghc6-digest-dev#1:8 +libghc6-edison-api-dev#1:8 +libghc6-edison-core-dev#1:8 +libghc6-editline-dev#1:8 +libghc6-erf-dev#1:8 +libghc6-event-list-dev#1:8 +libghc6-explicit-exception-dev#1:8 +libghc6-fastcgi-dev#1:8 +libghc6-feed-dev#1:8 +libghc6-fgl-dev#1:8 +libghc6-filemanip-dev#1:8 +libghc6-filestore-dev#1:8 +libghc6-ftphs-dev#1:8 +libghc6-gconf-dev#1:8 +libghc6-ghc-events-dev#1:8 +libghc6-ghc-mtl-dev#1:8 +libghc6-ghc-paths-dev#1:8 +libghc6-gio-dev#1:8 +libghc6-gitit-dev#1:8 +libghc6-glade-dev#1:8 +libghc6-glfw-dev#1:8 +libghc6-glib-dev#1:8 +libghc6-glut-dev#1:8 +libghc6-gstreamer-dev#1:8 +libghc6-gtk-dev#1:8 +libghc6-gtkglext-dev#1:8 +libghc6-gtksourceview2-dev#1:8 +libghc6-haddock-dev#1:8 +libghc6-happstack-dev#1:8 +libghc6-happstack-server-dev#1:8 +libghc6-harp-dev#1:8 +libghc6-hashed-storage-dev#1:8 +libghc6-haskeline-dev#1:8 +libghc6-haskell-lexer-dev#1:8 +libghc6-haskell-src-dev#1:8 +libghc6-haskelldb-dev#1:8 +libghc6-haskelldb-hdbc-dev#1:8 +libghc6-haskelldb-hdbc-odbc-dev#1:8 +libghc6-haskelldb-hdbc-postgresql-dev#1:8 +libghc6-haskelldb-hdbc-sqlite3-dev#1:8 +libghc6-haskore-dev#1:8 +libghc6-haxml-dev#1:8 +libghc6-haxr-dev#1:8 +libghc6-hdbc-dev#1:8 +libghc6-hdbc-odbc-dev#1:8 +libghc6-hdbc-postgresql-dev#1:8 +libghc6-hdbc-sqlite3-dev#1:8 +libghc6-highlighting-kate-dev#1:8 +libghc6-hint-dev#1:8 +libghc6-hjavascript-dev#1:8 +libghc6-hjscript-dev#1:8 +libghc6-hoauth-dev#1:8 +libghc6-hscolour-dev#1:8 +libghc6-hscurses-dev#1:8 +libghc6-hsemail-dev#1:8 +libghc6-hsh-dev#1:8 +libghc6-hslogger-dev#1:8 +libghc6-hsp-dev#1:8 +libghc6-hsql-dev#1:8 +libghc6-hsql-mysql-dev#1:8 +libghc6-hsql-odbc-dev#1:8 +libghc6-hsql-postgresql-dev#1:8 +libghc6-hsql-sqlite3-dev#1:8 +libghc6-hstringtemplate-dev#1:8 +libghc6-hsx-dev#1:8 +libghc6-html-dev#1:8 +libghc6-http-dev#1:8 +libghc6-hunit-dev#1:8 +libghc6-hxt-dev#1:8 +libghc6-ifelse-dev#1:8 +libghc6-irc-dev#1:8 +libghc6-json-dev#1:8 +libghc6-language-c-dev#1:8 +libghc6-lazysmallcheck-dev#1:8 +libghc6-ldap-dev#1:8 +libghc6-leksah-server-dev#1:8 +libghc6-llvm-dev#1:8 +libghc6-ltk-dev#1:8 +libghc6-magic-dev#1:8 +libghc6-markov-chain-dev#1:8 +libghc6-maybet-dev#1:8 +libghc6-midi-dev#1:8 +libghc6-missingh-dev#1:8 +libghc6-mmap-dev#1:8 +libghc6-monadcatchio-mtl-dev#1:8 +libghc6-monoid-transformer-dev#1:8 +libghc6-mtl-dev#1:8 +libghc6-mwc-random-dev#1:8 +libghc6-network-dev#1:8 +libghc6-non-negative-dev#1:8 +libghc6-openal-dev#1:8 +libghc6-opengl-dev#1:8 +libghc6-pandoc-dev#1:8 +libghc6-pango-dev#1:8 +libghc6-parallel-dev#1:8 +libghc6-parsec2-dev#1:8 +libghc6-parsec3-dev#1:8 +libghc6-pcre-light-dev#1:8 +libghc6-polyparse-dev#1:8 +libghc6-pretty-show-dev#1:8 +libghc6-primitive-dev#1:8 +libghc6-quickcheck1-dev#1:8 +libghc6-quickcheck2-dev#1:8 +libghc6-recaptcha-dev#1:8 +libghc6-regex-base-dev#1:8 +libghc6-regex-compat-dev#1:8 +libghc6-regex-posix-dev#1:8 +libghc6-regex-tdfa-dev#1:8 +libghc6-regex-tdfa-utf8-dev#1:8 +libghc6-safe-dev#1:8 +libghc6-sdl-dev#1:8 +libghc6-sdl-gfx-dev#1:8 +libghc6-sdl-image-dev#1:8 +libghc6-sdl-mixer-dev#1:8 +libghc6-sdl-ttf-dev#1:8 +libghc6-sendfile-dev#1:8 +libghc6-sha-dev#1:8 +libghc6-smtpclient-dev#1:8 +libghc6-split-dev#1:8 +libghc6-src-exts-dev#1:8 +libghc6-statistics-dev#1:8 +libghc6-stm-dev#1:8 +libghc6-stream-dev#1:8 +libghc6-strict-concurrency-dev#1:8 +libghc6-svgcairo-dev#1:8 +libghc6-syb-with-class-dev#1:8 +libghc6-syb-with-class-instances-text-dev#1:8 +libghc6-tagsoup-dev#1:8 +libghc6-tar-dev#1:8 +libghc6-terminfo-dev#1:8 +libghc6-testpack-dev#1:8 +libghc6-texmath-dev#1:8 +libghc6-text-dev#1:8 +libghc6-tokyocabinet-dev#1:8 +libghc6-transformers-dev#1:8 +libghc6-type-level-dev#1:8 +libghc6-uniplate-dev#1:8 +libghc6-unix-compat-dev#1:8 +libghc6-unixutils-dev#1:8 +libghc6-url-dev#1:8 +libghc6-utility-ht-dev#1:8 +libghc6-uulib-dev#1:8 +libghc6-vector-algorithms-dev#1:8 +libghc6-vector-dev#1:8 +libghc6-vte-dev#1:8 +libghc6-vty-dev#1:8 +libghc6-webkit-dev#1:8 +libghc6-x11-dev#1:8 +libghc6-x11-xft-dev#1:8 +libghc6-xhtml-dev#1:8 +libghc6-xml-dev#1:8 +libghc6-xmonad-contrib-dev#1:8 +libghc6-xmonad-dev#1:8 +libghc6-zip-archive-dev#1:8 +libghc6-zlib-dev#1:8 +libghemical-dev#3.0.0-2 +libgif-dev#4.1.6-10 +libgiftiio-dev#1.0.9-1 +libgig-dev#3.3.0-2 +libgii1-dev#1:1.0.2-4.1 +libgimp2.0-dev#2.8.2-2+deb7u1 +libginac-dev#1.6.2-1 +libginspx-dev#20050529-3.1 +libgio2.0-cil-dev#2.22.3-2 +libgirara-dev#0.1.2-3 +libgirepository1.0-dev#1.32.1-1 +libgjs-dev#1.32.0-5 +libgkeyfile-cil-dev#0.1-4 +libgksu2-dev#2.0.13~pre1-6 +libgl1-mesa-dev#8.0.5-4+deb7u2 +libgl1-mesa-swx11-dev#8.0.5-4+deb7u2 +libgl2ps-dev#1.3.6-1 +libglade2-dev#1:2.6.4-1 +libglade2.0-cil-dev#2.12.10-5 +libglademm-2.4-dev#2.6.7-2 +libgladeui-1-dev#3.6.7-2.1 +libgladeui-dev#3.12.1-1 +libglbsp-dev#2.24-1 +libglc-dev#0.7.2-5+b1 +libgle3-dev#3.1.0-7 +libgles1-mesa-dev#8.0.5-4+deb7u2 +libgles2-mesa-dev#8.0.5-4+deb7u2 +libglew-dev#1.7.0-3 +libglewmx-dev#1.7.0-3 +libglfw-dev#2.7.2-1 +libglib2.0-cil-dev#2.12.10-5 +libglib2.0-dev#2.33.12+really2.32.4-5 +libglibmm-2.4-dev#2.32.1-1 +libglide2-dev#2002.04.10ds1-7 +libglide3-dev#2002.04.10ds1-7 +libglm-dev#0.9.3.3+dfsg-0.1 +libglobus-authz-callout-error-dev#2.2-1 +libglobus-authz-dev#2.2-1 +libglobus-callout-dev#2.2-1 +libglobus-common-dev#14.7-2 +libglobus-ftp-client-dev#7.3-1 +libglobus-ftp-control-dev#4.4-1 +libglobus-gass-cache-dev#8.1-2 +libglobus-gass-copy-dev#8.4-1 +libglobus-gass-server-ez-dev#4.3-1 +libglobus-gass-transfer-dev#7.2-1 +libglobus-gfork-dev#3.2-1 +libglobus-gram-client-dev#12.4-1 +libglobus-gram-job-manager-callout-error-dev#2.1-2 +libglobus-gram-protocol-dev#11.3-1 +libglobus-gridftp-server-control-dev#2.5-2 +libglobus-gridftp-server-dev#6.10-2 +libglobus-gridmap-callout-error-dev#1.2-2 +libglobus-gsi-callback-dev#4.2-1 +libglobus-gsi-cert-utils-dev#8.3-1 +libglobus-gsi-credential-dev#5.3-1 +libglobus-gsi-openssl-error-dev#2.1-2 +libglobus-gsi-proxy-core-dev#6.2-1 +libglobus-gsi-proxy-ssl-dev#4.1-2 +libglobus-gsi-sysconfig-dev#5.2-1 +libglobus-gss-assist-dev#8.5-1 +libglobus-gssapi-error-dev#4.1-2 +libglobus-gssapi-gsi-dev#10.6-1 +libglobus-io-dev#9.3-1 +libglobus-openssl-module-dev#3.2-1 +libglobus-rls-client-dev#5.2-8 +libglobus-rsl-dev#9.1-2 +libglobus-scheduler-event-generator-dev#4.6-1 +libglobus-usage-dev#3.1-2 +libglobus-xio-dev#3.3-1 +libglobus-xio-gsi-driver-dev#2.3-1 +libglobus-xio-pipe-driver-dev#2.2-1 +libglobus-xio-popen-driver-dev#2.3-1 +libgloox-dev#1.0-1.1 +libglpk-dev#4.45-1 +libglrr-glib-dev#20050529-3.1 +libglrr-gobject-dev#20050529-3.1 +libglrr-gtk-dev#20050529-3.1 +libglrr-widgets-dev#20050529-3.1 +libglu1-mesa-dev#8.0.5-4+deb7u2 +libglui-dev#2.36-4 +libglw1-mesa-dev#8.0.0-1 +libgme-dev#0.5.5-2 +libgmerlin-avdec-dev#1.2.0~dfsg-1+b1 +libgmerlin-dev#1.2.0~dfsg+1-1 +libgmime-2.6-dev#2.6.10-1 +libgmime2.6-cil-dev#2.6.10-1 +libgmlib-dev#1.0.6-1 +libgmm++-dev#4.1.1+dfsg1-11 +libgmp-dev#2:5.0.5+dfsg-2 +libgmp-ocaml-dev#20021123-17+b3 +libgmp3-dev#2:5.0.5+dfsg-2 +libgmpada3-dev#0.0.20120331-1 +libgmt-dev#4.5.7-2 +libgmtk-dev#1.0.6-1 +libgnadecommon2-dev#1.6.2-9 +libgnadeodbc2-dev#1.6.2-9 +libgnadesqlite3-2-dev#1.6.2-9 +libgnatprj4.6-dev#4.6.3-8 +libgnatvsn4.6-dev#4.6.3-8 +libgnelib-dev#0.75+svn20091130-1+b1 +libgnet-dev#2.0.8-2.2 +libgnokii-dev#0.6.30+dfsg-1+b1 +libgnome-bluetooth-dev#3.4.2-1 +libgnome-desktop-3-dev#3.4.2-1 +libgnome-desktop-dev#2.32.1-2 +libgnome-keyring-dev#3.4.1-1 +libgnome-keyring1.0-cil-dev#1.0.0-4 +libgnome-mag-dev#1:0.16.3-1 +libgnome-media-profiles-dev#3.0.0-1 +libgnome-menu-3-dev#3.4.2-5 +libgnome-menu-dev#3.0.1-4 +libgnome-speech-dev#1:0.4.25-5 +libgnome-vfs2.0-cil-dev#2.24.2-3 +libgnome-vfsmm-2.6-dev#2.26.0-1 +libgnome2-dev#2.32.1-3 +libgnome2.0-cil-dev#2.24.2-3 +libgnomeada2.24.1-dev#2.24.1-7 +libgnomecanvas2-dev#2.30.3-1.2 +libgnomecanvasmm-2.6-dev#2.26.0-1 +libgnomecups1.0-dev#0.2.3-5 +libgnomedesktop2.0-cil-dev#2.26.0-8 +libgnomekbd-dev#3.4.0.2-1 +libgnomemm-2.6-dev#2.30.0-1 +libgnomeprint2.2-dev#2.18.8-3 +libgnomeprintui2.2-dev#2.18.6-3 +libgnomeui-dev#2.24.5-2 +libgnomeuimm-2.6-dev#2.28.0-1 +libgnomevfs2-dev#1:2.24.4-2 +libgnuift0-dev#0.1.14-12 +libgnuplot-ocaml-dev#0.8.3-3 +libgnustep-base-dev#1.22.1-4 +libgnustep-dl2-dev#0.12.0-9+nmu1 +libgnustep-gui-dev#0.20.0-3 +libgnutls-dev#2.12.20-8+deb7u1 +libgoa-1.0-dev#3.4.2-2 +libgoffice-0.8-dev#0.8.17-1.2 +libgofigure-dev#0.9.0-1+b2 +libgoocanvas-dev#0.15-1 +libgoocanvasmm-dev#0.15.4-1 +libgoogle-perftools-dev#2.0-2 +libgooglepinyin0-dev#0.1.2-1 +libgpac-dev#0.5.0~dfsg0-1 +libgpds-dev#1.5.1-6 +libgpelaunch-dev#0.14-6 +libgpepimc-dev#0.9-4 +libgpeschedule-dev#0.17-4 +libgpevtype-dev#0.50-6 +libgpewidget-dev#0.117-6 +libgpg-error-dev#1.10-3.1 +libgpgme11-dev#1.2.0-1.4 +libgphoto2-2-dev#2.4.14-2 +libgpiv3-dev#0.6.1-4 +libgpm-dev#1.20.4-6 +libgpod-cil-dev#0.8.2-7 +libgpod-dev#0.8.2-7 +libgpod-nogtk-dev#0.8.2-7 +libgportugol-dev#1.1-2 +libgps-dev#3.6-4+deb7u1 +libgraflib1-dev#20061220+dfsg3-2 +libgrafx11-1-dev#20061220+dfsg3-2 +libgrantlee-dev#0.1.4-1 +libgraphicsmagick++1-dev#1.3.16-1.1 +libgraphicsmagick1-dev#1.3.16-1.1 +libgraphite-dev#1:2.3.1-0.2 +libgraphite2-dev#1.1.3-1 +libgraphviz-dev#2.26.3-14+deb7u1 +libgretl1-dev#1.9.9-1 +libgrib-api-dev#1.9.16-2+b1 +libgrib2c-dev#1.2.2-2+b1 +libgridsite-dev#1.7.16-1 +libgrilo-0.1-dev#0.1.19-1 +libgringotts-dev#1.2.10~pre3-1 +libgrits-dev#0.7-1 +libgrok-dev#1.20110708.1-4 +libgrss-dev#0.5.0-1 +libgs-dev#9.05~dfsg-6.3+deb7u1 +libgsasl7-dev#1.8.0-2 +libgsecuredelete-dev#0.2-1 +libgsf-1-dev#1.14.21-2.1 +libgsf-gnome-1-dev#1.14.21-2.1 +libgsl0-dev#1.15+dfsg.2-2 +libgsm0710-dev#1.2.2-2 +libgsm0710mux-dev#0.11.2-1.1 +libgsm1-dev#1.0.13-4 +libgsmme-dev#1.10-13.2 +libgsnmp0-dev#0.3.0-1.1 +libgsql-dev#0.2.2-1.2+b1 +libgss-dev#1.0.2-1 +libgssdp-1.0-dev#0.12.2.1-2 +libgssglue-dev#0.4-2 +libgst-dev#3.2.4-2 +libgstbuzztard-dev#0.5.0-2+deb7u1 +libgstreamer-ocaml-dev#0.1.0-3+b1 +libgstreamer-plugins-bad0.10-dev#0.10.23-7.1+deb7u1 +libgstreamer-plugins-base0.10-dev#0.10.36-1.1 +libgstreamer0.10-cil-dev#0.9.2-4 +libgstreamer0.10-dev#0.10.36-1.2 +libgstrtspserver-0.10-dev#0.10.8-3 +libgtest-dev#1.6.0-2 +libgtextutils-dev#0.6.2-1 +libgtg-dev#0.2+dfsg-1 +libgtk-3-dev#3.4.2-7 +libgtk-sharp-beans2.0-cil-dev#2.14.1-3 +libgtk-vnc-1.0-dev#0.5.0-3.1 +libgtk-vnc-2.0-dev#0.5.0-3.1 +libgtk2.0-cil-dev#2.12.10-5 +libgtk2.0-dev#2.24.10-2 +libgtkada2.24.1-dev#2.24.1-7 +libgtkdatabox-0.9.1-1-dev#1:0.9.1.1-4 +libgtkgl2.0-dev#2.0.1-2 +libgtkglada2.24.1-dev#2.24.1-7 +libgtkglarea-cil-dev#0.0.17-6 +libgtkglext1-dev#1.2.0-2 +libgtkglextmm-x11-1.2-dev#1.2.0-4.1 +libgtkhex-3-dev#3.4.1-1 +libgtkhotkey-dev#0.2.1-3 +libgtkhtml-4.0-dev#4.4.4-1 +libgtkhtml-editor-3.14-dev#3.32.2-2.1 +libgtkhtml-editor-4.0-dev#4.4.4-1 +libgtkhtml3.14-cil-dev#2.26.0-8 +libgtkhtml3.14-dev#3.32.2-2.1 +libgtkimageview-dev#1.6.4+dfsg-0.1 +libgtkmathview-dev#0.8.0-8 +libgtkmm-2.4-dev#1:2.24.2-1 +libgtkmm-3.0-dev#3.4.2-1 +libgtkpod-dev#2.1.2-1 +libgtksourceview-3.0-dev#3.4.2-1 +libgtksourceview2-cil-dev#2.26.0-8 +libgtksourceview2.0-dev#2.10.4-1 +libgtksourceviewmm-3.0-dev#3.2.0-1 +libgtkspell-3-dev#3.0.0~hg20110814-1 +libgtkspell-dev#2.0.16-1 +libgtop2-dev#2.28.4-3 +libgts-dev#0.7.6+darcs110121-1.1 +libguac-dev#0.6.0-2 +libgucharmap-2-90-dev#1:3.4.1.1-2.1 +libgudev-1.0-dev#175-7.2 +libgudev1.0-cil-dev#0.1-3 +libguess-dev#1.1-1 +libguestfs-dev#1:1.18.1-1+deb7u3 +libguestfs-gobject-dev#1:1.18.1-1+deb7u3 +libguestfs-ocaml-dev#1:1.18.1-1+deb7u3 +libguichan-dev#0.8.2-10+b1 +libgupnp-1.0-dev#0.18.4-1 +libgupnp-av-1.0-dev#0.10.3-1 +libgupnp-dlna-1.0-dev#0.6.6-1 +libgupnp-igd-1.0-dev#0.2.1-2 +libgusb-dev#0.1.3-5 +libgutenprint-dev#5.2.9-1 +libgutenprintui2-dev#5.2.9-1 +libguytools2-dev#2.0.1-1.1 +libgvnc-1.0-dev#0.5.0-3.1 +libgweather-3-dev#3.4.1-1+build1 +libgwenhywfar60-dev#4.3.3-1 +libgwrap-runtime-dev#1.9.14-1.1 +libgwyddion20-dev#2.28-2 +libgxps-dev#0.2.2-2 +libgyoto0-dev#0.0.3-5 +libh323plus-dev#1.24.0~dfsg2-1 +libhaildb-dev#2.3.2-1.2 +libhal-dev#0.5.14-8 +libhal-storage-dev#0.5.14-8 +libhamlib++-dev#1.2.15.1-1 +libhamlib-dev#1.2.15.1-1 +libhandoff-dev#0.1-5 +libhangul-dev#0.1.0-2 +libharminv-dev#1.3.1-9 +libhashkit-dev#1.0.8-1 +libhawknl-dev#1.6.8+dfsg2-1 +libhbaapi-dev#2.2.5-1 +libhbalinux-dev#1.0.14-1 +libhd-dev#16.0-2.2 +libhdate-dev#1.6-1 +libhdf4-alt-dev#4.2r4-13 +libhdf4-dev#4.2r4-13 +libhdf4g-dev#4.2r4-13 +libhdf5-dev#1.8.8-9 +libhdf5-mpi-dev#1.8.8-9 +libhdf5-mpich2-dev#1.8.8-9 +libhdf5-openmpi-dev#1.8.8-9 +libhdf5-serial-dev#1.8.8-9 +libhdfeos-dev#2.17v1.00.dfsg.1-3 +libhdhomerun-dev#20120405-1 +libhe5-hdfeos-dev#5.1.13.dfsg.1-3 +libheartbeat2-dev#1:3.0.5-3 +libhepmc-dev#2.06.09-1 +libhepmcfio-dev#2.06.09-1 +libhepmcinterface8-dev#8.1.65-1 +libherwig59-2-dev#20061220+dfsg3-2 +libhesiod-dev#3.0.2-21 +libhfsp-dev#1.0.4-12 +libhighgui-dev#2.3.1-11 +libhippocanvas-dev#0.3.1-1.1 +libhiredis-dev#0.10.1-7 +libhivex-dev#1.3.6-2 +libhivex-ocaml-dev#1.3.6-2 +libhkl-dev#4.0.3-4 +libhmsbeagle-dev#1.0-6 +libhocr-dev#0.10.17-1+b2 +libhpdf-dev#2.2.1-1 +libhpmud-dev#3.12.6-3.1+deb7u1 +libhsclient-dev#1.1.0-7-g1044a28-1 +libhtmlcxx-dev#0.85-2 +libhtp-dev#0.2.6-2 +libhtsengine-dev#1.06-1 +libhttp-ocaml-dev#0.1.5-1+b2 +libhttrack-dev#3.46.1-1 +libhunspell-dev#1.3.2-4 +libhwloc-dev#1.4.1-4 +libhx-dev#3.12.1-1 +libhyantes-dev#1.3.0-1 +libhyena-cil-dev#0.5-2 +libhyphen-dev#2.8.3-2 +libhypre-dev#2.8.0b-1 +libhz-dev#0.3.16-3 +libi2c-dev#3.1.0-2 +libibcm-dev#1.0.4-1.1 +libibcommon-dev#1.1.2-20090314-1 +libibdm-dev#1.2-OFED-1.4.2-1.3 +libibmad-dev#1.2.3-20090314-1.1 +libibtk-dev#0.0.14-12 +libibumad-dev#1.2.3-20090314-1.1 +libibus-1.0-dev#1.4.1-9+deb7u1 +libibus-qt-dev#1.3.1-2.1 +libibverbs-dev#1.1.6-1 +libical-dev#0.48-2 +libicapapi-dev#1:0.1.6-1.1 +libicc-dev#2.12+argyll1.4.0-8 +libicc-utils-dev#1.6.4-1+b1 +libice-dev#2:1.0.8-2 +libicee-dev#1.2.0-6.1 +libicns-dev#0.8.1-1 +libiconv-hook-dev#0.0.20021209-10 +libics-dev#1.5.2-3 +libicu-dev#4.8.1.1-12+deb7u1 +libid3-3.8.3-dev#3.8.3-15 +libid3tag0-dev#0.15.1b-10 +libident-dev#0.22-3 +libidl-dev#0.8.14-0.2 +libidn11-dev#1.25-2 +libidn2-0-dev#0.8-2 +libido-0.1-dev#0.3.4-1 +libido3-0.1-dev#0.3.4-1 +libidzebra-2.0-dev#2.0.44-3 +libiec16022-dev#0.2.4-1 +libiec61883-dev#1.2.0-0.1 +libieee1284-3-dev#0.2.11-10 +libifp-dev#1.0.0.2-5 +libifstat-dev#1.1-8 +libigraph0-dev#0.5.4-2 +libigstk4-dev#4.4.0-2+b1 +libijs-dev#0.35-8 +libiksemel-dev#1.2-4 +libilmbase-dev#1.0.1-4 +libimdi-dev#1.4.0-8 +libiml-dev#1.0.3-4.2 +libimlib2-dev#1.4.5-1 +libimobiledevice-dev#1.1.1-4 +libindi-dev#0.9.1-2 +libindicate-dev#0.6.92-1 +libindicate-gtk-dev#0.6.92-1 +libindicate-gtk0.1-cil-dev#0.6.92-1 +libindicate-gtk3-dev#0.6.92-1 +libindicate-qt-dev#0.2.5.91-5 +libindicate0.1-cil-dev#0.6.92-1 +libindicator-dev#0.5.0-1 +libindicator-messages-status-provider-dev#0.6.0-1 +libindicator3-dev#0.5.0-1 +libindigo-dev#1.0.0-2 +libinfinity-0.5-dev#0.5.2-6.1 +libini-config-dev#0.1.3-2 +libinifiles-ocaml-dev#1.2-2 +libinnodb-dev#1.0.6.6750-1 +libinotify-ocaml-dev#1.0-1+b3 +libinotifytools0-dev#3.14-1 +libinput-pad-dev#1.0.1-2 +libinsighttoolkit3-dev#3.20.1+git20120521-3 +libinstpatch-dev#1.0.0-3 +libint-dev#1.1.4-1 +libiodbc2-dev#3.52.7-2+deb7u1 +libion-dev#3.0.1~dfsg1-1 +libipa-hbac-dev#1.8.4-2 +libipathverbs-dev#1.2-1 +libipe-dev#7.1.2-1 +libipmiconsole-dev#1.1.5-3 +libipmidetect-dev#1.1.5-3 +libipmimonitoring-dev#1.1.5-3 +libipset-dev#6.12.1-1 +libiptcdata0-dev#1.0.4-3 +libircclient-dev#1.3+dfsg1-3 +libirman-dev#0.4.4-2 +libirrlicht-dev#1.7.3+dfsg1-4 +libisajet758-3-dev#20061220+dfsg3-2 +libiscsi-dev#1.4.0-3 +libisl-dev#0.10-3 +libiso9660-dev#0.83-4 +libisoburn-dev#1.2.2-2 +libisofs-dev#1.2.2-1 +libitl-dev#0.7.0-3 +libitl-gobject-dev#0.2-1 +libitpp-dev#4.2-4 +libitsol-dev#1.0.0-2 +libivykis-dev#0.30.1-2 +libiw-dev#30~pre9-8 +libjack-dev#1:0.121.3+20120418git75e3e20b-2.1 +libjack-jackd2-dev#1.9.8~dfsg.4+20120529git007cdc37-5 +libjalali-dev#0.4.0-1.1 +libjama-dev#1.2.4-2 +libjana-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-ecal-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-gtk-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjansson-dev#2.3.1-2 +libjasper-dev#1.900.1-13 +libjaula-dev#1.4.0-3 +libjavascriptcoregtk-1.0-dev#1.8.1-3.4 +libjavascriptcoregtk-3.0-dev#1.8.1-3.4 +libjbig-dev#2.0-2+deb7u1 +libjbig2dec0-dev#0.11+20120125-1 +libjconv-dev#2.8-6+b1 +libjemalloc-dev#3.0.0-3 +libjim-dev#0.73-3 +libjpeg62-dev#6b1-3 +libjpeg8-dev#8d-1 +libjpgalleg4-dev#2:4.4.2-2.1 +libjs-of-ocaml-dev#1.2-2 +libjson-glib-dev#0.14.2-1 +libjson-spirit-dev#4.04-1+b1 +libjson-static-camlp4-dev#0.9.8-1+b5 +libjson-wheel-ocaml-dev#1.0.6-2+b8 +libjson0-dev#0.10-1.2 +libjsoncpp-dev#0.6.0~rc2-3 +libjte-dev#1.19-1 +libjthread-dev#1.3.1-3 +libjudy-dev#1.0.5-1 +libjuman-dev#5.1-2.1 +libk3b-dev#2.0.2-6 +libkactivities-dev#4:4.8.4-1 +libkakasi2-dev#2.3.5~pre1+cvs20071101-1 +libkal-dev#0.9.0-1 +libkarma-cil-dev#0.1.2-2.3 +libkarma-dev#0.1.2-2.3 +libkate-dev#0.4.1-1 +libkaya-gd-dev#0.4.4-6 +libkaya-gl-dev#0.4.4-6 +libkaya-mysql-dev#0.4.4-6 +libkaya-ncurses-dev#0.4.4-6 +libkaya-ncursesw-dev#0.4.4-6 +libkaya-pgsql-dev#0.4.4-6 +libkaya-sdl-dev#0.4.4-6 +libkaya-sqlite3-dev#0.4.4-6 +libkcddb-dev#4:4.8.4-2 +libkdcraw-dev#4:4.8.4-1 +libkdeedu-dev#4:4.8.4-1 +libkdegames-dev#4:4.8.4-3 +libkdtree++-dev#0.7.0-2 +libkernlib1-dev#20061220+dfsg3-2 +libkexiv2-dev#4:4.8.4-1 +libkeybinder-dev#0.2.2-4 +libkeyutils-dev#1.5.5-3 +libkibi-dev#0.1-1 +libkipi-dev#4:4.8.4-1 +libkiten-dev#4:4.8.4-1 +libklatexformula3-dev#3.2.6-1 +libklibc-dev#2.0.1-3.1 +libkmfl-dev#0.9.8-1 +libkmflcomp-dev#0.9.8-1 +libkml-dev#1.3.0~r863-4.1 +libkmod-dev#9-3 +libkokyu-dev#6.0.3+dfsg-0.1 +libkonq5-dev#4:4.8.4-2 +libkonqsidebarplugin-dev#4:4.8.4-2 +libkopete-dev#4:4.8.4-1+b1 +libkosd2-dev#0.8.1-1 +libkpathsea-dev#2012.20120628-4 +libkqueue-dev#1.0.4-2 +libkrb5-dev#1.10.1+dfsg-5+deb7u1 +libksane-dev#4:4.8.4-1 +libksba-dev#1.2.0-2 +libktoblzcheck1-dev#1.39-1 +libktorrent-dev#1.2.1-1 +libktpcommoninternalsprivate-dev#0.4.0-1 +libkvutils-dev#2.9.0-1 +libkvutils2.2-dev#2.9.0-1 +libkwnn-dev#1.1.1~a021+cvs20100325-6 +libkwwidgets1-dev#1.0.0~cvs20100930-8 +libkxl0-dev#1.1.7-16 +liblablgl-ocaml-dev#1.04-5+b3 +liblablgtk-extras-ocaml-dev#1.0-1+b2 +liblablgtk2-gl-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-gnome-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-ocaml-dev#2.14.2+dfsg-3 +liblablgtkmathview-ocaml-dev#0.7.8-6+b1 +liblablgtksourceview2-ocaml-dev#2.14.2+dfsg-3 +libladr-dev#0.0.200902a-2.1 +libladspa-ocaml-dev#0.1.4-1+b1 +liblapack-dev#3.4.1+dfsg-1+deb70u1 +liblapacke-dev#3.4.1+dfsg-1+deb70u1 +liblas-dev#1.2.1-5+b1 +liblash-compat-dev#1+dfsg0-3 +liblasi-dev#1.1.0-1 +liblasso3-dev#2.3.6-2 +liblastfm-dev#0.4.0~git20090710-2 +liblastfm-ocaml-dev#0.3.0-2+b6 +liblcgdm-dev#1.8.2-1+b2 +liblcms1-dev#1.19.dfsg-1.2 +liblcms2-dev#2.2+git20110628-2.2+deb7u1 +libldap-ocaml-dev#2.1.8-8+b9 +libldap2-dev#2.4.31-1+nmu2 +libldb-dev#1:1.1.6-1 +libldns-dev#1.6.13-1 +libledit-ocaml-dev#2.03-1+b2 +liblensfun-dev#0.2.5-2 +libleptonica-dev#1.69-3.1 +libleveldb-dev#0+20120530.gitdd0d562-1 +liblfc-dev#1.8.2-1+b2 +liblhapdf-dev#5.8.7+repack-1 +liblhasa-dev#0.0.7-2 +liblicense-dev#0.8.1-3 +liblightdm-gobject-dev#1.2.2-4 +liblightdm-qt-dev#1.2.2-4 +liblilv-dev#0.14.2~dfsg0-4 +liblinear-dev#1.8+dfsg-1 +liblinebreak2-dev#2.1-1 +liblink-grammar4-dev#4.7.4-2 +liblinphone-dev#3.5.2-10 +liblip-dev#2.0.0-1.1 +liblircclient-dev#0.9.0~pre1-1 +liblistaller-glib-dev#0.5.5-2 +liblivemedia-dev#2012.05.17-1 +libllvm-2.9-ocaml-dev#2.9+dfsg-7 +libllvm-3.0-ocaml-dev#3.0-10 +libllvm-3.1-ocaml-dev#3.1-1 +libllvm-ocaml-dev#1:3.0-14+nmu2 +liblo-dev#0.26~repack-7 +liblo-ocaml-dev#0.1.0-1+b1 +liblo10k1-dev#1.0.25-2 +libloadpng4-dev#2:4.4.2-2.1 +liblockdev1-dev#1.0.3-1.5 +liblockfile-dev#1.09-5 +liblodo3.0-dev#3.0.2+dfsg-4+b1 +liblog4ada2-dev#1.2-3 +liblog4c-dev#1.2.1-3 +liblog4cplus-dev#1.0.4-1 +liblog4cpp5-dev#1.0-4 +liblog4cxx10-dev#0.10.0-1.2 +liblog4net-cil-dev#1.2.10+dfsg-6 +liblog4shib-dev#1.0.4-1 +liblog4tango4-dev#7.2.6+dfsg-14 +liblogforwarderutils2-dev#2.7-1 +liblognorm-dev#0.3.4-1 +liblogservicecomponentbase2-dev#2.7-1 +liblogservicetoolbase2-dev#2.7-1 +liblogsys-dev#1.4.2-3 +liblogthread-dev#3.0.12-3.2+deb7u2 +libloki-dev#0.1.7-3 +libloudmouth1-dev#1.4.3-9 +liblouis-dev#2.4.1-1 +liblouisutdml-dev#2.2.0-1 +liblouisxml-dev#2.4.0-3 +liblowpan-dev#0.2.2-2.1 +liblpsolve55-dev#5.5.0.13-7 +liblqr-1-0-dev#0.4.1-2 +liblrdf0-dev#0.4.0-5 +liblrm2-dev#1.0.9+hg2665-1 +liblrs-dev#0.42c-1+b1 +liblscp-dev#0.5.6-6 +libltcsmpte-dev#0.4.4-1 +libltdl-dev#2.4.2-1.1 +liblttctl-dev#0.89-05122011-1 +liblttd-dev#0.89-05122011-1 +liblttng-ust-dev#2.0.4-1 +liblttoolbox3-3.1-0-dev#3.1.0-1.1 +liblttvtraceread-2.6-dev#0.12.38-21032011-1+b1 +liblua5.1-0-dev#5.1.5-4 +liblua5.1-apr-dev#0.23.2-1 +liblua5.1-bitop-dev#1.0.2-1 +liblua5.1-cgi-dev#5.1.4+dfsg-2 +liblua5.1-copas-dev#1.1.6-5 +liblua5.1-curl-dev#0.3.0-7 +liblua5.1-cyrussasl-dev#1.0.0-4 +liblua5.1-event-dev#0.4.1-2 +liblua5.1-expat-dev#1.2.0-5+deb7u1 +liblua5.1-filesystem-dev#1.5.0+16+g84f1af5-1 +liblua5.1-leg-dev#0.1.2-8 +liblua5.1-logging-dev#1.2.0-1 +liblua5.1-lpeg-dev#0.10.2-5 +liblua5.1-md5-dev#1.1.2-6 +liblua5.1-oocairo-dev#1.4-1.2 +liblua5.1-oopango-dev#1.1-1 +liblua5.1-orbit-dev#2.2.0+dfsg1-1 +liblua5.1-posix-dev#5.1.19-2 +liblua5.1-rex-onig-dev#2.6.0-2 +liblua5.1-rex-pcre-dev#2.6.0-2 +liblua5.1-rex-posix-dev#2.6.0-2 +liblua5.1-rings-dev#1.2.3-1 +liblua5.1-rrd-dev#1.4.7-2 +liblua5.1-sec-dev#0.4.1-1 +liblua5.1-soap-dev#3.0-3 +liblua5.1-socket-dev#2.0.2-8 +liblua5.1-sql-mysql-dev#2.3.0-1+build0 +liblua5.1-sql-postgres-dev#2.3.0-1+build0 +liblua5.1-sql-sqlite3-dev#2.3.0-1+build0 +liblua5.1-svn-dev#0.4.0-7 +liblua5.1-wsapi-fcgi-dev#1.5-3 +liblua5.1-xmlrpc-dev#1.2.1-5 +liblua5.1-zip-dev#1.2.3-11 +liblua5.2-dev#5.2.1-3 +liblua50-dev#5.0.3-6 +libluabind-dev#0.9.1+dfsg-5 +liblualib50-dev#5.0.3-6 +liblunar-1-dev#2.0.1-2.2 +liblunar-date-dev#2.4.0-1 +liblv2dynparam1-dev#2-5 +liblvm2-dev#2.02.95-8 +liblwipv6-dev#1.5a-2 +liblwt-glib-ocaml-dev#2.3.2-1+b3 +liblwt-ocaml-dev#2.3.2-1+b3 +liblwt-ssl-ocaml-dev#2.3.2-1+b3 +liblz-dev#1.3-2 +liblzma-dev#5.1.1alpha+20120614-2 +liblzo2-dev#2.06-1 +libm17n-dev#1.6.3-2 +libm17n-im-config-dev#0.9.0-3 +libm4ri-dev#0.0.20080521-2 +libmaa-dev#1.3.1-1 +libmad-ocaml-dev#0.4.4-1+b1 +libmad0-dev#0.15.1b-7 +libmadlib-dev#1.3.0-2.1 +libmagic-dev#5.11-2+deb7u3 +libmagic-ocaml-dev#0.7.3-5+b3 +libmagick++-dev#8:6.7.7.10-5+deb7u3 +libmagickcore-dev#8:6.7.7.10-5+deb7u3 +libmagickwand-dev#8:6.7.7.10-5+deb7u3 +libmagics++-dev#2.14.11-4 +libmailutils-dev#1:2.99.97-3 +libmalaga-dev#7.12-4 +libmaloc-dev#0.2-2.3 +libmapi-dev#1:1.0-3 +libmapiadmin-dev#1:1.0-3 +libmapipp-dev#1:1.0-3 +libmapiproxy-dev#1:1.0-3 +libmapistore-dev#1:1.0-3 +libmapnik-dev#2.0.0+ds1-3 +libmapnik2-dev#2.0.0+ds1-3+b4 +libmarble-dev#4:4.8.4-3 +libmarkdown2-dev#2.1.3-3 +libmatchbox-dev#1.9-osso8-3 +libmath++-dev#0.0.4-4 +libmatheval-dev#1.1.8-1 +libmathlib2-dev#20061220+dfsg3-2 +libmatio-dev#1.3.4-4 +libmatrixssl1.8-dev#1.8.8-1 +libmatroska-dev#1.3.0-2 +libmbt0-dev#3.2.8-1 +libmcpp-dev#2.7.2-1.1 +libmcrypt-dev#2.5.8-3.1 +libmcs-dev#0.7.2-2.1 +libmd3-dev#0.1.92-4 +libmdc2-dev#0.10.7-1+b2 +libmdds-dev#0.5.4-1 +libmdsp-dev#0.11-10 +libmeanwhile-dev#1.0.2-4 +libmecab-dev#0.99.3-3 +libmed-dev#3.0.3-3 +libmedc-dev#3.0.3-3 +libmediainfo-dev#0.7.58-1 +libmediastreamer-dev#3.5.2-10 +libmedimport-dev#3.0.3-3 +libmeep-dev#1.1.1-8+deb7u1 +libmeep-lam4-dev#1.1.1-10~deb7u1 +libmeep-mpi-default-dev#1.1.1-10~deb7u1 +libmeep-mpich2-dev#1.1.1-10~deb7u1 +libmeep-openmpi-dev#1.1.1-9~deb7u2 +libmelt-ocaml-dev#1.4.0-1 +libmemcache-dev#1.4.0.rc2-1 +libmemcached-dev#1.0.8-1 +libmemphis-0.2-dev#0.2.3-2 +libmenhir-ocaml-dev#20120123.dfsg-1 +libmenu-cache1-dev#0.3.3-1 +libmercator-0.3-dev#0.3.0-2 +libmeschach-dev#1.2b-13 +libmetacity-dev#1:2.34.3-4 +libmgl-dev#1.11.2-17 +libmhash-dev#0.9.9.9-1.1 +libmicrohttpd-dev#0.9.20-1+deb7u1 +libmigemo-dev#20110227-7 +libmikmatch-ocaml-dev#1.0.4-1+b1 +libmikmod2-dev#3.1.12-5 +libmilter-dev#8.14.4-4 +libmimedir-dev#0.5.1-4 +libmimedir-gnome-dev#0.4.2-5 +libmimelib1-dev#5:1.1.4-2 +libmimetic-dev#0.9.7-3 +libmimic-dev#1.0.4-2.1 +libminc-dev#2.1.10-1+b1 +libming-dev#1:0.4.4-1.1 +libmini18n-dev#0.2.1-1 +libminidjvu-dev#0.8.svn.2010.05.06+dfsg-0.2 +libminiupnpc-dev#1.5-2 +libmission-control-plugins-dev#1:5.12.3-1 +libmkv-dev#0.6.5.1-1 +libmlpcap-ocaml-dev#0.9-16 +libmlpost-ocaml-dev#0.8.1-3 +libmlt++-dev#0.8.0-4 +libmlt-dev#0.8.0-4 +libmlx4-dev#1.0.4-1 +libmm-dev#1.4.2-4 +libmm-ocaml-dev#0.2.0-1+b1 +libmmpong0.9-dev#0.9.1-2.1 +libmms-dev#0.6.2-3 +libmng-dev#1.0.10-3 +libmnl-dev#1.0.3-3 +libmodbus-dev#3.0.3-1 +libmodglue1-dev#1.17-2.1 +libmodplug-dev#1:0.8.8.4-3+deb7u1+git20130828 +libmoe-dev#1.5.8-1 +libmongo-client-dev#0.1.5-1+deb7u1 +libmono-2.0-dev#2.10.8.1-8 +libmono-addins-cil-dev#0.6.2-2 +libmono-addins-gui-cil-dev#0.6.2-2 +libmono-addins-msbuild-cil-dev#0.6.2-2 +libmono-cecil-cil-dev#0.9.5+dfsg-2 +libmono-cecil-flowanalysis-cil-dev#0.1~vcs20110809.r1.b34edf6-2 +libmono-cil-dev#2.10.8.1-8 +libmono-reflection-cil-dev#1.0+git20110407+d2343843-2 +libmono-uia-cil-dev#2.1-4 +libmono-upnp-cil-dev#0.1.2-1 +libmono-zeroconf-cil-dev#0.9.0-4 +libmonogame-cil-dev#2.5.1+dfsg-3 +libmopac7-dev#1.15-5 +libmorph-dev#1:20090926 +libmosquitto0-dev#0.15-2 +libmosquittopp0-dev#0.15-2 +libmount-dev#2.20.1-5.3 +libmowgli-dev#1.0.0-1 +libmozjs-dev#24.4.0esr-1~deb7u2 +libmozjs185-dev#1.8.5-1.0.0+dfsg-4 +libmp3lame-dev#3.99.5+repack1-3 +libmp3lame-ocaml-dev#0.3.1-1+b1 +libmp3splt-dev#0.7.2-2 +libmp4v2-dev#2.0.0~dfsg0-1 +libmpc-dev#0.9-4 +libmpcdec-dev#2:0.1~r459-4 +libmpd-dev#0.20.0-1.1 +libmpdclient-dev#2.3-1 +libmpeg2-4-dev#0.4.1-3 +libmpeg3-dev#1.5.4-5 +libmpfi-dev#1.5.1-1 +libmpfr-dev#3.1.0-5 +libmpg123-dev#1.14.4-1 +libmpich2-dev#1.4.1-4.2 +libmpikmeans-dev#1.5-1+b1 +libmrml1-dev#0.1.14-12 +libmrmpi-dev#1.0~20110620.dfsg-2 +libmrss0-dev#0.19.2-3 +libmsgpack-dev#0.5.7-2 +libmsn-dev#4.2-2 +libmsv-dev#0.0.0-1 +libmtbl-dev#0.2-1 +libmtcp-dev#1.2.5-1 +libmtdev-dev#1.1.2-1 +libmthca-dev#1.0.6-1 +libmtp-dev#1.1.3-35-g0ece104-5 +libmudflap0-4.4-dev#4.4.7-2 +libmudflap0-4.6-dev#4.6.3-14 +libmudflap0-4.7-dev#4.7.2-5 +libmulticobex1-dev#0.23-1.1 +libmumps-dev#4.10.0.dfsg-3 +libmumps-ptscotch-dev#4.10.0.dfsg-3 +libmumps-scotch-dev#4.10.0.dfsg-3 +libmumps-seq-dev#4.10.0.dfsg-3 +libmunge-dev#0.5.10-1 +libmuparser-dev#2.1.0-3 +libmupdf-dev#0.9-2 +libmupen64plus-dev#1.99.5-6 +libmuroar-dev#0.1.8-2 +libmusic-dev#1.0.7-1.2 +libmusicbrainz3-dev#3.0.2-2.1 +libmusicbrainz5-dev#5.0.1-2 +libmutter-dev#3.4.1-5 +libmx-dev#1.4.6-1 +libmxml-dev#2.6-2 +libmyproxy-dev#5.6-1 +libmysql++-dev#3.1.0-2+b1 +libmysql-cil-dev#6.4.3-2 +libmysql-ocaml-dev#1.1.1-1 +libmysqlclient-dev#5.5.35+dfsg-0+wheezy1 +libmysqlcppconn-dev#1.1.0-4+b1 +libmysqld-dev#5.5.35+dfsg-0+wheezy1 +libmythes-dev#2:1.2.2-1 +libnabrit-dev#0.4.1-1 +libnacl-dev#20110221-4 +libnacore-dev#0.4.0-3 +libnanohttp-dev#1.1.0-17.1 +libnatpmp-dev#20110808-3 +libnautilus-extension-dev#3.4.2-1+build1 +libnbio-dev#0.30-1 +libncap-dev#1.9.2-1+b2 +libncbi6-dev#6.1.20120620-2 +libncp-dev#2.2.6-9 +libncurses5-dev#5.9-10 +libncursesada2-dev#5.9.20110404-7 +libncursesw5-dev#5.9-10 +libndesk-dbus-glib1.0-cil-dev#0.4.1-4 +libndesk-dbus1.0-cil-dev#0.6.0-6 +libndr-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libndr-standard-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libnecpp-dev#1.5.0+cvs20101003-2.1 +libneon27-dev#0.29.6-3 +libneon27-gnutls-dev#0.29.6-3 +libnes-dev#1.1.3-1 +libnet1-dev#1.1.4-2.1 +libnet6-1.3-dev#1:1.3.14-1 +libnetcdf-dev#1:4.1.3-6+b1 +libnetcf-dev#0.1.9-2 +libnetclasses-dev#1.06.dfsg-5+b3 +libnetfilter-conntrack-dev#1.0.1-1 +libnetfilter-cttimeout-dev#1.0.0-1 +libnetfilter-log-dev#1.0.0-1 +libnetfilter-queue-dev#0.0.17-1 +libnethttpd-ocaml-dev#3.5.1-1 +libnetpbm10-dev#2:10.0-15+b1 +libnetpbm9-dev#2:10.0-15+b1 +libnetsvcs-dev#6.0.3+dfsg-0.1 +libnewlib-dev#1.18.0-6.2 +libnewmat10-dev#1.10.4-5 +libnewt-dev#0.52.14-11.1 +libnewtonsoft-json-cil-dev#4.5r6-1 +libnexus0-dev#4.2.1-svn1614-1+b2 +libnfnetlink-dev#1.0.0-1.1 +libnfo-dev#1.0.1-1 +libnfs-dev#1.3.0-2 +libnfsidmap-dev#0.25-4 +libnice-dev#0.1.2-1 +libnids-dev#1.23-2 +libnifti-dev#2.0.0-1 +libnih-dbus-dev#1.0.3-4.1 +libnih-dev#1.0.3-4.1 +libnini-cil-dev#1.1.0+dfsg.2-4 +libnjb-dev#2.2.7~dfsg0-3 +libnl-3-dev#3.2.7-4 +libnl-cli-3-dev#3.2.7-4 +libnl-dev#1.1-7 +libnl-genl-3-dev#3.2.7-4 +libnl-nf-3-dev#3.2.7-4 +libnl-route-3-dev#3.2.7-4 +libnm-glib-dev#0.9.4.0-10 +libnm-glib-vpn-dev#0.9.4.0-10 +libnm-gtk-dev#0.9.4.1-5 +libnm-util-dev#0.9.4.0-10 +libnmz7-dev#2.0.21-6 +libnoise-dev#1.0.0+nmu1 +libnotify-cil-dev#0.4.0~r3032-6 +libnotify-dev#0.7.5-1 +libnotmuch-dev#0.13.2-1 +libnova-dev#0.14.0-2 +libnpth0-dev#0.90-2 +libnsbmp0-dev#0.0.1-1.1 +libnsgif0-dev#0.0.1-1.1 +libnspr4-dev#2:4.9.2-1+deb7u1 +libnss3-dev#2:3.14.5-1 +libntfs-dev#2.0.0-1+b1 +libntl-dev#5.5.2-2 +libntlm0-dev#1.2-1 +libntrack-dev#016-1.1 +libntrack-glib-dev#016-1.1 +libntrack-gobject-dev#016-1.1 +libntrack-qt4-dev#016-1.1 +libnuclient-dev#2.4.3-2.2 +libnuma-dev#2.0.8~rc4-1 +libnunit-cil-dev#2.6.0.12051+dfsg-2 +libnussl-dev#2.4.3-2.2 +libnvtt-dev#2.0.8-1+dfsg-2 +libnxcl-dev#0.9-3.1 +libnxml0-dev#0.18.3-4 +libnzb-dev#0.0.20050629-6.1 +liboasis-ocaml-dev#0.2.0-6 +liboasis3-dev#3.3.beta.dfsg.1-8+b1 +liboath-dev#1.12.4-1 +liboauth-dev#0.9.4-3.1 +libobby-0.4-dev#0.4.8-1 +libobexftp0-dev#0.23-1.1 +libobrowser-ocaml-dev#1.1.1+dfsg-1+b9 +libobus-ocaml-dev#1.1.3-1+b8 +libocamlbricks-ocaml-dev#0.50.1-4+b5 +libocamlgraph-ocaml-dev#1.8.2-2 +libocamlgraph-viewer-ocaml-dev#1.8.2-2 +libocamlgsl-ocaml-dev#0.6.0-7+b2 +libocamlnet-gtk2-ocaml-dev#3.5.1-1 +libocamlnet-ocaml-dev#3.5.1-1 +libocamlnet-ssl-ocaml-dev#3.5.1-1 +libocamlodbc-ocaml-dev#2.15-5+b3 +libocamlviz-ocaml-dev#1.01-2+b2 +libocas-dev#0.93-1 +liboce-foundation-dev#0.9.1-3 +liboce-modeling-dev#0.9.1-3 +liboce-ocaf-dev#0.9.1-3 +liboce-ocaf-lite-dev#0.9.1-3 +liboce-visualization-dev#0.9.1-3 +libocpf-dev#1:1.0-3 +libocrad-dev#0.22~rc1-2 +libocsigen-ocaml-dev#1.3.4-2+b12 +libocsigen-xhtml-ocaml-dev#1.3.4-2+b12 +libocsigenserver-ocaml-dev#2.1-1 +liboctave-dev#3.6.2-5+deb7u1 +libode-dev#2:0.11.1-4 +libode-sp-dev#2:0.11.1-4 +libodin-dev#1.8.5-2 +libodn-ocaml-dev#0.0.8-1 +libofa0-dev#0.9.3-5 +libofapi-dev#0git20070620-6 +libofdt-dev#1.3.6-1 +libofetion-dev#2.2.2-1 +libofx-dev#1:0.9.4-2.1 +libogdi3.2-dev#3.2.0~beta2-7 +libogg-dev#1.3.0-4 +libogg-ocaml-dev#0.4.3-1+b1 +liboggkate-dev#0.4.1-1 +liboggplay1-dev#0.2.1~git20091227-1.2 +liboggz2-dev#1.1.1-1 +liboglappth-dev#1.0.0-2 +libogre-1.8-dev#1.8.0+dfsg1-3 +libogre-dev#1.7.4+dfsg1-7 +liboil0.3-dev#0.3.17-2 +libois-dev#1.3.0+dfsg0-5 +libomhacks-dev#0.16-1 +libomnievents-dev#1:2.6.2-2 +libomniorb4-dev#4.1.6-2 +libomnithread3-dev#4.1.6-2 +libomxil-bellagio-dev#0.9.3-1+b1 +libonig-dev#5.9.1-1 +liboobs-1-dev#3.0.0-1 +liboop-dev#1.0-9 +libooptools-dev#2.7-1 +libopal-dev#3.10.4~dfsg-3 +libopenafs-dev#1.6.1-3+deb7u2 +libopenais-dev#1.1.4-4.1 +libopenal-dev#1:1.14-4 +libopenbabel-dev#2.3.1+dfsg-4 +libopenblas-dev#0.1.1-6+deb7u3 +libopencc-dev#0.3.0-3 +libopenconnect-dev#3.20-4 +libopencore-amrnb-dev#0.1.3-2 +libopencore-amrwb-dev#0.1.3-2 +libopencryptoki-dev#2.3.1+dfsg-3 +libopencsg-dev#1.3.2-2 +libopenct1-dev#0.6.20-1.2 +libopencv-calib3d-dev#2.3.1-11 +libopencv-contrib-dev#2.3.1-11 +libopencv-core-dev#2.3.1-11 +libopencv-dev#2.3.1-11 +libopencv-features2d-dev#2.3.1-11 +libopencv-flann-dev#2.3.1-11 +libopencv-gpu-dev#2.3.1-11 +libopencv-highgui-dev#2.3.1-11 +libopencv-imgproc-dev#2.3.1-11 +libopencv-legacy-dev#2.3.1-11 +libopencv-ml-dev#2.3.1-11 +libopencv-objdetect-dev#2.3.1-11 +libopencv-video-dev#2.3.1-11 +libopendkim-dev#2.6.8-4 +libopenexr-dev#1.6.1-6 +libopenhpi-dev#2.14.1-1.2 +libopenigtlink1-dev#1.9.2~svn7468-1 +libopenimageio-dev#1.0.5+dfsg0-1 +libopenipmi-dev#2.0.16-1.3 +libopenjpeg-dev#1.3+dfsg-4.7 +libopenmeeg-dev#2.0.0.dfsg-5 +libopenmpi-dev#1.4.5-1 +libopenobex1-dev#1.5-2 +libopenr2-dev#1.3.2-1.1 +libopenraw-dev#0.0.9-3+b1 +libopenrawgnome-dev#0.0.9-3+b1 +libopenscap-dev#0.8.0-4+b1 +libopenscenegraph-dev#3.0.1-4 +libopenslide-dev#3.2.6-2 +libopensm2-dev#3.2.6-20090317-2.1 +libopenthreads-dev#3.0.1-4 +libopentk-cil-dev#1.0.20101006+dfsg1-1 +libopentoken3-dev#4.0b-3 +libopenturns-dev#1.0-4 +libopenusb-dev#1.1.0-2 +libopenvg1-mesa-dev#8.0.5-4+deb7u2 +libopenvrml-dev#0.18.9-5+deb7u1 +libopenwalnut1-dev#1.2.5-1.1+b1 +liboping-dev#1.6.2-1 +libopkele-dev#2.0.4-5.3 +libopts25-dev#1:5.12-0.1 +libopus-dev#0.9.14+20120615-1+nmu1 +liborange-dev#0.4-2 +liborbit2-dev#1:2.14.19-0.1 +liborc-0.4-dev#1:0.4.16-2 +liborigin-dev#20080225-2.1 +liborigin2-dev#2:20110117-1+b2 +libortp-dev#3.5.2-10 +liboscpack-dev#1.0.2-1 +libosgearth-dev#2.0+dfsg-4+b3 +libosinfo-1.0-dev#0.1.1-1 +libosip2-dev#3.6.0-4 +libosl-dev#0.5.0-1 +libosmesa6-dev#8.0.5-4+deb7u2 +libosmgpsmap-dev#0.7.3-3 +libosmium-dev#0.0~20111213-g7f3500a-3+b2 +libosmpbf-dev#1.2.1-3 +libosp-dev#1.5.2-10 +libosptk3-dev#3.4.2-1+b1 +libossim-dev#1.7.21-4 +libossp-sa-dev#1.2.6-1 +libossp-uuid-dev#1.6.2-1.3 +libostyle-dev#1.4devel1-20.1+b1 +libotcl1-dev#1.14+dfsg-2 +libotf-dev#0.9.12-2 +libotf-trace-dev#1.10.2+dfsg-2 +libotpw-dev#1.3-2 +libotr2-dev#3.2.1-1+deb7u1 +libots-dev#0.5.0-2.1 +libounit-ocaml-dev#1.1.1-1 +libow-dev#2.8p15-1 +libowfat-dev#0.28-6 +libowfat-dietlibc-dev#0.28-6 +libownet-dev#2.8p15-1 +libp11-dev#0.2.8-2 +libp11-kit-dev#0.12-3 +libpackagekit-glib2-dev#0.7.6-3 +libpackagekit-qt2-dev#0.7.6-3 +libpacketdump3-dev#3.0.14-1 +libpacklib-lesstif1-dev#20061220+dfsg3-2 +libpacklib1-dev#20061220+dfsg3-2 +libpacparser-dev#1.3.0-2 +libpam-ocaml-dev#1.1-4+b3 +libpam0g-dev#1.1.3-7.1 +libpanel-applet-4-dev#3.4.2.1-4 +libpango1.0-dev#1.30.0-1 +libpangomm-1.4-dev#2.28.4-1 +libpano13-dev#2.9.18+dfsg-5 +libpantomime1.2-dev#1.2.0~pre3+snap20071004+dfsg-4+b1 +libpaper-dev#1.1.24+nmu2 +libpaps-dev#0.6.8-6 +libpaq-dev#1.0.4-3+b1 +libpar2-0-dev#0.2.1-1 +libpari-dev#2.5.1-2 +libparpack2-dev#3.1.1-2.1 +libparrot-dev#4.0.0-3 +libparser++-dev#0.2.3-2 +libparted0-dev#2.3-12 +libpasswdqc-dev#1.2.0-1 +libpath-utils-dev#0.1.3-2 +libpathfinder-dev#1.1.3-0.4+b1 +libpawlib-lesstif3-dev#1:2.14.04.dfsg.2-8 +libpawlib2-dev#1:2.14.04.dfsg.2-8 +libpcap-dev#1.3.0-1 +libpcap0.8-dev#1.3.0-1 +libpcapnav0-dev#0.8-1 +libpci-dev#1:3.1.9-6 +libpciaccess-dev#0.13.1-2 +libpcl1-dev#1.6-1 +libpcre++-dev#0.9.5-5.1 +libpcre-ocaml-dev#6.2.5-1 +libpcre3-dev#1:8.30-5 +libpcscada2-dev#0.7.1-4 +libpcsclite-dev#1.8.4-1+deb7u1 +libpdflib804-2-dev#20061220+dfsg3-2 +libpe-rules2-dev#1.1.7-1 +libpe-status3-dev#1.1.7-1 +libpeas-dev#1.4.0-2 +libpengine3-dev#1.1.7-1 +libperl-dev#5.14.2-21+deb7u1 +libperl4caml-ocaml-dev#0.9.5-4+b4 +libpetsc3.2-dev#3.2.dfsg-6 +libpfqueue-dev#0.5.6-8 +libpfs-dev#1.8.5-1 +libpgm-dev#5.1.118-1~dfsg-0.1 +libpgocaml-ocaml-dev#1.5-2 +libpgpool-dev#3.1.3-5 +libpgtcl-dev#1:1.5-6 +libphash0-dev#0.9.4-1.2 +libphat-dev#0.4.1-5 +libphobos-4.4-dev#1.063-4.4.7-1 +libphobos2-4.6-dev#0.29.1-4.6.3-2 +libphone-ui-dev#1:0.0.1+git20110825-3 +libphone-utils-dev#0.1+git20110523-2.1 +libphonon-dev#4:4.6.0.0-3 +libphononexperimental-dev#4:4.6.0.0-3 +libphotos202-dev#20061220+dfsg3-2 +libphtools2-dev#20061220+dfsg3-2 +libphysfs-dev#2.0.2-6 +libpiano-dev#2012.05.06-2 +libpigment0.3-dev#0.3.17-1 +libpils2-dev#1.0.9+hg2665-1 +libpinyin0-dev#0.6.91-1 +libpion-common-dev#4.0.7+dfsg-3.1 +libpion-net-dev#4.0.7+dfsg-3.1 +libpipeline-dev#1.2.1-1 +libpisock-dev#0.12.5-5 +libpixman-1-dev#0.26.0-4+deb7u1 +libpkcs11-helper1-dev#1.09-1 +libplayer-dev#2.0.1-2.1 +libplayerc++3.0-dev#3.0.2+dfsg-4+b1 +libplayerc3.0-dev#3.0.2+dfsg-4+b1 +libplayercommon3.0-dev#3.0.2+dfsg-4+b1 +libplayercore3.0-dev#3.0.2+dfsg-4+b1 +libplayerdrivers3.0-dev#3.0.2+dfsg-4+b1 +libplayerinterface3.0-dev#3.0.2+dfsg-4+b1 +libplayerjpeg3.0-dev#3.0.2+dfsg-4+b1 +libplayertcp3.0-dev#3.0.2+dfsg-4+b1 +libplayerwkb3.0-dev#3.0.2+dfsg-4+b1 +libplib-dev#1.8.5-6 +libplist++-dev#1.8-1 +libplist-dev#1.8-1 +libpload-dev#1.4.2-3 +libplot-dev#2.6-3 +libploticus0-dev#2.41-5 +libplotmm-dev#0.1.2-2 +libplplot-ada0-dev#5.9.9-5 +libplplot-dev#5.9.9-5 +libplumb2-dev#1.0.9+hg2665-1 +libplumbgpl2-dev#1.0.9+hg2665-1 +libpmap3.0-dev#3.0.2+dfsg-4+b1 +libpmi0-dev#2.3.4-2+b1 +libpmount-dev#0.0.16 +libpng++-dev#0.2.5-1 +libpng12-dev#1.2.49-1 +libpnglite-dev#0.1.17-1 +libpoco-dev#1.3.6p1-4 +libpodofo-dev#0.9.0-1.1+b1 +libpoker-eval-dev#138.0-1 +libpolarssl-dev#1.2.9-1~deb7u2 +libpoldiff-dev#3.3.7-3 +libpolkit-agent-1-dev#0.105-3 +libpolkit-backend-1-dev#0.105-3 +libpolkit-gobject-1-dev#0.105-3 +libpolkit-qt-1-dev#0.103.0-1 +libpolybori-dev#0.5~rc1-2.2 +libpolylib64-dev#5.22.5-3+dfsg +libpolyml-dev#5.2.1-1.1 +libpolyorb2-dev#2.8~20110207-5.1 +libpomp-dev#1.1+dfsg-2 +libpoppler-cil-dev#0.0.3-2 +libpoppler-cpp-dev#0.18.4-6 +libpoppler-dev#0.18.4-6 +libpoppler-glib-dev#0.18.4-6 +libpoppler-private-dev#0.18.4-6 +libpoppler-qt4-dev#0.18.4-6 +libpopplerkit-dev#0.0.20051227svn-7+b1 +libpopt-dev#1.16-7 +libportaudio-dev#18.1-7.1 +libportaudio-ocaml-dev#0.2.0-1+b1 +libportmidi-dev#1:184-2.1 +libportsmf-dev#0.1~svn20101010-3 +libpostgresql-ocaml-dev#1.18.0-1 +libpostproc-dev#6:0.8.10-1 +libpotrace-dev#1.10-1 +libpowerman0-dev#2.3.5-1 +libppd-dev#2:0.10-7.1 +libppl0.11-dev#0.11.2-8 +libpq-dev#9.1.13-0wheezy1 +libpqxx3-dev#3.1-1.1 +libprelude-dev#1.0.0-9 +libpreludedb-dev#1.0.0-1.1+b2 +libpresage-dev#0.8.8-1 +libpri-dev#1.4.12-2 +libprinterconf-dev#0.5-12 +libprintsys-dev#0.6-13 +libprison-dev#1.0+dfsg-1 +libprocps0-dev#1:3.3.3-3 +libproj-dev#4.7.0-2 +libprojectm-dev#2.1.0+dfsg-1 +libprojectm-qt-dev#2.1.0+dfsg-1 +libprotobuf-c0-dev#0.14-1+b1 +libprotobuf-dev#2.4.1-3 +libprotoc-dev#2.4.1-3 +libproxy-dev#0.3.1-6 +libproxychains-dev#3.1-3 +libpspell-dev#0.60.7~20110707-1 +libpst-dev#0.6.54-4.1 +libpstoedit-dev#3.60-2+b1 +libpstreams-dev#0.7.0-2 +libpt-dev#2.10.4~dfsg-1 +libptexenc-dev#2012.20120628-4 +libpth-dev#2.0.7-16 +libpthread-stubs0-dev#0.3-3 +libpthread-workqueue-dev#0.8.2-1 +libptscotch-dev#5.1.12b.dfsg-1.2 +libpugl-dev#0~svn32+dfsg0-1 +libpulse-dev#2.0-6.1 +libpulse-ocaml-dev#0.1.2-1+b1 +libpuma-dev#1:1.1+svn20120529-2 +libpurelibc-dev#0.4.1-1 +libpurple-dev#2.10.9-1~deb7u1 +libpuzzle-dev#0.9-5 +libpwl-dev#0.11.2-8 +libpxp-ocaml-dev#1.2.2-1+b4 +libpycaml-ocaml-dev#0.82-14+b2 +libpyside-dev#1.1.1-3 +libpythia8-dev#8.1.65-1 +libpythonqt2-dev#2.0.1-1.1 +libqalculate-dev#0.9.7-8 +libqapt-dev#1.3.0-2 +libqb-dev#0.11.1-2 +libqca2-dev#2.0.3-4 +libqd-dev#2.3.11.dfsg-2.1 +libqdaccolib-dev#0.8.2-1 +libqdbm++-dev#1.8.78-2 +libqdbm-dev#1.8.78-2 +libqdjango-dev#0.2.5-2 +libqedje-dev#0.4.0+lgpl-3 +libqfits-dev#6.2.0-5 +libqgis-dev#1.7.4+1.7.5~20120320-1.1+b1 +libqglviewer-qt4-dev#2.3.4-4.2 +libqgpsmm-dev#3.6-4+deb7u1 +libqhull-dev#2009.1-3 +libqimageblitz-dev#1:0.0.6-4 +libqjson-dev#0.7.1-7 +libqmf-dev#0.16-6+deb7u1 +libqmf2-dev#0.16-6+deb7u1 +libqmfconsole2-dev#0.16-6+deb7u1 +libqmfengine1-dev#0.16-6+deb7u1 +libqmmp-dev#0.5.5-1+b1 +libqmmpui-dev#0.5.5-1+b1 +libqoauth-dev#1.0.1-1 +libqof-dev#0.8.6-1 +libqofexpensesobjects-dev#0.1.9-2 +libqpdf-dev#2.3.1-4 +libqpidbroker2-dev#0.16-6+deb7u1 +libqpidclient2-dev#0.16-6+deb7u1 +libqpidcommon2-dev#0.16-6+deb7u1 +libqpidmessaging2-dev#0.16-6+deb7u1 +libqpidtypes1-dev#0.16-6+deb7u1 +libqpol-dev#3.3.7-3 +libqpx-dev#0.7.1.002-5 +libqrencode-dev#3.3.0-2 +libqrupdate-dev#1.1.1-1 +libqsastime-dev#5.9.9-5 +libqscintilla2-dev#2.6.2-2 +libqt4-dev#4:4.8.2+dfsg-11 +libqt4-opengl-dev#4:4.8.2+dfsg-11 +libqt4-private-dev#4:4.8.2+dfsg-11 +libqt4pas-dev#2.5-6 +libqtassistantclient-dev#4.6.3-4 +libqtexengine-dev#0.3-3 +libqtgstreamer-dev#0.10.2-2 +libqtruby4shared-dev#4:4.8.4-1 +libqtwebkit-dev#2.2.1-5 +libquantlib0-dev#1.2-2+b1 +libquantum-dev#1.1.0-3 +libquicktime-dev#2:1.2.4-3 +libquorum-dev#1.4.2-3 +libquvi-dev#0.4.1-1 +libqwt-dev#6.0.0-1.2 +libqwt5-qt4-dev#5.2.2-3 +libqwtplot3d-qt4-dev#0.2.7+svn191-7 +libqxmlrpc-dev#0.0.svn6-2 +libqxmpp-dev#0.4.92-1 +libqxt-dev#0.6.1-6 +libqzeitgeist-dev#0.7.0-1+b1 +libqzion-dev#0.4.0+lgpl-4 +librabbitmq-dev#0.0.1.hg216-1 +libradare2-dev#0.9-3 +libradius1-dev#0.3.2-14 +libradiusclient-ng-dev#0.5.6-1.1 +libranlip-dev#1.0-4.1 +librapi2-dev#0.15-2.1 +libraptor1-dev#1.4.21-7.1 +libraptor2-dev#2.0.8-2 +librarian-dev#0.8.1-5 +librasqal3-dev#0.9.29-1 +librasterlite-dev#1.1~svn11-2 +libraul-dev#0.8.0+dfsg0-0.1+b1 +libraw-dev#0.14.6-2 +libraw1394-dev#2.0.9-1 +librcc-dev#0.2.9-3 +librcd-dev#0.1.13-3 +librdf0-dev#1.0.15-1+b1 +librdkit-dev#201203-3 +librdmacm-dev#1.0.15-1+deb7u1 +librdmawrap2-dev#0.16-6+deb7u1 +libreact-ocaml-dev#0.9.3-1 +libreadline-dev#6.2+dfsg-0.1 +libreadline-gplv2-dev#5.2+dfsg-2~deb7u1 +libreadline6-dev#6.2+dfsg-0.1 +librec-dev#1.5-1 +librecode-dev#3.6-20 +libref-array-dev#0.1.3-2 +libregina3-dev#3.6-2 +libregistry-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libreins-ocaml-dev#0.1a-4+b1 +libreiser4-dev#1.0.7-6.3 +librelp-dev#1.0.0-1 +libremctl-dev#3.2-4 +librenaissance0-dev#0.9.0-4+b3 +libreoffice-dev#1:3.5.4+dfsg2-0+deb7u2 +librep-dev#0.90.2-1.3 +libreplaygain-dev#1.0~r475-1 +libres-ocaml-dev#3.2.0-2+b3 +libresample1-dev#0.1.3-4 +libresid-builder-dev#2.1.1-14 +libresiprocate-1.8-dev#1.8.5-4 +libresiprocate-turn-client-1.8-dev#1.8.5-4 +librest-dev#0.7.12-3 +librest-extras-dev#0.7.12-3 +librhash-cil-dev#1.2.9-8+deb7u1 +librhash-dev#1.2.9-8+deb7u1 +librheolef-dev#6.1-2.1 +librivet-dev#1.8.0-1 +librlog-dev#1.4-2 +libroar-dev#1.0~beta2-3 +libroot-bindings-python-dev#5.34.00-2 +libroot-bindings-ruby-dev#5.34.00-2 +libroot-core-dev#5.34.00-2 +libroot-geom-dev#5.34.00-2 +libroot-graf2d-gpad-dev#5.34.00-2 +libroot-graf2d-graf-dev#5.34.00-2 +libroot-graf2d-postscript-dev#5.34.00-2 +libroot-graf3d-eve-dev#5.34.00-2 +libroot-graf3d-g3d-dev#5.34.00-2 +libroot-graf3d-gl-dev#5.34.00-2 +libroot-gui-dev#5.34.00-2 +libroot-gui-ged-dev#5.34.00-2 +libroot-hist-dev#5.34.00-2 +libroot-hist-spectrum-dev#5.34.00-2 +libroot-html-dev#5.34.00-2 +libroot-io-dev#5.34.00-2 +libroot-io-xmlparser-dev#5.34.00-2 +libroot-math-foam-dev#5.34.00-2 +libroot-math-genvector-dev#5.34.00-2 +libroot-math-mathcore-dev#5.34.00-2 +libroot-math-mathmore-dev#5.34.00-2 +libroot-math-matrix-dev#5.34.00-2 +libroot-math-minuit-dev#5.34.00-2 +libroot-math-mlp-dev#5.34.00-2 +libroot-math-physics-dev#5.34.00-2 +libroot-math-quadp-dev#5.34.00-2 +libroot-math-smatrix-dev#5.34.00-2 +libroot-math-splot-dev#5.34.00-2 +libroot-math-unuran-dev#5.34.00-2 +libroot-misc-memstat-dev#5.34.00-2 +libroot-misc-minicern-dev#5.34.00-2 +libroot-misc-table-dev#5.34.00-2 +libroot-montecarlo-eg-dev#5.34.00-2 +libroot-montecarlo-vmc-dev#5.34.00-2 +libroot-net-auth-dev#5.34.00-2 +libroot-net-bonjour-dev#5.34.00-2 +libroot-net-dev#5.34.00-2 +libroot-net-ldap-dev#5.34.00-2 +libroot-proof-clarens-dev#5.34.00-2 +libroot-proof-dev#5.34.00-2 +libroot-proof-proofplayer-dev#5.34.00-2 +libroot-roofit-dev#5.34.00-2 +libroot-tmva-dev#5.34.00-2 +libroot-tree-dev#5.34.00-2 +libroot-tree-treeplayer-dev#5.34.00-2 +librostlab-blast0-dev#1.0.0-2 +librostlab3-dev#1.0.20-1 +librpcsecgss-dev#0.19-5 +librplay3-dev#3.3.2-14 +librpm-dev#4.10.0-5+deb7u1 +librra-dev#0.14-1.2 +librrd-dev#1.4.7-2 +librsl-dev#1.42-2 +librsskit-dev#0.3-2 +librsvg2-2.0-cil-dev#2.26.0-8 +librsvg2-dev#2.36.1-2 +librsync-dev#0.9.7-9 +librtai-dev#3.8.1-4 +librtas-dev#1.3.6-1 +librtasevent-dev#1.3.6-1 +librtaudio-dev#4.0.10~ds0-2 +librtfcomp-dev#1.1-5+b1 +librtfilter-dev#1.1-4 +librtmidi-dev#1.0.15~ds0-2 +librtmp-dev#2.4+20111222.git4e06e21-1 +librubberband-dev#1.3-1.3 +librudecgi-dev#5.0.0-1 +libruli4-dev#0.33-1.1 +librxp-dev#1.5.0-1 +libs3-dev#2.0-1 +libs3d-dev#0.2.2-8 +libs3dw-dev#0.2.2-8 +libsaamf3-dev#1.1.4-4.1 +libsackpt3-dev#1.1.4-4.1 +libsaclm3-dev#1.1.4-4.1 +libsaevt3-dev#1.1.4-4.1 +libsage-dev#0.2.0-4.1 +libsalck3-dev#1.1.4-4.1 +libsam-dev#1.4.2-3 +libsamba-credentials-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-hostconfig-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-policy-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-util-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamdb-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsaml2-dev#2.4.3-4 +libsampleicc-dev#1.6.4-1+b1 +libsamplerate-ocaml-dev#0.1.1-1+b3 +libsamplerate0-dev#0.1.8-5 +libsamsg4-dev#1.1.4-4.1 +libsane-dev#1.0.22-7.4 +libsane-extras-dev#1.0.22.2 +libsanlock-dev#2.2-2 +libsary-dev#1:1.2.0-2.1 +libsasl2-dev#2.1.25.dfsg1-6+deb7u1 +libsatmr3-dev#1.1.4-4.1 +libsbjson-dev#2.3.2-2 +libsbsms-dev#2.0.1-1 +libsbuf-dev#9.0+ds1-4 +libsbuild-dev#1.6.4-4 +libsc-dev#2.3.1-14 +libscalapack-mpi-dev#1.8.0-9 +libscalapack-pvm-dev#1.8.0-9 +libscalc-dev#0.2.4-1 +libscamperfile0-dev#20111202b-1 +libschroedinger-dev#1.0.11-2 +libschroedinger-ocaml-dev#0.1.0-1+b3 +libscim-dev#1.4.13-5 +libscm-dev#5e5-3.2 +libscotch-dev#5.1.12b.dfsg-1.2 +libscotchmetis-dev#5.1.12b.dfsg-1.2 +libscotchparmetis-dev#5.1.12b.dfsg-1.2 +libsctp-dev#1.0.11+dfsg-2 +libscythestat-dev#1.0.2-1 +libsdl-console-dev#2.1-3 +libsdl-gfx1.2-dev#2.0.23-3 +libsdl-image1.2-dev#1.2.12-2 +libsdl-mixer1.2-dev#1.2.12-3 +libsdl-net1.2-dev#1.2.8-2 +libsdl-ocaml-dev#0.9.0-1 +libsdl-pango-dev#0.1.2-6 +libsdl-sge-dev#030809dfsg-3 +libsdl-sound1.2-dev#1.0.3-6 +libsdl-stretch-dev#0.3.1-3 +libsdl-ttf2.0-dev#2.0.11-2 +libsdl1.2-dev#1.2.15-5 +libsdpa-dev#7.3.8+dfsg-1 +libsearchclient-dev#0.7.7-3 +libseaudit-dev#3.3.7-3 +libseed-gtk3-dev#3.2.0-2 +libsefs-dev#3.3.7-3 +libselinux1-dev#2.1.9-5 +libsemanage1-dev#2.1.6-6 +libsensors-applet-plugin-dev#3.0.0-0.2 +libsensors4-dev#1:3.3.2-2+deb7u1 +libsepol1-dev#2.1.4-3 +libserd-dev#0.14.0~dfsg0-2 +libserf-dev#1.1.0-2 +libsexplib-camlp4-dev#7.0.4-2 +libsexy-dev#0.1.11-2+b1 +libsfml-dev#1.6+dfsg2-2 +libsfst1-1.2-0-dev#1.2.0-1.2 +libsgutils2-dev#1.33-1 +libsha-ocaml-dev#1.7-2+b2 +libshairport-dev#1.2.1~git20120110.aeb4987-2 +libshevek-dev#1.3-1 +libshhmsg1-dev#1.4.1-4.1 +libshhopt1-dev#1.1.7-2.1 +libshiboken-dev#1.1.1-1 +libshibsp-dev#2.4.3+dfsg-5+b1 +libshisa-dev#1.0.1-2 +libshishi-dev#1.0.1-2 +libshout-ocaml-dev#0.2.7-1+b3 +libshout3-dev#2.2.2-8 +libshp-dev#1.2.10-7 +libshr-glib-dev#2011.03.08.2~git20110930-2 +libsidl-dev#1.4.0.dfsg-8.1 +libsidplay1-dev#1.36.59-5 +libsidplay2-dev#2.1.1-14 +libsidplayfp-dev#0.3.5-1 +libsidutils-dev#2.1.1-14 +libsieve2-dev#2.2.6-1.1 +libsigc++-1.2-dev#1.2.7-2 +libsigc++-2.0-dev#2.2.10-0.2 +libsigc++-dev#1.0.4-9.4 +libsigrok0-dev#0.1.0-2 +libsigrokdecode0-dev#0.1.0-2 +libsigsegv-dev#2.9-4 +libsilly-dev#0.1.0-3 +libsilo-dev#4.8-13 +libsimage-dev#1.7.0-1.1+b1 +libsimplelist0-dev#0.3.4-2 +libsipwitch-dev#1.2.4-1 +libsiscone-dev#2.0.5-1 +libsiscone-spherical-dev#2.0.5-1 +libskk-dev#0.0.12-3 +libskstream-0.3-dev#0.3.8-1 +libslang2-dev#2.2.4-15 +libslepc3.2-dev#3.2-p5-1 +libslp-dev#1.2.1-9 +libslurm-dev#2.3.4-2+b1 +libslurmdb-dev#2.3.4-2+b1 +libslv2-dev#0.6.6+dfsg1-2 +libsm-dev#2:1.2.1-2 +libsmbclient-dev#2:3.6.6-6+deb7u3 +libsmbclient-raw-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsmbios-dev#2.0.3.dfsg-1.1 +libsmf-dev#1.3-2 +libsmi2-dev#0.4.8+dfsg2-7 +libsmokekde-dev#4:4.8.4-1 +libsmokeqt4-dev#4:4.8.4-1 +libsmpeg-dev#0.4.5+cvs20030824-5 +libsnacc-dev#1.3.1-1 +libsnack2-dev#2.2.10-dfsg1-12.1 +libsnappy-dev#1.0.5-2 +libsndfile1-dev#1.0.25-5 +libsndobj-dev#2.6.6.1-3 +libsnmp-dev#5.4.3~dfsg-2.8 +libsnmpkit-dev#0.9-16 +libsocialweb-client-dev#0.25.20-2.1 +libsocialweb-dev#0.25.20-2.1 +libsocksd0-dev#1.1.19.dfsg-3+b3 +libsofa-c-dev#2012.03.01-1 +libsofa1-dev#1.0~beta4-7 +libsofia-sip-ua-dev#1.12.11+20110422-1 +libsofia-sip-ua-glib-dev#1.12.11+20110422-1 +libsofthsm-dev#1.3.3-2 +libsoil-dev#1.07~20080707.dfsg-2 +libsombok-dev#2.2.1-1 +libsonic-dev#0.1.17-1.1 +libsope-dev#1.3.16-1 +libsoprano-dev#2.7.6+dfsg.1-2wheezy1 +libsoqt4-dev#1.5.0-2 +libsord-dev#0.8.0~dfsg0-1 +libsoundgen-dev#0.6-4 +libsoundtouch-dev#1.6.0-3 +libsoundtouch-ocaml-dev#0.1.7-1+b1 +libsoup-gnome2.4-dev#2.38.1-3 +libsoup2.4-dev#2.38.1-3 +libsoupcutter-dev#1.1.7-1.2 +libsource-highlight-dev#3.1.6-1.1 +libsox-dev#14.4.0-3 +libsp-gxmlcpp-dev#1.0.20040603-5 +libsp1-dev#1.3.4-1.2.1-47.1+b1 +libspandsp-dev#0.0.6~pre20-3.1 +libsparsehash-dev#1.10-1 +libsparskit-dev#2.0.0-2 +libspatialindex-dev#1.7.0-1 +libspatialite-dev#3.0.0~beta20110817-3+deb7u1 +libspctag-dev#0.2-1 +libspectre-dev#0.2.7-2 +libspectrum-dev#1.0.0-3 +libspeechd-dev#0.7.1-6.2 +libspeex-dev#1.2~rc1-7 +libspeex-ocaml-dev#0.2.0-1+b3 +libspeexdsp-dev#1.2~rc1-7 +libspf2-dev#1.2.9-7 +libsphere-dev#3.2-4 +libspice-client-glib-2.0-dev#0.12-5 +libspice-client-gtk-2.0-dev#0.12-5 +libspice-client-gtk-3.0-dev#0.12-5 +libspice-protocol-dev#0.10.1-1 +libspice-server-dev#0.11.0-1+deb7u1 +libspiro-dev#20071029-2 +libspnav-dev#0.2.2-1 +libspooles-dev#2.2-9 +libsprng2-dev#2.0a-8 +libsqlexpr-ocaml-dev#0.4.1-1+b5 +libsqlheavy-dev#0.1.1-1 +libsqlheavygtk-dev#0.1.1-1 +libsqlite0-dev#2.8.17-7 +libsqlite3-dev#3.7.13-1+deb7u1 +libsqlite3-ocaml-dev#1.6.1-1+b1 +libsquizz-dev#0.99a-2 +libsratom-dev#0.2.0~dfsg0-1 +libsrecord-dev#1.58-1+b1 +libsrf-dev#0.1+dfsg-1 +libsrtp0-dev#1.4.4+20100615~dfsg-2+deb7u1 +libss7-dev#1.0.2-3 +libsscm-dev#0.8.5-2.1 +libssh-dev#0.5.4-1+deb7u1 +libssh2-1-dev#1.4.2-1.1 +libssl-dev#1.0.1e-2+deb7u7 +libssl-ocaml-dev#0.4.6-1 +libsslcommon2-dev#0.16-6+deb7u1 +libssreflect-ocaml-dev#1.3pl4-1 +libsss-sudo-dev#1.8.4-2 +libst-dev#1.9-3 +libstaden-read-dev#1.12.4-1 +libstarlink-ast-dev#7.0.4+dfsg-1 +libstarlink-pal-dev#0.1.0-1 +libstarpu-dev#1.0.1+dfsg-1 +libstartup-notification0-dev#0.12-1 +libstatgrab-dev#0.17-1 +libstdc++6-4.4-dev#4.4.7-2 +libstdc++6-4.6-dev#4.6.3-14 +libstdc++6-4.7-dev#4.7.2-5 +libstemmer-dev#0+svn546-2 +libsteptalk-dev#0.10.0-5+b1 +libstfl-dev#0.22-1+b1 +libstk0-dev#4.4.3-2 +libstlport4.6-dev#4.6.2-7 +libstonith1-dev#1.0.9+hg2665-1 +libstonithd1-dev#1.1.7-1 +libstreamanalyzer-dev#0.7.7-3 +libstreams-dev#0.7.7-3 +libstrigihtmlgui-dev#0.7.7-3 +libstrigiqtdbusclient-dev#0.7.7-3 +libstroke0-dev#0.5.1-6 +libstxxl-dev#1.3.1-4 +libsublime-dev#1.3.1-2 +libsubtitleeditor-dev#0.33.0-1 +libsubunit-dev#0.0.8+bzr176-1 +libsugarext-dev#0.96.1-2 +libsuil-dev#0.6.4~dfsg0-3 +libsuitesparse-dev#1:3.4.0-3 +libsundials-serial-dev#2.5.0-3 +libsunpinyin-dev#2.0.3+git20120607-1 +libsuperlu3-dev#3.0+20070106-3 +libsvga1-dev#1:1.4.3-33 +libsvm-dev#3.12-1 +libsvn-dev#1.6.17dfsg-4+deb7u6 +libsvncpp-dev#0.12.0dfsg-6 +libsvnqt-dev#1.5.5-4.1 +libsvrcore-dev#1:4.0.4-15 +libswami-dev#2.0.0+svn389-2 +libswe-dev#1.77.00.0005-2 +libswiften-dev#2.0~beta1+dev47-1 +libsword-dev#1.6.2+dfsg-5 +libswscale-dev#6:0.8.10-1 +libsx-dev#2.05-3 +libsyfi1.0-dev#1.0.0.dfsg-1 +libsylph-dev#1.1.0-8 +libsymmetrica-dev#2.0-1 +libsynce0-dev#0.15-1.1 +libsyncml-dev#0.5.4-2.1 +libsynfig-dev#0.63.05-1 +libsynopsis0.12-dev#0.12-8 +libsynthesis-dev#3.4.0.16.7-1 +libsysactivity-dev#0.6.4-1 +libsysfs-dev#2.1.0+repack-2 +libsyslog-ng-dev#3.3.5-4 +libsyslog-ocaml-dev#1.4-6+b2 +libsystemd-daemon-dev#44-11+deb7u4 +libsystemd-id128-dev#44-11+deb7u4 +libsystemd-journal-dev#44-11+deb7u4 +libsystemd-login-dev#44-11+deb7u4 +libt1-dev#5.1.2-3.6 +libtacacs+1-dev#4.0.4.19-11 +libtachyon-dev#0.99~b2+dfsg-0.4 +libtag-extras-dev#1.0.1-3 +libtag1-dev#1.7.2-1 +libtagc0-dev#1.7.2-1 +libtagcoll2-dev#2.0.13-1.1 +libtaglib-cil-dev#2.0.4.0-1 +libtaglib-ocaml-dev#0.2.0-1+b1 +libtaktuk-1-dev#3.7.4-1 +libtalloc-dev#2.0.7+git20120207-1 +libtamuanova-dev#0.2-2 +libtango7-dev#7.2.6+dfsg-14 +libtaningia-dev#0.2.2-1 +libtaoframework-devil-cil-dev#2.1.svn20090801-9 +libtaoframework-ffmpeg-cil-dev#2.1.svn20090801-9 +libtaoframework-freeglut-cil-dev#2.1.svn20090801-9 +libtaoframework-freetype-cil-dev#2.1.svn20090801-9 +libtaoframework-ftgl-cil-dev#2.1.svn20090801-9 +libtaoframework-lua-cil-dev#2.1.svn20090801-9 +libtaoframework-ode-cil-dev#2.1.svn20090801-9 +libtaoframework-openal-cil-dev#2.1.svn20090801-9 +libtaoframework-opengl-cil-dev#2.1.svn20090801-9 +libtaoframework-physfs-cil-dev#2.1.svn20090801-9 +libtaoframework-sdl-cil-dev#2.1.svn20090801-9 +libtar-dev#1.2.16-1+deb7u2 +libtarantool-dev#1.4.6+20120629+2158-1 +libtasn1-3-dev#2.13-2 +libtbb-dev#4.0+r233-1 +libtcc-dev#0.9.26~git20120612.ad5f375-6 +libtcd-dev#2.2.2-1 +libtclap-dev#1.2.1-1 +libtclcl1-dev#1.20-6 +libtdb-dev#1.2.10-2 +libtecla1-dev#1.6.1-5 +libteem-dev#1.11.0~svn5226-1 +libtelepathy-farstream-dev#0.4.0-3 +libtelepathy-glib-dev#0.18.2-2 +libtelepathy-logger-dev#0.4.0-1 +libtelepathy-logger-qt4-dev#0.4.0-1 +libtelepathy-qt4-dev#0.9.1-4 +libtelnet-dev#0.21-1 +libtemplates-parser11.6-dev#11.6-2 +libterralib-dev#4.0.0-4 +libtesseract-dev#3.02.01-6 +libtevent-dev#0.9.16-1 +libtext-ocaml-dev#0.5-1+b2 +libtextwrap-dev#0.1-13 +libthai-dev#0.1.18-2 +libtheora-dev#1.1.1+dfsg.1-3.1 +libtheora-ocaml-dev#0.3.0-1+b3 +libthepeg-dev#1.8.0-1 +libthrust-dev#1.6.0-1 +libthunar-vfs-1-dev#1.2.0-3+b1 +libthunarx-2-dev#1.2.3-4+b1 +libticables-dev#1.2.0-2 +libticalcs-dev#1.1.3+dfsg1-1 +libticonv-dev#1.1.0-1.1 +libtidy-dev#20091223cvs-1.2 +libtiff4-dev#3.9.6-11 +libtiff5-alt-dev#4.0.2-6+deb7u2 +libtiff5-dev#4.0.2-6+deb7u2 +libtifiles-dev#1.1.1-1 +libtimbl3-dev#6.4.2-1 +libtimblserver2-dev#1.4-2 +libtinfo-dev#5.9-10 +libtinyxml-dev#2.6.2-1 +libtinyxml2-dev#0~git20120518.1.a2ae54e-1 +libtirpc-dev#0.2.2-5 +libtk-img-dev#1:1.3-release-12 +libtnt-dev#1.2.6-1 +libtntdb-dev#1.2-2+b1 +libtntnet-dev#2.1-2+deb7u1 +libtododb-dev#0.11-3 +libtogl-dev#1.7-12 +libtokyocabinet-dev#1.4.47-2 +libtokyotyrant-dev#1.1.40-4.1+b1 +libtolua++5.1-dev#1.0.93-3 +libtolua-dev#5.2.0-1 +libtomcrypt-dev#1.17-3.2 +libtommath-dev#0.42.0-1 +libtomoe-dev#0.6.0-1.3 +libtonezone-dev#1:2.5.0.1-2 +libtophide-ocaml-dev#1.0.0-3 +libtorch3-dev#3.1-2.1 +libtorque2-dev#2.4.16+dfsg-1+deb7u2 +libtorrent-dev#0.13.2-1 +libtorrent-rasterbar-dev#0.15.10-1+b1 +libtorture-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libtotem-dev#3.0.1-8 +libtotem-pg-dev#1.4.2-3 +libtotem-plparser-dev#3.4.2-1 +libtowitoko-dev#2.0.7-8.3 +libtpl-dev#1.5-2 +libtpm-unseal-dev#1.3.7-1 +libtrace3-dev#3.0.14-1 +libtracker-extract-0.14-dev#0.14.1-3 +libtracker-miner-0.14-dev#0.14.1-3 +libtracker-sparql-0.14-dev#0.14.1-3 +libtransitioner1-dev#1.1.7-1 +libtre-dev#0.8.0-3 +libtreil-dev#1.8-1.1 +libts-dev#1.0-11 +libtse3-dev#0.3.1-4.3 +libtsk-dev#3.2.3-2 +libtspi-dev#0.3.9-3+wheezy1 +libtulip-dev#3.7.0dfsg-4 +libtumbler-1-dev#0.1.25-1+b1 +libtut-dev#0.0.20070706-1 +libtuxcap-dev#1.4.0.dfsg2-2.1 +libtwin-dev#12.04.13.17.57-g130ee5f-2 +libtwofish-dev#0.3-3 +libtwolame-dev#0.3.13-1 +libtxc-dxtn-s2tc-dev#0~git20110809-3 +libtype-conv-camlp4-dev#3.0.4-1 +libtyxml-ocaml-dev#2.1-1 +libuchardet-dev#0.0.1-1 +libucimf-dev#2.3.8-4 +libucl-dev#1.03-5 +libuclmmbase1-dev#1.2.16.0-1 +libucommon-dev#5.2.2-4 +libucto1-dev#0.5.2-2 +libudev-dev#175-7.2 +libudf-dev#0.83-4 +libudt-dev#4.10+dfsg-1 +libudunits2-dev#2.1.23-3 +libuhd-dev#3.4.2-1 +libuim-dev#1:1.8.1-4 +libumlib-dev#0.8.2-1 +libunac1-dev#1.8.0-6 +libunbound-dev#1.4.17-3 +libunicap2-dev#0.9.12-2 +libuninameslist-dev#0.0.20091231-1.1 +libuninum-dev#2.7-1.1 +libunique-3.0-dev#3.0.2-1 +libunique-dev#1.1.6-4 +libunistring-dev#0.9.3-5 +libunittest++-dev#1.4.0-3 +libunshield-dev#0.6-3 +libunwind-setjmp0-dev#0.99-0.3 +libunwind7-dev#0.99-0.3 +libupnp-dev#1:1.6.17-1.2 +libupnp4-dev#1.8.0~svn20100507-1.2 +libupnp6-dev#1:1.6.17-1.2 +libupower-glib-dev#0.9.17-1 +libupsclient1-dev#2.6.4-2.3+deb7u1 +libupse-dev#1.0.0-1 +libuptimed-dev#1:0.3.17-3.1 +liburcu-dev#0.6.7-2 +liburfkill-glib-dev#0.3.0-1 +liburg0-dev#0.8.12-4 +liburiparser-dev#0.7.5-1 +libusb++-dev#2:0.1.12-20+nmu1 +libusb-1.0-0-dev#2:1.0.11-1 +libusb-dev#2:0.1.12-20+nmu1 +libusb-ocaml-dev#1.2.0-2+b7 +libusbip-dev#1.1.1+3.2.17-1 +libusbmuxd-dev#1.0.7-2 +libusbprog-dev#0.2.0-2 +libusbredirhost-dev#0.4.3-2 +libusbredirparser-dev#0.4.3-2 +libusbtc08-dev#1.7.2-1 +libuser1-dev#1:0.56.9.dfsg.1-1.2 +libust-dev#2.0.4-1 +libustr-dev#1.0.4-3 +libutempter-dev#1.1.5-4 +libuu-dev#0.5.20-3.3 +libuuidm-ocaml-dev#0.9.4-1 +libv4l-dev#0.8.8-3 +libv8-dev#3.8.9.20-2 +libv8-i18n-dev#0~0.svn7-3 +libva-dev#1.0.15-4 +libvala-0.14-dev#0.14.2-2 +libvala-0.16-dev#0.16.1-2 +libvaladoc-dev#0.3.2~git20120227-1 +libvalhalla-dev#2.0.0-4+b1 +libvanessa-adt-dev#0.0.9-1 +libvanessa-logger-dev#0.0.10-1.1 +libvanessa-socket-dev#0.0.12-1 +libvarconf-dev#0.6.7-2 +libvarnishapi-dev#3.0.2-2+deb7u1 +libvbr-dev#2.6.8-4 +libvc-dev#003.dfsg.1-12 +libvcdinfo-dev#0.7.24+dfsg-0.1 +libvde-dev#2.3.2-4 +libvdeplug-dev#2.3.2-4 +libvdk2-dev#2.4.0-5.3 +libvdkbuilder2-dev#2.4.0-4.3 +libvdkxdb2-dev#2.4.0-3.4 +libvdpau-dev#0.4.1-7 +libventrilo-dev#1.2.4-1 +libverbiste-dev#0.1.34-1 +libverto-dev#0.2.2-1 +libvformat-dev#1.13-10 +libvia-dev#2.0.4-2 +libvibrant6-dev#6.1.20120620-2 +libview-dev#0.6.6-2.1 +libvigraimpex-dev#1.7.1+dfsg1-3 +libvips-dev#7.28.5-1+deb7u1 +libvirt-dev#0.9.12.3-1 +libvirt-glib-1.0-dev#0.0.8-1 +libvirt-ocaml-dev#0.6.1.2-1 +libvisca-dev#1.0.1-1 +libvisio-dev#0.0.17-1 +libvisual-0.4-dev#0.4.0-5 +libvlc-dev#2.0.3-5 +libvlccore-dev#2.0.3-5 +libvmmlib-dev#1.0-2 +libvncserver-dev#0.9.9+dfsg-1 +libvo-aacenc-dev#0.1.2-1 +libvo-amrwbenc-dev#0.1.2-1 +libvoaacenc-ocaml-dev#0.1.0-1+b1 +libvoikko-dev#3.5-1.1 +libvolpack1-dev#1.0b3-3 +libvorbis-dev#1.3.2-1.3 +libvorbis-ocaml-dev#0.6.1-1+b1 +libvorbisidec-dev#1.0.2+svn18153-0.2 +libvotequorum-dev#1.4.2-3 +libvpb-dev#4.2.55-1 +libvpx-dev#1.1.0-1 +libvrb0-dev#0.5.1-5.1 +libvte-2.90-dev#1:0.32.2-1 +libvte-dev#1:0.28.2-5 +libvte0.16-cil-dev#2.26.0-8 +libvtk5-dev#5.8.0-13+b1 +libvtk5-qt4-dev#5.8.0-13+b1 +libvtkedge-dev#0.2.0~20110819-2 +libvtkgdcm2-dev#2.2.0-14.1 +libvxl1-dev#1.14.0-18 +libwacom-dev#0.6-1 +libwaei-dev#3.4.3-1 +libwaili-dev#19990723-20 +libwavefront-standalone3.0-dev#3.0.2+dfsg-4+b1 +libwavpack-dev#4.60.1-3 +libwayland-dev#0.85.0-2 +libwbclient-dev#2:3.6.6-6+deb7u3 +libwbxml2-dev#0.10.7-1 +libwcstools-dev#3.8.5-1 +libwebauth-dev#4.1.1-2 +libwebcam0-dev#0.2.2-1 +libwebkit-cil-dev#0.3-6 +libwebkit-dev#1.8.1-3.4 +libwebkitgtk-3.0-dev#1.8.1-3.4 +libwebkitgtk-dev#1.8.1-3.4 +libwebp-dev#0.1.3-3+nmu1 +libwebrtc-audio-processing-dev#0.1-2 +libweed-dev#1.6.2~ds1-2 +libwfmath-0.3-dev#0.3.12-3 +libwfut-0.2-dev#0.2.1-2 +libwibble-dev#0.1.28-1.1 +libwildmidi-dev#0.2.3.4-2.1 +libwine-dev#1.4.1-4 +libwings-dev#0.95.3-2 +libwireshark-dev#1.8.2-5wheezy10 +libwiretap-dev#1.8.2-5wheezy10 +libwmf-dev#0.2.8.4-10.3 +libwnck-3-dev#3.4.2-1 +libwnck-dev#2.30.7-1 +libwnck1.0-cil-dev#2.26.0-8 +libwnn-dev#1.1.1~a021+cvs20100325-6 +libwnn6-dev#1.0.0-14.2+b1 +libwpd-dev#0.9.4-3 +libwpg-dev#0.2.1-1 +libwps-dev#0.2.7-1 +libwrap0-dev#7.6.q-24 +libwraster3-dev#0.95.3-2 +libwreport-dev#2.4-1 +libwsutil-dev#1.8.2-5wheezy10 +libwt-dev#3.2.1-2 +libwtdbo-dev#3.2.1-2 +libwtdbofirebird-dev#3.2.1-2 +libwtdbopostgres-dev#3.2.1-2 +libwtdbosqlite-dev#3.2.1-2 +libwtext-dev#3.2.1-2 +libwtfcgi-dev#3.2.1-2 +libwthttp-dev#3.2.1-2 +libwttest-dev#3.2.1-2 +libwv-dev#1.2.9-3 +libwv2-dev#0.4.2.dfsg.2-1~deb7u1 +libwvstreams-dev#4.6.1-5 +libwxbase2.8-dev#2.8.12.1-12 +libwxgtk2.8-dev#2.8.12.1-12 +libwxsmithlib-dev#10.05-2.1 +libwxsmithlib0-dev#10.05-2.1 +libwxsqlite3-2.8-dev#3.0.0.1~dfsg0-2 +libwxsvg-dev#2:1.1.8~dfsg0-2 +libx11-dev#2:1.5.0-1+deb7u1 +libx11-xcb-dev#2:1.5.0-1+deb7u1 +libx264-dev#2:0.123.2189+git35cf912-1 +libx52pro-dev#0.1.1-2.1 +libx86-dev#1.1+ds1-10 +libxalan110-dev#1.10-6 +libxapian-dev#1.2.12-2 +libxatracker-dev#8.0.5-4+deb7u2 +libxau-dev#1:1.0.7-1 +libxaw7-dev#2:1.0.10-2 +libxbae-dev#4.60.4-3 +libxbase2.0-dev#2.0.0-8.5 +libxcb-composite0-dev#1.8.1-2+deb7u1 +libxcb-damage0-dev#1.8.1-2+deb7u1 +libxcb-dpms0-dev#1.8.1-2+deb7u1 +libxcb-dri2-0-dev#1.8.1-2+deb7u1 +libxcb-ewmh-dev#0.3.9-2 +libxcb-glx0-dev#1.8.1-2+deb7u1 +libxcb-icccm4-dev#0.3.9-2 +libxcb-image0-dev#0.3.9-1 +libxcb-keysyms1-dev#0.3.9-1 +libxcb-randr0-dev#1.8.1-2+deb7u1 +libxcb-record0-dev#1.8.1-2+deb7u1 +libxcb-render-util0-dev#0.3.8-1.1 +libxcb-render0-dev#1.8.1-2+deb7u1 +libxcb-res0-dev#1.8.1-2+deb7u1 +libxcb-screensaver0-dev#1.8.1-2+deb7u1 +libxcb-shape0-dev#1.8.1-2+deb7u1 +libxcb-shm0-dev#1.8.1-2+deb7u1 +libxcb-sync0-dev#1.8.1-2+deb7u1 +libxcb-util0-dev#0.3.8-2 +libxcb-xevie0-dev#1.8.1-2+deb7u1 +libxcb-xf86dri0-dev#1.8.1-2+deb7u1 +libxcb-xfixes0-dev#1.8.1-2+deb7u1 +libxcb-xinerama0-dev#1.8.1-2+deb7u1 +libxcb-xprint0-dev#1.8.1-2+deb7u1 +libxcb-xtest0-dev#1.8.1-2+deb7u1 +libxcb-xv0-dev#1.8.1-2+deb7u1 +libxcb-xvmc0-dev#1.8.1-2+deb7u1 +libxcb1-dev#1.8.1-2+deb7u1 +libxcomp-dev#3.5.0.12-1+b1 +libxcomposite-dev#1:0.4.3-2 +libxcp-ocaml-dev#0.5.2-3+b1 +libxcrypt-dev#1:2.4-3 +libxcursor-dev#1:1.1.13-1+deb7u1 +libxdamage-dev#1:1.1.3-2 +libxdb-dev#1.2.0-7.2 +libxdelta2-dev#1.1.3-9 +libxdffileio-dev#0.3-1 +libxdg-basedir-dev#1.1.1-2 +libxdmcp-dev#1:1.1.1-1 +libxdmf-dev#2.1.dfsg.1-5 +libxdo-dev#1:2.20100701.2961-3+deb7u3 +libxen-dev#4.1.4-3+deb7u1 +libxen-ocaml-dev#4.1.4-3+deb7u1 +libxenapi-ocaml-dev#1.3.2-15 +libxenomai-dev#2.6.0-2 +libxerces-c-dev#3.1.1-3 +libxerces-c2-dev#2.8.0+deb1-3 +libxext-dev#2:1.3.1-2+deb7u1 +libxfce4menu-0.1-dev#4.6.2-1 +libxfce4ui-1-dev#4.8.1-1 +libxfce4util-dev#4.8.2-1 +libxfcegui4-dev#4.8.1-5 +libxfconf-0-dev#4.8.1-1 +libxfixes-dev#1:5.0-4+deb7u1 +libxfont-dev#1:1.4.5-3 +libxft-dev#2.3.1-1 +libxi-dev#2:1.6.1-1+deb7u1 +libxine-dev#1.1.21-1+deb7u1 +libxine2-dev#1.2.2-5 +libxinerama-dev#2:1.1.2-1+deb7u1 +libxkbfile-dev#1:1.0.8-1 +libxklavier-dev#5.2.1-1 +libxml++2.6-dev#2.34.2-1 +libxml-light-ocaml-dev#2.2-15 +libxml-security-c-dev#1.6.1-5+deb7u2 +libxml2-dev#2.8.0+dfsg1-7+nmu3 +libxmlada4.1-dev#4.1-2 +libxmlezout2-dev#1.06.1-5 +libxmlm-ocaml-dev#1.1.0-1 +libxmlplaylist-ocaml-dev#0.1.3-1+b2 +libxmlrpc-c++4-dev#1.16.33-3.2 +libxmlrpc-c3-dev#1.16.33-3.2 +libxmlrpc-core-c3-dev#1.16.33-3.2 +libxmlrpc-epi-dev#0.54.2-1 +libxmlrpc-light-ocaml-dev#0.6.1-3+b5 +libxmlsec1-dev#1.2.18-2 +libxmltok1-dev#1.2-3 +libxmltooling-dev#1.4.2-5 +libxmmsclient++-dev#0.8+dfsg-4 +libxmmsclient++-glib-dev#0.8+dfsg-4 +libxmmsclient-dev#0.8+dfsg-4 +libxmmsclient-glib-dev#0.8+dfsg-4 +libxmpi4-dev#2.2.3b8-13 +libxmu-dev#2:1.1.1-1 +libxmuu-dev#2:1.1.1-1 +libxnee-dev#3.13-1 +libxneur-dev#0.15.0-1.1 +libxosd-dev#2.2.14-2 +libxp-dev#1:1.0.1-2+deb7u1 +libxpa-dev#2.1.14-2 +libxplc0.3.13-dev#0.3.13-3 +libxpm-dev#1:3.5.10-1 +libxqdbm-dev#1.8.78-2 +libxqilla-dev#2.3.0-1 +libxr1-dev#1.0-2.1 +libxrandr-dev#2:1.3.2-2+deb7u1 +libxrender-dev#1:0.9.7-1+deb7u1 +libxres-dev#2:1.0.6-1+deb7u1 +libxsettings-client-dev#0.17-6 +libxsettings-dev#0.11-3 +libxslt1-dev#1.1.26-14.1 +libxss-dev#1:1.2.2-1 +libxstr-ocaml-dev#0.2.1-21+b3 +libxstrp4-camlp4-dev#1.8-3 +libxt-dev#1:1.1.3-1+deb7u1 +libxtst-dev#2:1.2.1-1+deb7u1 +libxv-dev#2:1.0.7-1+deb7u1 +libxvidcore-dev#2:1.3.2-9 +libxvmc-dev#2:1.0.7-1+deb7u2 +libxxf86dga-dev#2:1.1.3-2+deb7u1 +libxxf86vm-dev#1:1.1.2-1+deb7u1 +libxy-dev#0.8-1+b1 +libyahoo2-dev#1.0.1-1 +libyajl-dev#2.0.4-2 +libyaml-cpp-dev#0.3.0-1 +libyaml-dev#0.1.4-2+deb7u4 +libyaz4-dev#4.2.30-2 +libyelp-dev#3.4.2-1+b1 +libygl4-dev#4.2e-4 +libykclient-dev#2.6-1 +libykpers-1-dev#1.7.0-1 +libyojson-ocaml-dev#1.0.3-1 +libytnef0-dev#1.5-4 +libyubikey-dev#1.8-1 +libz80ex-dev#1.1.19-3 +libzarith-ocaml-dev#1.1-2 +libzbar-dev#0.10+doc-8 +libzbargtk-dev#0.10+doc-8 +libzbarqt-dev#0.10+doc-8 +libzeep-dev#2.9.0-2 +libzeitgeist-cil-dev#0.8.0.0-4 +libzeitgeist-dev#0.3.18-1 +libzen-dev#0.4.27-2 +libzephyr-dev#3.0.2-2 +libzerg0-dev#1.0.7-3 +libzeroc-ice34-dev#3.4.2-8.2 +libzinnia-dev#0.06-1+b1 +libzip-dev#0.10.1-1.1 +libzip-ocaml-dev#1.04-6+b3 +libzipios++-dev#0.1.5.9+cvs.2007.04.28-5.1 +libzita-alsa-pcmi-dev#0.2.0-1 +libzita-convolver-dev#3.1.0-2 +libzita-resampler-dev#1.1.0-3 +libzlcore-dev#0.12.10dfsg-8 +libzltext-dev#0.12.10dfsg-8 +libzmq-dev#2.2.0+dfsg-2 +libzn-poly-dev#0.8-1.1 +libzookeeper-mt-dev#3.3.5+dfsg1-2 +libzookeeper-st-dev#3.3.5+dfsg1-2 +libzorp-dev#3.9.5-4 +libzorpll-dev#3.9.1.3-1 +libzrtpcpp-dev#2.0.0-3 +libzthread-dev#2.3.2-7 +libzvbi-dev#0.2.33-6 +libzzip-dev#0.13.56-1.1 +licq-dev#1.6.1-3 +linux-libc-dev#3.2.57-3 +lldpad-dev#0.9.44-1 +llvm-2.9-dev#2.9+dfsg-7 +llvm-3.0-dev#3.0-10 +llvm-3.1-dev#3.1-1 +llvm-dev#1:3.0-14+nmu2 +lttv-dev#0.12.38-21032011-1+b1 +lua-apr-dev#0.23.2-1 +lua-bitop-dev#1.0.2-1 +lua-curl-dev#0.3.0-7 +lua-curses-dev#5.1.19-2 +lua-cyrussasl-dev#1.0.0-4 +lua-dbi-mysql-dev#0.5+svn78-4 +lua-dbi-postgresql-dev#0.5+svn78-4 +lua-dbi-sqlite3-dev#0.5+svn78-4 +lua-event-dev#0.4.1-2 +lua-expat-dev#1.2.0-5+deb7u1 +lua-filesystem-dev#1.5.0+16+g84f1af5-1 +lua-iconv-dev#7-1 +lua-ldap-dev#1.1.0-1-geeac494-3 +lua-leg-dev#0.1.2-8 +lua-lgi-dev#0.6.2-1 +lua-lpeg-dev#0.10.2-5 +lua-md5-dev#1.1.2-6 +lua-penlight-dev#1.0.2+htmldoc-2 +lua-posix-dev#5.1.19-2 +lua-rex-onig-dev#2.6.0-2 +lua-rex-pcre-dev#2.6.0-2 +lua-rex-posix-dev#2.6.0-2 +lua-rex-tre-dev#2.6.0-2 +lua-rings-dev#1.2.3-1 +lua-sec-dev#0.4.1-1 +lua-socket-dev#2.0.2-8 +lua-sql-mysql-dev#2.3.0-1+build0 +lua-sql-postgres-dev#2.3.0-1+build0 +lua-sql-sqlite3-dev#2.3.0-1+build0 +lua-svn-dev#0.4.0-7 +lua-wsapi-fcgi-dev#1.5-3 +lua-zip-dev#1.2.3-11 +lua-zlib-dev#0.2-1 +lua5.1-policy-dev#33 +lv2-dev#1.0.0~dfsg2-2 +lxc-dev#0.8.0~rc1-8+deb7u2 +lzma-dev#9.22-2 +manpages-de-dev#1.2-1 +manpages-dev#3.44-1 +manpages-fr-dev#3.44d1p1-1 +manpages-ja-dev#0.5.0.0.20120606-1 +manpages-pl-dev#1:0.3-1 +manpages-pt-dev#20040726-4 +matlab-support-dev#0.0.18 +mdbtools-dev#0.7-1+deb7u1 +med-bio-dev#1.13.2 +med-imaging-dev#1.13.2 +mesa-common-dev#8.0.5-4+deb7u2 +mffm-fftw-dev#1.7-3 +mffm-timecode-dev#1.6-2 +mingw-w64-dev#2.0.3-1 +mingw-w64-i686-dev#2.0.3-1 +mingw-w64-x86-64-dev#2.0.3-1 +minpack-dev#19961126+dfsg1-1 +mongodb-dev#1:2.0.6-1.1 +mpi-default-dev#1.0.1 +muroard-dev#0.1.10-2 +neko-dev#1.8.1-6 +nettle-dev#2.4-3 +network-manager-dev#0.9.4.0-10 +ntfs-3g-dev#1:2012.1.15AR.5-2.1 +ocfs2-tools-dev#1.6.4-1+deb7u1 +ocl-icd-dev#1.3-3 +ocl-icd-opencl-dev#1.3-3 +ocsigen-dev#1.3.4-2 +octave-pkg-dev#1.0.2 +ofono-dev#1.6-2 +okteta-dev#4:4.8.4+dfsg-1 +okular-dev#4:4.8.4-3 +open-vm-tools-dev#2:8.8.0+2012.05.21-724730-1+nmu2 +openais-dev#1.1.4-4.1 +openbox-dev#3.5.0-7 +openchangeserver-dev#1:1.0-3 +oss4-dev#4.2-build2006-2+deb7u1 +pacemaker-dev#1.1.7-1 +packaging-dev#0.4 +paraview-dev#3.14.1-6 +parole-dev#0.2.0.6-1+b1 +parser3-dev#3.4.2-2 +pbs-drmaa-dev#1.0.10-3 +petsc-dev#3.2.dfsg-6 +php5-dev#5.4.4-14+deb7u9 +pidgin-dev#2.10.9-1~deb7u1 +pinball-dev#0.3.1-13.1 +planetpenguin-racer-gimp-dev#0.4-5 +planner-dev#0.14.6-1 +plplot-tcl-dev#5.9.9-5 +plptools-dev#1.0.9-2.4 +plymouth-dev#0.8.5.1-5 +portaudio19-dev#19+svn20111121-1 +postfix-dev#2.9.6-2 +ppl-dev#0.11.2-8 +ppp-dev#2.4.5-5.1 +prayer-templates-dev#1.3.4-dfsg1-1 +proftpd-dev#1.3.4a-5+deb7u1 +pslib-dev#0.4.5-3 +publib-dev#0.40-1 +puredata-dev#0.43.2-5 +pvm-dev#3.4.5-12.5 +pxlib-dev#0.6.5-1 +python-all-dev#2.7.3-4+deb7u1 +python-apt-dev#0.8.8.2 +python-cairo-dev#1.8.8-1 +python-cxx-dev#6.2.4-3 +python-dbus-dev#1.1.1-1 +python-dev#2.7.3-4+deb7u1 +python-egenix-mx-base-dev#3.2.1-1.1 +python-gamera-dev#3.3.3-2 +python-gi-dev#3.2.2-2 +python-gnome2-desktop-dev#2.32.0+dfsg-2 +python-gnome2-dev#2.28.1+dfsg-1 +python-gnome2-extras-dev#2.25.3-12 +python-gobject-2-dev#2.28.6-10 +python-gobject-dev#3.2.2-2 +python-greenlet-dev#0.3.1-2.5 +python-gst0.10-dev#0.10.22-3 +python-gtk2-dev#2.24.0-3 +python-kde4-dev#4:4.8.4-1 +python-ldb-dev#1:1.1.6-1 +python-openturns-dev#1.0-4 +python-pyorbit-dev#2.24.0-6 +python-qt4-dev#4.9.3-4 +python-sip-dev#4.13.3-2 +python-talloc-dev#2.0.7+git20120207-1 +python-webkit-dev#1.1.8-2 +python2.6-dev#2.6.8-1.1 +python2.7-dev#2.7.3-6+deb7u2 +python3-all-dev#3.2.3-6 +python3-cairo-dev#1.10.0+dfsg-2 +python3-cxx-dev#6.2.4-3 +python3-dev#3.2.3-6 +python3-sip-dev#4.13.3-2 +python3.2-dev#3.2.3-7 +qmf-dev#1.0.7~2011w23.2-2.1 +qtmobility-dev#1.2.0-3 +r-base-dev#2.15.1-4 +regina-normal-dev#4.93-1 +resource-agents-dev#1:3.9.2-5+deb7u2 +rhythmbox-dev#2.97-2.1 +rivet-plugins-dev#1.8.0-1 +roarplaylistd-dev#0.1.1-2 +robot-player-dev#3.0.2+dfsg-4 +ruby-dev#1:1.9.3 +ruby-gnome2-dev#1.1.3-2+b1 +ruby1.8-dev#1.8.7.358-7.1+deb7u1 +ruby1.9.1-dev#1.9.3.194-8.1+deb7u2 +rygel-1.0-dev#0.14.3-2+deb7u1 +samba4-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +sbnc-php-dev#1.2-26 +science-astronomy-dev#1.0 +science-dataacquisition-dev#1.0 +science-engineering-dev#1.0 +science-highenergy-physics-dev#1.0 +science-mathematics-dev#1.0 +science-meteorology-dev#1.0 +science-nanoscale-physics-dev#1.0 +science-physics-dev#1.0 +scim-dev#1.4.13-5 +sciplot-dev#1.36-15 +selinux-policy-dev#2:2.20110726-12 +seqan-dev#1.3.1-1 +sfftw-dev#2.1.5-1 +skalibs-dev#0.47-1 +slurm-drmaa-dev#1.0.4-3 +slurm-llnl-basic-plugins-dev#2.3.4-2+b1 +snappea-dev#3.0d3-22 +spl-dev#1.0~pre6-3.1+b1 +sra-toolkit-libs-dev#2.1.7a-1 +ss-dev#2.0-1.42.5-1.1 +stx-btree-dev#0.8.6-1 +styx-dev#1.8.0-1.1 +supercollider-dev#1:3.4.5-1wheezy1 +svdrpservice-dev#0.0.4-14 +sweep-dev#0.9.3-6 +swish-e-dev#2.4.7-3 +syfi-dev#1.0.0.dfsg-1 +system-tools-backends-dev#2.10.2-1 +systemtap-sdt-dev#1.7-1+deb7u1 +tcl-dev#8.5.0-2.1 +tcl-memchan-dev#2.3-2 +tcl-trf-dev#2.1.4-dfsg1-1 +tcl8.4-dev#8.4.19-5 +tcl8.5-dev#8.5.11-2 +tclcl-dev#1.20-6 +tclx8.4-dev#8.4.0-3 +tclxml-dev#3.3~svn11-2 +tdom-dev#0.8.3~20080525-3+nmu2 +tesseract-ocr-dev#3.02.01-6 +tix-dev#8.4.3-4 +tk-dev#8.5.0-2.1 +tk8.4-dev#8.4.19-5 +tk8.5-dev#8.5.11-2 +tqsllib-dev#2.2-5 +trafficserver-dev#3.0.5-1 +tuxpaint-dev#1:0.9.21-1.1 +unagi-dev#0.3.3-2 +unixodbc-dev#2.2.14p2-5 +uthash-dev#1.9.5-1 +uuid-dev#2.20.1-5.3 +vdr-dev#1.7.28-1 +vflib3-dev#3.6.14.dfsg-3+b1 +voms-dev#2.0.8-1 +vstream-client-dev#1.2-6.1 +wcslib-dev#4.13.4-1 +weechat-dev#0.3.8-1+deb7u1 +wireshark-dev#1.8.2-5wheezy10 +witty-dev#3.2.1-2 +wordnet-dev#1:3.0-29 +wzdftpd-dev#0.8.3-6.2 +x11proto-bigreqs-dev#1:1.1.2-1 +x11proto-composite-dev#1:0.4.2-2 +x11proto-core-dev#7.0.23-1 +x11proto-damage-dev#1:1.2.1-2 +x11proto-dmx-dev#1:2.3.1-2 +x11proto-dri2-dev#2.6-2 +x11proto-fixes-dev#1:5.0-2 +x11proto-fonts-dev#2.1.2-1 +x11proto-gl-dev#1.4.15-1 +x11proto-input-dev#2.2-1 +x11proto-kb-dev#1.0.6-2 +x11proto-print-dev#1.0.5-2 +x11proto-randr-dev#1.3.2-2 +x11proto-record-dev#1.14.2-1 +x11proto-render-dev#2:0.11.1-2 +x11proto-resource-dev#1.2.0-3 +x11proto-scrnsaver-dev#1.2.2-1 +x11proto-video-dev#2.3.1-2 +x11proto-xcmisc-dev#1.2.2-1 +x11proto-xext-dev#7.2.1-1 +x11proto-xf86bigfont-dev#1.2.0-3 +x11proto-xf86dga-dev#2.1-3 +x11proto-xf86dri-dev#2.1.1-2 +x11proto-xf86vidmode-dev#2.3.1-2 +x11proto-xinerama-dev#1.2.1-2 +xaw3dg-dev#1.5+E-18.2 +xbmc-eventclients-dev#2:11.0~git20120510.82388d5-1 +xfce4-panel-dev#4.8.6-4 +xfslibs-dev#3.1.7+b1 +xmhtml1-dev#1.1.7-18 +xmms2-dev#0.8+dfsg-4 +xorg-dev#1:7.7+3~deb7u1 +xotcl-dev#1.6.7-2 +xpaint-dev#2.9.1.4-3+b2 +xserver-xorg-dev#2:1.12.4-6+deb7u2 +xserver-xorg-input-evdev-dev#1:2.7.0-1 +xserver-xorg-input-joystick-dev#1:1.6.1-1 +xserver-xorg-input-synaptics-dev#1.6.2-2 +xtrans-dev#1.2.7-1 +xulrunner-dev#24.4.0esr-1~deb7u2 +xutils-dev#1:7.7~1 +xviewg-dev#3.2p1.4-28.1 +yate-dev#4.1.0-1~dfsg-3 +yorick-dev#2.2.02+dfsg-6 +zathura-dev#0.1.2-4 +zlib1g-dev#1:1.2.7.dfsg-13 +znc-dev#0.206-2 +zsh-dev#4.3.17-1 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t09_repo/__init__.py b/src/github.com/smira/aptly/system/t09_repo/__init__.py index 54b70ef5..302f65c1 100644 --- a/src/github.com/smira/aptly/system/t09_repo/__init__.py +++ b/src/github.com/smira/aptly/system/t09_repo/__init__.py @@ -14,3 +14,4 @@ from .remove import * from .show import * from .rename import * from .search import * +from .include import * diff --git a/src/github.com/smira/aptly/system/t09_repo/create.py b/src/github.com/smira/aptly/system/t09_repo/create.py index 3abd9c6f..3112dc58 100644 --- a/src/github.com/smira/aptly/system/t09_repo/create.py +++ b/src/github.com/smira/aptly/system/t09_repo/create.py @@ -1,6 +1,11 @@ +import os +import inspect from lib import BaseTest +changesRemove = lambda _, s: s.replace(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), "") + + class CreateRepo1Test(BaseTest): """ create local repo: regular repo @@ -30,3 +35,31 @@ class CreateRepo3Test(BaseTest): fixtureCmds = ["aptly repo create repo3"] runCmd = "aptly repo create -comment=Repository3 repo3" expectedCode = 1 + + +class CreateRepo4Test(BaseTest): + """ + create local repo: with uploaders.json + """ + runCmd = "aptly repo create -uploaders-file=${changes}/uploaders2.json repo4" + + def check(self): + self.check_output() + self.check_cmd_output("aptly repo show repo4", "repo_show") + + +class CreateRepo5Test(BaseTest): + """ + create local repo: with broken uploaders.json + """ + runCmd = "aptly repo create -uploaders-file=${changes}/uploaders3.json repo5" + expectedCode = 1 + + +class CreateRepo6Test(BaseTest): + """ + create local repo: with missing uploaders.json + """ + runCmd = "aptly repo create -uploaders-file=${changes}/uploaders-not-found.json repo6" + expectedCode = 1 + outputMatchPrepare = changesRemove diff --git a/src/github.com/smira/aptly/system/t09_repo/edit.py b/src/github.com/smira/aptly/system/t09_repo/edit.py index 075fcf89..55e56985 100644 --- a/src/github.com/smira/aptly/system/t09_repo/edit.py +++ b/src/github.com/smira/aptly/system/t09_repo/edit.py @@ -1,6 +1,11 @@ +import os +import inspect from lib import BaseTest +changesRemove = lambda _, s: s.replace(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), "") + + class EditRepo1Test(BaseTest): """ edit repo: change comment @@ -35,3 +40,54 @@ class EditRepo3Test(BaseTest): """ runCmd = "aptly repo edit repo3" expectedCode = 1 + + +class EditRepo4Test(BaseTest): + """ + edit repo: add uploaders.json + """ + fixtureCmds = [ + "aptly repo create repo4", + ] + runCmd = "aptly repo edit -uploaders-file=${changes}/uploaders2.json repo4" + + def check(self): + self.check_output() + self.check_cmd_output("aptly repo show repo4", "repo_show") + + +class EditRepo5Test(BaseTest): + """ + edit repo: with broken uploaders.json + """ + fixtureCmds = [ + "aptly repo create repo5", + ] + runCmd = "aptly repo edit -uploaders-file=${changes}/uploaders3.json repo5" + expectedCode = 1 + + +class EditRepo6Test(BaseTest): + """ + edit local repo: with missing uploaders.json + """ + fixtureCmds = [ + "aptly repo create repo6", + ] + runCmd = "aptly repo edit -uploaders-file=${changes}/uploaders-not-found.json repo6" + expectedCode = 1 + outputMatchPrepare = changesRemove + + +class EditRepo7Test(BaseTest): + """ + edit local repo: remove uploaders.json + """ + fixtureCmds = [ + "aptly repo create -uploaders-file=${changes}/uploaders2.json repo7", + ] + runCmd = "aptly repo edit -uploaders-file= repo7" + + def check(self): + self.check_output() + self.check_cmd_output("aptly repo show repo7", "repo_show") diff --git a/src/github.com/smira/aptly/system/t09_repo/include.py b/src/github.com/smira/aptly/system/t09_repo/include.py new file mode 100644 index 00000000..3f7aeabb --- /dev/null +++ b/src/github.com/smira/aptly/system/t09_repo/include.py @@ -0,0 +1,432 @@ +import tempfile +import shutil +import os +import inspect +import re +from lib import BaseTest + +gpgRemove = lambda _, s: re.sub(r'Signature made .* using|gpgv: keyblock resource .*$|gpgv: Can\'t check signature: .*$', '', s, flags=re.MULTILINE) +changesRemove = lambda _, s: s.replace(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), "") +tempDirRemove = lambda self, s: s.replace(self.tempSrcDir, "") + + +class IncludeRepo1Test(BaseTest): + """ + include packages to local repo: .changes file from directory + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = gpgRemove + + def check(self): + self.check_output() + self.check_cmd_output("aptly repo show -with-packages unstable", "repo_show") + + # check pool + self.check_exists('pool//20/81/hardlink_0.2.1_amd64.deb') + self.check_exists('pool/4e/fc/hardlink_0.2.1.dsc') + self.check_exists('pool/8e/2c/hardlink_0.2.1.tar.gz') + + +class IncludeRepo2Test(BaseTest): + """ + include packages to local repo: .changes file from file + custom repo + """ + fixtureCmds = [ + "aptly repo create my-unstable", + "aptly repo add my-unstable ${files}", + ] + runCmd = "aptly repo include -no-remove-files -keyring=${files}/aptly.pub -repo=my-{{.Distribution}} ${changes}/hardlink_0.2.1_amd64.changes" + outputMatchPrepare = gpgRemove + + def check(self): + self.check_output() + self.check_cmd_output("aptly repo show -with-packages my-unstable", "repo_show") + + # check pool + self.check_exists('pool//20/81/hardlink_0.2.1_amd64.deb') + self.check_exists('pool/4e/fc/hardlink_0.2.1.dsc') + self.check_exists('pool/8e/2c/hardlink_0.2.1.tar.gz') + + +class IncludeRepo3Test(BaseTest): + """ + include packages to local repo: broken repo flag + """ + fixtureCmds = [ + ] + runCmd = "aptly repo include -no-remove-files -keyring=${files}/aptly.pub -repo=my-{{.Distribution} ${changes}" + expectedCode = 1 + outputMatchPrepare = lambda _, s: s.replace('; missing space?', '') + + +class IncludeRepo4Test(BaseTest): + """ + include packages to local repo: missing repo + """ + fixtureCmds = [ + ] + runCmd = "aptly repo include -no-remove-files -ignore-signatures -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = changesRemove + expectedCode = 1 + + +class IncludeRepo5Test(BaseTest): + """ + include packages to local repo: remove files being added + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -keyring=${files}/aptly.pub " + outputMatchPrepare = gpgRemove + + def prepare(self): + super(IncludeRepo5Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + + shutil.copytree(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), os.path.join(self.tempSrcDir, "01")) + + shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "files", "pyspi_0.6.1-1.3.diff.gz"), + os.path.join(self.tempSrcDir, "01", "pyspi_0.6.1-1.3.diff.gz")) + + self.runCmd += self.tempSrcDir + + def check(self): + try: + self.check_output() + self.check_cmd_output("aptly repo show -with-packages unstable", "repo_show") + + # check pool + self.check_exists('pool//20/81/hardlink_0.2.1_amd64.deb') + self.check_exists('pool/4e/fc/hardlink_0.2.1.dsc') + self.check_exists('pool/8e/2c/hardlink_0.2.1.tar.gz') + + for path in ["hardlink_0.2.1.dsc", "hardlink_0.2.1.tar.gz", "hardlink_0.2.1_amd64.changes", "hardlink_0.2.1_amd64.deb"]: + path = os.path.join(self.tempSrcDir, "01", path) + if os.path.exists(path): + raise Exception("path %s shouldn't exist" % (path, )) + + path = os.path.join(self.tempSrcDir, "01", "pyspi_0.6.1-1.3.diff.gz") + if not os.path.exists(path): + raise Exception("path %s doesn't exist" % (path, )) + + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo6Test(BaseTest): + """ + include packages to local repo: missing files + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -keyring=${files}/aptly.pub " + outputMatchPrepare = lambda self, s: gpgRemove(self, tempDirRemove(self, s)) + expectedCode = 1 + + def prepare(self): + super(IncludeRepo6Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + os.makedirs(os.path.join(self.tempSrcDir, "01"), 0755) + + for path in ["hardlink_0.2.1.dsc", "hardlink_0.2.1_amd64.changes", "hardlink_0.2.1_amd64.deb"]: + shutil.copy(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes", path), + os.path.join(self.tempSrcDir, "01", path)) + + self.runCmd += self.tempSrcDir + + def check(self): + try: + super(IncludeRepo6Test, self).check() + + for path in ["hardlink_0.2.1.dsc", "hardlink_0.2.1_amd64.changes", "hardlink_0.2.1_amd64.deb"]: + path = os.path.join(self.tempSrcDir, "01", path) + if not os.path.exists(path): + raise Exception("path %s doesn't exist" % (path, )) + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo7Test(BaseTest): + """ + include packages to local repo: wrong checksum + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -keyring=${files}/aptly.pub " + outputMatchPrepare = lambda self, s: gpgRemove(self, tempDirRemove(self, s)) + expectedCode = 1 + + def prepare(self): + super(IncludeRepo7Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + + shutil.copytree(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), os.path.join(self.tempSrcDir, "01")) + + with open(os.path.join(self.tempSrcDir, "01", "hardlink_0.2.1.dsc"), "w") as f: + f.write("A" * 949) # file size + + self.runCmd += self.tempSrcDir + + def check(self): + try: + super(IncludeRepo7Test, self).check() + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo8Test(BaseTest): + """ + include packages to local repo: wrong signature + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -keyring=${files}/aptly.pub " + outputMatchPrepare = lambda self, s: gpgRemove(self, tempDirRemove(self, s)) + expectedCode = 1 + + def prepare(self): + super(IncludeRepo8Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + + shutil.copytree(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), os.path.join(self.tempSrcDir, "01")) + + with open(os.path.join(self.tempSrcDir, "01", "hardlink_0.2.1_amd64.changes"), "r+") as f: + contents = f.read() + f.seek(0, 0) + f.write(contents.replace('Julian', 'Andrey')) + f.truncate() + + self.runCmd += self.tempSrcDir + + def check(self): + try: + super(IncludeRepo8Test, self).check() + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo9Test(BaseTest): + """ + include packages to local repo: unsigned + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -keyring=${files}/aptly.pub " + outputMatchPrepare = lambda self, s: gpgRemove(self, tempDirRemove(self, s)) + expectedCode = 1 + + def prepare(self): + super(IncludeRepo9Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + + shutil.copytree(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), os.path.join(self.tempSrcDir, "01")) + + with open(os.path.join(self.tempSrcDir, "01", "hardlink_0.2.1_amd64.changes"), "r+") as f: + contents = f.readlines() + contents = contents[3:31] + f.seek(0, 0) + f.write("".join(contents)) + f.truncate() + + self.runCmd += self.tempSrcDir + + def check(self): + try: + super(IncludeRepo9Test, self).check() + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo10Test(BaseTest): + """ + include packages to local repo: wrong signature + -ignore-signatures + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -ignore-signatures " + outputMatchPrepare = lambda self, s: gpgRemove(self, tempDirRemove(self, s)) + + def prepare(self): + super(IncludeRepo10Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + + shutil.copytree(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), os.path.join(self.tempSrcDir, "01")) + + with open(os.path.join(self.tempSrcDir, "01", "hardlink_0.2.1_amd64.changes"), "r+") as f: + contents = f.read() + f.seek(0, 0) + f.write(contents.replace('Julian', 'Andrey')) + f.truncate() + + self.runCmd += self.tempSrcDir + + def check(self): + try: + super(IncludeRepo10Test, self).check() + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo11Test(BaseTest): + """ + include packages to local repo: unsigned + -accept-unsigned + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -accept-unsigned -keyring=${files}/aptly.pub " + outputMatchPrepare = lambda self, s: gpgRemove(self, tempDirRemove(self, s)) + + def prepare(self): + super(IncludeRepo11Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + + shutil.copytree(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), os.path.join(self.tempSrcDir, "01")) + + with open(os.path.join(self.tempSrcDir, "01", "hardlink_0.2.1_amd64.changes"), "r+") as f: + contents = f.readlines() + contents = contents[3:31] + f.seek(0, 0) + f.write("".join(contents)) + f.truncate() + + self.runCmd += self.tempSrcDir + + def check(self): + try: + super(IncludeRepo11Test, self).check() + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo12Test(BaseTest): + """ + include packages to local repo: unsigned + -accept-unsigned + restriction breakage + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -accept-unsigned -keyring=${files}/aptly.pub " + outputMatchPrepare = lambda self, s: gpgRemove(self, tempDirRemove(self, s)) + expectedCode = 1 + + def prepare(self): + super(IncludeRepo12Test, self).prepare() + + self.tempSrcDir = tempfile.mkdtemp() + + shutil.copytree(os.path.join(os.path.dirname(inspect.getsourcefile(BaseTest)), "changes"), os.path.join(self.tempSrcDir, "01")) + + with open(os.path.join(self.tempSrcDir, "01", "hardlink_0.2.1_amd64.changes"), "r+") as f: + contents = f.readlines() + contents = contents[3:31] + contents[3] = "Binary: hardlink-dbg\n" + f.seek(0, 0) + f.write("".join(contents)) + f.truncate() + + self.runCmd += self.tempSrcDir + + def check(self): + try: + super(IncludeRepo12Test, self).check() + finally: + shutil.rmtree(self.tempSrcDir) + + +class IncludeRepo13Test(BaseTest): + """ + include packages to local repo: with denying uploaders.json + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -uploaders-file=${changes}/uploaders1.json -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = lambda _, s: changesRemove(_, gpgRemove(_, s)) + expectedCode = 1 + + +class IncludeRepo14Test(BaseTest): + """ + include packages to local repo: allow with uploaders.json + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -uploaders-file=${changes}/uploaders2.json -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = lambda _, s: changesRemove(_, gpgRemove(_, s)) + + +class IncludeRepo15Test(BaseTest): + """ + include packages to local repo: no uploaders.json + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -uploaders-file=${changes}/uploaders-404.json -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = lambda _, s: changesRemove(_, gpgRemove(_, s)) + expectedCode = 1 + + +class IncludeRepo16Test(BaseTest): + """ + include packages to local repo: malformed JSON + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -uploaders-file=${changes}/uploaders3.json -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = lambda _, s: changesRemove(_, gpgRemove(_, s)) + expectedCode = 1 + + +class IncludeRepo17Test(BaseTest): + """ + include packages to local repo: malformed rule + """ + fixtureCmds = [ + "aptly repo create unstable", + ] + runCmd = "aptly repo include -uploaders-file=${changes}/uploaders4.json -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = lambda _, s: changesRemove(_, gpgRemove(_, s)) + expectedCode = 1 + + +class IncludeRepo18Test(BaseTest): + """ + include packages to local repo: repo uploaders.json + global uploaders.json + """ + fixtureCmds = [ + "aptly repo create -uploaders-file=${changes}/uploaders2.json unstable", + ] + runCmd = "aptly repo include -uploaders-file=${changes}/uploaders1.json -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = lambda _, s: changesRemove(_, gpgRemove(_, s)) + + +class IncludeRepo19Test(BaseTest): + """ + include packages to local repo: per-repo uploaders.json + """ + fixtureCmds = [ + "aptly repo create -uploaders-file=${changes}/uploaders1.json unstable", + ] + runCmd = "aptly repo include -no-remove-files -keyring=${files}/aptly.pub ${changes}" + outputMatchPrepare = lambda _, s: changesRemove(_, gpgRemove(_, s)) + expectedCode = 1 diff --git a/src/github.com/smira/aptly/system/t09_repo/search.py b/src/github.com/smira/aptly/system/t09_repo/search.py index 01a89558..46ca77e6 100644 --- a/src/github.com/smira/aptly/system/t09_repo/search.py +++ b/src/github.com/smira/aptly/system/t09_repo/search.py @@ -37,3 +37,13 @@ class SearchRepo4Test(BaseTest): fixtureCmds = ["aptly repo create wheezy-main", "aptly repo import wheezy-main wheezy-main Name"] outputMatchPrepare = lambda _, s: "\n".join(sorted(s.split("\n"))) runCmd = "aptly repo search -with-deps wheezy-main 'Name (nginx)'" + + +class SearchRepo5Test(BaseTest): + """ + search repo: with -format + """ + fixtureDB = True + outputMatchPrepare = lambda _, s: "\n".join(sorted(s.split("\n"))) + fixtureCmds = ["aptly repo create wheezy-main", "aptly repo import wheezy-main wheezy-main Name"] + runCmd = "aptly repo search -format='{{.Package}}#{{.Version}}' wheezy-main '$$Architecture (i386), Name (% *-dev)'" diff --git a/src/github.com/smira/aptly/system/t10_task/RunTask1Test_gold b/src/github.com/smira/aptly/system/t10_task/RunTask1Test_gold index 25b43e94..b54d8488 100644 --- a/src/github.com/smira/aptly/system/t10_task/RunTask1Test_gold +++ b/src/github.com/smira/aptly/system/t10_task/RunTask1Test_gold @@ -21,6 +21,6 @@ End command output: ------------------------------ 4) [Running]: version Begin command output: ---------------------------- -aptly version: 0.9.5 +aptly version: 0.9.6 End command output: ------------------------------ diff --git a/src/github.com/smira/aptly/system/t11_package/SearchPackage5Test_gold b/src/github.com/smira/aptly/system/t11_package/SearchPackage5Test_gold new file mode 100644 index 00000000..1f3aeeae --- /dev/null +++ b/src/github.com/smira/aptly/system/t11_package/SearchPackage5Test_gold @@ -0,0 +1,4309 @@ + +amd-opencl-dev#1:12-6+point-3 +amd-opencl-dev#1:13.12-4~bpo70+1 +aolserver4-dev#4.5.1-15.1 +apache2-prefork-dev#2.2.22-13+deb7u1 +apache2-threaded-dev#2.2.22-13+deb7u1 +apcalc-dev#2.12.4.4-3 +aplus-fsf-dev#4.22.1-6 +aroarfw-dev#0.1~beta4-5 +asterisk-dev#1:1.8.13.1~dfsg1-3+deb7u3 +asterisk-dev#1:11.10.2~dfsg-1~bpo70+1 +atfs-dev#1.4pl6-11 +audacious-dev#3.2.4-1 +autotools-dev#20120608.1 +binutils-dev#2.22-8 +biosquid-dev#1.9g+cvs20050121-2 +bitlbee-dev#3.0.5-1.2 +blacs-pvm-dev#1.1-21 +blends-dev#0.6.16.2 +blktap-dev#2.0.90-1 +blt-dev#2.4z-4.2 +boinc-dev#7.0.27+dfsg-5 +boinc-dev#7.2.47+dfsg-3~bpo70+1 +boolstuff-dev#0.1.12-3 +cairo-dock-dev#3.0.0-2+deb7u1 +cernlib-base-dev#20061220+dfsg3-2 +cernlib-core-dev#20061220+dfsg3-2 +chipmunk-dev#5.3.4-1 +cimg-dev#1.4.9-2 +clearsilver-dev#0.10.5-1.3 +cli-common-dev#0.8.2 +clinica-dev#0.2.1~dfsg-1 +clisp-dev#1:2.49-8.1 +cluster-glue-dev#1.0.9+hg2665-1 +codeblocks-dev#10.05-2.1 +codeblocks-dev#13.12-1~bpo70+1 +coinor-libcbc-dev#2.5.0-3 +coinor-libcgl-dev#0.55.0-1.1 +coinor-libclp-dev#1.12.0-2.1 +coinor-libcoinutils-dev#2.6.4-3 +coinor-libdylp-dev#1.6.0-1.1 +coinor-libflopc++-dev#1.0.6-3.1 +coinor-libipopt-dev#3.10.2-1.1 +coinor-libosi-dev#0.103.0-1 +coinor-libsymphony-dev#5.2.4-1.2 +coinor-libvol-dev#1.1.7-1 +collectd-dev#5.1.0-3 +comerr-dev#2.1-1.42.5-1.1 +condor-dev#7.8.2~dfsg.1-1+deb7u1 +config-package-dev#4.13 +config-package-dev#5.1.1~bpo70+1 +connman-dev#1.0-1.1+wheezy1+b1 +console-tools-dev#1:0.2.3dbs-70 +coop-computing-tools-dev#3.5.1-2 +corosync-dev#1.4.2-3 +courier-authlib-dev#0.63.0-6+b1 +crtmpserver-dev#1.0~dfsg-3 +ctapi-dev#1.1 +ctn-dev#3.0.6-13+b2 +cyrus-dev#2.4.16-4+deb7u1 +dcap-dev#2.47.6-2 +dico-dev#2.1-3+b2 +dictionaries-common-dev#1.12.11 +dietlibc-dev#0.33~cvs20120325-4 +dolfin-dev#1.0.0-7 +dovecot-dev#1:2.1.7-7 +dovecot-dev#1:2.2.9-1~bpo70+1 +dpkg-dev#1.16.12 +drac-dev#1.12-7.2 +drizzle-plugin-dev#1:7.1.36-stable-1 +dssi-dev#1.1.1~dfsg0-1 +e2fslibs-dev#1.42.5-1.1 +emerillon-dev#0.1.90-1 +eog-dev#3.4.2-1+build1 +eom-dev#1.8.0+dfsg1-2~bpo70+1 +epiphany-browser-dev#3.4.2-2.1 +erlang-dev#1:15.b.1-dfsg-4+deb7u1 +erlang-dev#1:17.0-dfsg-3~bpo70+1 +erlang-esdl-dev#1.2-2 +etl-dev#0.04.15-1 +evolution-data-server-dev#3.4.4-3 +evolution-dev#3.4.4-3 +exim4-dev#4.80-7 +expect-dev#5.45-2 +expeyes-firmware-dev#2.0.0-3 +extremetuxracer-gimp-dev#0.4-5 +falconpl-dev#0.9.6.9-git20120606-2 +fatrat-dev#1.1.3-5 +fcitx-libs-dev#1:4.2.4.1-7 +fcitx-libs-dev#1:4.2.8.3-3~bpo70+1 +fenix-dev#0.92a.dfsg1-9 +festival-dev#1:2.1~release-5.1 +fftw-dev#2.1.5-1 +finch-dev#2.10.7-2~bpo70+1 +finch-dev#2.10.9-1~deb7u1 +firebird-dev#2.5.2.26540.ds4-1~deb7u1 +flite1-dev#1.4-release-6 +flow-tools-dev#1:0.68-12.1+b1 +fosfat-dev#0.4.0-3 +freecad-dev#0.13.2800-dfsg-1~bpo70+1 +freeglut3-dev#2.6.0-4 +freetds-dev#0.91-2+deb7u1 +frei0r-plugins-dev#1.1.22git20091109-1.2 +ftgl-dev#2.1.3~rc5-4 +ftplib-dev#3.1-1-9 +gambas3-dev#3.1.1-2+b1 +gap-dev#4r4p12-2 +gauche-dev#0.9.1-5.1 +gcc-4.6-plugin-dev#4.6.3-14 +gcc-4.7-plugin-dev#4.7.2-5 +gcin-dev#2.7.6.1+dfsg-1 +gedit-dev#3.4.2-1 +gem-dev#1:0.93.3-5 +genius-dev#1.0.14-1 +gfxboot-dev#4.5.0-3 +giblib-dev#1.2.4-8 +glabels-dev#3.0.0-3+b1 +glee-dev#5.4.0-1 +gmpc-dev#11.8.16-6 +gnash-dev#0.8.11~git20120629-1+deb7u1 +gnash-dev#0.8.11~git20140319+dfsg-1~bpo70+1 +gnome-control-center-dev#1:3.4.3.1-2 +gnome-settings-daemon-dev#3.4.2+git20121218.7c1322-3+deb7u3 +gnome-video-effects-dev#0.4.0-1 +gnumach-dev#2:1.3.99.dfsg.git20120610-1 +gnunet-dev#0.9.3-7 +gnunet-gtk-dev#0.9.3-1 +gnuradio-dev#3.5.3.2-1 +gnuradio-dev#3.7.2.1-5~bpo70+1 +gosa-dev#2.7.4-4.3~deb7u1 +gpe-ownerinfo-dev#0.28-3 +gpsim-dev#0.26.1-2.1 +graphviz-dev#2.26.3-14+deb7u1 +grass-dev#6.4.2-2 +gridengine-drmaa-dev#6.2u5-7.1 +gromacs-dev#4.5.5-2 +gsettings-desktop-schemas-dev#3.4.2-3 +gthumb-dev#3:3.0.1-2 +guile-1.6-dev#1.6.8-10.3 +guile-1.8-dev#1.8.8+1-8 +guile-2.0-dev#2.0.5+1-3 +guile-cairo-dev#1.4.0-3 +heartbeat-dev#1:3.0.5-3 +heimdal-dev#1.6~git20120403+dfsg1-2 +hime-dev#0.9.9+git20120619+dfsg-1 +hybrid-dev#1:7.2.2.dfsg.2-10 +icedove-dev#10.0.12-1 +inn2-dev#2.5.3-3 +inventor-dev#2.1.5-10-16 +iproute-dev#20120521-3+b3 +iptables-dev#1.4.14-3.1 +irssi-dev#0.8.15-5 +isc-dhcp-dev#4.2.2.dfsg.1-5+deb70u6 +itcl3-dev#3.4.1-1 +itk3-dev#3.3-4 +ivtools-dev#1.2.10a1-1 +kadu-dev#0.11.2-1 +kannel-dev#1.4.3-2+b2 +kde-workspace-dev#4:4.8.4-6 +kdebase-workspace-dev#4:4.8.4-6 +kdelibs5-dev#4:4.8.4-4 +kdemultimedia-dev#4:4.8.4-2 +kdepimlibs5-dev#4:4.8.4-2 +kdevelop-dev#4:4.3.1-3+b1 +kdevplatform-dev#1.3.1-2 +kmymoney-dev#4.6.2-3.2 +konwert-dev#1.8-11.2 +lam4-dev#7.1.4-3 +lesstif2-dev#1:0.95.2-1.1 +lib3ds-dev#1.3.0-6 +lib4store-dev#1.1.4-2 +lib64bz2-dev#1.0.6-4 +lib64expat1-dev#2.1.0-1+deb7u1 +lib64ffi-dev#3.0.10-3 +lib64ncurses5-dev#5.9-10 +lib64readline-gplv2-dev#5.2+dfsg-2~deb7u1 +lib64readline6-dev#6.2+dfsg-0.1 +lib64z1-dev#1:1.2.7.dfsg-13 +liba52-0.7.4-dev#0.7.4-16 +libaa1-dev#1.4p5-40 +libaac-tactics-ocaml-dev#0.2.pl2-7 +libaacs-dev#0.4.0-1 +libaal-dev#1.0.5-5.1 +libabiword-2.9-dev#2.9.2+svn20120603-8 +libaccountsservice-dev#0.6.21-8 +libace-dev#6.0.3+dfsg-0.1 +libace-flreactor-dev#6.0.3+dfsg-0.1 +libace-foxreactor-dev#6.0.3+dfsg-0.1 +libace-htbp-dev#6.0.3+dfsg-0.1 +libace-inet-dev#6.0.3+dfsg-0.1 +libace-inet-ssl-dev#6.0.3+dfsg-0.1 +libace-qtreactor-dev#6.0.3+dfsg-0.1 +libace-rmcast-dev#6.0.3+dfsg-0.1 +libace-ssl-dev#6.0.3+dfsg-0.1 +libace-tkreactor-dev#6.0.3+dfsg-0.1 +libace-tmcast-dev#6.0.3+dfsg-0.1 +libace-xtreactor-dev#6.0.3+dfsg-0.1 +libacexml-dev#6.0.3+dfsg-0.1 +libacl1-dev#2.2.51-8 +libacpi-dev#0.2-4 +libacr38ucontrol-dev#1.7.11-1 +libadasockets4-dev#1.8.10-2 +libaddresses-dev#0.4.7-1+b5 +libaddressview-dev#0.4.7-1+b5 +libadios-dev#1.3-11 +libadminutil-dev#1.1.15-1 +libadns1-dev#1.4-2 +libadolc-dev#2.3.0-1 +libadplug-dev#2.2.1+dfsg3-0.1 +libafflib-dev#3.6.6-1.1+b1 +libafrodite-0.12-dev#0.12.1-3 +libafterimage-dev#2.2.11-7 +libagg-dev#2.5+dfsg1-8 +libagrep-ocaml-dev#1.0-11+b3 +libahven3-dev#2.1-4 +libaiksaurus-1.2-dev#1.2.1+dev-0.12-6.1 +libaiksaurusgtk-1.2-dev#1.2.1+dev-0.12-6.1 +libaio-dev#0.3.109-3 +libakonadi-dev#1.7.2-3 +libalberta2-dev#2.0.1-5 +libaldmb1-dev#1:0.9.3-5.4 +libalglib-dev#2.6.0-6 +libalkimia-dev#4.3.2-1.1 +liballeggl4-dev#2:4.4.2-2.1 +liballegro4.2-dev#2:4.4.2-2.1 +libalog0.4.1-base-dev#0.4.1-2 +libalog0.4.1-full-dev#0.4.1-2 +libalsa-ocaml-dev#0.2.1-1+b1 +libalsaplayer-dev#0.99.80-5.1 +libalure-dev#1.2-6 +libalut-dev#1.1.0-3 +libampsharp-cil-dev#2.0.4-2 +libamu-dev#6.2+rc20110530-3 +libanalitza-dev#4:4.8.4-2 +libanet0.1-dev#0.1-3 +libanjuta-dev#2:3.4.3-1 +libann-dev#1.1.2+doc-3 +libanthy-dev#9100h-16 +libantlr-dev#2.7.7+dfsg-4 +libantlr3c-dev#3.2-2 +libao-dev#1.1.0-2 +libao-ocaml-dev#0.2.0-1+b2 +libaosd-dev#0.2.7-1 +libapache2-mod-perl2-dev#2.0.7-3 +libapertium3-3.1-0-dev#3.1.0-2 +libapm-dev#3.2.2-14 +libapol-dev#3.3.7-3 +libapparmor-dev#2.7.103-4 +libappindicator-dev#0.4.92-2 +libappindicator0.1-cil-dev#0.4.92-2 +libappindicator3-dev#0.4.92-2 +libapq-postgresql3.2.0-dev#3.2.0-2 +libapq3.2.0-dev#3.2.0-1 +libapr-memcache-dev#0.7.0-1 +libapr1-dev#1.4.6-3+deb7u1 +libapreq2-dev#2.13-1+b2 +libapron-dev#0.9.10-5.2 +libapron-ocaml-dev#0.9.10-5.2+b3 +libaprutil1-dev#1.4.1-3 +libapt-pkg-dev#0.9.7.9+deb7u1 +libaqbanking34-dev#5.0.24-3 +libaqbanking34-dev#5.4.3beta-1~bpo70+1 +libaqsis-dev#1.8.1-3 +libarchive-dev#3.0.4-3+nmu1 +libarchive-dev#3.1.2-8~bpo70+1 +libargtable2-dev#12-1 +libarmadillo-dev#1:3.2.3+dfsg-1 +libarmadillo-dev#1:4.200.0+dfsg-1~bpo70+1 +libarpack++2-dev#2.3-2 +libarpack2-dev#3.1.1-2.1 +libart-2.0-dev#2.3.21-2 +libart2.0-cil-dev#2.24.2-3 +libasio-dev#1.4.1-3.2 +libasis2010-dev#2010-5 +libasm-dev#0.152-1+wheezy1 +libasound2-dev#1.0.25-4 +libaspell-dev#0.60.7~20110707-1 +libasprintf-dev#0.18.3-1~bpo7+1 +libass-dev#0.10.0-3 +libassa3.5-5-dev#3.5.1-2 +libassimp-dev#3.0~dfsg-1 +libassuan-dev#2.0.3-1 +libast2-dev#0.7-6+b1 +libasyncns-dev#0.8-4 +libatasmart-dev#0.19-1 +libatd-ocaml-dev#1.0.1-1+b1 +libatdgen-ocaml-dev#1.2.2-1+b1 +libatk-bridge2.0-dev#2.5.3-2 +libatk1.0-dev#2.4.0-2 +libatkmm-1.6-dev#2.22.6-1 +libatlas-base-dev#3.8.4-9+deb7u1 +libatlas-cpp-0.6-dev#0.6.2-3 +libatlas-dev#3.8.4-9+deb7u1 +libatm1-dev#1:2.5.1-1.5 +libatomic-ops-dev#7.2~alpha5+cvs20101124-1+deb7u1 +libatomicparsley-dev#2.1.2-1 +libatrildocument-dev#1.8.0+dfsg1-2~bpo70+1 +libatrilview-dev#1.8.0+dfsg1-2~bpo70+1 +libatspi-dev#1.32.0-2 +libatspi2.0-dev#2.5.3-2 +libattica-dev#0.2.0-1 +libattr1-dev#1:2.4.46-8 +libaubio-dev#0.3.2-4.2+b1 +libaudio-dev#1.9.3-5wheezy1 +libaudiofile-dev#0.3.4-2 +libaudiomask-dev#1.0-2 +libaudit-dev#1:1.7.18-1.1 +libaugeas-dev#0.10.0-1 +libaunit2-dev#1.03-7 +libautotrace-dev#0.31.1-16+b1 +libautounit-dev#0.20.1-4 +libavahi-cil-dev#0.6.19-4.2 +libavahi-client-dev#0.6.31-2 +libavahi-common-dev#0.6.31-2 +libavahi-compat-libdnssd-dev#0.6.31-2 +libavahi-core-dev#0.6.31-2 +libavahi-glib-dev#0.6.31-2 +libavahi-gobject-dev#0.6.31-2 +libavahi-qt4-dev#0.6.31-2 +libavahi-ui-cil-dev#0.6.19-4.2 +libavahi-ui-dev#0.6.31-2 +libavahi-ui-gtk3-dev#0.6.31-2 +libavbin-dev#7-1.3 +libavc1394-dev#0.5.4-2 +libavcodec-dev#6:0.8.10-1 +libavcodec-dev#6:10.1-1~bpo70+1 +libavdevice-dev#6:0.8.10-1 +libavdevice-dev#6:10.1-1~bpo70+1 +libavfilter-dev#6:0.8.10-1 +libavfilter-dev#6:10.1-1~bpo70+1 +libavformat-dev#6:0.8.10-1 +libavformat-dev#6:10.1-1~bpo70+1 +libavifile-0.7-dev#1:0.7.48~20090503.ds-13 +libavl-dev#0.3.5-3 +libavogadro-dev#1.0.3-5 +libavresample-dev#6:10.1-1~bpo70+1 +libavutil-dev#6:0.8.10-1 +libavutil-dev#6:10.1-1~bpo70+1 +libaws2.10.2-dev#2.10.2-4 +libax25-dev#0.0.12-rc2+cvs20120204-2 +libbabl-dev#0.1.10-1 +libball1.4-dev#1.4.1+20111206-4 +libballview1.4-dev#1.4.1+20111206-4 +libbam-dev#0.1.18-1 +libbam-dev#0.1.19-1~bpo70+1 +libbamf-dev#0.2.118-1 +libbamf3-dev#0.2.118-1 +libbarry-dev#0.18.3-5 +libbatteries-ocaml-dev#1.4.3-1 +libbdd-dev#2.4-8 +libbeecrypt-dev#4.2.1-4 +libbenchmark-ocaml-dev#0.9-2+b3 +libbfb0-dev#0.23-1.1 +libbfio-dev#20130507-1~bpo70+1 +libbg1-dev#1.106-1 +libbibutils-dev#4.12-5 +libbin-prot-camlp4-dev#2.0.7-1 +libbind-dev#1:9.8.4.dfsg.P1-6+nmu2+deb7u1 +libbind-dev#1:9.9.5.dfsg-4~bpo70+1 +libbind4-dev#6.0-1 +libbinio-dev#1.4+dfsg1-1 +libbiniou-ocaml-dev#1.0.0-1+b1 +libbio2jack0-dev#0.9-2.1 +libbiococoa-dev#2.2.2-1+b2 +libbiosig-dev#1.3.0-2 +libbisho-common-dev#0.27.2+git20111122.9e68ef3d-1 +libbison-dev#1:2.5.dfsg-2.1 +libbitmask-dev#2.0-2 +libbitstream-dev#1.0-1 +libbitstring-ocaml-dev#2.0.2-3+b1 +libbjack-ocaml-dev#0.1.3-5+b1 +libblacs-mpi-dev#1.1-31 +libbladerf-dev#0.10.7.47.ebe70c4-4~bpo70+1 +libblas-dev#1.2.20110419-5 +libbliss-dev#0.72-4 +libblitz0-dev#1:0.9-13 +libblkid-dev#2.20.1-5.3 +libblocksruntime-dev#0.1-1 +libbluedevil-dev#1.9.2-1 +libbluetooth-dev#4.99-2 +libbluray-dev#1:0.2.2-1 +libbml-dev#0.6.1-1 +libbobcat-dev#3.01.00-1+b1 +libbogl-dev#0.1.18-8+b1 +libbognor-regis-dev#0.6.12+git20101007.02c25268-7 +libboinc-app-dev#7.2.47+dfsg-3~bpo70+1 +libbonobo2-dev#2.24.3-1 +libbonoboui2-dev#2.24.3-1 +libboo-cil-dev#0.9.5~git20110729.r1.202a430-2 +libboost-all-dev#1.49.0.1 +libboost-chrono-dev#1.49.0.1 +libboost-chrono1.49-dev#1.49.0-3.2 +libboost-date-time-dev#1.49.0.1 +libboost-date-time1.49-dev#1.49.0-3.2 +libboost-dev#1.49.0.1 +libboost-filesystem-dev#1.49.0.1 +libboost-filesystem1.49-dev#1.49.0-3.2 +libboost-graph-dev#1.49.0.1 +libboost-graph-parallel-dev#1.49.0.1 +libboost-graph-parallel1.49-dev#1.49.0-3.2 +libboost-graph1.49-dev#1.49.0-3.2 +libboost-iostreams-dev#1.49.0.1 +libboost-iostreams1.49-dev#1.49.0-3.2 +libboost-locale-dev#1.49.0.1 +libboost-locale1.49-dev#1.49.0-3.2 +libboost-math-dev#1.49.0.1 +libboost-math1.49-dev#1.49.0-3.2 +libboost-mpi-dev#1.49.0.1 +libboost-mpi-python-dev#1.49.0.1 +libboost-mpi-python1.49-dev#1.49.0-3.2 +libboost-mpi1.49-dev#1.49.0-3.2 +libboost-program-options-dev#1.49.0.1 +libboost-program-options1.49-dev#1.49.0-3.2 +libboost-python-dev#1.49.0.1 +libboost-python1.49-dev#1.49.0-3.2 +libboost-random-dev#1.49.0.1 +libboost-random1.49-dev#1.49.0-3.2 +libboost-regex-dev#1.49.0.1 +libboost-regex1.49-dev#1.49.0-3.2 +libboost-serialization-dev#1.49.0.1 +libboost-serialization1.49-dev#1.49.0-3.2 +libboost-signals-dev#1.49.0.1 +libboost-signals1.49-dev#1.49.0-3.2 +libboost-system-dev#1.49.0.1 +libboost-system1.49-dev#1.49.0-3.2 +libboost-test-dev#1.49.0.1 +libboost-test1.49-dev#1.49.0-3.2 +libboost-thread-dev#1.49.0.1 +libboost-thread1.49-dev#1.49.0-3.2 +libboost-timer-dev#1.49.0.1 +libboost-timer1.49-dev#1.49.0-3.2 +libboost-wave-dev#1.49.0.1 +libboost-wave1.49-dev#1.49.0-3.2 +libboost1.49-all-dev#1.49.0-3.2 +libboost1.49-dev#1.49.0-3.2 +libbotan1.10-dev#1.10.5-1 +libbox-dev#2.5-2 +libbox2d-dev#2.0.1+dfsg1-1 +libbpp-core-dev#2.0.3-1 +libbpp-phyl-dev#2.0.3-1 +libbpp-popgen-dev#2.0.3-1 +libbpp-qt-dev#2.0.2-1 +libbpp-raa-dev#2.0.3-1 +libbpp-seq-dev#2.0.3-1 +libbrahe-dev#1.3.2-3 +libbrasero-media3-dev#3.4.1-4 +libbrlapi-dev#4.4-10+deb7u1 +libbs2b-dev#3.1.0+dfsg-2 +libbsd-dev#0.4.2-1 +libbse-dev#0.7.4-5 +libbt-dev#0.70.1-13 +libbtparse-dev#0.63-1 +libbuffy-dev#1.7-1 +libbullet-dev#2.82-r2704+dfsg-2~bpo70+1 +libbullet-extras-dev#2.82-r2704+dfsg-2~bpo70+1 +libbulletml-dev#0.0.6-5 +libburn-dev#1.2.2-2 +libbuzztard-dev#0.5.0-4 +libbz2-dev#1.0.6-4 +libbz2-ocaml-dev#0.6.0-6+b2 +libc-ares-dev#1.9.1-3 +libc-client2007e-dev#8:2007f~dfsg-2 +libc6-dev#2.13-38+deb7u1 +libcableswig-dev#0.1.0+cvs20111009-1 +libcaca-dev#0.99.beta18-1 +libcairo-ocaml-dev#1:1.2.0-2+b1 +libcairo2-dev#1.12.2-3 +libcairomm-1.0-dev#1.10.0-1 +libcaja-extension-dev#1.8.1-2~bpo70+1 +libcajun-dev#2.0.3-1~bpo70+1 +libcal3d12-dev#0.11.0-4.1 +libcalendar-ocaml-dev#2.03-1+b2 +libcamel1.2-dev#3.4.4-3 +libcameleon-ocaml-dev#1.9.21-2+b1 +libcaml2html-ocaml-dev#1.4.1-3 +libcamlimages-ocaml-dev#1:4.0.1-4+b2 +libcamljava-ocaml-dev#0.3-1+b3 +libcamlpdf-ocaml-dev#0.5-1+b2 +libcamltemplate-ocaml-dev#1.0.2-1+b2 +libcamomile-ocaml-dev#0.8.4-2 +libcanberra-dev#0.28-6 +libcanberra-gtk-common-dev#0.28-6 +libcanberra-gtk-dev#0.28-6 +libcanberra-gtk3-dev#0.28-6 +libcanlock2-dev#2b-6 +libcanna1g-dev#3.7p3-11 +libcap-dev#1:2.22-1.2 +libcap-ng-dev#0.6.6-2 +libcapi20-dev#1:3.25+dfsg1-3.3~deb7u1 +libcapsinetwork-dev#0.3.0-7 +libcaribou-dev#0.4.4-1 +libcbf-dev#0.7.9.1-3 +libccaudio2-dev#2.0.5-3 +libccfits-dev#2.4-1 +libcconv-dev#0.6.2-1 +libccrtp-dev#2.0.3-4 +libccs-dev#3.0.12-3.2+deb7u2 +libccscript3-dev#1.1.7-2 +libccss-dev#0.5.0-4 +libcdaudio-dev#0.99.12p2-12 +libcdb-dev#0.78 +libcdd-dev#094b.dfsg-4.2 +libcddb2-dev#1.3.2-3 +libcdi-dev#1.5.4+dfsg.1-5 +libcdio-cdda-dev#0.83-4 +libcdio-dev#0.83-4 +libcdio-paranoia-dev#0.83-4 +libcdk5-dev#5.0.20060507-4 +libcdparanoia-dev#3.10.2+debian-10.1 +libcec-dev#1.6.2-1.1 +libcec-dev#2.1.4-1~bpo70+1 +libcegui-mk2-dev#0.7.6-2+b1 +libcephfs-dev#0.80.1-1~bpo70+1 +libcext-dev#6.1.1-2 +libcf-ocaml-dev#0.10-3+b3 +libcfg-dev#1.4.2-3 +libcfitsio3-dev#3.300-2 +libcgal-dev#4.0-5 +libcgic-dev#2.05-3 +libcgicc5-dev#3.2.9-3 +libcgns-dev#3.1.3.4-1+b1 +libcgroup-dev#0.38-1 +libcgsi-gsoap-dev#1.3.5-1 +libchamplain-0.12-dev#0.12.3-1 +libchamplain-gtk-0.12-dev#0.12.3-1 +libcharls-dev#1.0-2 +libchasen-dev#2.4.5-6 +libcheese-dev#3.4.2-2 +libcheese-gtk-dev#3.4.2-2 +libchewing3-dev#0.3.3-4 +libchicken-dev#4.7.0-1 +libchipcard-dev#5.0.3beta-3 +libchise-dev#0.3.0-2+b1 +libchm-dev#2:0.40a-2 +libchromaprint-dev#0.6-2 +libchromaprint-dev#1.1-1~bpo70+1 +libcib1-dev#1.1.7-1 +libcitadel-dev#8.14-1 +libcitygml0-dev#0.14+svn128-1+3p0p1+4 +libck-connector-dev#0.4.5-3.1 +libck-connector-dev#0.4.6-4~bpo70+1 +libckyapplet1-dev#1.1.0-12 +libclalsadrv-dev#2.0.0-3 +libclam-dev#1.4.0-5.1 +libclam-qtmonitors-dev#1.4.0-3.1 +libclamav-dev#0.98.1+dfsg-1+deb7u3 +libclamav-dev#0.98.1+dfsg-1+deb7u4 +libclang-common-dev#1:3.0-6.2 +libclang-dev#1:3.0-6.2 +libclanlib-dev#1.0~svn3827-3 +libclassad-dev#7.8.2~dfsg.1-1+deb7u1 +libclaw-application-dev#1.7.0-3 +libclaw-configuration-file-dev#1.7.0-3 +libclaw-dev#1.7.0-3 +libclaw-dynamic-library-dev#1.7.0-3 +libclaw-graphic-dev#1.7.0-3 +libclaw-logger-dev#1.7.0-3 +libclaw-net-dev#1.7.0-3 +libclaw-tween-dev#1.7.0-3 +libclaws-mail-dev#3.8.1-2 +libclaws-mail-dev#3.9.3-1~bpo70+1 +libclhep-dev#2.1.2.3-1 +libcli-dev#1.9.6-1 +libclippoly-dev#0.11-3 +libclips-dev#6.24-3 +libcliquer-dev#1.21-1 +libcln-dev#1.3.2-1.2 +libcloog-isl-dev#0.17.0-3 +libcloog-ppl-dev#0.15.11-4 +libclthreads-dev#2.4.0-4 +libclucene-dev#0.9.21b-2+b1 +libclustalo-dev#1.1.0-1 +libcluster-glue-dev#1.0.9+hg2665-1 +libclutter-1.0-dev#1.10.8-2 +libclutter-cil-dev#1.0.0~alpha3~git20090817.r1.349dba6-8 +libclutter-gst-dev#1.5.4-1+build0 +libclutter-gtk-1.0-dev#1.2.0-2 +libclutter-imcontext-0.1-dev#0.1.4-3 +libcluttergesture-dev#0.0.2.1-7 +libclxclient-dev#3.6.1-6 +libcman-dev#3.0.12-3.2+deb7u2 +libcminpack-dev#1.2.2-1 +libcmis-dev#0.1.0-1+b1 +libcmor-dev#2.8.0-2+b1 +libcmph-dev#0.9-1 +libcneartree-dev#3.1.1-1 +libcnf-dev#4.0-2 +libcob1-dev#1.1-1 +libcogl-dev#1.10.2-7 +libcogl-pango-dev#1.10.2-7 +libcoin60-dev#3.1.3-2.2 +libcoin80-dev#3.1.4~abc9f50-3~bpo70+1 +libcojets2-dev#20061220+dfsg3-2 +libcollectdclient-dev#5.1.0-3 +libcollection-dev#0.1.3-2 +libcolorblind-dev#0.0.1-1 +libcolord-dev#0.1.21-1 +libcolord-gtk-dev#0.1.21-1 +libcolorhug-dev#0.1.10-1 +libcomedi-dev#0.10.0-3 +libcommoncpp2-dev#1.8.1-5 +libcompfaceg1-dev#1:1.5.2-5 +libconcord-dev#0.24-1.1 +libconfdb-dev#1.4.2-3 +libconfig++-dev#1.4.8-5 +libconfig++8-dev#1.4.8-5 +libconfig-dev#1.4.8-5 +libconfig-file-ocaml-dev#1.1-1 +libconfig8-dev#1.4.8-5 +libconfuse-dev#2.7-4 +libcontactsdb-dev#0.5-8 +libcoq-ocaml-dev#8.3.pl4+dfsg-2 +libcore++-dev#1.7-12 +libcore-ocaml-dev#107.01-5 +libcorelinux-dev#0.4.32-7.3 +libcoroipcc-dev#1.4.2-3 +libcoroipcs-dev#1.4.2-3 +libcorosync-dev#1.4.2-3 +libcos4-dev#4.1.6-2 +libcothreads-ocaml-dev#0.10-3+b3 +libcoyotl-dev#3.1.0-5 +libcpg-dev#1.4.2-3 +libcpl-dev#6.1.1-2 +libcppcutter-dev#1.1.7-1.2 +libcppunit-dev#1.12.1-4 +libcppunit-subunit-dev#0.0.8+bzr176-1 +libcpputest-dev#3.1-2 +libcpufreq-dev#008-1 +libcpuset-dev#1.0-3 +libcqrlib2-dev#1.1.2-1 +libcr-dev#0.8.5-2 +libcrack2-dev#2.8.19-3 +libcreal-ocaml-dev#0.7-6+b3 +libcrmcluster1-dev#1.1.7-1 +libcrmcommon2-dev#1.1.7-1 +libcroco3-dev#0.6.6-2 +libcry-ocaml-dev#0.2.2-1+b1 +libcryptgps-ocaml-dev#0.2.1-7+b3 +libcrypto++-dev#5.6.1-6 +libcryptokit-ocaml-dev#1.5-1 +libcryptsetup-dev#2:1.4.3-4 +libcryptui-dev#3.2.2-1 +libcrystalhd-dev#1:0.0~git20110715.fdd2f19-9 +libcsfml-dev#1.6-1 +libcsnd-dev#1:5.17.11~dfsg-3 +libcsoap-dev#1.1.0-17.1 +libcsound64-dev#1:5.17.11~dfsg-3 +libcsoundac-dev#1:5.17.11~dfsg-3 +libcsv-ocaml-dev#1.2.2-1+b1 +libcsvimp-dev#0.4.7-2~bpo70+1 +libctapimkt0-dev#1.0.1-1.1 +libctdb-dev#1.12+git20120201-4 +libctdb-dev#2.5.3+debian0-1~bpo70+1 +libctemplate-dev#2.2-3 +libctl-dev#3.1.0-5 +libctpl-dev#0.3.3.dfsg-2 +libcuba3-dev#3.0+20111124-2 +libcudf-dev#0.6.2-1 +libcudf-ocaml-dev#0.6.2-1 +libcue-dev#1.4.0-1 +libcuneiform-dev#1.1.0+dfsg-4 +libcunit1-dev#2.1-0.dfsg-10 +libcunit1-ncurses-dev#2.1-0.dfsg-10 +libcups2-dev#1.5.3-5+deb7u1 +libcupscgi1-dev#1.5.3-5+deb7u1 +libcupsdriver1-dev#1.5.3-5+deb7u1 +libcupsfilters-dev#1.0.18-2.1+deb7u1 +libcupsimage2-dev#1.5.3-5+deb7u1 +libcupsmime1-dev#1.5.3-5+deb7u1 +libcupsppdc1-dev#1.5.3-5+deb7u1 +libcupt2-dev#2.5.9 +libcupti-dev#4.2.9-2 +libcupti-dev#5.0.35-8~bpo70+1 +libcurl-ocaml-dev#0.5.3-2+b1 +libcurl4-gnutls-dev#7.26.0-1+wheezy9 +libcurl4-nss-dev#7.26.0-1+wheezy9 +libcurl4-openssl-dev#7.26.0-1+wheezy9 +libcurses-ocaml-dev#1.0.3-2 +libcutter-dev#1.1.7-1.2 +libcv-dev#2.3.1-11 +libcvaux-dev#2.3.1-11 +libcvc3-dev#2.4.1-4 +libcvector2-dev#1.0.3-1 +libcvm1-dev#0.96-1+b1 +libcw3-dev#3.0.2-1 +libcwidget-dev#0.5.16-3.4 +libcwiid-dev#0.6.00+svn201-3+b1 +libcwnn-dev#1.1.1~a021+cvs20100325-6 +libcxgb3-dev#1.3.1-1 +libcxxtools-dev#2.1.1-1 +libdacs-dev#1.4.27b-2 +libdaemon-dev#0.14-2 +libdancer-xml0-dev#0.8.2.1-3 +libdap-dev#3.11.1-11 +libdapl-dev#2.0.19-1.1 +libdaq-dev#0.6.2-2 +libdar-dev#2.4.5.debian.1-1 +libdatrie-dev#0.2.5-3 +libdawgdic-dev#0.4.3-1 +libdb++-dev#5.1.6 +libdb-dev#5.1.6 +libdb-java-dev#5.1.6 +libdb-sql-dev#5.1.6 +libdb4o-cil-dev#8.0.184.15484+dfsg-2 +libdb5.1++-dev#5.1.29-5 +libdb5.1-dev#5.1.29-5 +libdb5.1-java-dev#5.1.29-5 +libdb5.1-sql-dev#5.1.29-5 +libdb5.1-stl-dev#5.1.29-5 +libdballe-dev#5.18-1 +libdballef-dev#5.18-1 +libdbaudiolib0-dev#0.9.8-6.2 +libdbi-dev#0.8.4-6 +libdbus-1-dev#1.6.8-1+deb7u1 +libdbus-c++-dev#0.9.0-6 +libdbus-glib-1-dev#0.100.2-1 +libdbus-glib1.0-cil-dev#0.5.0-4 +libdbus-ocaml-dev#0.29-1+b3 +libdbus1.0-cil-dev#0.7.0-5 +libdbusada0.2-dev#0.2-2 +libdbusmenu-glib-dev#0.6.2-1 +libdbusmenu-gtk-dev#0.6.2-1 +libdbusmenu-gtk3-dev#0.6.2-1 +libdbusmenu-jsonloader-dev#0.6.2-1 +libdbusmenu-qt-dev#0.9.0-1 +libdc-dev#0.3.24~svn3121-2 +libdc1394-22-dev#2.2.0-2 +libdca-dev#0.0.5-5 +libdcerpc-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcerpc-server-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libdcmtk2-dev#3.6.0-12 +libdconf-dbus-1-dev#0.12.1-3 +libdconf-dev#0.12.1-3 +libddccontrol-dev#0.4.2-10 +libdds-dev#2.1.2+ddd105-1 +libdebconf-kde-dev#0.2-2 +libdebconfclient0-dev#0.182 +libdebian-installer4-dev#0.87 +libdebug0-dev#0.4.4-1.1 +libdecodeqr-dev#0.9.3-6.2 +libdee-dev#1.0.10-3 +libderiving-ocaml-dev#0.1.1a-3+b1 +libderiving-ocsigen-ocaml-dev#0.3c-1 +libdesktop-agnostic-dev#0.3.92+dfsg-1 +libdessert0.87-dev#0.87.2-1 +libdevhelp-dev#3.4.1-1 +libdevil-dev#1.7.8-6.1+b1 +libdevmapper-dev#2:1.02.74-8 +libdhash-dev#0.1.3-2 +libdiagnostics-dev#0.3.3-1.3 +libdianewcanvas2-dev#0.6.10-5.4 +libdieharder-dev#3.31.1-4 +libdiet-admin2.8-dev#2.8.0-1+b1 +libdiet-client2.8-dev#2.8.0-1+b1 +libdiet-dagda2.8-dev#2.8.0-1+b1 +libdiet-sed2.8-dev#2.8.0-1+b1 +libdime-dev#0.20030921-2 +libdirac-dev#1.0.2-6 +libdirectfb-dev#1.2.10.0-5 +libdisasm-dev#0.23-5 +libdiscid0-dev#0.2.2-3 +libdiscover-dev#2.1.2-5.2 +libdispatch-dev#0~svn197-3.1 +libdisplaymigration0-dev#0.28-10 +libdistorm64-dev#1.7.30-1 +libdivecomputer-dev#0.1.0-3 +libdjconsole-dev#0.1.3-1 +libdjvulibre-dev#3.5.25.3-1 +libdkim-dev#1:1.0.21-3 +libdlm-dev#3.0.12-3.2+deb7u2 +libdlmcontrol-dev#3.0.12-3.2+deb7u2 +libdlrestrictions-dev#0.15.3 +libdm0-dev#2.2.10-1 +libdmalloc-dev#5.5.2-5 +libdmapsharing-3.0-dev#2.9.15-1 +libdmraid-dev#1.0.0.rc16-4.2 +libdmtcpaware-dev#1.2.5-1 +libdmtx-dev#0.7.2-2+build1 +libdmx-dev#1:1.1.2-1+deb7u1 +libdnet-dev#2.60 +libdockapp-dev#1:0.5.0-3 +libdolfin1.0-dev#1.0.0-7 +libdoodle-dev#0.7.0-5 +libdose2-ocaml-dev#1.4.2-4+b3 +libdose3-ocaml-dev#3.0.2-3 +libdotconf-dev#1.0.13-3 +libdpkg-dev#1.16.12 +libdpm-dev#1.8.2-1+b2 +libdrawtk-dev#2.0-2 +libdrizzle-dev#1:7.1.36-stable-1 +libdrizzledmessage-dev#1:7.1.36-stable-1 +libdrm-dev#2.4.40-1~deb7u2 +libdrumstick-dev#0.5.0-3 +libdsdp-dev#5.8-9.1 +libdshconfig1-dev#0.20.13-1 +libdspam7-dev#3.10.1+dfsg-11 +libdssi-ocaml-dev#0.1.0-1+b1 +libdssialsacompat-dev#1.0.8a-1 +libdtools-ocaml-dev#0.3.0-1 +libdts-dev#0.0.5-5 +libdumb1-dev#1:0.9.3-5.4 +libdumbnet-dev#1.12-3.1 +libdune-common-dev#2.2.0-1 +libdune-geometry-dev#2.2.0-1 +libdune-grid-dev#2.2.0-1 +libdune-istl-dev#2.2.0-1 +libdune-localfunctions-dev#2.2.0-1 +libduo-dev#1.8-1 +libduo-dev#1.8.1-1~deb7u1 +libduppy-ocaml-dev#0.4.2-1+b2 +libdv4-dev#1.0.0-6 +libdvb-dev#0.5.5.1-5.1 +libdvbcsa-dev#1.1.0-2 +libdvbpsi-dev#0.2.2-1 +libdvdnav-dev#4.2.0+20120524-2 +libdvdread-dev#4.2.0+20120521-2 +libdvdread-dev#4.2.1-2~bpo70+1 +libdw-dev#0.152-1+wheezy1 +libdwarf-dev#20120410-2 +libdx4-dev#1:4.4.4-4+b2 +libdxflib-dev#2.2.0.0-8 +libdynamite-dev#0.1.1-2 +libeasy-format-ocaml-dev#1.0.0-1+b2 +libeb16-dev#4.4.3-6 +libebackend1.2-dev#3.4.4-3 +libebml-dev#1.2.2-2 +libebook1.2-dev#3.4.4-3 +libecal1.2-dev#3.4.4-3 +libecasoundc-dev#2.9.0-1 +libecasoundc2.2-dev#2.9.0-1 +libechonest-dev#1.2.1-1 +libecm-dev#6.4.2-1 +libecore-dev#1.2.0-2 +libecpg-dev#9.1.13-0wheezy1 +libecryptfs-dev#99-1 +libedac-dev#0.18-1 +libedata-book1.2-dev#3.4.4-3 +libedata-cal1.2-dev#3.4.4-3 +libedataserver1.2-dev#3.4.4-3 +libedataserverui-3.0-dev#3.4.4-3 +libedbus-dev#1.2.0-1 +libedit-dev#2.11-20080614-5 +libeditline-dev#1.12-6 +libedje-dev#1.2.0-1 +libee-dev#0.4.1-1 +libeegdev-dev#0.2-3 +libeet-dev#1.6.0-1 +libefreet-dev#1.2.0-1 +libegl1-mesa-dev#8.0.5-4+deb7u2 +libeigen2-dev#2.0.17-1 +libeigen3-dev#3.1.0-1 +libeigen3-dev#3.2.1-2~bpo70+1 +libeina-dev#1.2.0-2 +libeiskaltdcpp-dev#2.2.9-3~bpo70+1 +libelektra-cpp-dev#0.7.1-1 +libelektra-dev#0.7.1-1 +libelektratools-dev#0.7.1-1 +libelemental-dev#1.2.0-8 +libelementary-dev#0.7.0.55225-1 +libelf-dev#0.152-1+wheezy1 +libelfg0-dev#0.8.13-3 +libeliom-ocaml-dev#2.2.2-1 +libelk0-dev#3.99.8-2 +libelmer-dev#6.1.0.svn.5396.dfsg2-2 +libembryo-dev#1.2.0-1 +libemos-dev#000382+dfsg-2 +libenca-dev#1.13-4 +libenchant-dev#1.6.0-7 +libenet-dev#1.3.3-2 +libepc-dev#0.4.4-1 +libepc-ui-dev#0.4.4-1 +libepr-api2-dev#2.2-2 +libepsilon-dev#0.9.1-2 +libept-dev#1.0.9 +libepub-dev#0.2.1-2+b1 +liberis-1.3-dev#1.3.19-5 +liberuby-dev#1.0.5-2.1 +libescpr-dev#1.1.1-2 +libesd0-dev#0.2.41-10+b1 +libesmtp-dev#1.0.6-1+b1 +libespeak-dev#1.46.02-2 +libestools2.1-dev#1:2.1~release-5 +libestr-dev#0.1.1-2 +libestr-dev#0.1.9-1~bpo70+1 +libethos-dev#0.2.2-3 +libethos-ui-dev#0.2.2-3 +libetpan-dev#1.0-5 +libetsf-io-dev#1.0.3-4+b1 +libeurodec1-dev#20061220+dfsg3-2 +libev-dev#1:4.11-1 +libev-libevent-dev#1:4.11-1 +libeval0-dev#0.29.6-2 +libevas-dev#1.2.0-2 +libevd-0.1-dev#0.1.20-2 +libevent-dev#2.0.19-stable-3 +libeventdb-dev#0.90-5 +libevince-dev#3.4.0-3.1 +libevocosm-dev#4.0.2-2.1 +libevs-dev#1.4.2-3 +libevtlog-dev#0.2.12-5 +libewf-dev#20100226-1+b1 +libewf-dev#20130416-3~bpo70+1 +libexchangemapi-1.0-dev#3.4.4-1 +libexempi-dev#2.2.0-1 +libexif-dev#0.6.20-3 +libexif-gtk-dev#0.3.5-5 +libexiv2-dev#0.23-1 +libexo-1-dev#0.6.2-5 +libexodusii-dev#5.14.dfsg.1-2+b1 +libexosip2-dev#3.6.0-4 +libexpat-ocaml-dev#0.9.1+debian1-7+b2 +libexpat1-dev#2.1.0-1+deb7u1 +libexpect-ocaml-dev#0.0.2-1+b6 +libexplain-dev#0.52.D002-1 +libextlib-ocaml-dev#1.5.2-1+b1 +libextractor-dev#1:0.6.3-5 +libextractor-java-dev#0.6.0-6 +libexttextcat-dev#3.2.0-2 +libextunix-ocaml-dev#0.0.5-2 +libeztrace-dev#0.7-2-4 +libf2c2-dev#20090411-2 +libfaad-dev#2.7-8 +libfaad-ocaml-dev#0.3.0-1+b1 +libfacile-ocaml-dev#1.1-8+b1 +libfaifa-dev#0.2~svn82-1 +libfakekey-dev#0.1-7 +libfam-dev#2.7.0-17 +libfann-dev#2.1.0~beta~dfsg-8 +libfarstream-0.1-dev#0.1.2-1 +libfastjet-dev#3.0.2+dfsg-2 +libfastjet-fortran-dev#3.0.2+dfsg-2 +libfastjetplugins-dev#3.0.2+dfsg-2 +libfastjettools-dev#3.0.2+dfsg-2 +libfauhdli-dev#20110812-1 +libfcgi-dev#2.4.0-8.1 +libfdt-dev#1.3.0-4 +libfence-dev#3.0.12-3.2+deb7u2 +libffado-dev#2.0.99+svn2171-2 +libffcall1-dev#1.10+cvs20100619-2 +libffi-dev#3.0.10-3 +libffindex0-dev#0.9.6.1-1 +libffmpegthumbnailer-dev#2.0.7-2 +libffms2-dev#2.17-1 +libfftw3-dev#3.3.2-3.1 +libfftw3-mpi-dev#3.3.2-3.1 +libfields-camlp4-dev#107.01-1+b2 +libfileutils-ocaml-dev#0.4.2-1+b2 +libfindlib-ocaml-dev#1.3.1-1 +libfiredns-dev#0.9.12+dfsg-3 +libfirestring-dev#0.9.12-8 +libfishsound1-dev#1.0.0-1.1 +libfiu-dev#0.90-3 +libfixposix-dev#20110316.git47f17f7-1 +libfko0-dev#2.0.0rc2-2+deb7u2 +libfko2-dev#2.5.1-1~bpo70+1 +libflac++-dev#1.2.1-6 +libflac-dev#1.2.1-6 +libflac-ocaml-dev#0.1.1-1 +libflake-dev#0.11-2 +libflann-dev#1.7.1-4 +libflatzebra-dev#0.1.5-4+b1 +libflickrnet-cil-dev#1:2.2.0-4 +libflorist2011-dev#2011-1 +libflowcanvas-dev#0.7.1+dfsg0-0.2 +libfltk1.1-dev#1.1.10-14 +libfltk1.3-dev#1.3.0-8 +libfluidsynth-dev#1.1.5-2 +libfm-dev#0.1.17-2.1 +libfm-dev#1.1.2.2-1~bpo70+1 +libfm-gtk-dev#1.1.2.2-1~bpo70+1 +libfolia1-dev#0.9-2 +libfolks-dev#0.6.9-1+b1 +libfolks-eds-dev#0.6.9-1+b1 +libfolks-telepathy-dev#0.6.9-1+b1 +libfontconfig1-dev#2.9.0-7.1 +libfontenc-dev#1:1.1.1-1 +libfontforge-dev#0.0.20120101+git-2 +libforms-dev#1.0.93sp1-2 +libformsgl-dev#1.0.93sp1-2 +libfox-1.6-dev#1.6.45-1 +libfprint-dev#1:0.4.0-4-gdfff16f-4 +libfreecell-solver-dev#3.12.0-1 +libfreefem++-dev#3.19.1-1 +libfreefem-dev#3.5.8-5 +libfreehdl0-dev#0.0.7-1.1 +libfreeimage-dev#3.15.1-1+b1 +libfreeipmi-dev#1.1.5-3 +libfreenect-dev#1:0.1.2+dfsg-6 +libfreeradius-client-dev#1.1.6-7~bpo70+1 +libfreeradius-dev#2.1.12+dfsg-1.2 +libfreerdp-dev#1.0.1-1.1+deb7u3 +libfreetype6-dev#2.4.9-1.1 +libfreexl-dev#1.0.0b-1 +libfribidi-dev#0.19.2-3 +libfs-dev#2:1.0.4-1+deb7u1 +libfso-glib-dev#2012.05.24.1-1.1 +libfsobasics-dev#0.11.0-1.1 +libfsoframework-dev#0.11.0-1.1 +libfsoresource-dev#0.11.0-1.1 +libfsosystem-dev#0.11.0-1 +libfsotransport-dev#0.11.1-2.1 +libfsplib-dev#0.11-2 +libfstrcmp-dev#0.4.D001-1+deb7u1 +libftdi-dev#0.20-1+b1 +libftdipp-dev#0.20-1+b1 +libftgl-dev#2.1.3~rc5-4 +libfuntools-dev#1.4.4-3 +libfuse-dev#2.9.0-2+deb7u1 +libfuzzy-dev#2.7-2 +libfxt-dev#0.2.6-2 +libg15-dev#1.2.7-2 +libg15daemon-client-dev#1.9.5.3-8.2 +libg15render-dev#1.3.0~svn316-2.2 +libg2-dev#0.72-2.1 +libg3d-dev#0.0.8-17 +libga-dev#2.4.7-3 +libgadap-dev#2.0-1 +libgadu-dev#1:1.11.2-1+deb7u1 +libgail-3-dev#3.4.2-7 +libgail-dev#2.24.10-2 +libgalax-ocaml-dev#1.1-10+b3 +libgambc4-dev#4.2.8-1.1 +libgamin-dev#0.1.10-4.1 +libgammu-dev#1.31.90-1+b1 +libganglia1-dev#3.3.8-1+nmu1 +libganv-dev#0~svn4468~dfsg0-1 +libgarcon-1-0-dev#0.1.12-1 +libgarmin-dev#0~svn320-3 +libgatos-dev#0.0.5-19 +libgavl-dev#1.4.0-1 +libgavl-ocaml-dev#0.1.4-1+b1 +libgbm-dev#8.0.5-4+deb7u2 +libgc-dev#1:7.1-9.1 +libgcal-dev#0.9.6-3 +libgccxml-dev#0.9.0+cvs20120420-4 +libgcgi-dev#0.9.5.dfsg-7 +libgcj12-dev#4.6.3-1 +libgcj13-dev#4.7.2-3 +libgck-1-dev#3.4.1-3 +libgconf-bridge-dev#0.1-2.2 +libgconf2-dev#3.2.5-1+build1 +libgconf2.0-cil-dev#2.24.2-3 +libgconfmm-2.6-dev#2.28.0-1 +libgcr-3-dev#3.4.1-3 +libgcroots-dev#0.8.5-2.1 +libgcrypt11-dev#1.5.0-5+deb7u1 +libgctp-dev#1.0-1 +libgd-gd2-noxpm-ocaml-dev#1.0~alpha5-5 +libgd2-noxpm-dev#2.0.36~rc1~dfsg-6.1 +libgd2-xpm-dev#2.0.36~rc1~dfsg-6.1 +libgda-5.0-dev#5.0.3-2 +libgdal-dev#1.9.0-3.1 +libgdal1-dev#1.9.0-3.1 +libgdata-cil-dev#2.1.0.0-1 +libgdata-dev#0.12.0-1 +libgdb-dev#7.4.1+dfsg-0.1 +libgdbm-dev#1.8.3-11 +libgdchart-gd2-noxpm-dev#0.11.5-7+b1 +libgdchart-gd2-xpm-dev#0.11.5-7+b1 +libgdcm2-dev#2.2.0-14.1 +libgdf-dev#0.1.2-2 +libgdict-1.0-dev#3.4.0-2 +libgdk-pixbuf2.0-dev#2.26.1-1 +libgdkcutter-pixbuf-dev#1.1.7-1.2 +libgdl-3-dev#3.4.2-1 +libgdome2-cpp-smart-dev#0.2.6-6+b1 +libgdome2-dev#0.8.1+debian-4.1 +libgdome2-ocaml-dev#0.2.6-6+b1 +libgdu-dev#3.0.2-3 +libgdu-gtk-dev#3.0.2-3 +libgeant321-2-dev#1:3.21.14.dfsg-10 +libgearman-dev#0.33-2 +libgecode-dev#3.7.3-1 +libgeda-dev#1:1.6.2-4.3 +libgee-dev#0.6.4-2 +libgegl-dev#0.2.0-2+nmu1 +libgeier-dev#0.13-1+b1 +libgenders0-dev#1.18-1 +libgenome-1.3-0-dev#1.3.1-3 +libgensec-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libgeoclue-dev#0.12.0-4 +libgeocode-glib-dev#0.99.0-1 +libgeographiclib-dev#1.21-1 +libgeoip-dev#1.4.8+dfsg-3 +libgeoip-dev#1.5.0-3~bpo70+1 +libgeomview-dev#1.9.4-3 +libgeos++-dev#3.3.3-1.1 +libgeos-dev#3.3.3-1.1 +libgeotiff-dev#1.3.0+dfsg-3 +libgeotranz3-dev#3.1-2.1 +libges-0.10-dev#0.10.1-2 +libgetdata-dev#0.7.3-6 +libgetfem++-dev#4.1.1+dfsg1-11 +libgetopt++-dev#0.0.2-p22-3 +libgetopt-ocaml-dev#0.0.20040811-10+b3 +libgettext-ocaml-dev#0.3.4-1+b2 +libgettextpo-dev#0.18.3-1~bpo7+1 +libgexiv2-dev#0.4.1-3 +libgfarm-dev#2.4.1-1.1 +libgflags-dev#2.0-1 +libgfshare-dev#1.0.5-2 +libghc-acid-state-dev#0.6.3-1+b2 +libghc-active-dev#0.1.0.1-2+b2 +libghc-adjunctions-dev#2.4.0.2-1 +libghc-aeson-dev#0.6.0.2-1+b4 +libghc-agda-dev#2.3.0.1-2 +libghc-algebra-dev#2.1.1.2-1 +libghc-alut-dev#2.1.0.2-4+b1 +libghc-ami-dev#0.1-1+b5 +libghc-ansi-terminal-dev#0.5.5-3+b1 +libghc-ansi-wl-pprint-dev#0.6.4-1+b1 +libghc-arrows-dev#0.4.4.0-3+b1 +libghc-asn1-data-dev#0.6.1.3-2+b3 +libghc-async-dev#2.0.1.3-1~bpo70+1 +libghc-attempt-dev#0.4.0-1+b2 +libghc-attoparsec-conduit-dev#0.4.0.1-1 +libghc-attoparsec-dev#0.10.1.1-2+b1 +libghc-attoparsec-enumerator-dev#0.3-3+b3 +libghc-augeas-dev#0.6.1-1 +libghc-authenticate-dev#1.2.1.1-2+b1 +libghc-base-unicode-symbols-dev#0.2.2.3-1+b1 +libghc-base16-bytestring-dev#0.1.1.4-2+b1 +libghc-base64-bytestring-dev#0.1.1.1-2 +libghc-base64-bytestring-dev#1.0.0.1-1~bpo70+1 +libghc-bifunctors-dev#0.1.3.3-1+b1 +libghc-binary-shared-dev#0.8.1-1+b1 +libghc-bindings-dsl-dev#1.0.15-1+b1 +libghc-bindings-gpgme-dev#0.1.4-1 +libghc-bindings-libzip-dev#0.10-2 +libghc-bitarray-dev#0.0.1-2+b1 +libghc-blaze-builder-conduit-dev#0.4.0.2-1 +libghc-blaze-builder-dev#0.3.1.0-1+b2 +libghc-blaze-builder-enumerator-dev#0.2.0.4-1+b1 +libghc-blaze-html-dev#0.4.3.1-3+b2 +libghc-blaze-markup-dev#0.5.1.0-1 +libghc-blaze-textual-dev#0.2.0.6-2+b2 +libghc-bloomfilter-dev#1.2.6.8-1 +libghc-boolean-dev#0.0.1-2+b1 +libghc-boomerang-dev#1.3.1-1 +libghc-brainfuck-dev#0.1-2+b2 +libghc-byteorder-dev#1.0.3-2+b1 +libghc-bytestring-lexing-dev#0.4.0-1+b1 +libghc-bytestring-mmap-dev#0.2.2-2+b1 +libghc-bytestring-nums-dev#0.3.5-2+b1 +libghc-bytestring-show-dev#0.3.5.1-1+b1 +libghc-bzlib-dev#0.5.0.3-2+b1 +libghc-cabal-file-th-dev#0.2.2-1 +libghc-cairo-dev#0.12.3-1+b1 +libghc-case-insensitive-dev#0.4.0.1-2+b2 +libghc-categories-dev#1.0.3-1+b1 +libghc-cautious-file-dev#1.0.1-1 +libghc-cereal-conduit-dev#0.5-1+b1 +libghc-cereal-dev#0.3.5.2-1 +libghc-certificate-dev#1.2.3-2 +libghc-cgi-dev#3001.1.8.2-2+b3 +libghc-chart-dev#0.15-1+b2 +libghc-chell-dev#0.3-1 +libghc-citeproc-hs-dev#0.3.4-1+b4 +libghc-clientsession-dev#0.7.5-3+b1 +libghc-clock-dev#0.2.0.0-2+b1 +libghc-cmdargs-dev#0.9.5-1+b1 +libghc-colour-dev#2.3.3-1+b1 +libghc-comonad-dev#1.1.1.5-1+b1 +libghc-comonad-transformers-dev#2.1.1.1-1+b1 +libghc-comonads-fd-dev#2.1.1.2-1+b1 +libghc-conduit-dev#0.4.2-2 +libghc-configfile-dev#1.0.6-4+b3 +libghc-configurator-dev#0.2.0.0-1+b2 +libghc-contravariant-dev#0.2.0.2-1+b1 +libghc-convertible-dev#1.0.11.0-3+b3 +libghc-cookie-dev#0.4.0-1+b3 +libghc-cpphs-dev#1.13.3-2+b1 +libghc-cprng-aes-dev#0.2.3-3+b4 +libghc-cpu-dev#0.1.1-1 +libghc-criterion-dev#0.6.0.1-3+b4 +libghc-crypto-api-dev#0.10.2-1+b2 +libghc-crypto-conduit-dev#0.3.2-1+b1 +libghc-crypto-dev#4.2.4-1+b1 +libghc-crypto-pubkey-types-dev#0.1.1-1+b3 +libghc-cryptocipher-dev#0.3.5-1+b1 +libghc-cryptohash-dev#0.7.5-1+b2 +libghc-css-text-dev#0.1.1-3+b2 +libghc-csv-conduit-dev#0.2-1 +libghc-csv-dev#0.1.2-2+b3 +libghc-curl-dev#1.3.7-1+b1 +libghc-darcs-dev#2.8.1-1+b1 +libghc-data-accessor-dev#0.2.2.2-1+b1 +libghc-data-accessor-mtl-dev#0.2.0.3-1+b1 +libghc-data-accessor-template-dev#0.2.1.9-1+b2 +libghc-data-binary-ieee754-dev#0.4.2.1-3+b1 +libghc-data-default-dev#0.4.0-1 +libghc-data-inttrie-dev#0.0.7-1+b1 +libghc-data-lens-dev#2.10.0-1+b1 +libghc-data-memocombinators-dev#0.4.3-1+b1 +libghc-dataenc-dev#0.14.0.3-1+b1 +libghc-datetime-dev#0.2.1-3 +libghc-dbus-dev#0.10.3-1 +libghc-debian-dev#3.64-3 +libghc-diagrams-cairo-dev#0.5.0.2-1 +libghc-diagrams-core-dev#0.5.0.1-1+b1 +libghc-diagrams-dev#0.5-2 +libghc-diagrams-lib-dev#0.5-2 +libghc-diff-dev#0.1.3-1+b1 +libghc-digest-dev#0.0.1.0-1+b1 +libghc-dimensional-dev#0.10.1.2-2+b1 +libghc-directory-tree-dev#0.10.0-2+b1 +libghc-distributive-dev#0.2.2-1+b1 +libghc-dlist-dev#0.5-3+b1 +libghc-doctest-dev#0.9.1-1~bpo70+1 +libghc-download-curl-dev#0.1.3-3+b3 +libghc-dpkg-dev#0.0.3-1 +libghc-dyre-dev#0.8.7-1 +libghc-edison-api-dev#1.2.1-18+b1 +libghc-edison-core-dev#1.2.1.3-9+b1 +libghc-edit-distance-dev#0.2.1-2 +libghc-editline-dev#0.2.1.0-5+b1 +libghc-ekg-dev#0.3.1.0-1+b2 +libghc-email-validate-dev#0.2.8-1+b3 +libghc-entropy-dev#0.2.1-2+b1 +libghc-enumerator-dev#0.4.19-1+b1 +libghc-erf-dev#2.0.0.0-2+b1 +libghc-event-list-dev#0.1.0.1-1+b1 +libghc-exception-transformers-dev#0.3.0.2-1+b1 +libghc-exceptions-dev#0.5-1~bpo70+1 +libghc-executable-path-dev#0.0.3-1+b1 +libghc-explicit-exception-dev#0.1.7-1+b1 +libghc-failure-dev#0.2.0.1-1+b1 +libghc-fast-logger-dev#0.0.2-1+b2 +libghc-fastcgi-dev#3001.0.2.3-3+b3 +libghc-fclabels-dev#1.1.3-1+b1 +libghc-feed-dev#0.3.8-3 +libghc-fgl-dev#5.4.2.4-2+b2 +libghc-file-embed-dev#0.0.4.4-1 +libghc-filemanip-dev#0.3.5.2-2+b2 +libghc-filestore-dev#0.5-1 +libghc-filesystem-conduit-dev#0.4.0-1 +libghc-free-dev#2.1.1.1-1+b1 +libghc-ftphs-dev#1.0.8-1+b3 +libghc-gconf-dev#0.12.1-1+b1 +libghc-gd-dev#3000.7.3-1 +libghc-generic-deriving-dev#1.4.0-2~bpo70+1 +libghc-ghc-events-dev#0.4.0.0-2+b1 +libghc-ghc-mtl-dev#1.0.1.1-1+b3 +libghc-ghc-paths-dev#0.1.0.8-2+b1 +libghc-ghc-syb-utils-dev#0.2.1.0-1+b3 +libghc-gio-dev#0.12.3-1+b1 +libghc-github-dev#0.4.0-2 +libghc-gitit-dev#0.10.0.1-1+b1 +libghc-glade-dev#0.12.1-1+b3 +libghc-glfw-dev#0.5.0.1-1+b1 +libghc-glib-dev#0.12.2-1+b1 +libghc-glut-dev#2.1.2.2-1 +libghc-gnuidn-dev#0.2-2+b2 +libghc-gnutls-dev#0.1.2-1+b1 +libghc-gnutls-dev#0.1.4-3~bpo70+1 +libghc-gsasl-dev#0.3.4-1+b1 +libghc-gstreamer-dev#0.12.1-1+b2 +libghc-gtk-dev#0.12.3-1+b2 +libghc-gtkglext-dev#0.12.1-1+b3 +libghc-gtksourceview2-dev#0.12.3-1+b3 +libghc-haddock-dev#2.10.0-1+b2 +libghc-hakyll-dev#3.2.7.2-1+b5 +libghc-hamlet-dev#1.0.1.3-1+b1 +libghc-happstack-dev#7.0.0-1+b1 +libghc-happstack-server-dev#7.0.1-1+b1 +libghc-harp-dev#0.4-3+b1 +libghc-hashable-dev#1.1.2.3-1+b2 +libghc-hashed-storage-dev#0.5.9-2+b2 +libghc-hashmap-dev#1.3.0.1-1+b2 +libghc-hashtables-dev#1.0.1.4-1+b1 +libghc-haskeline-dev#0.6.4.7-1+b1 +libghc-haskell-lexer-dev#1.0-3+b1 +libghc-haskell-src-dev#1.0.1.5-1+b2 +libghc-haskelldb-dev#2.1.1-5+b1 +libghc-haskelldb-hdbc-dev#2.1.0-4 +libghc-haskelldb-hdbc-odbc-dev#2.1.0-3 +libghc-haskelldb-hdbc-postgresql-dev#2.1.0-3 +libghc-haskelldb-hdbc-sqlite3-dev#2.1.0-3 +libghc-haskore-dev#0.2.0.3-2 +libghc-hastache-dev#0.3.3-2+b3 +libghc-haxml-dev#1:1.22.5-2+b2 +libghc-haxr-dev#3000.8.5-1+b3 +libghc-hcard-dev#0.0-2+b2 +libghc-hcwiid-dev#0.0.1-3+b1 +libghc-hdbc-dev#2.3.1.1-1+b3 +libghc-hdbc-odbc-dev#2.2.3.0-5+b3 +libghc-hdbc-postgresql-dev#2.3.2.1-1+b3 +libghc-hdbc-sqlite3-dev#2.3.3.0-1+b3 +libghc-hfuse-dev#0.2.4.1-1 +libghc-highlighting-kate-dev#0.5.1-1 +libghc-hinotify-dev#0.3.2-1+b1 +libghc-hint-dev#0.3.3.4-2+b4 +libghc-hipmunk-dev#5.2.0.8-1+b1 +libghc-hjavascript-dev#0.4.7-3+b1 +libghc-hjscript-dev#0.5.0-3+b2 +libghc-hjsmin-dev#0.1.1-1+b2 +libghc-hlint-dev#1.8.28-1+b3 +libghc-hoauth-dev#0.3.4-1+b1 +libghc-hostname-dev#1.0-4+b1 +libghc-hs-bibutils-dev#4.12-5+b2 +libghc-hs3-dev#0.5.6-2+b4 +libghc-hscolour-dev#1.19-3+b1 +libghc-hscurses-dev#1.4.1.0-1+b2 +libghc-hsemail-dev#1.7.1-2+b3 +libghc-hsh-dev#2.0.3-6+b3 +libghc-hslogger-dev#1.1.4+dfsg1-2+b3 +libghc-hsp-dev#0.6.1-2+b3 +libghc-hspec-dev#1.1.0-1+b1 +libghc-hsql-dev#1.8.1-4 +libghc-hsql-mysql-dev#1.8.1-4+b1 +libghc-hsql-odbc-dev#1.8.1.1-2 +libghc-hsql-postgresql-dev#1.8.1-3 +libghc-hsql-sqlite3-dev#1.8.1-2 +libghc-hssyck-dev#0.50-2+b2 +libghc-hstringtemplate-dev#0.6.8-1 +libghc-hsx-dev#0.9.1-3 +libghc-html-conduit-dev#0.0.1-2 +libghc-html-dev#1.0.1.2-5+b1 +libghc-http-conduit-dev#1.4.1.6-3 +libghc-http-date-dev#0.0.2-1+b2 +libghc-http-dev#1:4000.2.3-1+b2 +libghc-http-types-dev#0.6.11-1 +libghc-hunit-dev#1.2.4.2-2+b1 +libghc-hxt-cache-dev#9.0.2-2+b3 +libghc-hxt-charproperties-dev#9.1.1-2+b1 +libghc-hxt-curl-dev#9.1.1-1+b4 +libghc-hxt-dev#9.2.2-2+b3 +libghc-hxt-http-dev#9.1.4-2+b3 +libghc-hxt-regex-xmlschema-dev#9.0.4-2+b3 +libghc-hxt-relaxng-dev#9.1.4-1+b3 +libghc-hxt-tagsoup-dev#9.1.1-1+b4 +libghc-hxt-unicode-dev#9.0.2-2+b1 +libghc-hxt-xpath-dev#9.1.2-1+b4 +libghc-hxt-xslt-dev#9.1.1-1+b3 +libghc-iconv-dev#0.4.1.0-2+b1 +libghc-ieee754-dev#0.7.3-1+b1 +libghc-ifelse-dev#0.85-4+b1 +libghc-io-choice-dev#0.0.1-1+b3 +libghc-io-storage-dev#0.3-2+b1 +libghc-iospec-dev#0.2.5-1+b2 +libghc-irc-dev#0.5.0.0-1+b3 +libghc-iteratee-dev#0.8.8.2-2+b1 +libghc-ixset-dev#1.0.3-2+b1 +libghc-json-dev#0.5-2+b2 +libghc-keys-dev#2.1.3.2-1+b1 +libghc-knob-dev#0.1.1-1 +libghc-lambdabot-utils-dev#4.2.1-3+b3 +libghc-language-c-dev#0.4.2-2+b2 +libghc-language-haskell-extract-dev#0.2.1-4+b1 +libghc-language-javascript-dev#0.5.4-1+b2 +libghc-largeword-dev#1.0.1-2+b1 +libghc-lazysmallcheck-dev#0.6-1+b1 +libghc-ldap-dev#0.6.6-4.1+b1 +libghc-leksah-server-dev#0.12.0.4-3 +libghc-libtagc-dev#0.12.0-2+b1 +libghc-libxml-sax-dev#0.7.2-2+b1 +libghc-libzip-dev#0.10-1+b2 +libghc-lifted-base-dev#0.1.1-1+b1 +libghc-listlike-dev#3.1.4-1+b1 +libghc-llvm-base-dev#3.0.1.0-1 +libghc-llvm-dev#3.0.1.0-1+b1 +libghc-logict-dev#0.5.0.1-1+b1 +libghc-ltk-dev#0.12.0.0-2+b1 +libghc-maccatcher-dev#2.1.5-2+b3 +libghc-magic-dev#1.0.8-8+b1 +libghc-markov-chain-dev#0.0.3.2-1+b1 +libghc-math-functions-dev#0.1.1.0-2+b2 +libghc-maths-dev#0.4.3-1+b1 +libghc-maybet-dev#0.1.2-3+b2 +libghc-mbox-dev#0.1-2+b1 +libghc-memotrie-dev#0.5-1 +libghc-mersenne-random-dev#1.0.0.1-2+b1 +libghc-midi-dev#0.2.0.1-1+b1 +libghc-mime-mail-dev#0.4.1.1-2+b3 +libghc-missingh-dev#1.1.0.3-6+b3 +libghc-mmap-dev#0.5.7-2+b1 +libghc-monad-control-dev#0.3.1.3-1+b1 +libghc-monad-loops-dev#0.3.2.0-1 +libghc-monad-par-dev#0.1.0.3-2+b1 +libghc-monadcatchio-mtl-dev#0.3.0.4-2+b2 +libghc-monadcatchio-transformers-dev#0.3.0.0-2+b1 +libghc-monadcryptorandom-dev#0.4.1-1+b2 +libghc-monadrandom-dev#0.1.6-2+b2 +libghc-monads-tf-dev#0.1.0.0-1+b2 +libghc-monoid-transformer-dev#0.0.2-3+b1 +libghc-mtl-dev#2.1.1-1 +libghc-mtlparse-dev#0.1.2-2+b2 +libghc-murmur-hash-dev#0.1.0.5-2+b1 +libghc-mwc-random-dev#0.11.0.0-4+b1 +libghc-ncurses-dev#0.2.1-1+b1 +libghc-netwire-dev#3.1.0-2+b5 +libghc-network-conduit-dev#0.4.0.1-2 +libghc-network-dev#2.3.0.13-1+b2 +libghc-network-info-dev#0.2.0.1-2~bpo70+1 +libghc-network-multicast-dev#0.0.10-1~bpo70+1 +libghc-network-protocol-xmpp-dev#0.4.3-1 +libghc-network-protocol-xmpp-dev#0.4.4-2~bpo70+1 +libghc-newtype-dev#0.2-1 +libghc-non-negative-dev#0.1-2+b1 +libghc-numbers-dev#2009.8.9-2+b1 +libghc-numeric-quest-dev#0.2-1+b1 +libghc-numinstances-dev#1.0-2+b1 +libghc-numtype-dev#1.0-2+b1 +libghc-oeis-dev#0.3.1-2+b3 +libghc-openal-dev#1.3.1.3-4+b1 +libghc-opengl-dev#2.2.3.1-1+b1 +libghc-openpgp-asciiarmor-dev#0.1-1+b2 +libghc-options-dev#0.1.1-1 +libghc-pandoc-dev#1.9.4.2-2 +libghc-pandoc-types-dev#1.9.1-1+b2 +libghc-pango-dev#0.12.2-1+b2 +libghc-parallel-dev#3.2.0.2-2+b1 +libghc-parseargs-dev#0.1.3.2-2+b1 +libghc-parsec2-dev#2.1.0.1-6+b1 +libghc-parsec3-dev#3.1.2-1+b3 +libghc-pastis-dev#0.1.2-2+b3 +libghc-path-pieces-dev#0.1.0-1+b2 +libghc-patience-dev#0.1.1-1 +libghc-pcre-light-dev#0.4-3+b1 +libghc-pem-dev#0.1.1-1+b3 +libghc-persistent-dev#0.9.0.4-2 +libghc-persistent-sqlite-dev#0.9.0.2-2 +libghc-persistent-template-dev#0.9.0.2-1 +libghc-polyparse-dev#1.7-1+b2 +libghc-pool-conduit-dev#0.1.0.2-1 +libghc-postgresql-libpq-dev#0.8.2-1 +libghc-postgresql-simple-dev#0.1.4.3-1 +libghc-pretty-show-dev#1.1.1-4+b1 +libghc-primes-dev#0.2.1.0-2+b1 +libghc-primitive-dev#0.4.1-1+b1 +libghc-psqueue-dev#1.1-2+b1 +libghc-puremd5-dev#2.1.0.3-2+b4 +libghc-pwstore-fast-dev#2.2-2+b4 +libghc-quickcheck1-dev#1.2.0.1-2+b1 +libghc-quickcheck2-dev#2.4.2-1+b1 +libghc-random-dev#1.0.1.1-1+b1 +libghc-random-shuffle-dev#0.0.3-2+b2 +libghc-ranged-sets-dev#0.3.0-2+b1 +libghc-ranges-dev#0.2.4-2+b1 +libghc-reactive-banana-dev#0.6.0.0-1+b3 +libghc-readline-dev#1.0.1.0-3+b1 +libghc-recaptcha-dev#0.1-4+b3 +libghc-regex-base-dev#0.93.2-2+b2 +libghc-regex-compat-dev#0.95.1-2+b1 +libghc-regex-pcre-dev#0.94.2-2+b1 +libghc-regex-posix-dev#0.95.1-2+b1 +libghc-regex-tdfa-dev#1.1.8-2+b1 +libghc-regex-tdfa-utf8-dev#1.0-5+b3 +libghc-regexpr-dev#0.5.4-2+b2 +libghc-representable-functors-dev#2.4.0.2-1+b1 +libghc-representable-tries-dev#2.4.0.2-1 +libghc-resource-pool-dev#0.2.1.0-2+b4 +libghc-resourcet-dev#0.3.2.1-1+b1 +libghc-rsa-dev#1.2.1.0-1+b1 +libghc-safe-dev#0.3.3-1+b1 +libghc-safecopy-dev#0.6.1-1+b1 +libghc-safesemaphore-dev#0.9.0-1~bpo70+1 +libghc-sdl-dev#0.6.3-1+b1 +libghc-sdl-gfx-dev#0.6.0-3+b1 +libghc-sdl-image-dev#0.6.1-3+b1 +libghc-sdl-mixer-dev#0.6.1-3+b1 +libghc-sdl-ttf-dev#0.6.1-3+b1 +libghc-semigroupoids-dev#1.3.1.2-1+b1 +libghc-semigroups-dev#0.8.3.2-1 +libghc-sendfile-dev#0.7.6-1+b2 +libghc-sha-dev#1.5.0.1-1 +libghc-shakespeare-css-dev#1.0.1.2-1+b1 +libghc-shakespeare-dev#1.0.0.2-1+b1 +libghc-shakespeare-i18n-dev#1.0.0.2-1+b1 +libghc-shakespeare-js-dev#1.0.0.2-1+b1 +libghc-shakespeare-text-dev#1.0.0.2-1+b1 +libghc-shellac-dev#0.9.5.1-2+b2 +libghc-show-dev#0.4.1.2-1+b2 +libghc-silently-dev#1.1.4-1+b2 +libghc-simple-sendfile-dev#0.2.3-1+b2 +libghc-simpleea-dev#0.1.1-2+b2 +libghc-simpleirc-dev#0.2.1-2+b3 +libghc-skein-dev#0.1.0.7-2+b1 +libghc-smallcheck-dev#0.6-1+b1 +libghc-smtpclient-dev#1.0.4-3+b3 +libghc-snap-core-dev#0.8.1-1+b4 +libghc-snap-server-dev#0.8.1.1-1 +libghc-socks-dev#0.4.1-1+b4 +libghc-split-dev#0.1.4.2-2 +libghc-src-exts-dev#1.11.1-3+b1 +libghc-statevar-dev#1.0.0.0-2+b1 +libghc-static-hash-dev#0.0.1-3+b2 +libghc-statistics-dev#0.10.1.0-2+b1 +libghc-stm-dev#2.3-1 +libghc-stream-dev#0.4.6-1+b1 +libghc-strict-concurrency-dev#0.2.4.1-2+b1 +libghc-strict-dev#0.3.2-2+b1 +libghc-strptime-dev#1.0.6-1 +libghc-svgcairo-dev#0.12.1-1+b2 +libghc-syb-dev#0.3.6.1-1 +libghc-syb-with-class-dev#0.6.1.3-1+b1 +libghc-syb-with-class-instances-text-dev#0.0.1-3+b2 +libghc-system-fileio-dev#0.3.8-1 +libghc-system-filepath-dev#0.4.6-1+b2 +libghc-tagged-dev#0.4.2.1-1 +libghc-tagsoup-dev#0.12.6-1+b3 +libghc-tagstream-conduit-dev#0.3.2-1 +libghc-tar-dev#0.3.2.0-2+b1 +libghc-template-dev#0.2.0.7-1+b1 +libghc-temporary-dev#1.1.2.3-1+b1 +libghc-terminfo-dev#0.3.2.3-1+b1 +libghc-test-framework-dev#0.6-1+b1 +libghc-test-framework-hunit-dev#0.2.7-1+b3 +libghc-test-framework-quickcheck2-dev#0.2.12.1-1+b1 +libghc-test-framework-th-dev#0.2.2-5 +libghc-test-framework-th-prime-dev#0.0.5-1 +libghc-testpack-dev#2.1.1-1+b2 +libghc-texmath-dev#0.6.0.6-1+b2 +libghc-text-dev#0.11.2.0-1 +libghc-text-icu-dev#0.6.3.4-2+b2 +libghc-tinyurl-dev#0.1.0-2+b3 +libghc-tls-dev#0.9.5-1+b4 +libghc-tls-extra-dev#0.4.6.1-2 +libghc-tokyocabinet-dev#0.0.5-5+b3 +libghc-transformers-base-dev#0.4.1-2+b2 +libghc-transformers-dev#0.3.0.0-1 +libghc-type-level-dev#0.2.4-5 +libghc-uniplate-dev#1.6.7-1+b2 +libghc-unix-bytestring-dev#0.3.5-2+b1 +libghc-unix-compat-dev#0.3.0.1-1+b1 +libghc-unixutils-dev#1.50-1+b1 +libghc-unlambda-dev#0.1-2+b2 +libghc-unordered-containers-dev#0.2.1.0-1 +libghc-uri-dev#0.1.6-1+b2 +libghc-url-dev#2.1.2-4+b1 +libghc-utf8-light-dev#0.4.0.1-2+b1 +libghc-utf8-string-dev#0.3.7-1+b1 +libghc-utility-ht-dev#0.0.5.1-3+b1 +libghc-uuagc-cabal-dev#1.0.2.0-1+b1 +libghc-uuid-dev#1.2.3-2+b4 +libghc-uulib-dev#0.9.14-2 +libghc-vault-dev#0.2.0.0-1+b2 +libghc-vector-algorithms-dev#0.5.4-1+b2 +libghc-vector-dev#0.9.1-2+b1 +libghc-vector-space-dev#0.8.1-1 +libghc-vector-space-points-dev#0.1.1.0-1+b1 +libghc-void-dev#0.5.5.1-2+b1 +libghc-vte-dev#0.12.1-1+b3 +libghc-vty-dev#4.7.0.14-1+b1 +libghc-wai-app-file-cgi-dev#0.5.8-1+b4 +libghc-wai-app-static-dev#1.2.0.3-1+b3 +libghc-wai-dev#1.2.0.2-1+b2 +libghc-wai-extra-dev#1.2.0.4-1 +libghc-wai-logger-dev#0.1.4-1+b6 +libghc-wai-logger-prefork-dev#0.1.3-1+b6 +libghc-wai-test-dev#1.2.0.2-1 +libghc-warp-dev#1.2.1.1-1 +libghc-warp-tls-dev#1.2.0.4-1+b4 +libghc-web-routes-dev#0.25.3-2+b3 +libghc-webkit-dev#0.12.3-2+b1 +libghc-weighted-regexp-dev#0.3.1.1-2+b1 +libghc-x11-dev#1.5.0.1-1+b2 +libghc-x11-xft-dev#0.3.1-1+b3 +libghc-xdg-basedir-dev#0.2.1-2+b1 +libghc-xhtml-dev#3000.2.1-1 +libghc-xml-conduit-dev#0.7.0.2-1 +libghc-xml-dev#1.3.12-1+b2 +libghc-xml-hamlet-dev#0.3.0.1-1~bpo70+1 +libghc-xml-types-dev#0.3.1-2+b2 +libghc-xml2html-dev#0.1.2.3-1 +libghc-xmonad-contrib-dev#0.10-4~deb7u1 +libghc-xmonad-dev#0.10-4+b2 +libghc-xss-sanitize-dev#0.3.2-1+b1 +libghc-yaml-dev#0.7.0.2-1+b2 +libghc-yaml-light-dev#0.1.4-2+b2 +libghc-yesod-auth-dev#1.0.2.1-2+b2 +libghc-yesod-core-dev#1.0.1.2-1+b3 +libghc-yesod-default-dev#1.0.1.1-1+b1 +libghc-yesod-dev#1.0.1.6-2+b3 +libghc-yesod-form-dev#1.0.0.4-1+b1 +libghc-yesod-json-dev#1.0.0.1-1+b3 +libghc-yesod-markdown-dev#0.4.0-1+b3 +libghc-yesod-persistent-dev#1.0.0.1-1+b1 +libghc-yesod-routes-dev#1.0.1.2-1 +libghc-yesod-static-dev#1.0.0.2-1+b3 +libghc-yesod-test-dev#0.2.0.6-1 +libghc-zip-archive-dev#0.1.1.7-3+b2 +libghc-zlib-bindings-dev#0.1.0.1-1 +libghc-zlib-conduit-dev#0.4.0.1-1 +libghc-zlib-dev#0.5.3.3-1+b1 +libghc-zlib-enum-dev#0.2.2.1-1+b1 +libghc6-agda-dev#1:8 +libghc6-alut-dev#1:8 +libghc6-arrows-dev#1:8 +libghc6-binary-dev#1:8 +libghc6-binary-shared-dev#1:8 +libghc6-bzlib-dev#1:8 +libghc6-cairo-dev#1:8 +libghc6-cautious-file-dev#1:8 +libghc6-cgi-dev#1:8 +libghc6-colour-dev#1:8 +libghc6-configfile-dev#1:8 +libghc6-convertible-dev#1:8 +libghc6-cpphs-dev#1:8 +libghc6-criterion-dev#1:8 +libghc6-csv-dev#1:8 +libghc6-curl-dev#1:8 +libghc6-data-accessor-dev#1:8 +libghc6-dataenc-dev#1:8 +libghc6-datetime-dev#1:8 +libghc6-debian-dev#1:8 +libghc6-deepseq-dev#1:8 +libghc6-diagrams-dev#1:8 +libghc6-diff-dev#1:8 +libghc6-digest-dev#1:8 +libghc6-edison-api-dev#1:8 +libghc6-edison-core-dev#1:8 +libghc6-editline-dev#1:8 +libghc6-erf-dev#1:8 +libghc6-event-list-dev#1:8 +libghc6-explicit-exception-dev#1:8 +libghc6-fastcgi-dev#1:8 +libghc6-feed-dev#1:8 +libghc6-fgl-dev#1:8 +libghc6-filemanip-dev#1:8 +libghc6-filestore-dev#1:8 +libghc6-ftphs-dev#1:8 +libghc6-gconf-dev#1:8 +libghc6-ghc-events-dev#1:8 +libghc6-ghc-mtl-dev#1:8 +libghc6-ghc-paths-dev#1:8 +libghc6-gio-dev#1:8 +libghc6-gitit-dev#1:8 +libghc6-glade-dev#1:8 +libghc6-glfw-dev#1:8 +libghc6-glib-dev#1:8 +libghc6-glut-dev#1:8 +libghc6-gstreamer-dev#1:8 +libghc6-gtk-dev#1:8 +libghc6-gtkglext-dev#1:8 +libghc6-gtksourceview2-dev#1:8 +libghc6-haddock-dev#1:8 +libghc6-happstack-dev#1:8 +libghc6-happstack-server-dev#1:8 +libghc6-harp-dev#1:8 +libghc6-hashed-storage-dev#1:8 +libghc6-haskeline-dev#1:8 +libghc6-haskell-lexer-dev#1:8 +libghc6-haskell-src-dev#1:8 +libghc6-haskelldb-dev#1:8 +libghc6-haskelldb-hdbc-dev#1:8 +libghc6-haskelldb-hdbc-odbc-dev#1:8 +libghc6-haskelldb-hdbc-postgresql-dev#1:8 +libghc6-haskelldb-hdbc-sqlite3-dev#1:8 +libghc6-haskore-dev#1:8 +libghc6-haxml-dev#1:8 +libghc6-haxr-dev#1:8 +libghc6-hdbc-dev#1:8 +libghc6-hdbc-odbc-dev#1:8 +libghc6-hdbc-postgresql-dev#1:8 +libghc6-hdbc-sqlite3-dev#1:8 +libghc6-highlighting-kate-dev#1:8 +libghc6-hint-dev#1:8 +libghc6-hjavascript-dev#1:8 +libghc6-hjscript-dev#1:8 +libghc6-hoauth-dev#1:8 +libghc6-hscolour-dev#1:8 +libghc6-hscurses-dev#1:8 +libghc6-hsemail-dev#1:8 +libghc6-hsh-dev#1:8 +libghc6-hslogger-dev#1:8 +libghc6-hsp-dev#1:8 +libghc6-hsql-dev#1:8 +libghc6-hsql-mysql-dev#1:8 +libghc6-hsql-odbc-dev#1:8 +libghc6-hsql-postgresql-dev#1:8 +libghc6-hsql-sqlite3-dev#1:8 +libghc6-hstringtemplate-dev#1:8 +libghc6-hsx-dev#1:8 +libghc6-html-dev#1:8 +libghc6-http-dev#1:8 +libghc6-hunit-dev#1:8 +libghc6-hxt-dev#1:8 +libghc6-ifelse-dev#1:8 +libghc6-irc-dev#1:8 +libghc6-json-dev#1:8 +libghc6-language-c-dev#1:8 +libghc6-lazysmallcheck-dev#1:8 +libghc6-ldap-dev#1:8 +libghc6-leksah-server-dev#1:8 +libghc6-llvm-dev#1:8 +libghc6-ltk-dev#1:8 +libghc6-magic-dev#1:8 +libghc6-markov-chain-dev#1:8 +libghc6-maybet-dev#1:8 +libghc6-midi-dev#1:8 +libghc6-missingh-dev#1:8 +libghc6-mmap-dev#1:8 +libghc6-monadcatchio-mtl-dev#1:8 +libghc6-monoid-transformer-dev#1:8 +libghc6-mtl-dev#1:8 +libghc6-mwc-random-dev#1:8 +libghc6-network-dev#1:8 +libghc6-non-negative-dev#1:8 +libghc6-openal-dev#1:8 +libghc6-opengl-dev#1:8 +libghc6-pandoc-dev#1:8 +libghc6-pango-dev#1:8 +libghc6-parallel-dev#1:8 +libghc6-parsec2-dev#1:8 +libghc6-parsec3-dev#1:8 +libghc6-pcre-light-dev#1:8 +libghc6-polyparse-dev#1:8 +libghc6-pretty-show-dev#1:8 +libghc6-primitive-dev#1:8 +libghc6-quickcheck1-dev#1:8 +libghc6-quickcheck2-dev#1:8 +libghc6-recaptcha-dev#1:8 +libghc6-regex-base-dev#1:8 +libghc6-regex-compat-dev#1:8 +libghc6-regex-posix-dev#1:8 +libghc6-regex-tdfa-dev#1:8 +libghc6-regex-tdfa-utf8-dev#1:8 +libghc6-safe-dev#1:8 +libghc6-sdl-dev#1:8 +libghc6-sdl-gfx-dev#1:8 +libghc6-sdl-image-dev#1:8 +libghc6-sdl-mixer-dev#1:8 +libghc6-sdl-ttf-dev#1:8 +libghc6-sendfile-dev#1:8 +libghc6-sha-dev#1:8 +libghc6-smtpclient-dev#1:8 +libghc6-split-dev#1:8 +libghc6-src-exts-dev#1:8 +libghc6-statistics-dev#1:8 +libghc6-stm-dev#1:8 +libghc6-stream-dev#1:8 +libghc6-strict-concurrency-dev#1:8 +libghc6-svgcairo-dev#1:8 +libghc6-syb-with-class-dev#1:8 +libghc6-syb-with-class-instances-text-dev#1:8 +libghc6-tagsoup-dev#1:8 +libghc6-tar-dev#1:8 +libghc6-terminfo-dev#1:8 +libghc6-testpack-dev#1:8 +libghc6-texmath-dev#1:8 +libghc6-text-dev#1:8 +libghc6-tokyocabinet-dev#1:8 +libghc6-transformers-dev#1:8 +libghc6-type-level-dev#1:8 +libghc6-uniplate-dev#1:8 +libghc6-unix-compat-dev#1:8 +libghc6-unixutils-dev#1:8 +libghc6-url-dev#1:8 +libghc6-utility-ht-dev#1:8 +libghc6-uulib-dev#1:8 +libghc6-vector-algorithms-dev#1:8 +libghc6-vector-dev#1:8 +libghc6-vte-dev#1:8 +libghc6-vty-dev#1:8 +libghc6-webkit-dev#1:8 +libghc6-x11-dev#1:8 +libghc6-x11-xft-dev#1:8 +libghc6-xhtml-dev#1:8 +libghc6-xml-dev#1:8 +libghc6-xmonad-contrib-dev#1:8 +libghc6-xmonad-dev#1:8 +libghc6-zip-archive-dev#1:8 +libghc6-zlib-dev#1:8 +libghemical-dev#3.0.0-2 +libgif-dev#4.1.6-10 +libgiftiio-dev#1.0.9-1 +libgig-dev#3.3.0-2 +libgii1-dev#1:1.0.2-4.1 +libgimp2.0-dev#2.8.2-2+deb7u1 +libginac-dev#1.6.2-1 +libginspx-dev#20050529-3.1 +libgio2.0-cil-dev#2.22.3-2 +libgirara-dev#0.1.2-3 +libgirepository1.0-dev#1.32.1-1 +libgjs-dev#1.32.0-5 +libgkeyfile-cil-dev#0.1-4 +libgksu2-dev#2.0.13~pre1-6 +libgl1-mesa-dev#8.0.5-4+deb7u2 +libgl1-mesa-swx11-dev#8.0.5-4+deb7u2 +libgl2ps-dev#1.3.6-1 +libglade2-dev#1:2.6.4-1 +libglade2.0-cil-dev#2.12.10-5 +libglademm-2.4-dev#2.6.7-2 +libgladeui-1-dev#3.6.7-2.1 +libgladeui-dev#3.12.1-1 +libglbsp-dev#2.24-1 +libglc-dev#0.7.2-5+b1 +libgle3-dev#3.1.0-7 +libgles1-mesa-dev#8.0.5-4+deb7u2 +libgles2-mesa-dev#8.0.5-4+deb7u2 +libglew-dev#1.7.0-3 +libglewmx-dev#1.7.0-3 +libglfw-dev#2.7.2-1 +libglib2.0-cil-dev#2.12.10-5 +libglib2.0-dev#2.33.12+really2.32.4-5 +libglibmm-2.4-dev#2.32.1-1 +libglide2-dev#2002.04.10ds1-7 +libglide3-dev#2002.04.10ds1-7 +libglm-dev#0.9.3.3+dfsg-0.1 +libglobus-authz-callout-error-dev#2.2-1 +libglobus-authz-dev#2.2-1 +libglobus-callout-dev#2.2-1 +libglobus-common-dev#14.7-2 +libglobus-ftp-client-dev#7.3-1 +libglobus-ftp-control-dev#4.4-1 +libglobus-gass-cache-dev#8.1-2 +libglobus-gass-copy-dev#8.4-1 +libglobus-gass-server-ez-dev#4.3-1 +libglobus-gass-transfer-dev#7.2-1 +libglobus-gfork-dev#3.2-1 +libglobus-gram-client-dev#12.4-1 +libglobus-gram-job-manager-callout-error-dev#2.1-2 +libglobus-gram-protocol-dev#11.3-1 +libglobus-gridftp-server-control-dev#2.5-2 +libglobus-gridftp-server-dev#6.10-2 +libglobus-gridmap-callout-error-dev#1.2-2 +libglobus-gsi-callback-dev#4.2-1 +libglobus-gsi-cert-utils-dev#8.3-1 +libglobus-gsi-credential-dev#5.3-1 +libglobus-gsi-openssl-error-dev#2.1-2 +libglobus-gsi-proxy-core-dev#6.2-1 +libglobus-gsi-proxy-ssl-dev#4.1-2 +libglobus-gsi-sysconfig-dev#5.2-1 +libglobus-gss-assist-dev#8.5-1 +libglobus-gssapi-error-dev#4.1-2 +libglobus-gssapi-gsi-dev#10.6-1 +libglobus-io-dev#9.3-1 +libglobus-openssl-module-dev#3.2-1 +libglobus-rls-client-dev#5.2-8 +libglobus-rsl-dev#9.1-2 +libglobus-scheduler-event-generator-dev#4.6-1 +libglobus-usage-dev#3.1-2 +libglobus-xio-dev#3.3-1 +libglobus-xio-gsi-driver-dev#2.3-1 +libglobus-xio-pipe-driver-dev#2.2-1 +libglobus-xio-popen-driver-dev#2.3-1 +libgloox-dev#1.0-1.1 +libgloox-dev#1.0.9-3~bpo70+1 +libglpk-dev#4.45-1 +libglrr-glib-dev#20050529-3.1 +libglrr-gobject-dev#20050529-3.1 +libglrr-gtk-dev#20050529-3.1 +libglrr-widgets-dev#20050529-3.1 +libglu1-mesa-dev#8.0.5-4+deb7u2 +libglui-dev#2.36-4 +libglw1-mesa-dev#8.0.0-1 +libgme-dev#0.5.5-2 +libgmerlin-avdec-dev#1.2.0~dfsg-1+b1 +libgmerlin-dev#1.2.0~dfsg+1-1 +libgmime-2.6-dev#2.6.10-1 +libgmime2.6-cil-dev#2.6.10-1 +libgmlib-dev#1.0.6-1 +libgmm++-dev#4.1.1+dfsg1-11 +libgmp-dev#2:5.0.5+dfsg-2 +libgmp-ocaml-dev#20021123-17+b3 +libgmp3-dev#2:5.0.5+dfsg-2 +libgmpada3-dev#0.0.20120331-1 +libgmsh-dev#2.7.0.dfsg-1~bpo70+1 +libgmt-dev#4.5.7-2 +libgmtk-dev#1.0.6-1 +libgnadecommon2-dev#1.6.2-9 +libgnadeodbc2-dev#1.6.2-9 +libgnadesqlite3-2-dev#1.6.2-9 +libgnatprj4.6-dev#4.6.3-8 +libgnatvsn4.6-dev#4.6.3-8 +libgnelib-dev#0.75+svn20091130-1+b1 +libgnet-dev#2.0.8-2.2 +libgnokii-dev#0.6.30+dfsg-1+b1 +libgnome-bluetooth-dev#3.4.2-1 +libgnome-desktop-3-dev#3.4.2-1 +libgnome-desktop-dev#2.32.1-2 +libgnome-keyring-dev#3.4.1-1 +libgnome-keyring1.0-cil-dev#1.0.0-4 +libgnome-mag-dev#1:0.16.3-1 +libgnome-media-profiles-dev#3.0.0-1 +libgnome-menu-3-dev#3.4.2-5 +libgnome-menu-dev#3.0.1-4 +libgnome-speech-dev#1:0.4.25-5 +libgnome-vfs2.0-cil-dev#2.24.2-3 +libgnome-vfsmm-2.6-dev#2.26.0-1 +libgnome2-dev#2.32.1-3 +libgnome2.0-cil-dev#2.24.2-3 +libgnomeada2.24.1-dev#2.24.1-7 +libgnomecanvas2-dev#2.30.3-1.2 +libgnomecanvasmm-2.6-dev#2.26.0-1 +libgnomecups1.0-dev#0.2.3-5 +libgnomedesktop2.0-cil-dev#2.26.0-8 +libgnomekbd-dev#3.4.0.2-1 +libgnomemm-2.6-dev#2.30.0-1 +libgnomeprint2.2-dev#2.18.8-3 +libgnomeprintui2.2-dev#2.18.6-3 +libgnomeui-dev#2.24.5-2 +libgnomeuimm-2.6-dev#2.28.0-1 +libgnomevfs2-dev#1:2.24.4-2 +libgnuift0-dev#0.1.14-12 +libgnuplot-ocaml-dev#0.8.3-3 +libgnustep-base-dev#1.22.1-4 +libgnustep-dl2-dev#0.12.0-9+nmu1 +libgnustep-gui-dev#0.20.0-3 +libgnutls-dev#2.12.20-8+deb7u1 +libgnutls28-dev#3.2.15-2~bpo70+1 +libgoa-1.0-dev#3.4.2-2 +libgoffice-0.8-dev#0.8.17-1.2 +libgofigure-dev#0.9.0-1+b2 +libgoocanvas-dev#0.15-1 +libgoocanvasmm-dev#0.15.4-1 +libgoogle-perftools-dev#2.0-2 +libgooglepinyin0-dev#0.1.2-1 +libgpac-dev#0.5.0~dfsg0-1 +libgpcl-dev#2.32-1 +libgpds-dev#1.5.1-6 +libgpelaunch-dev#0.14-6 +libgpepimc-dev#0.9-4 +libgpeschedule-dev#0.17-4 +libgpevtype-dev#0.50-6 +libgpewidget-dev#0.117-6 +libgpg-error-dev#1.10-3.1 +libgpg-error-dev#1.12-0.2~bpo70+1 +libgpgme11-dev#1.2.0-1.4 +libgpgme11-dev#1.4.3-0.1~bpo70+1 +libgphoto2-2-dev#2.4.14-2 +libgpiv3-dev#0.6.1-4 +libgpm-dev#1.20.4-6 +libgpod-cil-dev#0.8.2-7 +libgpod-dev#0.8.2-7 +libgpod-nogtk-dev#0.8.2-7 +libgportugol-dev#1.1-2 +libgps-dev#3.6-4+deb7u1 +libgps-dev#3.9-3~bpo70+1 +libgraflib1-dev#20061220+dfsg3-2 +libgrafx11-1-dev#20061220+dfsg3-2 +libgrantlee-dev#0.1.4-1 +libgraphicsmagick++1-dev#1.3.16-1.1 +libgraphicsmagick1-dev#1.3.16-1.1 +libgraphite-dev#1:2.3.1-0.2 +libgraphite2-dev#1.1.3-1 +libgraphviz-dev#2.26.3-14+deb7u1 +libgretl1-dev#1.9.9-1 +libgrib-api-dev#1.9.16-2+b1 +libgrib2c-dev#1.2.2-2+b1 +libgridsite-dev#1.7.16-1 +libgrilo-0.1-dev#0.1.19-1 +libgringotts-dev#1.2.10~pre3-1 +libgrits-dev#0.7-1 +libgrok-dev#1.20110708.1-4 +libgrss-dev#0.5.0-1 +libgs-dev#9.05~dfsg-6.3+deb7u1 +libgsasl7-dev#1.8.0-2 +libgsecuredelete-dev#0.2-1 +libgsf-1-dev#1.14.21-2.1 +libgsf-gnome-1-dev#1.14.21-2.1 +libgsl0-dev#1.15+dfsg.2-2 +libgsm0710-dev#1.2.2-2 +libgsm0710mux-dev#0.11.2-1.1 +libgsm1-dev#1.0.13-4 +libgsmme-dev#1.10-13.2 +libgsnmp0-dev#0.3.0-1.1 +libgsoap-dev#2.8.16-2~bpo70+1 +libgsql-dev#0.2.2-1.2+b1 +libgss-dev#1.0.2-1 +libgssdp-1.0-dev#0.12.2.1-2 +libgssglue-dev#0.4-2 +libgst-dev#3.2.4-2 +libgstbuzztard-dev#0.5.0-2+deb7u1 +libgstreamer-ocaml-dev#0.1.0-3+b1 +libgstreamer-plugins-bad0.10-dev#0.10.23-7.1+deb7u1 +libgstreamer-plugins-bad1.0-dev#1.2.4-1~bpo70+1 +libgstreamer-plugins-base0.10-dev#0.10.36-1.1 +libgstreamer-plugins-base1.0-dev#1.2.4-1~bpo70+1 +libgstreamer0.10-cil-dev#0.9.2-4 +libgstreamer0.10-dev#0.10.36-1.2 +libgstreamer1.0-dev#1.2.4-1~bpo70+1 +libgstrtspserver-0.10-dev#0.10.8-3 +libgtest-dev#1.6.0-2 +libgtextutils-dev#0.6.2-1 +libgtg-dev#0.2+dfsg-1 +libgtk-3-dev#3.4.2-7 +libgtk-sharp-beans2.0-cil-dev#2.14.1-3 +libgtk-vnc-1.0-dev#0.5.0-3.1 +libgtk-vnc-2.0-dev#0.5.0-3.1 +libgtk2.0-cil-dev#2.12.10-5 +libgtk2.0-dev#2.24.10-2 +libgtkada2.24.1-dev#2.24.1-7 +libgtkdatabox-0.9.1-1-dev#1:0.9.1.1-4 +libgtkgl2.0-dev#2.0.1-2 +libgtkglada2.24.1-dev#2.24.1-7 +libgtkglarea-cil-dev#0.0.17-6 +libgtkglext1-dev#1.2.0-2 +libgtkglextmm-x11-1.2-dev#1.2.0-4.1 +libgtkhex-3-dev#3.4.1-1 +libgtkhotkey-dev#0.2.1-3 +libgtkhtml-4.0-dev#4.4.4-1 +libgtkhtml-editor-3.14-dev#3.32.2-2.1 +libgtkhtml-editor-4.0-dev#4.4.4-1 +libgtkhtml3.14-cil-dev#2.26.0-8 +libgtkhtml3.14-dev#3.32.2-2.1 +libgtkimageview-dev#1.6.4+dfsg-0.1 +libgtkmathview-dev#0.8.0-8 +libgtkmm-2.4-dev#1:2.24.2-1 +libgtkmm-3.0-dev#3.4.2-1 +libgtkpod-dev#2.1.2-1 +libgtksourceview-3.0-dev#3.4.2-1 +libgtksourceview2-cil-dev#2.26.0-8 +libgtksourceview2.0-dev#2.10.4-1 +libgtksourceviewmm-3.0-dev#3.2.0-1 +libgtkspell-3-dev#3.0.0~hg20110814-1 +libgtkspell-dev#2.0.16-1 +libgtop2-dev#2.28.4-3 +libgts-dev#0.7.6+darcs110121-1.1 +libguac-dev#0.6.0-2 +libgucharmap-2-90-dev#1:3.4.1.1-2.1 +libgudev-1.0-dev#175-7.2 +libgudev-1.0-dev#204-8~bpo70+1 +libgudev1.0-cil-dev#0.1-3 +libguess-dev#1.1-1 +libguestfs-dev#1:1.18.1-1+deb7u3 +libguestfs-gobject-dev#1:1.18.1-1+deb7u3 +libguestfs-ocaml-dev#1:1.18.1-1+deb7u3 +libguichan-dev#0.8.2-10+b1 +libgupnp-1.0-dev#0.18.4-1 +libgupnp-av-1.0-dev#0.10.3-1 +libgupnp-dlna-1.0-dev#0.6.6-1 +libgupnp-igd-1.0-dev#0.2.1-2 +libgusb-dev#0.1.3-5 +libgutenprint-dev#5.2.9-1 +libgutenprintui2-dev#5.2.9-1 +libguytools2-dev#2.0.1-1.1 +libgvnc-1.0-dev#0.5.0-3.1 +libgweather-3-dev#3.4.1-1+build1 +libgwenhywfar60-dev#4.12.0beta-1~bpo70+1 +libgwenhywfar60-dev#4.3.3-1 +libgwrap-runtime-dev#1.9.14-1.1 +libgwyddion20-dev#2.28-2 +libgxps-dev#0.2.2-2 +libgyoto0-dev#0.0.3-5 +libgyoto1-dev#0.1.0-2~bpo70+1 +libh323plus-dev#1.24.0~dfsg2-1 +libhackrf-dev#2014.04.1-1~bpo70+1 +libhaildb-dev#2.3.2-1.2 +libhal-dev#0.5.14-8 +libhal-storage-dev#0.5.14-8 +libhamlib++-dev#1.2.15.1-1 +libhamlib-dev#1.2.15.1-1 +libhandoff-dev#0.1-5 +libhangul-dev#0.1.0-2 +libharminv-dev#1.3.1-9 +libhashkit-dev#1.0.8-1 +libhavege-dev#1.9.1-1~bpo70+1 +libhawknl-dev#1.6.8+dfsg2-1 +libhbaapi-dev#2.2.5-1 +libhbalinux-dev#1.0.14-1 +libhd-dev#16.0-2.2 +libhdate-dev#1.6-1 +libhdf4-alt-dev#4.2r4-13 +libhdf4-dev#4.2r4-13 +libhdf4g-dev#4.2r4-13 +libhdf5-dev#1.8.8-9 +libhdf5-mpi-dev#1.8.8-9 +libhdf5-mpich2-dev#1.8.8-9 +libhdf5-openmpi-dev#1.8.8-9 +libhdf5-serial-dev#1.8.8-9 +libhdfeos-dev#2.17v1.00.dfsg.1-3 +libhdhomerun-dev#20120405-1 +libhe5-hdfeos-dev#5.1.13.dfsg.1-3 +libheartbeat2-dev#1:3.0.5-3 +libhepmc-dev#2.06.09-1 +libhepmcfio-dev#2.06.09-1 +libhepmcinterface8-dev#8.1.65-1 +libherwig59-2-dev#20061220+dfsg3-2 +libhesiod-dev#3.0.2-21 +libhfsp-dev#1.0.4-12 +libhighgui-dev#2.3.1-11 +libhippocanvas-dev#0.3.1-1.1 +libhiredis-dev#0.10.1-7 +libhivex-dev#1.3.6-2 +libhivex-dev#1.3.9-1~bpo70+1 +libhivex-ocaml-dev#1.3.6-2 +libhivex-ocaml-dev#1.3.9-1~bpo70+1 +libhkl-dev#4.0.3-4 +libhmsbeagle-dev#1.0-6 +libhocr-dev#0.10.17-1+b2 +libhpdf-dev#2.2.1-1 +libhpmud-dev#3.12.6-3.1+deb7u1 +libhsclient-dev#1.1.0-7-g1044a28-1 +libhtmlcxx-dev#0.85-2 +libhtp-dev#0.2.6-2 +libhtsengine-dev#1.06-1 +libhttp-ocaml-dev#0.1.5-1+b2 +libhttrack-dev#3.46.1-1 +libhunspell-dev#1.3.2-4 +libhwloc-dev#1.4.1-4 +libhx-dev#3.12.1-1 +libhyantes-dev#1.3.0-1 +libhyena-cil-dev#0.5-2 +libhyphen-dev#2.8.3-2 +libhypre-dev#2.8.0b-1 +libhz-dev#0.3.16-3 +libi2c-dev#3.1.0-2 +libibcm-dev#1.0.4-1.1 +libibcommon-dev#1.1.2-20090314-1 +libibdm-dev#1.2-OFED-1.4.2-1.3 +libibmad-dev#1.2.3-20090314-1.1 +libibtk-dev#0.0.14-12 +libibumad-dev#1.2.3-20090314-1.1 +libibus-1.0-dev#1.4.1-9+deb7u1 +libibus-1.0-dev#1.5.1.is.1.4.2-1~bpo70+1 +libibus-qt-dev#1.3.1-2.1 +libibverbs-dev#1.1.6-1 +libical-dev#0.48-2 +libicapapi-dev#1:0.1.6-1.1 +libicc-dev#2.12+argyll1.4.0-8 +libicc-utils-dev#1.6.4-1+b1 +libice-dev#2:1.0.8-2 +libicecc-dev#1.0.1-1~bpo70+1 +libicee-dev#1.2.0-6.1 +libicns-dev#0.8.1-1 +libiconv-hook-dev#0.0.20021209-10 +libics-dev#1.5.2-3 +libicu-dev#4.8.1.1-12+deb7u1 +libid3-3.8.3-dev#3.8.3-15 +libid3tag0-dev#0.15.1b-10 +libident-dev#0.22-3 +libidl-dev#0.8.14-0.2 +libidn11-dev#1.25-2 +libidn2-0-dev#0.8-2 +libido-0.1-dev#0.3.4-1 +libido3-0.1-dev#0.3.4-1 +libidzebra-2.0-dev#2.0.44-3 +libiec16022-dev#0.2.4-1 +libiec61883-dev#1.2.0-0.1 +libieee1284-3-dev#0.2.11-10 +libifp-dev#1.0.0.2-5 +libifstat-dev#1.1-8 +libigraph0-dev#0.5.4-2 +libigstk4-dev#4.4.0-2+b1 +libijs-dev#0.35-8 +libiksemel-dev#1.2-4 +libilmbase-dev#1.0.1-4 +libimdi-dev#1.4.0-8 +libiml-dev#1.0.3-4.2 +libimlib2-dev#1.4.5-1 +libimobiledevice-dev#1.1.1-4 +libindi-dev#0.9.1-2 +libindicate-dev#0.6.92-1 +libindicate-gtk-dev#0.6.92-1 +libindicate-gtk0.1-cil-dev#0.6.92-1 +libindicate-gtk3-dev#0.6.92-1 +libindicate-qt-dev#0.2.5.91-5 +libindicate0.1-cil-dev#0.6.92-1 +libindicator-dev#0.5.0-1 +libindicator-messages-status-provider-dev#0.6.0-1 +libindicator3-dev#0.5.0-1 +libindigo-dev#1.0.0-2 +libinfinity-0.5-dev#0.5.2-6.1 +libini-config-dev#0.1.3-2 +libinifiles-ocaml-dev#1.2-2 +libinnodb-dev#1.0.6.6750-1 +libinotify-ocaml-dev#1.0-1+b3 +libinotifytools0-dev#3.14-1 +libinput-pad-dev#1.0.1-2 +libinsighttoolkit3-dev#3.20.1+git20120521-3 +libinstpatch-dev#1.0.0-3 +libint-dev#1.1.4-1 +libiodbc2-dev#3.52.7-2+deb7u1 +libion-dev#3.0.1~dfsg1-1 +libipa-hbac-dev#1.8.4-2 +libipathverbs-dev#1.2-1 +libipe-dev#7.1.2-1 +libipmiconsole-dev#1.1.5-3 +libipmidetect-dev#1.1.5-3 +libipmimonitoring-dev#1.1.5-3 +libipset-dev#6.12.1-1 +libiptcdata0-dev#1.0.4-3 +libircclient-dev#1.3+dfsg1-3 +libirman-dev#0.4.4-2 +libirrlicht-dev#1.7.3+dfsg1-4 +libisajet758-3-dev#20061220+dfsg3-2 +libiscsi-dev#1.4.0-3 +libisl-dev#0.10-3 +libiso9660-dev#0.83-4 +libisoburn-dev#1.2.2-2 +libisofs-dev#1.2.2-1 +libitl-dev#0.7.0-3 +libitl-gobject-dev#0.2-1 +libitpp-dev#4.2-4 +libitsol-dev#1.0.0-2 +libivykis-dev#0.30.1-2 +libiw-dev#30~pre9-8 +libjack-dev#1:0.121.3+20120418git75e3e20b-2.1 +libjack-jackd2-dev#1.9.8~dfsg.4+20120529git007cdc37-5 +libjalali-dev#0.4.0-1.1 +libjama-dev#1.2.4-2 +libjana-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-ecal-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjana-gtk-dev#0.0.0+git20091215.9ec1da8a-2+b4 +libjansson-dev#2.3.1-2 +libjasper-dev#1.900.1-13 +libjaula-dev#1.4.0-3 +libjavascriptcoregtk-1.0-dev#1.8.1-3.4 +libjavascriptcoregtk-3.0-dev#1.8.1-3.4 +libjbig-dev#2.0-2+deb7u1 +libjbig2dec0-dev#0.11+20120125-1 +libjconv-dev#2.8-6+b1 +libjemalloc-dev#3.0.0-3 +libjim-dev#0.73-3 +libjpeg62-dev#6b1-3 +libjpeg8-dev#8d-1 +libjpgalleg4-dev#2:4.4.2-2.1 +libjs-of-ocaml-dev#1.2-2 +libjson-c-dev#0.11-3~bpo7+1 +libjson-glib-dev#0.14.2-1 +libjson-spirit-dev#4.04-1+b1 +libjson-static-camlp4-dev#0.9.8-1+b5 +libjson-wheel-ocaml-dev#1.0.6-2+b8 +libjson0-dev#0.10-1.2 +libjson0-dev#0.11-3~bpo7+1 +libjsoncpp-dev#0.6.0~rc2-3 +libjte-dev#1.19-1 +libjthread-dev#1.3.1-3 +libjudy-dev#1.0.5-1 +libjuman-dev#5.1-2.1 +libk3b-dev#2.0.2-6 +libkactivities-dev#4:4.8.4-1 +libkakasi2-dev#2.3.5~pre1+cvs20071101-1 +libkal-dev#0.9.0-1 +libkarma-cil-dev#0.1.2-2.3 +libkarma-dev#0.1.2-2.3 +libkate-dev#0.4.1-1 +libkaya-gd-dev#0.4.4-6 +libkaya-gl-dev#0.4.4-6 +libkaya-mysql-dev#0.4.4-6 +libkaya-ncurses-dev#0.4.4-6 +libkaya-ncursesw-dev#0.4.4-6 +libkaya-pgsql-dev#0.4.4-6 +libkaya-sdl-dev#0.4.4-6 +libkaya-sqlite3-dev#0.4.4-6 +libkcddb-dev#4:4.8.4-2 +libkdcraw-dev#4:4.8.4-1 +libkdeedu-dev#4:4.8.4-1 +libkdegames-dev#4:4.8.4-3 +libkdtree++-dev#0.7.0-2 +libkernlib1-dev#20061220+dfsg3-2 +libkexiv2-dev#4:4.8.4-1 +libkeybinder-dev#0.2.2-4 +libkeyutils-dev#1.5.5-3 +libkibi-dev#0.1-1 +libkipi-dev#4:4.8.4-1 +libkiten-dev#4:4.8.4-1 +libklatexformula3-dev#3.2.6-1 +libklibc-dev#2.0.1-3.1 +libkmfl-dev#0.9.8-1 +libkmflcomp-dev#0.9.8-1 +libkml-dev#1.3.0~r863-4.1 +libkmod-dev#9-3 +libkokyu-dev#6.0.3+dfsg-0.1 +libkonq5-dev#4:4.8.4-2 +libkonqsidebarplugin-dev#4:4.8.4-2 +libkopete-dev#4:4.8.4-1+b1 +libkosd2-dev#0.8.1-1 +libkpathsea-dev#2012.20120628-4 +libkqueue-dev#1.0.4-2 +libkrb5-dev#1.10.1+dfsg-5+deb7u1 +libksane-dev#4:4.8.4-1 +libksba-dev#1.2.0-2 +libktoblzcheck1-dev#1.39-1 +libktorrent-dev#1.2.1-1 +libktpcommoninternalsprivate-dev#0.4.0-1 +libkvutils-dev#2.9.0-1 +libkvutils2.2-dev#2.9.0-1 +libkwnn-dev#1.1.1~a021+cvs20100325-6 +libkwwidgets1-dev#1.0.0~cvs20100930-8 +libkxl0-dev#1.1.7-16 +liblablgl-ocaml-dev#1.04-5+b3 +liblablgtk-extras-ocaml-dev#1.0-1+b2 +liblablgtk2-gl-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-gnome-ocaml-dev#2.14.2+dfsg-3 +liblablgtk2-ocaml-dev#2.14.2+dfsg-3 +liblablgtkmathview-ocaml-dev#0.7.8-6+b1 +liblablgtksourceview2-ocaml-dev#2.14.2+dfsg-3 +libladr-dev#0.0.200902a-2.1 +libladspa-ocaml-dev#0.1.4-1+b1 +liblapack-dev#3.4.1+dfsg-1+deb70u1 +liblapacke-dev#3.4.1+dfsg-1+deb70u1 +liblas-dev#1.2.1-5+b1 +liblash-compat-dev#1+dfsg0-3 +liblasi-dev#1.1.0-1 +liblasso3-dev#2.3.6-2 +liblastfm-dev#0.4.0~git20090710-2 +liblastfm-ocaml-dev#0.3.0-2+b6 +liblcgdm-dev#1.8.2-1+b2 +liblcms1-dev#1.19.dfsg-1.2 +liblcms2-dev#2.2+git20110628-2.2+deb7u1 +libldap-ocaml-dev#2.1.8-8+b9 +libldap2-dev#2.4.31-1+nmu2 +libldb-dev#1:1.1.16-1~bpo70+1 +libldb-dev#1:1.1.6-1 +libldns-dev#1.6.13-1 +libldns-dev#1.6.16-1~bpo70+1 +libledit-ocaml-dev#2.03-1+b2 +liblensfun-dev#0.2.5-2 +libleptonica-dev#1.69-3.1 +libleveldb-dev#0+20120530.gitdd0d562-1 +liblfc-dev#1.8.2-1+b2 +liblhapdf-dev#5.8.7+repack-1 +liblhasa-dev#0.0.7-2 +liblicense-dev#0.8.1-3 +libliggghts-dev#3.0.0+repack-1~bpo70+1 +liblightdm-gobject-dev#1.2.2-4 +liblightdm-qt-dev#1.2.2-4 +liblilv-dev#0.14.2~dfsg0-4 +liblinear-dev#1.8+dfsg-1 +liblinebreak2-dev#2.1-1 +liblink-grammar4-dev#4.7.4-2 +liblinphone-dev#3.5.2-10 +liblip-dev#2.0.0-1.1 +liblircclient-dev#0.9.0~pre1-1 +liblistaller-glib-dev#0.5.5-2 +liblivemedia-dev#2012.05.17-1 +liblldpctl-dev#0.7.9-1~bpo70+1 +libllvm-2.9-ocaml-dev#2.9+dfsg-7 +libllvm-3.0-ocaml-dev#3.0-10 +libllvm-3.1-ocaml-dev#3.1-1 +libllvm-ocaml-dev#1:3.0-14+nmu2 +liblo-dev#0.26~repack-7 +liblo-ocaml-dev#0.1.0-1+b1 +liblo10k1-dev#1.0.25-2 +libloadpng4-dev#2:4.4.2-2.1 +liblockdev1-dev#1.0.3-1.5 +liblockfile-dev#1.09-5 +liblodo3.0-dev#3.0.2+dfsg-4+b1 +liblog4ada2-dev#1.2-3 +liblog4c-dev#1.2.1-3 +liblog4cplus-dev#1.0.4-1 +liblog4cpp5-dev#1.0-4 +liblog4cxx10-dev#0.10.0-1.2 +liblog4net-cil-dev#1.2.10+dfsg-6 +liblog4shib-dev#1.0.4-1 +liblog4tango4-dev#7.2.6+dfsg-14 +liblog4tango5-dev#8.1.2c+dfsg-4~bpo70+1 +liblogforwarderutils2-dev#2.7-1 +liblogging-stdlog-dev#1.0.4-1~bpo70+1 +liblognorm-dev#0.3.4-1 +liblogservicecomponentbase2-dev#2.7-1 +liblogservicetoolbase2-dev#2.7-1 +liblogsys-dev#1.4.2-3 +liblogthread-dev#3.0.12-3.2+deb7u2 +libloki-dev#0.1.7-3 +libloudmouth1-dev#1.4.3-9 +liblouis-dev#2.4.1-1 +liblouisutdml-dev#2.2.0-1 +liblouisxml-dev#2.4.0-3 +liblowpan-dev#0.2.2-2.1 +liblpsolve55-dev#5.5.0.13-7 +liblqr-1-0-dev#0.4.1-2 +liblrdf0-dev#0.4.0-5 +liblrm2-dev#1.0.9+hg2665-1 +liblrs-dev#0.42c-1+b1 +liblscp-dev#0.5.6-6 +libltcsmpte-dev#0.4.4-1 +libltdl-dev#2.4.2-1.1 +liblttctl-dev#0.89-05122011-1 +liblttd-dev#0.89-05122011-1 +liblttng-ust-dev#2.0.4-1 +liblttoolbox3-3.1-0-dev#3.1.0-1.1 +liblttvtraceread-2.6-dev#0.12.38-21032011-1+b1 +liblua5.1-0-dev#5.1.5-4 +liblua5.1-apr-dev#0.23.2-1 +liblua5.1-bitop-dev#1.0.2-1 +liblua5.1-cgi-dev#5.1.4+dfsg-2 +liblua5.1-copas-dev#1.1.6-5 +liblua5.1-curl-dev#0.3.0-7 +liblua5.1-cyrussasl-dev#1.0.0-4 +liblua5.1-event-dev#0.4.1-2 +liblua5.1-expat-dev#1.2.0-5+deb7u1 +liblua5.1-filesystem-dev#1.5.0+16+g84f1af5-1 +liblua5.1-leg-dev#0.1.2-8 +liblua5.1-logging-dev#1.2.0-1 +liblua5.1-lpeg-dev#0.10.2-5 +liblua5.1-md5-dev#1.1.2-6 +liblua5.1-oocairo-dev#1.4-1.2 +liblua5.1-oopango-dev#1.1-1 +liblua5.1-orbit-dev#2.2.0+dfsg1-1 +liblua5.1-posix-dev#5.1.19-2 +liblua5.1-rex-onig-dev#2.6.0-2 +liblua5.1-rex-pcre-dev#2.6.0-2 +liblua5.1-rex-posix-dev#2.6.0-2 +liblua5.1-rings-dev#1.2.3-1 +liblua5.1-rrd-dev#1.4.7-2 +liblua5.1-sec-dev#0.4.1-1 +liblua5.1-soap-dev#3.0-3 +liblua5.1-socket-dev#2.0.2-8 +liblua5.1-sql-mysql-dev#2.3.0-1+build0 +liblua5.1-sql-postgres-dev#2.3.0-1+build0 +liblua5.1-sql-sqlite3-dev#2.3.0-1+build0 +liblua5.1-svn-dev#0.4.0-7 +liblua5.1-wsapi-fcgi-dev#1.5-3 +liblua5.1-xmlrpc-dev#1.2.1-5 +liblua5.1-zip-dev#1.2.3-11 +liblua5.2-dev#5.2.1-3 +liblua50-dev#5.0.3-6 +libluabind-dev#0.9.1+dfsg-5 +liblualib50-dev#5.0.3-6 +liblunar-1-dev#2.0.1-2.2 +liblunar-date-dev#2.4.0-1 +liblv2dynparam1-dev#2-5 +liblvm2-dev#2.02.95-8 +liblwipv6-dev#1.5a-2 +liblwt-glib-ocaml-dev#2.3.2-1+b3 +liblwt-ocaml-dev#2.3.2-1+b3 +liblwt-ssl-ocaml-dev#2.3.2-1+b3 +liblz-dev#1.3-2 +liblz4-dev#0.0~r114-2~bpo70+1 +liblzma-dev#5.1.1alpha+20120614-2 +liblzo2-dev#2.06-1 +libm17n-dev#1.6.3-2 +libm17n-im-config-dev#0.9.0-3 +libm4ri-dev#0.0.20080521-2 +libmaa-dev#1.3.1-1 +libmad-ocaml-dev#0.4.4-1+b1 +libmad0-dev#0.15.1b-7 +libmadlib-dev#1.3.0-2.1 +libmagic-dev#1:5.17-1~bpo70+1 +libmagic-dev#5.11-2+deb7u3 +libmagic-ocaml-dev#0.7.3-5+b3 +libmagick++-dev#8:6.7.7.10-5+deb7u3 +libmagickcore-dev#8:6.7.7.10-5+deb7u3 +libmagickwand-dev#8:6.7.7.10-5+deb7u3 +libmagics++-dev#2.14.11-4 +libmailutils-dev#1:2.99.97-3 +libmalaga-dev#7.12-4 +libmaloc-dev#0.2-2.3 +libmapi-dev#1:1.0-3 +libmapi-dev#1:2.1-1~bpo70+1 +libmapiadmin-dev#1:1.0-3 +libmapiadmin-dev#1:2.1-1~bpo70+1 +libmapipp-dev#1:1.0-3 +libmapipp-dev#1:2.1-1~bpo70+1 +libmapiproxy-dev#1:1.0-3 +libmapiproxy-dev#1:2.1-1~bpo70+1 +libmapistore-dev#1:1.0-3 +libmapistore-dev#1:2.1-1~bpo70+1 +libmapnik-dev#2.0.0+ds1-3 +libmapnik2-dev#2.0.0+ds1-3+b4 +libmarble-dev#4:4.8.4-3 +libmarco-dev#1.8.0+dfsg1-5~bpo70+1 +libmarkdown2-dev#2.1.3-3 +libmatchbox-dev#1.9-osso8-3 +libmate-desktop-dev#1.8.1+dfsg1-1~bpo70+1 +libmate-menu-dev#1.8.0-2~bpo70+1 +libmate-panel-applet-dev#1.8.0+dfsg1-2~bpo70+1 +libmate-sensors-applet-plugin-dev#1.8.0+dfsg1-1~bpo70+1 +libmate-slab-dev#1.8.1+dfsg1-3~bpo70+1 +libmate-window-settings-dev#1.8.1+dfsg1-3~bpo70+1 +libmatedict-dev#1.8.0+dfsg1-4~bpo70+1 +libmatekbd-dev#1.8.0-2~bpo70+1 +libmatepolkit-dev#1.8.0+dfsg1-3~bpo70+1 +libmateweather-dev#1.8.0-2~bpo70+1 +libmath++-dev#0.0.4-4 +libmatheval-dev#1.1.8-1 +libmathlib2-dev#20061220+dfsg3-2 +libmatio-dev#1.3.4-4 +libmatrixssl1.8-dev#1.8.8-1 +libmatroska-dev#1.3.0-2 +libmbt0-dev#3.2.8-1 +libmcpp-dev#2.7.2-1.1 +libmcrypt-dev#2.5.8-3.1 +libmcs-dev#0.7.2-2.1 +libmd3-dev#0.1.92-4 +libmdc2-dev#0.10.7-1+b2 +libmdds-dev#0.5.4-1 +libmdsp-dev#0.11-10 +libmeanwhile-dev#1.0.2-4 +libmecab-dev#0.99.3-3 +libmed-dev#3.0.3-3 +libmedc-dev#3.0.3-3 +libmediainfo-dev#0.7.58-1 +libmediastreamer-dev#3.5.2-10 +libmedimport-dev#3.0.3-3 +libmeep-dev#1.1.1-8+deb7u1 +libmeep-lam4-dev#1.1.1-10~deb7u1 +libmeep-mpi-default-dev#1.1.1-10~deb7u1 +libmeep-mpich2-dev#1.1.1-10~deb7u1 +libmeep-openmpi-dev#1.1.1-9~deb7u2 +libmelt-ocaml-dev#1.4.0-1 +libmemcache-dev#1.4.0.rc2-1 +libmemcached-dev#1.0.8-1 +libmemphis-0.2-dev#0.2.3-2 +libmenhir-ocaml-dev#20120123.dfsg-1 +libmenu-cache1-dev#0.3.3-1 +libmercator-0.3-dev#0.3.0-2 +libmeschach-dev#1.2b-13 +libmetacity-dev#1:2.34.3-4 +libmgl-dev#1.11.2-17 +libmhash-dev#0.9.9.9-1.1 +libmicrohttpd-dev#0.9.20-1+deb7u1 +libmigemo-dev#20110227-7 +libmikmatch-ocaml-dev#1.0.4-1+b1 +libmikmod2-dev#3.1.12-5 +libmilter-dev#8.14.4-4 +libmimedir-dev#0.5.1-4 +libmimedir-gnome-dev#0.4.2-5 +libmimelib1-dev#5:1.1.4-2 +libmimetic-dev#0.9.7-3 +libmimic-dev#1.0.4-2.1 +libminc-dev#2.1.10-1+b1 +libming-dev#1:0.4.4-1.1 +libmini18n-dev#0.2.1-1 +libminidjvu-dev#0.8.svn.2010.05.06+dfsg-0.2 +libminiupnpc-dev#1.5-2 +libminiupnpc-dev#1.6-3~bpo70+1 +libmirisdr-dev#0.0.4.59ba37-2~bpo70+1 +libmission-control-plugins-dev#1:5.12.3-1 +libmkv-dev#0.6.5.1-1 +libmlpcap-ocaml-dev#0.9-16 +libmlpost-ocaml-dev#0.8.1-3 +libmlt++-dev#0.8.0-4 +libmlt-dev#0.8.0-4 +libmlx4-dev#1.0.4-1 +libmm-dev#1.4.2-4 +libmm-ocaml-dev#0.2.0-1+b1 +libmmpong0.9-dev#0.9.1-2.1 +libmms-dev#0.6.2-3 +libmng-dev#1.0.10-3 +libmnl-dev#1.0.3-3 +libmodbus-dev#3.0.3-1 +libmodglue1-dev#1.17-2.1 +libmodplug-dev#1:0.8.8.4-3+deb7u1+git20130828 +libmoe-dev#1.5.8-1 +libmongo-client-dev#0.1.5-1+deb7u1 +libmono-2.0-dev#2.10.8.1-8 +libmono-addins-cil-dev#0.6.2-2 +libmono-addins-gui-cil-dev#0.6.2-2 +libmono-addins-msbuild-cil-dev#0.6.2-2 +libmono-cecil-cil-dev#0.9.5+dfsg-2 +libmono-cecil-flowanalysis-cil-dev#0.1~vcs20110809.r1.b34edf6-2 +libmono-cil-dev#2.10.8.1-8 +libmono-reflection-cil-dev#1.0+git20110407+d2343843-2 +libmono-uia-cil-dev#2.1-4 +libmono-upnp-cil-dev#0.1.2-1 +libmono-zeroconf-cil-dev#0.9.0-4 +libmonogame-cil-dev#2.5.1+dfsg-3 +libmopac7-dev#1.15-5 +libmorph-dev#1:20090926 +libmosquitto0-dev#0.15-2 +libmosquittopp0-dev#0.15-2 +libmotif-dev#2.3.3-8 +libmount-dev#2.20.1-5.3 +libmowgli-dev#1.0.0-1 +libmozjs-dev#24.4.0esr-1~deb7u2 +libmozjs185-dev#1.8.5-1.0.0+dfsg-4 +libmp3lame-dev#3.99.5+repack1-3 +libmp3lame-ocaml-dev#0.3.1-1+b1 +libmp3splt-dev#0.7.2-2 +libmp4v2-dev#2.0.0~dfsg0-1 +libmpc-dev#0.9-4 +libmpcdec-dev#2:0.1~r459-4 +libmpd-dev#0.20.0-1.1 +libmpdclient-dev#2.3-1 +libmpeg2-4-dev#0.4.1-3 +libmpeg3-dev#1.5.4-5 +libmpfi-dev#1.5.1-1 +libmpfr-dev#3.1.0-5 +libmpg123-dev#1.14.4-1 +libmpich2-dev#1.4.1-4.2 +libmpikmeans-dev#1.5-1+b1 +libmrml1-dev#0.1.14-12 +libmrmpi-dev#1.0~20110620.dfsg-2 +libmrss0-dev#0.19.2-3 +libmsgpack-dev#0.5.7-2 +libmsn-dev#4.2-2 +libmspub-dev#0.0.6-1~bpo70+1 +libmsv-dev#0.0.0-1 +libmsv-dev#1.0-1~bpo70+1 +libmtbl-dev#0.2-1 +libmtcp-dev#1.2.5-1 +libmtdev-dev#1.1.2-1 +libmthca-dev#1.0.6-1 +libmtp-dev#1.1.3-35-g0ece104-5 +libmtp-dev#1.1.6-20-g1b9f164-1~bpo70+1 +libmudflap0-4.4-dev#4.4.7-2 +libmudflap0-4.6-dev#4.6.3-14 +libmudflap0-4.7-dev#4.7.2-5 +libmulticobex1-dev#0.23-1.1 +libmumps-dev#4.10.0.dfsg-3 +libmumps-ptscotch-dev#4.10.0.dfsg-3 +libmumps-scotch-dev#4.10.0.dfsg-3 +libmumps-seq-dev#4.10.0.dfsg-3 +libmunge-dev#0.5.10-1 +libmuparser-dev#2.1.0-3 +libmupdf-dev#0.9-2 +libmupen64plus-dev#1.99.5-6 +libmuroar-dev#0.1.8-2 +libmusic-dev#1.0.7-1.2 +libmusicbrainz3-dev#3.0.2-2.1 +libmusicbrainz5-dev#5.0.1-2 +libmutter-dev#3.4.1-5 +libmx-dev#1.4.6-1 +libmxml-dev#2.6-2 +libmyproxy-dev#5.6-1 +libmysql++-dev#3.1.0-2+b1 +libmysql-cil-dev#6.4.3-2 +libmysql-ocaml-dev#1.1.1-1 +libmysqlclient-dev#5.5.35+dfsg-0+wheezy1 +libmysqlcppconn-dev#1.1.0-4+b1 +libmysqld-dev#5.5.35+dfsg-0+wheezy1 +libmythes-dev#2:1.2.2-1 +libnabrit-dev#0.4.1-1 +libnacl-dev#20110221-4 +libnacore-dev#0.4.0-3 +libnanohttp-dev#1.1.0-17.1 +libnatpmp-dev#20110808-3 +libnautilus-extension-dev#3.4.2-1+build1 +libnauty-dev#2.4r2-1 +libnbio-dev#0.30-1 +libncap-dev#1.9.2-1+b2 +libncbi6-dev#6.1.20120620-2 +libncp-dev#2.2.6-9 +libncurses5-dev#5.9-10 +libncursesada2-dev#5.9.20110404-7 +libncursesw5-dev#5.9-10 +libndesk-dbus-glib1.0-cil-dev#0.4.1-4 +libndesk-dbus1.0-cil-dev#0.6.0-6 +libndr-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libndr-standard-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libnecpp-dev#1.5.0+cvs20101003-2.1 +libneon27-dev#0.29.6-3 +libneon27-gnutls-dev#0.29.6-3 +libnes-dev#1.1.3-1 +libnet1-dev#1.1.4-2.1 +libnet6-1.3-dev#1:1.3.14-1 +libnetcdf-dev#1:4.1.3-6+b1 +libnetcf-dev#0.1.9-2 +libnetclasses-dev#1.06.dfsg-5+b3 +libnetfilter-conntrack-dev#1.0.1-1 +libnetfilter-cttimeout-dev#1.0.0-1 +libnetfilter-log-dev#1.0.0-1 +libnetfilter-queue-dev#0.0.17-1 +libnethttpd-ocaml-dev#3.5.1-1 +libnetpbm10-dev#2:10.0-15+b1 +libnetpbm9-dev#2:10.0-15+b1 +libnetsvcs-dev#6.0.3+dfsg-0.1 +libnewlib-dev#1.18.0-6.2 +libnewmat10-dev#1.10.4-5 +libnewt-dev#0.52.14-11.1 +libnewtonsoft-json-cil-dev#4.5r6-1 +libnexus0-dev#4.2.1-svn1614-1+b2 +libnfnetlink-dev#1.0.0-1.1 +libnfo-dev#1.0.1-1 +libnfs-dev#1.3.0-2 +libnfsidmap-dev#0.25-4 +libnice-dev#0.1.2-1 +libnids-dev#1.23-2 +libnifti-dev#2.0.0-1 +libnih-dbus-dev#1.0.3-4.1 +libnih-dev#1.0.3-4.1 +libnini-cil-dev#1.1.0+dfsg.2-4 +libnjb-dev#2.2.7~dfsg0-3 +libnl-3-dev#3.2.7-4 +libnl-cli-3-dev#3.2.7-4 +libnl-dev#1.1-7 +libnl-genl-3-dev#3.2.7-4 +libnl-nf-3-dev#3.2.7-4 +libnl-route-3-dev#3.2.7-4 +libnm-glib-dev#0.9.4.0-10 +libnm-glib-vpn-dev#0.9.4.0-10 +libnm-gtk-dev#0.9.4.1-5 +libnm-util-dev#0.9.4.0-10 +libnmz7-dev#2.0.21-6 +libnoise-dev#1.0.0+nmu1 +libnotify-cil-dev#0.4.0~r3032-6 +libnotify-dev#0.7.5-1 +libnotmuch-dev#0.13.2-1 +libnotmuch-dev#0.16-1~bpo70+1 +libnova-dev#0.14.0-2 +libnpth0-dev#0.90-2 +libnsbmp0-dev#0.0.1-1.1 +libnsgif0-dev#0.0.1-1.1 +libnspr4-dev#2:4.9.2-1+deb7u1 +libnss3-dev#2:3.14.5-1 +libntdb-dev#1.0-2~bpo70+1 +libntfs-dev#2.0.0-1+b1 +libntl-dev#5.5.2-2 +libntlm0-dev#1.2-1 +libntrack-dev#016-1.1 +libntrack-glib-dev#016-1.1 +libntrack-gobject-dev#016-1.1 +libntrack-qt4-dev#016-1.1 +libnuclient-dev#2.4.3-2.2 +libnuma-dev#2.0.8~rc4-1 +libnunit-cil-dev#2.6.0.12051+dfsg-2 +libnussl-dev#2.4.3-2.2 +libnvtt-dev#2.0.8-1+dfsg-2 +libnvtt-dev#2.0.8-1+dfsg-4~bpo70+1 +libnxcl-dev#0.9-3.1 +libnxml0-dev#0.18.3-4 +libnzb-dev#0.0.20050629-6.1 +liboasis-ocaml-dev#0.2.0-6 +liboasis3-dev#3.3.beta.dfsg.1-8+b1 +liboath-dev#1.12.4-1 +liboauth-dev#0.9.4-3.1 +libobby-0.4-dev#0.4.8-1 +libobexftp0-dev#0.23-1.1 +libobrowser-ocaml-dev#1.1.1+dfsg-1+b9 +libobus-ocaml-dev#1.1.3-1+b8 +libocamlbricks-ocaml-dev#0.50.1-4+b5 +libocamlbricks-ocaml-dev#0.90+bzr367-1~bpo70+1 +libocamlgraph-ocaml-dev#1.8.2-2 +libocamlgraph-viewer-ocaml-dev#1.8.2-2 +libocamlgsl-ocaml-dev#0.6.0-7+b2 +libocamlnet-gtk2-ocaml-dev#3.5.1-1 +libocamlnet-ocaml-dev#3.5.1-1 +libocamlnet-ssl-ocaml-dev#3.5.1-1 +libocamlodbc-ocaml-dev#2.15-5+b3 +libocamlviz-ocaml-dev#1.01-2+b2 +libocas-dev#0.93-1 +liboce-foundation-dev#0.9.1-3 +liboce-modeling-dev#0.9.1-3 +liboce-ocaf-dev#0.9.1-3 +liboce-ocaf-lite-dev#0.9.1-3 +liboce-visualization-dev#0.9.1-3 +libocpf-dev#1:1.0-3 +libocpf-dev#1:2.1-1~bpo70+1 +libocrad-dev#0.22~rc1-2 +libocsigen-ocaml-dev#1.3.4-2+b12 +libocsigen-xhtml-ocaml-dev#1.3.4-2+b12 +libocsigenserver-ocaml-dev#2.1-1 +libocsync-dev#0.91.4-1~bpo70+1 +liboctave-dev#3.6.2-5+deb7u1 +liboctave-dev#3.8.1-1~bpo70+1 +libode-dev#2:0.11.1-4 +libode-sp-dev#2:0.11.1-4 +libodin-dev#1.8.5-2 +libodn-ocaml-dev#0.0.8-1 +libofa0-dev#0.9.3-5 +libofapi-dev#0git20070620-6 +libofdt-dev#1.3.6-1 +libofetion-dev#2.2.2-1 +libofx-dev#1:0.9.4-2.1 +libogdi3.2-dev#3.2.0~beta2-7 +libogg-dev#1.3.0-4 +libogg-ocaml-dev#0.4.3-1+b1 +liboggkate-dev#0.4.1-1 +liboggplay1-dev#0.2.1~git20091227-1.2 +liboggz2-dev#1.1.1-1 +liboglappth-dev#1.0.0-2 +libogre-1.8-dev#1.8.0+dfsg1-3 +libogre-dev#1.7.4+dfsg1-7 +liboil0.3-dev#0.3.17-2 +libois-dev#1.3.0+dfsg0-5 +libomhacks-dev#0.16-1 +libomnievents-dev#1:2.6.2-2 +libomniorb4-dev#4.1.6-2 +libomnithread3-dev#4.1.6-2 +libomxil-bellagio-dev#0.9.3-1+b1 +libonig-dev#5.9.1-1 +liboobs-1-dev#3.0.0-1 +liboop-dev#1.0-9 +libooptools-dev#2.7-1 +libopal-dev#3.10.4~dfsg-3 +libopenafs-dev#1.6.1-3+deb7u2 +libopenafs-dev#1.6.9-1~bpo70+1 +libopenais-dev#1.1.4-4.1 +libopenal-dev#1:1.14-4 +libopenbabel-dev#2.3.1+dfsg-4 +libopenblas-dev#0.1.1-6+deb7u3 +libopencc-dev#0.3.0-3 +libopenconnect-dev#3.20-4 +libopencore-amrnb-dev#0.1.3-2 +libopencore-amrwb-dev#0.1.3-2 +libopencryptoki-dev#2.3.1+dfsg-3 +libopencsg-dev#1.3.2-2 +libopenct1-dev#0.6.20-1.2 +libopencv-calib3d-dev#2.3.1-11 +libopencv-contrib-dev#2.3.1-11 +libopencv-core-dev#2.3.1-11 +libopencv-dev#2.3.1-11 +libopencv-features2d-dev#2.3.1-11 +libopencv-flann-dev#2.3.1-11 +libopencv-gpu-dev#2.3.1-11 +libopencv-highgui-dev#2.3.1-11 +libopencv-imgproc-dev#2.3.1-11 +libopencv-legacy-dev#2.3.1-11 +libopencv-ml-dev#2.3.1-11 +libopencv-objdetect-dev#2.3.1-11 +libopencv-video-dev#2.3.1-11 +libopendbx1-dev#1.4.6-5~bpo70+1 +libopendkim-dev#2.6.8-4 +libopendmarc-dev#1.2.0+dfsg-1~bpo70+1 +libopenexr-dev#1.6.1-6 +libopenhpi-dev#2.14.1-1.2 +libopenigtlink1-dev#1.9.2~svn7468-1 +libopenimageio-dev#1.0.5+dfsg0-1 +libopenipmi-dev#2.0.16-1.3 +libopenjpeg-dev#1.3+dfsg-4.7 +libopenmeeg-dev#2.0.0.dfsg-5 +libopenmpi-dev#1.4.5-1 +libopenobex1-dev#1.5-2 +libopenr2-dev#1.3.2-1.1 +libopenraw-dev#0.0.9-3+b1 +libopenrawgnome-dev#0.0.9-3+b1 +libopenrpt-dev#3.3.4-6~bpo70+1 +libopenscap-dev#0.8.0-4+b1 +libopenscenegraph-dev#3.0.1-4 +libopenslide-dev#3.2.6-2 +libopensm2-dev#3.2.6-20090317-2.1 +libopenthreads-dev#3.0.1-4 +libopentk-cil-dev#1.0.20101006+dfsg1-1 +libopentoken3-dev#4.0b-3 +libopenturns-dev#1.0-4 +libopenusb-dev#1.1.0-2 +libopenvg1-mesa-dev#8.0.5-4+deb7u2 +libopenvrml-dev#0.18.9-5+deb7u1 +libopenwalnut1-dev#1.2.5-1.1+b1 +liboping-dev#1.6.2-1 +libopkele-dev#2.0.4-5.3 +libopts25-dev#1:5.12-0.1 +libopus-dev#0.9.14+20120615-1+nmu1 +libopus-dev#1.1-1~bpo70+1 +liborange-dev#0.4-2 +liborbit2-dev#1:2.14.19-0.1 +liborc-0.4-dev#1:0.4.16-2 +liborc-0.4-dev#1:0.4.19-1~bpo70+1 +liborigin-dev#20080225-2.1 +liborigin2-dev#2:20110117-1+b2 +libortp-dev#3.5.2-10 +liboscpack-dev#1.0.2-1 +libosgearth-dev#2.0+dfsg-4+b3 +libosinfo-1.0-dev#0.1.1-1 +libosip2-dev#3.6.0-4 +libosl-dev#0.5.0-1 +libosmesa6-dev#8.0.5-4+deb7u2 +libosmgpsmap-dev#0.7.3-3 +libosmium-dev#0.0~20111213-g7f3500a-3+b2 +libosmosdr-dev#0.1.8.effcaa7-1~bpo70+1 +libosmpbf-dev#1.2.1-3 +libosp-dev#1.5.2-10 +libosptk3-dev#3.4.2-1+b1 +libossim-dev#1.7.21-4 +libossp-sa-dev#1.2.6-1 +libossp-uuid-dev#1.6.2-1.3 +libostyle-dev#1.4devel1-20.1+b1 +libotcl1-dev#1.14+dfsg-2 +libotf-dev#0.9.12-2 +libotf-trace-dev#1.10.2+dfsg-2 +libotpw-dev#1.3-2 +libotr2-dev#3.2.1-1+deb7u1 +libotr5-dev#4.0.0-2.2~bpo70+1 +libots-dev#0.5.0-2.1 +libounit-ocaml-dev#1.1.1-1 +libow-dev#2.8p15-1 +libowfat-dev#0.28-6 +libowfat-dietlibc-dev#0.28-6 +libownet-dev#2.8p15-1 +libp11-dev#0.2.8-2 +libp11-kit-dev#0.12-3 +libp11-kit-dev#0.20.2-1~bpo70+1 +libpackagekit-glib2-dev#0.7.6-3 +libpackagekit-qt2-dev#0.7.6-3 +libpacketdump3-dev#3.0.14-1 +libpacklib-lesstif1-dev#20061220+dfsg3-2 +libpacklib1-dev#20061220+dfsg3-2 +libpacparser-dev#1.3.0-2 +libpam-ocaml-dev#1.1-4+b3 +libpam0g-dev#1.1.3-7.1 +libpanel-applet-4-dev#3.4.2.1-4 +libpango1.0-dev#1.30.0-1 +libpangomm-1.4-dev#2.28.4-1 +libpano13-dev#2.9.18+dfsg-5 +libpantomime1.2-dev#1.2.0~pre3+snap20071004+dfsg-4+b1 +libpaper-dev#1.1.24+nmu2 +libpaps-dev#0.6.8-6 +libpaq-dev#1.0.4-3+b1 +libpar2-0-dev#0.2.1-1 +libpari-dev#2.5.1-2 +libpari-dev#2.7.1-1~bpo70+1 +libparmetis-dev#3.1.1-4 +libparpack2-dev#3.1.1-2.1 +libparrot-dev#4.0.0-3 +libparser++-dev#0.2.3-2 +libparted0-dev#2.3-12 +libpasswdqc-dev#1.2.0-1 +libpath-utils-dev#0.1.3-2 +libpathfinder-dev#1.1.3-0.4+b1 +libpawlib-lesstif3-dev#1:2.14.04.dfsg.2-8 +libpawlib2-dev#1:2.14.04.dfsg.2-8 +libpcap-dev#1.3.0-1 +libpcap0.8-dev#1.3.0-1 +libpcapnav0-dev#0.8-1 +libpci-dev#1:3.1.9-6 +libpciaccess-dev#0.13.1-2 +libpcl1-dev#1.6-1 +libpcre++-dev#0.9.5-5.1 +libpcre-ocaml-dev#6.2.5-1 +libpcre3-dev#1:8.30-5 +libpcscada2-dev#0.7.1-4 +libpcsclite-dev#1.8.4-1+deb7u1 +libpdflib804-2-dev#20061220+dfsg3-2 +libpe-rules2-dev#1.1.7-1 +libpe-status3-dev#1.1.7-1 +libpeas-dev#1.4.0-2 +libpengine3-dev#1.1.7-1 +libperl-dev#5.14.2-21+deb7u1 +libperl4caml-ocaml-dev#0.9.5-4+b4 +libpetsc3.2-dev#3.2.dfsg-6 +libpfqueue-dev#0.5.6-8 +libpfs-dev#1.8.5-1 +libpgm-dev#5.1.118-1~dfsg-0.1 +libpgocaml-ocaml-dev#1.5-2 +libpgpool-dev#3.1.3-5 +libpgtcl-dev#1:1.5-6 +libphash0-dev#0.9.4-1.2 +libphat-dev#0.4.1-5 +libphobos-4.4-dev#1.063-4.4.7-1 +libphobos2-4.6-dev#0.29.1-4.6.3-2 +libphone-ui-dev#1:0.0.1+git20110825-3 +libphone-utils-dev#0.1+git20110523-2.1 +libphonon-dev#4:4.6.0.0-3 +libphononexperimental-dev#4:4.6.0.0-3 +libphotos202-dev#20061220+dfsg3-2 +libphtools2-dev#20061220+dfsg3-2 +libphysfs-dev#2.0.2-6 +libpiano-dev#2012.05.06-2 +libpigment0.3-dev#0.3.17-1 +libpils2-dev#1.0.9+hg2665-1 +libpinyin0-dev#0.6.91-1 +libpion-common-dev#4.0.7+dfsg-3.1 +libpion-net-dev#4.0.7+dfsg-3.1 +libpipeline-dev#1.2.1-1 +libpisock-dev#0.12.5-5 +libpixman-1-dev#0.26.0-4+deb7u1 +libpjproject-dev#2.1.0.0.ast20130823-1~bpo70+1 +libpkcs11-helper1-dev#1.09-1 +libplayer-dev#2.0.1-2.1 +libplayerc++3.0-dev#3.0.2+dfsg-4+b1 +libplayerc3.0-dev#3.0.2+dfsg-4+b1 +libplayercommon3.0-dev#3.0.2+dfsg-4+b1 +libplayercore3.0-dev#3.0.2+dfsg-4+b1 +libplayerdrivers3.0-dev#3.0.2+dfsg-4+b1 +libplayerinterface3.0-dev#3.0.2+dfsg-4+b1 +libplayerjpeg3.0-dev#3.0.2+dfsg-4+b1 +libplayertcp3.0-dev#3.0.2+dfsg-4+b1 +libplayerwkb3.0-dev#3.0.2+dfsg-4+b1 +libplib-dev#1.8.5-6 +libplist++-dev#1.8-1 +libplist-dev#1.8-1 +libpload-dev#1.4.2-3 +libplot-dev#2.6-3 +libploticus0-dev#2.41-5 +libplotmm-dev#0.1.2-2 +libplplot-ada0-dev#5.9.9-5 +libplplot-dev#5.9.9-5 +libplumb2-dev#1.0.9+hg2665-1 +libplumbgpl2-dev#1.0.9+hg2665-1 +libpmap3.0-dev#3.0.2+dfsg-4+b1 +libpmi0-dev#2.3.4-2+b1 +libpmount-dev#0.0.16 +libpng++-dev#0.2.5-1 +libpng12-dev#1.2.49-1 +libpnglite-dev#0.1.17-1 +libpoco-dev#1.3.6p1-4 +libpodofo-dev#0.9.0-1.1+b1 +libpoker-eval-dev#138.0-1 +libpolarssl-dev#1.2.9-1~deb7u2 +libpoldiff-dev#3.3.7-3 +libpolkit-agent-1-dev#0.105-3 +libpolkit-backend-1-dev#0.105-3 +libpolkit-gobject-1-dev#0.105-3 +libpolkit-qt-1-dev#0.103.0-1 +libpolybori-dev#0.5~rc1-2.2 +libpolylib64-dev#5.22.5-3+dfsg +libpolyml-dev#5.2.1-1.1 +libpolyorb2-dev#2.8~20110207-5.1 +libpomp-dev#1.1+dfsg-2 +libpoppler-cil-dev#0.0.3-2 +libpoppler-cpp-dev#0.18.4-6 +libpoppler-cpp-dev#0.24.5-4~bpo70+1 +libpoppler-dev#0.18.4-6 +libpoppler-dev#0.24.5-4~bpo70+1 +libpoppler-glib-dev#0.18.4-6 +libpoppler-glib-dev#0.24.5-4~bpo70+1 +libpoppler-private-dev#0.18.4-6 +libpoppler-private-dev#0.24.5-4~bpo70+1 +libpoppler-qt4-dev#0.18.4-6 +libpoppler-qt4-dev#0.24.5-4~bpo70+1 +libpopplerkit-dev#0.0.20051227svn-7+b1 +libpopt-dev#1.16-7 +libportaudio-dev#18.1-7.1 +libportaudio-ocaml-dev#0.2.0-1+b1 +libportmidi-dev#1:184-2.1 +libportsmf-dev#0.1~svn20101010-3 +libpostgresql-ocaml-dev#1.18.0-1 +libpostproc-dev#6:0.8.10-1 +libpostproc-dev#6:0.git20120821-4~bpo70+1 +libpotrace-dev#1.10-1 +libpowerman0-dev#2.3.5-1 +libppd-dev#2:0.10-7.1 +libppl0.11-dev#0.11.2-8 +libpq-dev#9.1.13-0wheezy1 +libpqxx3-dev#3.1-1.1 +libprelude-dev#1.0.0-9 +libpreludedb-dev#1.0.0-1.1+b2 +libpresage-dev#0.8.8-1 +libpri-dev#1.4.12-2 +libprinterconf-dev#0.5-12 +libprintsys-dev#0.6-13 +libprison-dev#1.0+dfsg-1 +libprocps0-dev#1:3.3.3-3 +libproj-dev#4.7.0-2 +libprojectm-dev#2.1.0+dfsg-1 +libprojectm-qt-dev#2.1.0+dfsg-1 +libprotobuf-c0-dev#0.14-1+b1 +libprotobuf-dev#2.4.1-3 +libprotoc-dev#2.4.1-3 +libproxy-dev#0.3.1-6 +libproxychains-dev#3.1-3 +libpspell-dev#0.60.7~20110707-1 +libpst-dev#0.6.54-4.1 +libpstoedit-dev#3.60-2+b1 +libpstreams-dev#0.7.0-2 +libpt-dev#2.10.4~dfsg-1 +libptexenc-dev#2012.20120628-4 +libpth-dev#2.0.7-16 +libpthread-stubs0-dev#0.3-3 +libpthread-workqueue-dev#0.8.2-1 +libptscotch-dev#5.1.12b.dfsg-1.2 +libpugl-dev#0~svn32+dfsg0-1 +libpulse-dev#2.0-6.1 +libpulse-dev#4.0-6~bpo7+1 +libpulse-ocaml-dev#0.1.2-1+b1 +libpuma-dev#1:1.1+svn20120529-2 +libpurelibc-dev#0.4.1-1 +libpurple-dev#2.10.7-2~bpo70+1 +libpurple-dev#2.10.9-1~deb7u1 +libpuzzle-dev#0.9-5 +libpwl-dev#0.11.2-8 +libpxp-ocaml-dev#1.2.2-1+b4 +libpycaml-ocaml-dev#0.82-14+b2 +libpyside-dev#1.1.1-3 +libpythia8-dev#8.1.65-1 +libpythonqt2-dev#2.0.1-1.1 +libqalculate-dev#0.9.7-8 +libqapt-dev#1.3.0-2 +libqb-dev#0.11.1-2 +libqca2-dev#2.0.3-4 +libqd-dev#2.3.11.dfsg-2.1 +libqdaccolib-dev#0.8.2-1 +libqdbm++-dev#1.8.78-2 +libqdbm-dev#1.8.78-2 +libqdjango-dev#0.2.5-2 +libqedje-dev#0.4.0+lgpl-3 +libqfits-dev#6.2.0-5 +libqgis-dev#1.7.4+1.7.5~20120320-1.1+b1 +libqglviewer-qt4-dev#2.3.4-4.2 +libqgpsmm-dev#3.6-4+deb7u1 +libqgpsmm-dev#3.9-3~bpo70+1 +libqhull-dev#2009.1-3 +libqimageblitz-dev#1:0.0.6-4 +libqjson-dev#0.7.1-7 +libqmf-dev#0.16-6+deb7u1 +libqmf2-dev#0.16-6+deb7u1 +libqmfconsole2-dev#0.16-6+deb7u1 +libqmfengine1-dev#0.16-6+deb7u1 +libqmmp-dev#0.5.5-1+b1 +libqmmpui-dev#0.5.5-1+b1 +libqoauth-dev#1.0.1-1 +libqof-dev#0.8.6-1 +libqofexpensesobjects-dev#0.1.9-2 +libqpdf-dev#2.3.1-4 +libqpidbroker2-dev#0.16-6+deb7u1 +libqpidclient2-dev#0.16-6+deb7u1 +libqpidcommon2-dev#0.16-6+deb7u1 +libqpidmessaging2-dev#0.16-6+deb7u1 +libqpidtypes1-dev#0.16-6+deb7u1 +libqpol-dev#3.3.7-3 +libqpx-dev#0.7.1.002-5 +libqpx-dev#0.7.2-4~bpo70+1 +libqrencode-dev#3.3.0-2 +libqrupdate-dev#1.1.1-1 +libqsastime-dev#5.9.9-5 +libqscintilla2-dev#2.6.2-2 +libqt4-dev#4:4.8.2+dfsg-11 +libqt4-opengl-dev#4:4.8.2+dfsg-11 +libqt4-private-dev#4:4.8.2+dfsg-11 +libqt4pas-dev#2.5-6 +libqtassistantclient-dev#4.6.3-4 +libqtexengine-dev#0.3-3 +libqtgstreamer-dev#0.10.2-2 +libqtruby4shared-dev#4:4.8.4-1 +libqtwebkit-dev#2.2.1-5 +libquantlib0-dev#1.2-2+b1 +libquantum-dev#1.1.0-3 +libquicktime-dev#2:1.2.4-3 +libquorum-dev#1.4.2-3 +libquvi-dev#0.4.1-1 +libqwt-dev#6.0.0-1.2 +libqwt5-qt4-dev#5.2.2-3 +libqwtplot3d-qt4-dev#0.2.7+svn191-7 +libqxmlrpc-dev#0.0.svn6-2 +libqxmpp-dev#0.4.92-1 +libqxmpp-dev#0.8.0-1~bpo70+1 +libqxt-dev#0.6.1-6 +libqzeitgeist-dev#0.7.0-1+b1 +libqzion-dev#0.4.0+lgpl-4 +librabbitmq-dev#0.0.1.hg216-1 +libradare2-dev#0.9-3 +libradius1-dev#0.3.2-14 +libradiusclient-ng-dev#0.5.6-1.1 +librados-dev#0.80.1-1~bpo70+1 +libranlip-dev#1.0-4.1 +librapi2-dev#0.15-2.1 +libraptor1-dev#1.4.21-7.1 +libraptor2-dev#2.0.8-2 +librarian-dev#0.8.1-5 +librasqal3-dev#0.9.29-1 +librasterlite-dev#1.1~svn11-2 +libraul-dev#0.8.0+dfsg0-0.1+b1 +libraw-dev#0.14.6-2 +libraw1394-dev#2.0.9-1 +librbd-dev#0.80.1-1~bpo70+1 +librcc-dev#0.2.9-3 +librcd-dev#0.1.13-3 +librdf0-dev#1.0.15-1+b1 +librdkit-dev#201203-3 +librdmacm-dev#1.0.15-1+deb7u1 +librdmacm-dev#1.0.16-1~bpo70+1 +librdmawrap2-dev#0.16-6+deb7u1 +libreact-ocaml-dev#0.9.3-1 +libreadline-dev#6.2+dfsg-0.1 +libreadline-gplv2-dev#5.2+dfsg-2~deb7u1 +libreadline6-dev#6.2+dfsg-0.1 +librec-dev#1.5-1 +librecode-dev#3.6-20 +librecon-1.9-dev#1.9.7-1~bpo70+1 +libref-array-dev#0.1.3-2 +libregina3-dev#3.6-2 +libregistry-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libreins-ocaml-dev#0.1a-4+b1 +libreiser4-dev#1.0.7-6.3 +librelp-dev#1.0.0-1 +librelp-dev#1.2.7-1~bpo70+1 +libremctl-dev#3.2-4 +libremctl-dev#3.8-1~bpo70+1 +librenaissance0-dev#0.9.0-4+b3 +libreoffice-dev#1:3.5.4+dfsg2-0+deb7u2 +libreoffice-dev#1:4.2.5-1~bpo70+1 +librep-dev#0.90.2-1.3 +libreplaygain-dev#1.0~r475-1 +libres-ocaml-dev#3.2.0-2+b3 +libresample1-dev#0.1.3-4 +libresid-builder-dev#2.1.1-14 +libresiprocate-1.8-dev#1.8.5-4 +libresiprocate-1.9-dev#1.9.7-1~bpo70+1 +libresiprocate-turn-client-1.8-dev#1.8.5-4 +libresiprocate-turn-client-1.9-dev#1.9.7-1~bpo70+1 +librest-dev#0.7.12-3 +librest-extras-dev#0.7.12-3 +librgxg-dev#0.1-1~bpo70+1 +librhash-cil-dev#1.2.9-8+deb7u1 +librhash-dev#1.2.9-8+deb7u1 +librheolef-dev#6.1-2.1 +librivet-dev#1.8.0-1 +librlog-dev#1.4-2 +libroar-dev#1.0~beta2-3 +libroot-bindings-python-dev#5.34.00-2 +libroot-bindings-ruby-dev#5.34.00-2 +libroot-core-dev#5.34.00-2 +libroot-geom-dev#5.34.00-2 +libroot-graf2d-gpad-dev#5.34.00-2 +libroot-graf2d-graf-dev#5.34.00-2 +libroot-graf2d-postscript-dev#5.34.00-2 +libroot-graf3d-eve-dev#5.34.00-2 +libroot-graf3d-g3d-dev#5.34.00-2 +libroot-graf3d-gl-dev#5.34.00-2 +libroot-gui-dev#5.34.00-2 +libroot-gui-ged-dev#5.34.00-2 +libroot-hist-dev#5.34.00-2 +libroot-hist-spectrum-dev#5.34.00-2 +libroot-html-dev#5.34.00-2 +libroot-io-dev#5.34.00-2 +libroot-io-xmlparser-dev#5.34.00-2 +libroot-math-foam-dev#5.34.00-2 +libroot-math-genvector-dev#5.34.00-2 +libroot-math-mathcore-dev#5.34.00-2 +libroot-math-mathmore-dev#5.34.00-2 +libroot-math-matrix-dev#5.34.00-2 +libroot-math-minuit-dev#5.34.00-2 +libroot-math-mlp-dev#5.34.00-2 +libroot-math-physics-dev#5.34.00-2 +libroot-math-quadp-dev#5.34.00-2 +libroot-math-smatrix-dev#5.34.00-2 +libroot-math-splot-dev#5.34.00-2 +libroot-math-unuran-dev#5.34.00-2 +libroot-misc-memstat-dev#5.34.00-2 +libroot-misc-minicern-dev#5.34.00-2 +libroot-misc-table-dev#5.34.00-2 +libroot-montecarlo-eg-dev#5.34.00-2 +libroot-montecarlo-vmc-dev#5.34.00-2 +libroot-net-auth-dev#5.34.00-2 +libroot-net-bonjour-dev#5.34.00-2 +libroot-net-dev#5.34.00-2 +libroot-net-ldap-dev#5.34.00-2 +libroot-proof-clarens-dev#5.34.00-2 +libroot-proof-dev#5.34.00-2 +libroot-proof-proofplayer-dev#5.34.00-2 +libroot-roofit-dev#5.34.00-2 +libroot-tmva-dev#5.34.00-2 +libroot-tree-dev#5.34.00-2 +libroot-tree-treeplayer-dev#5.34.00-2 +librostlab-blast0-dev#1.0.0-2 +librostlab3-dev#1.0.20-1 +librpcsecgss-dev#0.19-5 +librplay3-dev#3.3.2-14 +librpm-dev#4.10.0-5+deb7u1 +librra-dev#0.14-1.2 +librrd-dev#1.4.7-2 +librsl-dev#1.42-2 +librsskit-dev#0.3-2 +librsvg2-2.0-cil-dev#2.26.0-8 +librsvg2-dev#2.36.1-2 +librsync-dev#0.9.7-9 +librtai-dev#3.8.1-4 +librtas-dev#1.3.6-1 +librtasevent-dev#1.3.6-1 +librtaudio-dev#4.0.10~ds0-2 +librtfcomp-dev#1.1-5+b1 +librtfilter-dev#1.1-4 +librtlsdr-dev#0.5.3-3~bpo70+1 +librtmidi-dev#1.0.15~ds0-2 +librtmp-dev#2.4+20111222.git4e06e21-1 +librubberband-dev#1.3-1.3 +librudecgi-dev#5.0.0-1 +libruli4-dev#0.33-1.1 +librxp-dev#1.5.0-1 +libs3-dev#2.0-1 +libs3d-dev#0.2.2-8 +libs3dw-dev#0.2.2-8 +libsaamf3-dev#1.1.4-4.1 +libsackpt3-dev#1.1.4-4.1 +libsaclm3-dev#1.1.4-4.1 +libsaevt3-dev#1.1.4-4.1 +libsage-dev#0.2.0-4.1 +libsalck3-dev#1.1.4-4.1 +libsam-dev#1.4.2-3 +libsamba-credentials-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-hostconfig-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-policy-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamba-util-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsamdb-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsaml2-dev#2.4.3-4 +libsaml2-dev#2.5.3-2~bpo70+1 +libsampleicc-dev#1.6.4-1+b1 +libsamplerate-ocaml-dev#0.1.1-1+b3 +libsamplerate0-dev#0.1.8-5 +libsamsg4-dev#1.1.4-4.1 +libsane-dev#1.0.22-7.4 +libsane-extras-dev#1.0.22.2 +libsanlock-dev#2.2-2 +libsary-dev#1:1.2.0-2.1 +libsasl2-dev#2.1.25.dfsg1-6+deb7u1 +libsatmr3-dev#1.1.4-4.1 +libsbc-dev#1.1-2~bpo7+1 +libsbjson-dev#2.3.2-2 +libsbsms-dev#2.0.1-1 +libsbuf-dev#9.0+ds1-4 +libsbuild-dev#1.6.4-4 +libsc-dev#2.3.1-14 +libscalapack-mpi-dev#1.8.0-9 +libscalapack-pvm-dev#1.8.0-9 +libscalc-dev#0.2.4-1 +libscamperfile0-dev#20111202b-1 +libschroedinger-dev#1.0.11-2 +libschroedinger-ocaml-dev#0.1.0-1+b3 +libscim-dev#1.4.13-5 +libscm-dev#5e5-3.2 +libscotch-dev#5.1.12b.dfsg-1.2 +libscotchmetis-dev#5.1.12b.dfsg-1.2 +libscotchparmetis-dev#5.1.12b.dfsg-1.2 +libsctp-dev#1.0.11+dfsg-2 +libscythestat-dev#1.0.2-1 +libsdl-console-dev#2.1-3 +libsdl-gfx1.2-dev#2.0.23-3 +libsdl-image1.2-dev#1.2.12-2 +libsdl-mixer1.2-dev#1.2.12-3 +libsdl-net1.2-dev#1.2.8-2 +libsdl-ocaml-dev#0.9.0-1 +libsdl-pango-dev#0.1.2-6 +libsdl-sge-dev#030809dfsg-3 +libsdl-sound1.2-dev#1.0.3-6 +libsdl-stretch-dev#0.3.1-3 +libsdl-ttf2.0-dev#2.0.11-2 +libsdl1.2-dev#1.2.15-5 +libsdl2-dev#2.0.0+dfsg1-2~bpo70+1 +libsdpa-dev#7.3.8+dfsg-1 +libsearchclient-dev#0.7.7-3 +libseaudit-dev#3.3.7-3 +libseccomp-dev#2.1.1-1~bpo70+1 +libseed-gtk3-dev#3.2.0-2 +libsefs-dev#3.3.7-3 +libselinux1-dev#2.1.9-5 +libsemanage1-dev#2.1.6-6 +libsensors-applet-plugin-dev#3.0.0-0.2 +libsensors4-dev#1:3.3.2-2+deb7u1 +libsepol1-dev#2.1.4-3 +libserd-dev#0.14.0~dfsg0-2 +libserf-dev#1.1.0-2 +libsexplib-camlp4-dev#7.0.4-2 +libsexy-dev#0.1.11-2+b1 +libsfml-dev#1.6+dfsg2-2 +libsfst1-1.2-0-dev#1.2.0-1.2 +libsgutils2-dev#1.33-1 +libsha-ocaml-dev#1.7-2+b2 +libshairport-dev#1.2.1~git20120110.aeb4987-2 +libshevek-dev#1.3-1 +libshhmsg1-dev#1.4.1-4.1 +libshhopt1-dev#1.1.7-2.1 +libshiboken-dev#1.1.1-1 +libshibsp-dev#2.4.3+dfsg-5+b1 +libshibsp-dev#2.5.2+dfsg-2~bpo70+1 +libshisa-dev#1.0.1-2 +libshishi-dev#1.0.1-2 +libshout-ocaml-dev#0.2.7-1+b3 +libshout3-dev#2.2.2-8 +libshp-dev#1.2.10-7 +libshr-glib-dev#2011.03.08.2~git20110930-2 +libsidl-dev#1.4.0.dfsg-8.1 +libsidplay1-dev#1.36.59-5 +libsidplay2-dev#2.1.1-14 +libsidplayfp-dev#0.3.5-1 +libsidutils-dev#2.1.1-14 +libsieve2-dev#2.2.6-1.1 +libsigc++-1.2-dev#1.2.7-2 +libsigc++-2.0-dev#2.2.10-0.2 +libsigc++-dev#1.0.4-9.4 +libsigrok0-dev#0.1.0-2 +libsigrokdecode0-dev#0.1.0-2 +libsigsegv-dev#2.9-4 +libsilly-dev#0.1.0-3 +libsilo-dev#4.8-13 +libsimage-dev#1.7.0-1.1+b1 +libsimplelist0-dev#0.3.4-2 +libsipwitch-dev#1.2.4-1 +libsipxtapi-dev#3.3.0~test15-1~bpo70+1 +libsiscone-dev#2.0.5-1 +libsiscone-spherical-dev#2.0.5-1 +libskk-dev#0.0.12-3 +libskstream-0.3-dev#0.3.8-1 +libslang2-dev#2.2.4-15 +libslepc3.2-dev#3.2-p5-1 +libslp-dev#1.2.1-9 +libslurm-dev#2.3.4-2+b1 +libslurmdb-dev#2.3.4-2+b1 +libslv2-dev#0.6.6+dfsg1-2 +libsm-dev#2:1.2.1-2 +libsmbclient-dev#2:3.6.6-6+deb7u3 +libsmbclient-dev#2:4.1.9+dfsg-1~bpo70+1 +libsmbclient-raw-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libsmbios-dev#2.0.3.dfsg-1.1 +libsmbsharemodes-dev#2:4.1.9+dfsg-1~bpo70+1 +libsmf-dev#1.3-2 +libsmi2-dev#0.4.8+dfsg2-7 +libsmokekde-dev#4:4.8.4-1 +libsmokeqt4-dev#4:4.8.4-1 +libsmpeg-dev#0.4.5+cvs20030824-5 +libsnacc-dev#1.3.1-1 +libsnack2-dev#2.2.10-dfsg1-12.1 +libsnappy-dev#1.0.5-2 +libsndfile1-dev#1.0.25-5 +libsndobj-dev#2.6.6.1-3 +libsnmp-dev#5.4.3~dfsg-2.8 +libsnmpkit-dev#0.9-16 +libsocialweb-client-dev#0.25.20-2.1 +libsocialweb-dev#0.25.20-2.1 +libsocksd0-dev#1.1.19.dfsg-3+b3 +libsofa-c-dev#2012.03.01-1 +libsofa1-dev#1.0~beta4-7 +libsofia-sip-ua-dev#1.12.11+20110422-1 +libsofia-sip-ua-glib-dev#1.12.11+20110422-1 +libsofthsm-dev#1.3.3-2 +libsoil-dev#1.07~20080707.dfsg-2 +libsombok-dev#2.2.1-1 +libsonic-dev#0.1.17-1.1 +libsope-dev#1.3.16-1 +libsope-dev#2.0.5-1~bpo70+1 +libsoprano-dev#2.7.6+dfsg.1-2wheezy1 +libsoqt4-dev#1.5.0-2 +libsoqt4-dev#1.6.0~e8310f-1~bpo70+1 +libsord-dev#0.8.0~dfsg0-1 +libsoundgen-dev#0.6-4 +libsoundtouch-dev#1.6.0-3 +libsoundtouch-ocaml-dev#0.1.7-1+b1 +libsoup-gnome2.4-dev#2.38.1-3 +libsoup2.4-dev#2.38.1-3 +libsoupcutter-dev#1.1.7-1.2 +libsource-highlight-dev#3.1.6-1.1 +libsox-dev#14.4.0-3 +libsp-gxmlcpp-dev#1.0.20040603-5 +libsp1-dev#1.3.4-1.2.1-47.1+b1 +libspandsp-dev#0.0.6~pre20-3.1 +libsparsehash-dev#1.10-1 +libsparskit-dev#2.0.0-2 +libspatialindex-dev#1.7.0-1 +libspatialite-dev#3.0.0~beta20110817-3+deb7u1 +libspctag-dev#0.2-1 +libspectre-dev#0.2.7-2 +libspectrum-dev#1.0.0-3 +libspeechd-dev#0.7.1-6.2 +libspeex-dev#1.2~rc1-7 +libspeex-ocaml-dev#0.2.0-1+b3 +libspeexdsp-dev#1.2~rc1-7 +libspf2-dev#1.2.9-7 +libsphere-dev#3.2-4 +libspice-client-glib-2.0-dev#0.12-5 +libspice-client-gtk-2.0-dev#0.12-5 +libspice-client-gtk-3.0-dev#0.12-5 +libspice-protocol-dev#0.10.1-1 +libspice-protocol-dev#0.12.6-1~bpo70+2 +libspice-server-dev#0.11.0-1+deb7u1 +libspice-server-dev#0.12.4-0nocelt2~bpo70+1 +libspiro-dev#20071029-2 +libspnav-dev#0.2.2-1 +libspooles-dev#2.2-9 +libsprng2-dev#2.0a-8 +libsqlcipher-dev#2.2.1-2~bpo70+1 +libsqlexpr-ocaml-dev#0.4.1-1+b5 +libsqlheavy-dev#0.1.1-1 +libsqlheavygtk-dev#0.1.1-1 +libsqlite0-dev#2.8.17-7 +libsqlite3-dev#3.7.13-1+deb7u1 +libsqlite3-ocaml-dev#1.6.1-1+b1 +libsquizz-dev#0.99a-2 +libsratom-dev#0.2.0~dfsg0-1 +libsrecord-dev#1.58-1+b1 +libsrf-dev#0.1+dfsg-1 +libsrtp0-dev#1.4.4+20100615~dfsg-2+deb7u1 +libss7-dev#1.0.2-3 +libsscm-dev#0.8.5-2.1 +libssh-dev#0.5.4-1+deb7u1 +libssh-dev#0.5.4-3~bpo70+1 +libssh2-1-dev#1.4.2-1.1 +libssl-dev#1.0.1e-2+deb7u7 +libssl-ocaml-dev#0.4.6-1 +libsslcommon2-dev#0.16-6+deb7u1 +libssreflect-ocaml-dev#1.3pl4-1 +libsss-sudo-dev#1.8.4-2 +libst-dev#1.9-3 +libstaden-read-dev#1.12.4-1 +libstarlink-ast-dev#7.0.4+dfsg-1 +libstarlink-pal-dev#0.1.0-1 +libstarpu-contrib-dev#1.0.1+dfsg-1 +libstarpu-dev#1.0.1+dfsg-1 +libstartup-notification0-dev#0.12-1 +libstatgrab-dev#0.17-1 +libstdc++6-4.4-dev#4.4.7-2 +libstdc++6-4.6-dev#4.6.3-14 +libstdc++6-4.7-dev#4.7.2-5 +libstemmer-dev#0+svn546-2 +libsteptalk-dev#0.10.0-5+b1 +libstfl-dev#0.22-1+b1 +libstk0-dev#4.4.3-2 +libstlport4.6-dev#4.6.2-7 +libstonith1-dev#1.0.9+hg2665-1 +libstonithd1-dev#1.1.7-1 +libstreamanalyzer-dev#0.7.7-3 +libstreams-dev#0.7.7-3 +libstrigihtmlgui-dev#0.7.7-3 +libstrigiqtdbusclient-dev#0.7.7-3 +libstroke0-dev#0.5.1-6 +libstxxl-dev#1.3.1-4 +libsublime-dev#1.3.1-2 +libsubtitleeditor-dev#0.33.0-1 +libsubunit-dev#0.0.8+bzr176-1 +libsugarext-dev#0.96.1-2 +libsuil-dev#0.6.4~dfsg0-3 +libsuitesparse-dev#1:3.4.0-3 +libsuitesparse-metis-dev#3.1.0-2 +libsundials-serial-dev#2.5.0-3 +libsunpinyin-dev#2.0.3+git20120607-1 +libsuperlu3-dev#3.0+20070106-3 +libsvga1-dev#1:1.4.3-33 +libsvm-dev#3.12-1 +libsvn-dev#1.6.17dfsg-4+deb7u6 +libsvncpp-dev#0.12.0dfsg-6 +libsvnqt-dev#1.5.5-4.1 +libsvrcore-dev#1:4.0.4-15 +libswami-dev#2.0.0+svn389-2 +libswe-dev#1.77.00.0005-2 +libswiften-dev#2.0~beta1+dev47-1 +libsword-dev#1.6.2+dfsg-5 +libswscale-dev#6:0.8.10-1 +libswscale-dev#6:10.1-1~bpo70+1 +libsx-dev#2.05-3 +libsyfi1.0-dev#1.0.0.dfsg-1 +libsylph-dev#1.1.0-8 +libsymmetrica-dev#2.0-1 +libsynce0-dev#0.15-1.1 +libsyncml-dev#0.5.4-2.1 +libsynfig-dev#0.63.05-1 +libsynopsis0.12-dev#0.12-8 +libsynthesis-dev#3.4.0.16.7-1 +libsynthesis-dev#3.4.0.47.1-1~bpo70+1 +libsysactivity-dev#0.6.4-1 +libsysfs-dev#2.1.0+repack-2 +libsyslog-ng-dev#3.3.5-4 +libsyslog-ocaml-dev#1.4-6+b2 +libsystemd-daemon-dev#204-8~bpo70+1 +libsystemd-daemon-dev#44-11+deb7u4 +libsystemd-id128-dev#204-8~bpo70+1 +libsystemd-id128-dev#44-11+deb7u4 +libsystemd-journal-dev#204-8~bpo70+1 +libsystemd-journal-dev#44-11+deb7u4 +libsystemd-login-dev#204-8~bpo70+1 +libsystemd-login-dev#44-11+deb7u4 +libt1-dev#5.1.2-3.6 +libtacacs+1-dev#4.0.4.19-11 +libtachyon-dev#0.99~b2+dfsg-0.4 +libtag-extras-dev#1.0.1-3 +libtag1-dev#1.7.2-1 +libtag1-dev#1.9.1-2~bpo70+1 +libtagc0-dev#1.7.2-1 +libtagc0-dev#1.9.1-2~bpo70+1 +libtagcoll2-dev#2.0.13-1.1 +libtaglib-cil-dev#2.0.4.0-1 +libtaglib-ocaml-dev#0.2.0-1+b1 +libtaktuk-1-dev#3.7.4-1 +libtalloc-dev#2.0.7+git20120207-1 +libtalloc-dev#2.1.1-1~bpo70+1 +libtamuanova-dev#0.2-2 +libtango7-dev#7.2.6+dfsg-14 +libtango8-dev#8.1.2c+dfsg-4~bpo70+1 +libtaningia-dev#0.2.2-1 +libtaoframework-devil-cil-dev#2.1.svn20090801-9 +libtaoframework-ffmpeg-cil-dev#2.1.svn20090801-9 +libtaoframework-freeglut-cil-dev#2.1.svn20090801-9 +libtaoframework-freetype-cil-dev#2.1.svn20090801-9 +libtaoframework-ftgl-cil-dev#2.1.svn20090801-9 +libtaoframework-lua-cil-dev#2.1.svn20090801-9 +libtaoframework-ode-cil-dev#2.1.svn20090801-9 +libtaoframework-openal-cil-dev#2.1.svn20090801-9 +libtaoframework-opengl-cil-dev#2.1.svn20090801-9 +libtaoframework-physfs-cil-dev#2.1.svn20090801-9 +libtaoframework-sdl-cil-dev#2.1.svn20090801-9 +libtar-dev#1.2.16-1+deb7u2 +libtarantool-dev#1.4.6+20120629+2158-1 +libtasn1-3-dev#2.13-2 +libtasn1-6-dev#3.6-1~bpo70+1 +libtbb-dev#4.0+r233-1 +libtcc-dev#0.9.26~git20120612.ad5f375-6 +libtcd-dev#2.2.2-1 +libtclap-dev#1.2.1-1 +libtclcl1-dev#1.20-6 +libtcplay-dev#1.1-1~bpo70+1 +libtdb-dev#1.2.10-2 +libtdb-dev#1.2.12-1~bpo70+1 +libtecla1-dev#1.6.1-5 +libteem-dev#1.11.0~svn5226-1 +libtelepathy-farstream-dev#0.4.0-3 +libtelepathy-glib-dev#0.18.2-2 +libtelepathy-logger-dev#0.4.0-1 +libtelepathy-logger-qt4-dev#0.4.0-1 +libtelepathy-qt4-dev#0.9.1-4 +libtelnet-dev#0.21-1 +libtemplates-parser11.6-dev#11.6-2 +libterralib-dev#4.0.0-4 +libtesseract-dev#3.02.01-6 +libtet1.4-dev#1.4.3-1 +libtevent-dev#0.9.16-1 +libtevent-dev#0.9.21-1~bpo70+1 +libtext-ocaml-dev#0.5-1+b2 +libtextwrap-dev#0.1-13 +libthai-dev#0.1.18-2 +libtheora-dev#1.1.1+dfsg.1-3.1 +libtheora-ocaml-dev#0.3.0-1+b3 +libthepeg-dev#1.8.0-1 +libthrust-dev#1.6.0-1 +libthunar-vfs-1-dev#1.2.0-3+b1 +libthunarx-2-dev#1.2.3-4+b1 +libticables-dev#1.2.0-2 +libticalcs-dev#1.1.3+dfsg1-1 +libticonv-dev#1.1.0-1.1 +libtidy-dev#20091223cvs-1.2 +libtiff4-dev#3.9.6-11 +libtiff5-alt-dev#4.0.2-6+deb7u2 +libtiff5-dev#4.0.2-6+deb7u2 +libtifiles-dev#1.1.1-1 +libtimbl3-dev#6.4.2-1 +libtimblserver2-dev#1.4-2 +libtinfo-dev#5.9-10 +libtinyxml-dev#2.6.2-1 +libtinyxml2-dev#0~git20120518.1.a2ae54e-1 +libtirpc-dev#0.2.2-5 +libtk-img-dev#1:1.3-release-12 +libtnt-dev#1.2.6-1 +libtntdb-dev#1.2-2+b1 +libtntnet-dev#2.1-2+deb7u1 +libtododb-dev#0.11-3 +libtogl-dev#1.7-12 +libtokyocabinet-dev#1.4.47-2 +libtokyotyrant-dev#1.1.40-4.1+b1 +libtolua++5.1-dev#1.0.93-3 +libtolua-dev#5.2.0-1 +libtomcrypt-dev#1.17-3.2 +libtommath-dev#0.42.0-1 +libtomoe-dev#0.6.0-1.3 +libtonezone-dev#1:2.5.0.1-2 +libtophide-ocaml-dev#1.0.0-3 +libtorch3-dev#3.1-2.1 +libtorque2-dev#2.4.16+dfsg-1+deb7u2 +libtorrent-dev#0.13.2-1 +libtorrent-rasterbar-dev#0.15.10-1+b1 +libtorture-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +libtotem-dev#3.0.1-8 +libtotem-pg-dev#1.4.2-3 +libtotem-plparser-dev#3.4.2-1 +libtowitoko-dev#2.0.7-8.3 +libtpl-dev#1.5-2 +libtpm-unseal-dev#1.3.7-1 +libtrace3-dev#3.0.14-1 +libtracker-extract-0.14-dev#0.14.1-3 +libtracker-miner-0.14-dev#0.14.1-3 +libtracker-sparql-0.14-dev#0.14.1-3 +libtrain-dev#0.9b-11 +libtransitioner1-dev#1.1.7-1 +libtre-dev#0.8.0-3 +libtreil-dev#1.8-1.1 +libtriangle-dev#1.6-2 +libts-dev#1.0-11 +libtse3-dev#0.3.1-4.3 +libtsk-dev#3.2.3-2 +libtsk-dev#4.1.3-3~bpo70+1 +libtspi-dev#0.3.9-3+wheezy1 +libttspico-dev#1.0+git20110131-2 +libtulip-dev#3.7.0dfsg-4 +libtumbler-1-dev#0.1.25-1+b1 +libtut-dev#0.0.20070706-1 +libtuxcap-dev#1.4.0.dfsg2-2.1 +libtwin-dev#12.04.13.17.57-g130ee5f-2 +libtwofish-dev#0.3-3 +libtwolame-dev#0.3.13-1 +libtxc-dxtn-s2tc-dev#0~git20110809-3 +libtype-conv-camlp4-dev#3.0.4-1 +libtyxml-ocaml-dev#2.1-1 +libu1db-dev#0.1.4-2~bpo70+1 +libuchardet-dev#0.0.1-1 +libucimf-dev#2.3.8-4 +libucl-dev#1.03-5 +libuclmmbase1-dev#1.2.16.0-1 +libucommon-dev#5.2.2-4 +libucto1-dev#0.5.2-2 +libudev-dev#175-7.2 +libudev-dev#204-8~bpo70+1 +libudf-dev#0.83-4 +libudt-dev#4.10+dfsg-1 +libudunits2-dev#2.1.23-3 +libuhd-dev#3.4.2-1 +libuhd-dev#3.5.5-1~bpo70+1 +libuim-dev#1:1.8.1-4 +libumlib-dev#0.8.2-1 +libunac1-dev#1.8.0-6 +libunbound-dev#1.4.17-3 +libunbound-dev#1.4.22-1~bpo70+1 +libunicap2-dev#0.9.12-2 +libuninameslist-dev#0.0.20091231-1.1 +libuninum-dev#2.7-1.1 +libunique-3.0-dev#3.0.2-1 +libunique-dev#1.1.6-4 +libunistring-dev#0.9.3-5 +libunittest++-dev#1.4.0-3 +libunshield-dev#0.6-3 +libunwind-setjmp0-dev#0.99-0.3 +libunwind7-dev#0.99-0.3 +libupnp-dev#1:1.6.17-1.2 +libupnp4-dev#1.8.0~svn20100507-1.2 +libupnp6-dev#1:1.6.17-1.2 +libupower-glib-dev#0.9.17-1 +libupsclient1-dev#2.6.4-2.3+deb7u1 +libupse-dev#1.0.0-1 +libuptimed-dev#1:0.3.17-3.1 +liburcu-dev#0.6.7-2 +liburfkill-glib-dev#0.3.0-1 +liburg0-dev#0.8.12-4 +liburiparser-dev#0.7.5-1 +libusb++-dev#2:0.1.12-20+nmu1 +libusb-1.0-0-dev#2:1.0.11-1 +libusb-1.0-0-dev#2:1.0.18-2~bpo70+1 +libusb-dev#2:0.1.12-20+nmu1 +libusb-ocaml-dev#1.2.0-2+b7 +libusbip-dev#1.1.1+3.14-1~bpo70+1 +libusbip-dev#1.1.1+3.2.17-1 +libusbmuxd-dev#1.0.7-2 +libusbprog-dev#0.2.0-2 +libusbredirhost-dev#0.4.3-2 +libusbredirhost-dev#0.6-2~bpo70+1 +libusbredirparser-dev#0.4.3-2 +libusbredirparser-dev#0.6-2~bpo70+1 +libusbtc08-dev#1.7.2-1 +libuser1-dev#1:0.56.9.dfsg.1-1.2 +libust-dev#2.0.4-1 +libustr-dev#1.0.4-3 +libutempter-dev#1.1.5-4 +libuu-dev#0.5.20-3.3 +libuuidm-ocaml-dev#0.9.4-1 +libv4l-dev#0.8.8-3 +libv8-3.14-dev#3.14.5.8-8~bpo70+1 +libv8-dev#3.14.5.8-8~bpo70+1 +libv8-dev#3.8.9.20-2 +libv8-i18n-dev#0~0.svn7-3 +libva-dev#1.0.15-4 +libvala-0.14-dev#0.14.2-2 +libvala-0.16-dev#0.16.1-2 +libvaladoc-dev#0.3.2~git20120227-1 +libvalhalla-dev#2.0.0-4+b1 +libvanessa-adt-dev#0.0.9-1 +libvanessa-logger-dev#0.0.10-1.1 +libvanessa-socket-dev#0.0.12-1 +libvarconf-dev#0.6.7-2 +libvarnishapi-dev#3.0.2-2+deb7u1 +libvbr-dev#2.6.8-4 +libvc-dev#003.dfsg.1-12 +libvcdinfo-dev#0.7.24+dfsg-0.1 +libvde-dev#2.3.2-4 +libvdeplug-dev#2.3.2-4 +libvdk2-dev#2.4.0-5.3 +libvdkbuilder2-dev#2.4.0-4.3 +libvdkxdb2-dev#2.4.0-3.4 +libvdpau-dev#0.4.1-7 +libventrilo-dev#1.2.4-1 +libverbiste-dev#0.1.34-1 +libverto-dev#0.2.2-1 +libvformat-dev#1.13-10 +libvia-dev#2.0.4-2 +libvibrant6-dev#6.1.20120620-2 +libviennacl-dev#1.2.0-2 +libview-dev#0.6.6-2.1 +libvigraimpex-dev#1.7.1+dfsg1-3 +libvips-dev#7.28.5-1+deb7u1 +libvirt-dev#0.9.12.3-1 +libvirt-dev#1.2.4-1~bpo70+1 +libvirt-glib-1.0-dev#0.0.8-1 +libvirt-ocaml-dev#0.6.1.2-1 +libvisca-dev#1.0.1-1 +libvisio-dev#0.0.17-1 +libvisual-0.4-dev#0.4.0-5 +libvlc-dev#2.0.3-5 +libvlc-dev#2.1.2-2~bpo70+3 +libvlccore-dev#2.0.3-5 +libvlccore-dev#2.1.2-2~bpo70+3 +libvmmlib-dev#1.0-2 +libvmtk-dev#1.0.1-1 +libvncserver-dev#0.9.9+dfsg-1 +libvo-aacenc-dev#0.1.2-1 +libvo-amrwbenc-dev#0.1.2-1 +libvoaacenc-ocaml-dev#0.1.0-1+b1 +libvoikko-dev#3.5-1.1 +libvolpack1-dev#1.0b3-3 +libvorbis-dev#1.3.2-1.3 +libvorbis-ocaml-dev#0.6.1-1+b1 +libvorbisidec-dev#1.0.2+svn18153-0.2 +libvotequorum-dev#1.4.2-3 +libvpb-dev#4.2.55-1 +libvpx-dev#1.1.0-1 +libvrb0-dev#0.5.1-5.1 +libvte-2.90-dev#1:0.32.2-1 +libvte-dev#1:0.28.2-5 +libvte0.16-cil-dev#2.26.0-8 +libvtk5-dev#5.8.0-13+b1 +libvtk5-qt4-dev#5.8.0-13+b1 +libvtkedge-dev#0.2.0~20110819-2 +libvtkgdcm2-dev#2.2.0-14.1 +libvxl1-dev#1.14.0-18 +libwacom-dev#0.6-1 +libwaei-dev#3.4.3-1 +libwaili-dev#19990723-20 +libwavefront-standalone3.0-dev#3.0.2+dfsg-4+b1 +libwavpack-dev#4.60.1-3 +libwayland-dev#0.85.0-2 +libwbclient-dev#2:3.6.6-6+deb7u3 +libwbclient-dev#2:4.1.9+dfsg-1~bpo70+1 +libwbxml2-dev#0.10.7-1 +libwcstools-dev#3.8.5-1 +libwebauth-dev#4.1.1-2 +libwebauth-dev#4.6.0-2~bpo70+1 +libwebcam0-dev#0.2.2-1 +libwebkit-cil-dev#0.3-6 +libwebkit-dev#1.8.1-3.4 +libwebkitgtk-3.0-dev#1.8.1-3.4 +libwebkitgtk-dev#1.8.1-3.4 +libwebp-dev#0.1.3-3+nmu1 +libwebrtc-audio-processing-dev#0.1-2 +libweed-dev#1.6.2~ds1-2 +libwfmath-0.3-dev#0.3.12-3 +libwfut-0.2-dev#0.2.1-2 +libwibble-dev#0.1.28-1.1 +libwildmidi-dev#0.2.3.4-2.1 +libwine-dev#1.4.1-4 +libwings-dev#0.95.3-2 +libwireshark-dev#1.10.7-1~bpo70+1 +libwireshark-dev#1.8.2-5wheezy10 +libwiretap-dev#1.10.7-1~bpo70+1 +libwiretap-dev#1.8.2-5wheezy10 +libwmf-dev#0.2.8.4-10.3 +libwnck-3-dev#3.4.2-1 +libwnck-dev#2.30.7-1 +libwnck1.0-cil-dev#2.26.0-8 +libwnn-dev#1.1.1~a021+cvs20100325-6 +libwnn6-dev#1.0.0-14.2+b1 +libwpd-dev#0.9.4-3 +libwpg-dev#0.2.1-1 +libwps-dev#0.2.7-1 +libwrap0-dev#7.6.q-24 +libwraster3-dev#0.95.3-2 +libwreport-dev#2.4-1 +libwsutil-dev#1.10.7-1~bpo70+1 +libwsutil-dev#1.8.2-5wheezy10 +libwt-dev#3.2.1-2 +libwtdbo-dev#3.2.1-2 +libwtdbofirebird-dev#3.2.1-2 +libwtdbopostgres-dev#3.2.1-2 +libwtdbosqlite-dev#3.2.1-2 +libwtext-dev#3.2.1-2 +libwtfcgi-dev#3.2.1-2 +libwthttp-dev#3.2.1-2 +libwttest-dev#3.2.1-2 +libwv-dev#1.2.9-3 +libwv2-dev#0.4.2.dfsg.2-1~deb7u1 +libwvstreams-dev#4.6.1-5 +libwxbase2.8-dev#2.8.12.1-12 +libwxgtk2.8-dev#2.8.12.1-12 +libwxsmithlib-dev#10.05-2.1 +libwxsmithlib-dev#13.12-1~bpo70+1 +libwxsmithlib0-dev#10.05-2.1 +libwxsmithlib0-dev#13.12-1~bpo70+1 +libwxsqlite3-2.8-dev#3.0.0.1~dfsg0-2 +libwxsvg-dev#2:1.1.8~dfsg0-2 +libx11-dev#2:1.5.0-1+deb7u1 +libx11-xcb-dev#2:1.5.0-1+deb7u1 +libx264-dev#2:0.123.2189+git35cf912-1 +libx52pro-dev#0.1.1-2.1 +libx86-dev#1.1+ds1-10 +libxalan110-dev#1.10-6 +libxapian-dev#1.2.12-2 +libxapian-dev#1.2.16-2~bpo70+1 +libxatracker-dev#8.0.5-4+deb7u2 +libxau-dev#1:1.0.7-1 +libxaw7-dev#2:1.0.10-2 +libxbae-dev#4.60.4-3 +libxbase2.0-dev#2.0.0-8.5 +libxcb-composite0-dev#1.8.1-2+deb7u1 +libxcb-cursor-dev#0.1.1-2~bpo70+1 +libxcb-damage0-dev#1.8.1-2+deb7u1 +libxcb-dpms0-dev#1.8.1-2+deb7u1 +libxcb-dri2-0-dev#1.8.1-2+deb7u1 +libxcb-ewmh-dev#0.3.9-2 +libxcb-glx0-dev#1.8.1-2+deb7u1 +libxcb-icccm4-dev#0.3.9-2 +libxcb-image0-dev#0.3.9-1 +libxcb-keysyms1-dev#0.3.9-1 +libxcb-randr0-dev#1.8.1-2+deb7u1 +libxcb-record0-dev#1.8.1-2+deb7u1 +libxcb-render-util0-dev#0.3.8-1.1 +libxcb-render0-dev#1.8.1-2+deb7u1 +libxcb-res0-dev#1.8.1-2+deb7u1 +libxcb-screensaver0-dev#1.8.1-2+deb7u1 +libxcb-shape0-dev#1.8.1-2+deb7u1 +libxcb-shm0-dev#1.8.1-2+deb7u1 +libxcb-sync0-dev#1.8.1-2+deb7u1 +libxcb-util0-dev#0.3.8-2 +libxcb-xevie0-dev#1.8.1-2+deb7u1 +libxcb-xf86dri0-dev#1.8.1-2+deb7u1 +libxcb-xfixes0-dev#1.8.1-2+deb7u1 +libxcb-xinerama0-dev#1.8.1-2+deb7u1 +libxcb-xprint0-dev#1.8.1-2+deb7u1 +libxcb-xtest0-dev#1.8.1-2+deb7u1 +libxcb-xv0-dev#1.8.1-2+deb7u1 +libxcb-xvmc0-dev#1.8.1-2+deb7u1 +libxcb1-dev#1.8.1-2+deb7u1 +libxcomp-dev#3.5.0.12-1+b1 +libxcomposite-dev#1:0.4.3-2 +libxcp-ocaml-dev#0.5.2-3+b1 +libxcrypt-dev#1:2.4-3 +libxcursor-dev#1:1.1.13-1+deb7u1 +libxdamage-dev#1:1.1.3-2 +libxdb-dev#1.2.0-7.2 +libxdelta2-dev#1.1.3-9 +libxdffileio-dev#0.3-1 +libxdg-basedir-dev#1.1.1-2 +libxdmcp-dev#1:1.1.1-1 +libxdmf-dev#2.1.dfsg.1-5 +libxdo-dev#1:2.20100701.2961-3+deb7u3 +libxen-dev#4.1.4-3+deb7u1 +libxen-ocaml-dev#4.1.4-3+deb7u1 +libxenapi-ocaml-dev#1.3.2-15 +libxenomai-dev#2.6.0-2 +libxerces-c-dev#3.1.1-3 +libxerces-c2-dev#2.8.0+deb1-3 +libxext-dev#2:1.3.1-2+deb7u1 +libxfce4menu-0.1-dev#4.6.2-1 +libxfce4ui-1-dev#4.8.1-1 +libxfce4util-dev#4.8.2-1 +libxfcegui4-dev#4.8.1-5 +libxfconf-0-dev#4.8.1-1 +libxfixes-dev#1:5.0-4+deb7u1 +libxfont-dev#1:1.4.5-3 +libxft-dev#2.3.1-1 +libxi-dev#2:1.6.1-1+deb7u1 +libxine-dev#1.1.21-1+deb7u1 +libxine2-dev#1.2.2-5 +libxinerama-dev#2:1.1.2-1+deb7u1 +libxkbfile-dev#1:1.0.8-1 +libxklavier-dev#5.2.1-1 +libxml++2.6-dev#2.34.2-1 +libxml-light-ocaml-dev#2.2-15 +libxml-security-c-dev#1.6.1-5+deb7u2 +libxml-security-c-dev#1.7.2-2~bpo70+1 +libxml2-dev#2.8.0+dfsg1-7+nmu3 +libxmlada4.1-dev#4.1-2 +libxmlezout2-dev#1.06.1-5 +libxmlm-ocaml-dev#1.1.0-1 +libxmlplaylist-ocaml-dev#0.1.3-1+b2 +libxmlrpc-c++4-dev#1.16.33-3.2 +libxmlrpc-c3-dev#1.16.33-3.2 +libxmlrpc-core-c3-dev#1.16.33-3.2 +libxmlrpc-epi-dev#0.54.2-1 +libxmlrpc-light-ocaml-dev#0.6.1-3+b5 +libxmlsec1-dev#1.2.18-2 +libxmltok1-dev#1.2-3 +libxmltooling-dev#1.4.2-5 +libxmltooling-dev#1.5.3-2~bpo70+1 +libxmmsclient++-dev#0.8+dfsg-4 +libxmmsclient++-glib-dev#0.8+dfsg-4 +libxmmsclient-dev#0.8+dfsg-4 +libxmmsclient-glib-dev#0.8+dfsg-4 +libxmpi4-dev#2.2.3b8-13 +libxmu-dev#2:1.1.1-1 +libxmuu-dev#2:1.1.1-1 +libxnee-dev#3.13-1 +libxneur-dev#0.15.0-1.1 +libxnvctrl-dev#304.88-1 +libxnvctrl-dev#319.72-1~bpo70+1 +libxosd-dev#2.2.14-2 +libxp-dev#1:1.0.1-2+deb7u1 +libxpa-dev#2.1.14-2 +libxplc0.3.13-dev#0.3.13-3 +libxpm-dev#1:3.5.10-1 +libxqdbm-dev#1.8.78-2 +libxqilla-dev#2.3.0-1 +libxr1-dev#1.0-2.1 +libxrandr-dev#2:1.3.2-2+deb7u1 +libxrender-dev#1:0.9.7-1+deb7u1 +libxres-dev#2:1.0.6-1+deb7u1 +libxsettings-client-dev#0.17-6 +libxsettings-dev#0.11-3 +libxslt1-dev#1.1.26-14.1 +libxss-dev#1:1.2.2-1 +libxstr-ocaml-dev#0.2.1-21+b3 +libxstrp4-camlp4-dev#1.8-3 +libxt-dev#1:1.1.3-1+deb7u1 +libxtst-dev#2:1.2.1-1+deb7u1 +libxtuplecommon-dev#4.1.0-3~bpo70+1 +libxv-dev#2:1.0.7-1+deb7u1 +libxvbaw-dev#1:12-6+point-3 +libxvbaw-dev#1:13.12-4~bpo70+1 +libxvidcore-dev#2:1.3.2-9 +libxvmc-dev#2:1.0.7-1+deb7u2 +libxxf86dga-dev#2:1.1.3-2+deb7u1 +libxxf86vm-dev#1:1.1.2-1+deb7u1 +libxy-dev#0.8-1+b1 +libyahoo2-dev#1.0.1-1 +libyajl-dev#2.0.4-2 +libyaml-cpp-dev#0.3.0-1 +libyaml-dev#0.1.4-2+deb7u4 +libyara-dev#2.0.0-2~bpo70+1 +libyaz4-dev#4.2.30-2 +libydpdict2-dev#1.0.2-1 +libyelp-dev#3.4.2-1+b1 +libygl4-dev#4.2e-4 +libykclient-dev#2.6-1 +libykpers-1-dev#1.7.0-1 +libyojson-ocaml-dev#1.0.3-1 +libytnef0-dev#1.5-4 +libyubikey-dev#1.8-1 +libz80ex-dev#1.1.19-3 +libzarith-ocaml-dev#1.1-2 +libzbar-dev#0.10+doc-8 +libzbargtk-dev#0.10+doc-8 +libzbarqt-dev#0.10+doc-8 +libzeep-dev#2.9.0-2 +libzeitgeist-cil-dev#0.8.0.0-4 +libzeitgeist-dev#0.3.18-1 +libzen-dev#0.4.27-2 +libzephyr-dev#3.0.2-2 +libzerg0-dev#1.0.7-3 +libzeroc-ice34-dev#3.4.2-8.2 +libzinnia-dev#0.06-1+b1 +libzip-dev#0.10.1-1.1 +libzip-ocaml-dev#1.04-6+b3 +libzipios++-dev#0.1.5.9+cvs.2007.04.28-5.1 +libzita-alsa-pcmi-dev#0.2.0-1 +libzita-convolver-dev#3.1.0-2 +libzita-resampler-dev#1.1.0-3 +libzlcore-dev#0.12.10dfsg-8 +libzltext-dev#0.12.10dfsg-8 +libzmq-dev#2.2.0+dfsg-2 +libzmq3-dev#3.2.3+dfsg-2~bpo70+1 +libzn-poly-dev#0.8-1.1 +libzookeeper-mt-dev#3.3.5+dfsg1-2 +libzookeeper-st-dev#3.3.5+dfsg1-2 +libzorp-dev#3.9.5-4 +libzorpll-dev#3.9.1.3-1 +libzrtpcpp-dev#2.0.0-3 +libzthread-dev#2.3.2-7 +libzvbi-dev#0.2.33-6 +libzzip-dev#0.13.56-1.1 +licq-dev#1.6.1-3 +linux-libc-dev#3.14.7-1~bpo70+1 +linux-libc-dev#3.2.57-3 +lldpad-dev#0.9.44-1 +llvm-2.9-dev#2.9+dfsg-7 +llvm-3.0-dev#3.0-10 +llvm-3.1-dev#3.1-1 +llvm-dev#1:3.0-14+nmu2 +lttv-dev#0.12.38-21032011-1+b1 +lua-apr-dev#0.23.2-1 +lua-bitop-dev#1.0.2-1 +lua-curl-dev#0.3.0-7 +lua-curses-dev#5.1.19-2 +lua-cyrussasl-dev#1.0.0-4 +lua-dbi-mysql-dev#0.5+svn78-4 +lua-dbi-postgresql-dev#0.5+svn78-4 +lua-dbi-sqlite3-dev#0.5+svn78-4 +lua-event-dev#0.4.1-2 +lua-expat-dev#1.2.0-5+deb7u1 +lua-filesystem-dev#1.5.0+16+g84f1af5-1 +lua-iconv-dev#7-1 +lua-ldap-dev#1.1.0-1-geeac494-3 +lua-leg-dev#0.1.2-8 +lua-lgi-dev#0.6.2-1 +lua-lpeg-dev#0.10.2-5 +lua-md5-dev#1.1.2-6 +lua-penlight-dev#1.0.2+htmldoc-2 +lua-posix-dev#5.1.19-2 +lua-rex-onig-dev#2.6.0-2 +lua-rex-pcre-dev#2.6.0-2 +lua-rex-posix-dev#2.6.0-2 +lua-rex-tre-dev#2.6.0-2 +lua-rings-dev#1.2.3-1 +lua-sec-dev#0.4.1+git063e8a8-2~bpo70+1 +lua-sec-dev#0.4.1-1 +lua-socket-dev#2.0.2-8 +lua-socket-dev#3.0~rc1-3~bpo70+1 +lua-sql-mysql-dev#2.3.0-1+build0 +lua-sql-postgres-dev#2.3.0-1+build0 +lua-sql-sqlite3-dev#2.3.0-1+build0 +lua-svn-dev#0.4.0-7 +lua-wsapi-fcgi-dev#1.5-3 +lua-zip-dev#1.2.3-11 +lua-zlib-dev#0.2-1 +lua5.1-policy-dev#33 +lv2-dev#1.0.0~dfsg2-2 +lxc-dev#0.8.0~rc1-8+deb7u2 +lzma-dev#9.22-2 +manpages-de-dev#1.2-1 +manpages-dev#3.44-1 +manpages-fr-dev#3.44d1p1-1 +manpages-ja-dev#0.5.0.0.20120606-1 +manpages-pl-dev#1:0.3-1 +manpages-posix-dev#2.16-1 +manpages-pt-dev#20040726-4 +matlab-support-dev#0.0.18 +mdbtools-dev#0.7-1+deb7u1 +med-bio-dev#1.13.2 +med-imaging-dev#1.13.2 +mesa-common-dev#8.0.5-4+deb7u2 +mffm-fftw-dev#1.7-3 +mffm-timecode-dev#1.6-2 +mingw-w64-dev#2.0.3-1 +mingw-w64-i686-dev#2.0.3-1 +mingw-w64-x86-64-dev#2.0.3-1 +minpack-dev#19961126+dfsg1-1 +mongodb-dev#1:2.0.6-1.1 +mongodb-dev#1:2.4.8-2~bpo70+1 +mpi-default-dev#1.0.1 +muroard-dev#0.1.10-2 +neko-dev#1.8.1-6 +nettle-dev#2.4-3 +nettle-dev#2.7.1-1~bpo70+1 +network-manager-dev#0.9.4.0-10 +nodejs-dev#0.10.26~dfsg1-1~bpo70+1 +notion-dev#3+2012042300-1 +ntfs-3g-dev#1:2012.1.15AR.5-2.1 +nvidia-cg-dev#3.1.0013-1 +nvidia-cuda-dev#4.2.9-2 +nvidia-cuda-dev#5.0.35-8~bpo70+1 +nvidia-glx-legacy-71xx-dev#71.86.15-3 +nvidia-glx-legacy-dev#71.86.15-3 +nvidia-opencl-dev#4.2.9-2 +nvidia-opencl-dev#5.0.35-8~bpo70+1 +ocfs2-tools-dev#1.6.4-1+deb7u1 +ocl-icd-dev#1.3-3 +ocl-icd-opencl-dev#1.3-3 +ocsigen-dev#1.3.4-2 +octave-pkg-dev#1.0.2 +ofono-dev#1.6-2 +okteta-dev#4:4.8.4+dfsg-1 +okular-dev#4:4.8.4-3 +open-vm-tools-dev#2:8.8.0+2012.05.21-724730-1+nmu2 +open-vm-tools-dev#2:9.4.0-1280544-8~bpo70+1 +openais-dev#1.1.4-4.1 +openbox-dev#3.5.0-7 +openbox-dev#3.5.2-6~bpo70+1 +openchangeserver-dev#1:1.0-3 +openchangeserver-dev#1:2.1-1~bpo70+1 +oss4-dev#4.2-build2006-2+deb7u1 +pacemaker-dev#1.1.7-1 +packaging-dev#0.4 +paraview-dev#3.14.1-6 +paraview-dev#4.0.1-1~bpo70+1 +parole-dev#0.2.0.6-1+b1 +parser3-dev#3.4.2-2 +pbs-drmaa-dev#1.0.10-3 +petsc-dev#3.2.dfsg-6 +php5-dev#5.4.4-14+deb7u9 +pidgin-dev#2.10.7-2~bpo70+1 +pidgin-dev#2.10.9-1~deb7u1 +pike7.8-dev#7.8.700-7~bpo70+1 +pinball-dev#0.3.1-13.1 +planetpenguin-racer-gimp-dev#0.4-5 +planner-dev#0.14.6-1 +plplot-tcl-dev#5.9.9-5 +plptools-dev#1.0.9-2.4 +pluma-dev#1.8.1+dfsg1-2~bpo70+1 +plymouth-dev#0.8.5.1-5 +portaudio19-dev#19+svn20111121-1 +postfix-dev#2.11.1-1~bpo70+1 +postfix-dev#2.9.6-2 +ppl-dev#0.11.2-8 +ppp-dev#2.4.5-5.1 +prayer-templates-dev#1.3.4-dfsg1-1 +proftpd-dev#1.3.4a-5+deb7u1 +pslib-dev#0.4.5-3 +publib-dev#0.40-1 +puredata-dev#0.43.2-5 +pvm-dev#3.4.5-12.5 +pxlib-dev#0.6.5-1 +python-all-dev#2.7.3-4+deb7u1 +python-apt-dev#0.8.8.2 +python-cairo-dev#1.8.8-1 +python-cxx-dev#6.2.4-3 +python-dbus-dev#1.1.1-1 +python-dev#2.7.3-4+deb7u1 +python-egenix-mx-base-dev#3.2.1-1.1 +python-gamera-dev#3.3.3-2 +python-gi-dev#3.2.2-2 +python-gnome2-desktop-dev#2.32.0+dfsg-2 +python-gnome2-dev#2.28.1+dfsg-1 +python-gnome2-extras-dev#2.25.3-12 +python-gobject-2-dev#2.28.6-10 +python-gobject-dev#3.2.2-2 +python-greenlet-dev#0.3.1-2.5 +python-gst0.10-dev#0.10.22-3 +python-gtk2-dev#2.24.0-3 +python-kde4-dev#4:4.8.4-1 +python-ldb-dev#1:1.1.16-1~bpo70+1 +python-ldb-dev#1:1.1.6-1 +python-openturns-dev#1.0-4 +python-pyorbit-dev#2.24.0-6 +python-qt4-dev#4.9.3-4 +python-sip-dev#4.13.3-2 +python-talloc-dev#2.0.7+git20120207-1 +python-talloc-dev#2.1.1-1~bpo70+1 +python-webkit-dev#1.1.8-2 +python2.6-dev#2.6.8-1.1 +python2.7-dev#2.7.3-6+deb7u2 +python3-all-dev#3.2.3-6 +python3-cairo-dev#1.10.0+dfsg-2 +python3-cxx-dev#6.2.4-3 +python3-dev#3.2.3-6 +python3-sip-dev#4.13.3-2 +python3.2-dev#3.2.3-7 +qmf-dev#1.0.7~2011w23.2-2.1 +qtkeychain-dev#0.1.0-2~bpo70+1 +qtmobility-dev#1.2.0-3 +r-base-dev#2.15.1-4 +regina-normal-dev#4.93-1 +resource-agents-dev#1:3.9.2-5+deb7u2 +rhythmbox-dev#2.97-2.1 +rivet-plugins-dev#1.8.0-1 +roarplaylistd-dev#0.1.1-2 +robot-player-dev#3.0.2+dfsg-4 +ruby-dev#1:1.9.3 +ruby-gnome2-dev#1.1.3-2+b1 +ruby1.8-dev#1.8.7.358-7.1+deb7u1 +ruby1.9.1-dev#1.9.3.194-8.1+deb7u2 +rygel-1.0-dev#0.14.3-2+deb7u1 +samba-dev#2:4.1.9+dfsg-1~bpo70+1 +samba4-dev#4.0.0~beta2+dfsg1-3.2+deb7u2 +sbnc-php-dev#1.2-26 +science-astronomy-dev#1.0 +science-dataacquisition-dev#1.0 +science-engineering-dev#1.0 +science-highenergy-physics-dev#1.0 +science-mathematics-dev#1.0 +science-meteorology-dev#1.0 +science-nanoscale-physics-dev#1.0 +science-physics-dev#1.0 +scim-dev#1.4.13-5 +sciplot-dev#1.36-15 +selinux-policy-dev#2:2.20110726-12 +seqan-dev#1.3.1-1 +sfftw-dev#2.1.5-1 +skalibs-dev#0.47-1 +slurm-drmaa-dev#1.0.4-3 +slurm-llnl-basic-plugins-dev#2.3.4-2+b1 +snappea-dev#3.0d3-22 +spl-dev#1.0~pre6-3.1+b1 +sra-toolkit-libs-dev#2.1.7a-1 +ss-dev#2.0-1.42.5-1.1 +stx-btree-dev#0.8.6-1 +styx-dev#1.8.0-1.1 +supercollider-dev#1:3.4.5-1wheezy1 +svdrpservice-dev#0.0.4-14 +sweep-dev#0.9.3-6 +swish-e-dev#2.4.7-3 +syfi-dev#1.0.0.dfsg-1 +system-tools-backends-dev#2.10.2-1 +systemtap-sdt-dev#1.7-1+deb7u1 +tcl-dev#8.5.0-2.1 +tcl-memchan-dev#2.3-2 +tcl-trf-dev#2.1.4-dfsg1-1 +tcl8.4-dev#8.4.19-5 +tcl8.5-dev#8.5.11-2 +tclcl-dev#1.20-6 +tclx8.4-dev#8.4.0-3 +tclxml-dev#3.3~svn11-2 +tdom-dev#0.8.3~20080525-3+nmu2 +tesseract-ocr-dev#3.02.01-6 +tix-dev#8.4.3-4 +tk-dev#8.5.0-2.1 +tk8.4-dev#8.4.19-5 +tk8.5-dev#8.5.11-2 +tqsllib-dev#2.2-5 +trafficserver-dev#3.0.5-1 +tuxpaint-dev#1:0.9.21-1.1 +unagi-dev#0.3.3-2 +unixodbc-dev#2.2.14p2-5 +uthash-dev#1.9.5-1 +uuid-dev#2.20.1-5.3 +vdr-dev#1.7.28-1 +vflib3-dev#3.6.14.dfsg-3+b1 +voms-dev#2.0.8-1 +vstream-client-dev#1.2-6.1 +wcslib-dev#4.13.4-1 +weechat-dev#0.3.8-1+deb7u1 +weechat-dev#0.4.3-2~bpo70+1 +wireshark-dev#1.10.7-1~bpo70+1 +wireshark-dev#1.8.2-5wheezy10 +witty-dev#3.2.1-2 +wordnet-dev#1:3.0-29 +wzdftpd-dev#0.8.3-6.2 +x11proto-bigreqs-dev#1:1.1.2-1 +x11proto-composite-dev#1:0.4.2-2 +x11proto-core-dev#7.0.23-1 +x11proto-damage-dev#1:1.2.1-2 +x11proto-dmx-dev#1:2.3.1-2 +x11proto-dri2-dev#2.6-2 +x11proto-fixes-dev#1:5.0-2 +x11proto-fonts-dev#2.1.2-1 +x11proto-gl-dev#1.4.15-1 +x11proto-input-dev#2.2-1 +x11proto-kb-dev#1.0.6-2 +x11proto-print-dev#1.0.5-2 +x11proto-randr-dev#1.3.2-2 +x11proto-record-dev#1.14.2-1 +x11proto-render-dev#2:0.11.1-2 +x11proto-resource-dev#1.2.0-3 +x11proto-scrnsaver-dev#1.2.2-1 +x11proto-video-dev#2.3.1-2 +x11proto-xcmisc-dev#1.2.2-1 +x11proto-xext-dev#7.2.1-1 +x11proto-xf86bigfont-dev#1.2.0-3 +x11proto-xf86dga-dev#2.1-3 +x11proto-xf86dri-dev#2.1.1-2 +x11proto-xf86vidmode-dev#2.3.1-2 +x11proto-xinerama-dev#1.2.1-2 +xaw3dg-dev#1.5+E-18.2 +xbmc-addons-dev#2:13.1~rc1+dfsg1-1~bpo70+1 +xbmc-eventclients-dev#2:11.0~git20120510.82388d5-1 +xbmc-eventclients-dev#2:13.1~rc1+dfsg1-1~bpo70+1 +xfce4-panel-dev#4.8.6-4 +xfslibs-dev#3.1.7+b1 +xmhtml1-dev#1.1.7-18 +xmms2-dev#0.8+dfsg-4 +xorg-dev#1:7.7+3~deb7u1 +xotcl-dev#1.6.7-2 +xpaint-dev#2.9.1.4-3+b2 +xserver-xorg-dev#2:1.12.4-6+deb7u2 +xserver-xorg-input-evdev-dev#1:2.7.0-1 +xserver-xorg-input-joystick-dev#1:1.6.1-1 +xserver-xorg-input-synaptics-dev#1.6.2-2 +xtrans-dev#1.2.7-1 +xulrunner-dev#24.4.0esr-1~deb7u2 +xutils-dev#1:7.7~1 +xviewg-dev#3.2p1.4-28.1 +yate-dev#4.1.0-1~dfsg-3 +yorick-dev#2.2.02+dfsg-6 +zathura-dev#0.1.2-4 +zlib1g-dev#1:1.2.7.dfsg-13 +znc-dev#0.206-2 +zsh-dev#4.3.17-1 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t11_package/ShowPackage3Test_gold b/src/github.com/smira/aptly/system/t11_package/ShowPackage3Test_gold index d8eeb960..9915dade 100644 --- a/src/github.com/smira/aptly/system/t11_package/ShowPackage3Test_gold +++ b/src/github.com/smira/aptly/system/t11_package/ShowPackage3Test_gold @@ -1,21 +1,22 @@ -Package: nginx-full -Version: 1.2.1-2.2+wheezy2 -Installed-Size: 915 -Priority: optional -Section: httpd -Maintainer: Kartik Mistry + + Architecture: amd64 +Conflicts: nginx-extras, nginx-light, nginx-naxsi +Depends: nginx-common (= 1.2.1-2.2+wheezy2), libc6 (>= 2.10), libexpat1 (>= 2.0.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libgeoip1 (>= 1.4.8+dfsg), libpam0g (>= 0.99.7.1), libpcre3 (>= 8.10), libssl1.0.0 (>= 1.0.0), libxml2 (>= 2.7.4), libxslt1.1 (>= 1.1.25), zlib1g (>= 1:1.1.4) +Description-md5: b334eec6202adf5e9045cc6066a082d1 Description: nginx web/proxy server (standard version) +Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb +Homepage: http://nginx.net +Installed-Size: 915 MD5sum: 586a2ff5648004cd0114447f5df46a29 +Maintainer: Kartik Mistry +Package: nginx-full +Priority: optional +Provides: httpd, nginx SHA1: 7bf9b91714046f12d765adad860677f5b650c616 SHA256: aa724376b6bf534c8ff38a8c5de4d4208d4de2b57946f875857349436542306b -Description-md5: b334eec6202adf5e9045cc6066a082d1 -Conflicts: nginx-extras, nginx-light, nginx-naxsi -Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb +Section: httpd Size: 435328 -Homepage: http://nginx.net -Depends: nginx-common (= 1.2.1-2.2+wheezy2), libc6 (>= 2.10), libexpat1 (>= 2.0.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libgeoip1 (>= 1.4.8+dfsg), libpam0g (>= 0.99.7.1), libpcre3 (>= 8.10), libssl1.0.0 (>= 1.0.0), libxml2 (>= 2.7.4), libxslt1.1 (>= 1.1.25), zlib1g (>= 1:1.1.4) -Provides: httpd, nginx Source: nginx Tag: network::server, protocol::http, role::program - +Version: 1.2.1-2.2+wheezy2 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t11_package/ShowPackage4Test_gold b/src/github.com/smira/aptly/system/t11_package/ShowPackage4Test_gold index 4d72b1df..ebf14cd3 100644 --- a/src/github.com/smira/aptly/system/t11_package/ShowPackage4Test_gold +++ b/src/github.com/smira/aptly/system/t11_package/ShowPackage4Test_gold @@ -1,24 +1,25 @@ -Package: nginx-full -Version: 1.2.1-2.2+wheezy2 -Installed-Size: 915 -Priority: optional -Section: httpd -Maintainer: Kartik Mistry + + + + ${HOME}/.aptly/pool/58/6a/nginx-full_1.2.1-2.2+wheezy2_amd64.deb Architecture: amd64 +Conflicts: nginx-extras, nginx-light, nginx-naxsi +Depends: nginx-common (= 1.2.1-2.2+wheezy2), libc6 (>= 2.10), libexpat1 (>= 2.0.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libgeoip1 (>= 1.4.8+dfsg), libpam0g (>= 0.99.7.1), libpcre3 (>= 8.10), libssl1.0.0 (>= 1.0.0), libxml2 (>= 2.7.4), libxslt1.1 (>= 1.1.25), zlib1g (>= 1:1.1.4) +Description-md5: b334eec6202adf5e9045cc6066a082d1 Description: nginx web/proxy server (standard version) +Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb +Files in the pool: +Homepage: http://nginx.net +Installed-Size: 915 MD5sum: 586a2ff5648004cd0114447f5df46a29 +Maintainer: Kartik Mistry +Package: nginx-full +Priority: optional +Provides: httpd, nginx SHA1: 7bf9b91714046f12d765adad860677f5b650c616 SHA256: aa724376b6bf534c8ff38a8c5de4d4208d4de2b57946f875857349436542306b -Conflicts: nginx-extras, nginx-light, nginx-naxsi -Description-md5: b334eec6202adf5e9045cc6066a082d1 -Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb +Section: httpd Size: 435328 -Depends: nginx-common (= 1.2.1-2.2+wheezy2), libc6 (>= 2.10), libexpat1 (>= 2.0.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libgeoip1 (>= 1.4.8+dfsg), libpam0g (>= 0.99.7.1), libpcre3 (>= 8.10), libssl1.0.0 (>= 1.0.0), libxml2 (>= 2.7.4), libxslt1.1 (>= 1.1.25), zlib1g (>= 1:1.1.4) -Homepage: http://nginx.net -Provides: httpd, nginx Source: nginx Tag: network::server, protocol::http, role::program - -Files in the pool: - ${HOME}/.aptly/pool/58/6a/nginx-full_1.2.1-2.2+wheezy2_amd64.deb - +Version: 1.2.1-2.2+wheezy2 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t11_package/ShowPackage5Test_gold b/src/github.com/smira/aptly/system/t11_package/ShowPackage5Test_gold index a8f69479..148d5d60 100644 --- a/src/github.com/smira/aptly/system/t11_package/ShowPackage5Test_gold +++ b/src/github.com/smira/aptly/system/t11_package/ShowPackage5Test_gold @@ -1,25 +1,26 @@ -Package: nginx-full -Version: 1.2.1-2.2+wheezy2 -Installed-Size: 915 -Priority: optional -Section: httpd -Maintainer: Kartik Mistry + + + + mirror [wheezy-main-src]: http://mirror.yandex.ru/debian/ wheezy [src] + mirror [wheezy-main]: http://mirror.yandex.ru/debian/ wheezy Architecture: amd64 +Conflicts: nginx-extras, nginx-light, nginx-naxsi +Depends: nginx-common (= 1.2.1-2.2+wheezy2), libc6 (>= 2.10), libexpat1 (>= 2.0.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libgeoip1 (>= 1.4.8+dfsg), libpam0g (>= 0.99.7.1), libpcre3 (>= 8.10), libssl1.0.0 (>= 1.0.0), libxml2 (>= 2.7.4), libxslt1.1 (>= 1.1.25), zlib1g (>= 1:1.1.4) +Description-md5: b334eec6202adf5e9045cc6066a082d1 Description: nginx web/proxy server (standard version) +Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb +Homepage: http://nginx.net +Installed-Size: 915 MD5sum: 586a2ff5648004cd0114447f5df46a29 +Maintainer: Kartik Mistry +Package: nginx-full +Priority: optional +Provides: httpd, nginx +References to package: SHA1: 7bf9b91714046f12d765adad860677f5b650c616 SHA256: aa724376b6bf534c8ff38a8c5de4d4208d4de2b57946f875857349436542306b -Homepage: http://nginx.net -Source: nginx +Section: httpd Size: 435328 -Conflicts: nginx-extras, nginx-light, nginx-naxsi -Description-md5: b334eec6202adf5e9045cc6066a082d1 +Source: nginx Tag: network::server, protocol::http, role::program -Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb -Depends: nginx-common (= 1.2.1-2.2+wheezy2), libc6 (>= 2.10), libexpat1 (>= 2.0.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libgeoip1 (>= 1.4.8+dfsg), libpam0g (>= 0.99.7.1), libpcre3 (>= 8.10), libssl1.0.0 (>= 1.0.0), libxml2 (>= 2.7.4), libxslt1.1 (>= 1.1.25), zlib1g (>= 1:1.1.4) -Provides: httpd, nginx - -References to package: - mirror [wheezy-main]: http://mirror.yandex.ru/debian/ wheezy - mirror [wheezy-main-src]: http://mirror.yandex.ru/debian/ wheezy [src] - +Version: 1.2.1-2.2+wheezy2 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t11_package/ShowPackage6Test_gold b/src/github.com/smira/aptly/system/t11_package/ShowPackage6Test_gold index 122178d8..00a4039e 100644 --- a/src/github.com/smira/aptly/system/t11_package/ShowPackage6Test_gold +++ b/src/github.com/smira/aptly/system/t11_package/ShowPackage6Test_gold @@ -1,29 +1,30 @@ -Package: nginx-full -Version: 1.2.1-2.2+wheezy2 -Installed-Size: 915 -Priority: optional -Section: httpd -Maintainer: Kartik Mistry + + + + local repo [repo1] + mirror [wheezy-main-src]: http://mirror.yandex.ru/debian/ wheezy [src] + mirror [wheezy-main]: http://mirror.yandex.ru/debian/ wheezy + snapshot [snap1]: Snapshot from mirror [wheezy-main]: http://mirror.yandex.ru/debian/ wheezy + snapshot [snap3]: Snapshot from mirror [wheezy-main-src]: http://mirror.yandex.ru/debian/ wheezy [src] + snapshot [snap4]: Merged from sources: 'snap1', 'snap2', 'snap3' Architecture: amd64 -Description: nginx web/proxy server (standard version) -MD5sum: 586a2ff5648004cd0114447f5df46a29 -SHA1: 7bf9b91714046f12d765adad860677f5b650c616 -SHA256: aa724376b6bf534c8ff38a8c5de4d4208d4de2b57946f875857349436542306b -Homepage: http://nginx.net -Tag: network::server, protocol::http, role::program Conflicts: nginx-extras, nginx-light, nginx-naxsi -Source: nginx -Size: 435328 -Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb -Provides: httpd, nginx Depends: nginx-common (= 1.2.1-2.2+wheezy2), libc6 (>= 2.10), libexpat1 (>= 2.0.1), libgd2-noxpm (>= 2.0.36~rc1~dfsg) | libgd2-xpm (>= 2.0.36~rc1~dfsg), libgeoip1 (>= 1.4.8+dfsg), libpam0g (>= 0.99.7.1), libpcre3 (>= 8.10), libssl1.0.0 (>= 1.0.0), libxml2 (>= 2.7.4), libxslt1.1 (>= 1.1.25), zlib1g (>= 1:1.1.4) Description-md5: b334eec6202adf5e9045cc6066a082d1 - +Description: nginx web/proxy server (standard version) +Filename: nginx-full_1.2.1-2.2+wheezy2_amd64.deb +Homepage: http://nginx.net +Installed-Size: 915 +MD5sum: 586a2ff5648004cd0114447f5df46a29 +Maintainer: Kartik Mistry +Package: nginx-full +Priority: optional +Provides: httpd, nginx References to package: - mirror [wheezy-main]: http://mirror.yandex.ru/debian/ wheezy - mirror [wheezy-main-src]: http://mirror.yandex.ru/debian/ wheezy [src] - local repo [repo1] - snapshot [snap1]: Snapshot from mirror [wheezy-main]: http://mirror.yandex.ru/debian/ wheezy - snapshot [snap4]: Merged from sources: 'snap1', 'snap2', 'snap3' - snapshot [snap3]: Snapshot from mirror [wheezy-main-src]: http://mirror.yandex.ru/debian/ wheezy [src] - +SHA1: 7bf9b91714046f12d765adad860677f5b650c616 +SHA256: aa724376b6bf534c8ff38a8c5de4d4208d4de2b57946f875857349436542306b +Section: httpd +Size: 435328 +Source: nginx +Tag: network::server, protocol::http, role::program +Version: 1.2.1-2.2+wheezy2 \ No newline at end of file diff --git a/src/github.com/smira/aptly/system/t11_package/search.py b/src/github.com/smira/aptly/system/t11_package/search.py index a8feac90..a4da9a1e 100644 --- a/src/github.com/smira/aptly/system/t11_package/search.py +++ b/src/github.com/smira/aptly/system/t11_package/search.py @@ -33,3 +33,12 @@ class SearchPackage4Test(BaseTest): fixtureDB = True outputMatchPrepare = lambda _, s: "\n".join(sorted(s.split("\n"))) runCmd = "aptly package search coreutils" + + +class SearchPackage5Test(BaseTest): + """ + search package: with format + """ + fixtureDB = True + outputMatchPrepare = lambda _, s: "\n".join(sorted(s.split("\n"))) + runCmd = "aptly package search -format='{{.Package}}#{{.Version}}' '$$Architecture (i386), Name (% *-dev)'" diff --git a/src/github.com/smira/aptly/system/t12_api/publish.py b/src/github.com/smira/aptly/system/t12_api/publish.py index 8ff020df..1a64a591 100644 --- a/src/github.com/smira/aptly/system/t12_api/publish.py +++ b/src/github.com/smira/aptly/system/t12_api/publish.py @@ -54,6 +54,7 @@ class PublishAPITestRepo(APITest): self.check_exists("public/" + prefix + "/dists/wheezy/Release") self.check_exists("public/" + prefix + "/dists/wheezy/main/binary-i386/Packages") + self.check_exists("public/" + prefix + "/dists/wheezy/main/Contents-i386.gz") self.check_exists("public/" + prefix + "/dists/wheezy/main/source/Sources") self.check_exists("public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb") @@ -81,7 +82,9 @@ class PublishAPITestRepo(APITest): self.check_exists("public/dists/" + distribution + "/Release") self.check_exists("public/dists/" + distribution + "/main/binary-i386/Packages") + self.check_exists("public/dists/" + distribution + "/main/Contents-i386.gz") self.check_exists("public/dists/" + distribution + "/main/binary-amd64/Packages") + self.check_not_exists("public/dists/" + distribution + "/main/Contents-amd64.gz") self.check_exists("public/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb") all_repos = self.get("/api/publish") @@ -132,6 +135,7 @@ class PublishSnapshotAPITest(APITest): self.check_exists("public/" + prefix + "/dists/squeeze/Release") self.check_exists("public/" + prefix + "/dists/squeeze/main/binary-i386/Packages") + self.check_exists("public/" + prefix + "/dists/squeeze/main/Contents-i386.gz") self.check_exists("public/" + prefix + "/pool/main/b/boost-defaults/libboost-program-options-dev_1.49.0.1_i386.deb") diff --git a/src/github.com/smira/aptly/system/t12_api/version.py b/src/github.com/smira/aptly/system/t12_api/version.py index b0f27d75..ddd4d992 100644 --- a/src/github.com/smira/aptly/system/t12_api/version.py +++ b/src/github.com/smira/aptly/system/t12_api/version.py @@ -7,4 +7,4 @@ class VersionAPITest(APITest): """ def check(self): - self.check_equal(self.get("/api/version").json(), {'Version': '0.9.5'}) + self.check_equal(self.get("/api/version").json(), {'Version': '0.9.6'}) diff --git a/src/github.com/smira/aptly/utils/config.go b/src/github.com/smira/aptly/utils/config.go index 1eb936dc..dfc7aa25 100644 --- a/src/github.com/smira/aptly/utils/config.go +++ b/src/github.com/smira/aptly/utils/config.go @@ -29,6 +29,7 @@ type ConfigStructure struct { type S3PublishRoot struct { Region string `json:"region"` Bucket string `json:"bucket"` + Endpoint string `json:"endpoint"` AccessKeyID string `json:"awsAccessKeyID"` SecretAccessKey string `json:"awsSecretAccessKey"` Prefix string `json:"prefix"` @@ -36,6 +37,7 @@ type S3PublishRoot struct { StorageClass string `json:"storageClass"` EncryptionMethod string `json:"encryptionMethod"` PlusWorkaround bool `json:"plusWorkaround"` + DisableMultiDel bool `json:"disableMultiDel"` } // SwiftPublishRoot describes single OpenStack Swift publishing entry point diff --git a/src/github.com/smira/aptly/utils/config_test.go b/src/github.com/smira/aptly/utils/config_test.go index a90650df..23036f4f 100644 --- a/src/github.com/smira/aptly/utils/config_test.go +++ b/src/github.com/smira/aptly/utils/config_test.go @@ -66,13 +66,15 @@ func (s *ConfigSuite) TestSaveConfig(c *C) { " \"test\": {\n"+ " \"region\": \"us-east-1\",\n"+ " \"bucket\": \"repo\",\n"+ + " \"endpoint\": \"\",\n"+ " \"awsAccessKeyID\": \"\",\n"+ " \"awsSecretAccessKey\": \"\",\n"+ " \"prefix\": \"\",\n"+ " \"acl\": \"\",\n"+ " \"storageClass\": \"\",\n"+ " \"encryptionMethod\": \"\",\n"+ - " \"plusWorkaround\": false\n"+ + " \"plusWorkaround\": false,\n"+ + " \"disableMultiDel\": false\n"+ " }\n"+ " },\n"+ " \"SwiftPublishEndpoints\": {\n"+ diff --git a/src/github.com/smira/aptly/utils/copyfile.go b/src/github.com/smira/aptly/utils/copyfile.go new file mode 100644 index 00000000..c9689a58 --- /dev/null +++ b/src/github.com/smira/aptly/utils/copyfile.go @@ -0,0 +1,28 @@ +package utils + +import ( + "io" + "os" +) + +// CopyFile copeis file from src to dst, not preserving attributes +func CopyFile(src, dst string) error { + sf, err := os.Open(src) + if err != nil { + return err + } + defer sf.Close() + + df, err := os.Create(dst) + if err != nil { + return err + } + + _, err = io.Copy(df, sf) + if err != nil { + df.Close() + return err + } + + return df.Close() +} diff --git a/src/github.com/smira/aptly/utils/gpg.go b/src/github.com/smira/aptly/utils/gpg.go index 080aa74a..9727b2ca 100644 --- a/src/github.com/smira/aptly/utils/gpg.go +++ b/src/github.com/smira/aptly/utils/gpg.go @@ -1,6 +1,7 @@ package utils import ( + "bufio" "bytes" "fmt" "io" @@ -8,7 +9,6 @@ import ( "os" "os/exec" "path/filepath" - "regexp" "strings" ) @@ -28,7 +28,8 @@ type Verifier interface { InitKeyring() error AddKeyring(keyring string) VerifyDetachedSignature(signature, cleartext io.Reader) error - VerifyClearsigned(clearsigned io.Reader) error + IsClearSigned(clearsigned io.Reader) (bool, error) + VerifyClearsigned(clearsigned io.Reader, showKeyTip bool) (*GpgKeyInfo, error) ExtractClearsigned(clearsigned io.Reader) (text *os.File, err error) } @@ -38,6 +39,32 @@ var ( _ Verifier = &GpgVerifier{} ) +// GpgKey is key in GPG representation +type GpgKey string + +// Matches checks two keys for equality +func (key1 GpgKey) Matches(key2 GpgKey) bool { + if key1 == key2 { + return true + } + + if len(key1) == 8 && len(key2) == 16 { + return key1 == key2[8:] + } + + if len(key1) == 16 && len(key2) == 8 { + return key1[8:] == key2 + } + + return false +} + +// GpgKeyInfo is response from signature verification +type GpgKeyInfo struct { + GoodKeys []GpgKey + MissingKeys []GpgKey +} + // GpgSigner is implementation of Signer interface using gpg type GpgSigner struct { keyRef string @@ -182,47 +209,82 @@ func (g *GpgVerifier) argsKeyrings() (args []string) { return } -func (g *GpgVerifier) runGpgv(args []string, context string) error { +func (g *GpgVerifier) runGpgv(args []string, context string, showKeyTip bool) (*GpgKeyInfo, error) { + args = append([]string{"--status-fd", "3"}, args...) cmd := exec.Command("gpgv", args...) + tempf, err := ioutil.TempFile("", "aptly-gpg-status") + if err != nil { + return nil, err + } + defer tempf.Close() + + err = os.Remove(tempf.Name()) + if err != nil { + return nil, err + } + + cmd.ExtraFiles = []*os.File{tempf} + stderr, err := cmd.StderrPipe() if err != nil { - return err + return nil, err } defer stderr.Close() err = cmd.Start() if err != nil { - return err + return nil, err } buffer := &bytes.Buffer{} _, err = io.Copy(io.MultiWriter(os.Stderr, buffer), stderr) if err != nil { - return err + return nil, err } - matches := regexp.MustCompile("ID ([0-9A-F]{8})").FindAllStringSubmatch(buffer.String(), -1) + cmderr := cmd.Wait() - err = cmd.Wait() - if err != nil { - if len(g.keyRings) == 0 && len(matches) > 0 { + tempf.Seek(0, 0) + + statusr := bufio.NewScanner(tempf) + + result := &GpgKeyInfo{} + + for statusr.Scan() { + line := strings.TrimSpace(statusr.Text()) + + if strings.HasPrefix(line, "[GNUPG:] GOODSIG ") { + result.GoodKeys = append(result.GoodKeys, GpgKey(strings.Fields(line)[2])) + } else if strings.HasPrefix(line, "[GNUPG:] NO_PUBKEY ") { + result.MissingKeys = append(result.MissingKeys, GpgKey(strings.Fields(line)[2])) + } + } + + if err = statusr.Err(); err != nil { + return nil, err + } + + if cmderr != nil { + if showKeyTip && len(g.keyRings) == 0 && len(result.MissingKeys) > 0 { fmt.Printf("\nLooks like some keys are missing in your trusted keyring, you may consider importing them from keyserver:\n\n") - keyIDs := []string{} - for _, match := range matches { - keyIDs = append(keyIDs, match[1]) + keys := make([]string, len(result.MissingKeys)) + + for i := range result.MissingKeys { + keys[i] = string(result.MissingKeys[i]) } + fmt.Printf("gpg --no-default-keyring --keyring trustedkeys.gpg --keyserver keys.gnupg.net --recv-keys %s\n\n", - strings.Join(keyIDs, " ")) + strings.Join(keys, " ")) fmt.Printf("Sometimes keys are stored in repository root in file named Release.key, to import such key:\n\n") fmt.Printf("wget -O - https://some.repo/repository/Release.key | gpg --no-default-keyring --keyring trustedkeys.gpg --import\n\n") } - return fmt.Errorf("verification of %s failed: %s", context, err) + return result, fmt.Errorf("verification of %s failed: %s", context, cmderr) } - return nil + return result, nil } // VerifyDetachedSignature verifies combination of signature and cleartext using gpgv @@ -254,27 +316,44 @@ func (g *GpgVerifier) VerifyDetachedSignature(signature, cleartext io.Reader) er } args = append(args, sigf.Name(), clearf.Name()) - return g.runGpgv(args, "detached signature") + _, err = g.runGpgv(args, "detached signature", true) + return err +} + +// IsClearSigned returns true if file contains signature +func (g *GpgVerifier) IsClearSigned(clearsigned io.Reader) (bool, error) { + scanner := bufio.NewScanner(clearsigned) + for scanner.Scan() { + if strings.Index(scanner.Text(), "BEGIN PGP SIGN") != -1 { + return true, nil + } + } + + if err := scanner.Err(); err != nil { + return false, err + } + + return false, nil } // VerifyClearsigned verifies clearsigned file using gpgv -func (g *GpgVerifier) VerifyClearsigned(clearsigned io.Reader) error { +func (g *GpgVerifier) VerifyClearsigned(clearsigned io.Reader, showKeyTip bool) (*GpgKeyInfo, error) { args := g.argsKeyrings() clearf, err := ioutil.TempFile("", "aptly-gpg") if err != nil { - return err + return nil, err } defer os.Remove(clearf.Name()) defer clearf.Close() _, err = io.Copy(clearf, clearsigned) if err != nil { - return err + return nil, err } args = append(args, clearf.Name()) - return g.runGpgv(args, "clearsigned file") + return g.runGpgv(args, "clearsigned file", showKeyTip) } // ExtractClearsigned extracts cleartext from clearsigned file WITHOUT signature verification diff --git a/src/github.com/smira/aptly/utils/gpg_test.go b/src/github.com/smira/aptly/utils/gpg_test.go new file mode 100644 index 00000000..12503b21 --- /dev/null +++ b/src/github.com/smira/aptly/utils/gpg_test.go @@ -0,0 +1,20 @@ +package utils + +import ( + . "gopkg.in/check.v1" +) + +type GpgSuite struct{} + +var _ = Suite(&GpgSuite{}) + +func (s *GpgSuite) TestGpgKeyMatch(c *C) { + c.Check(GpgKey("EC4B033C70096AD1").Matches(GpgKey("EC4B033C70096AD1")), Equals, true) + c.Check(GpgKey("37E1C17570096AD1").Matches(GpgKey("EC4B033C70096AD1")), Equals, false) + + c.Check(GpgKey("70096AD1").Matches(GpgKey("70096AD1")), Equals, true) + c.Check(GpgKey("70096AD1").Matches(GpgKey("EC4B033C")), Equals, false) + + c.Check(GpgKey("37E1C17570096AD1").Matches(GpgKey("70096AD1")), Equals, true) + c.Check(GpgKey("70096AD1").Matches(GpgKey("EC4B033C70096AD1")), Equals, true) +}