Skip to content
This repository has been archived by the owner on Apr 9, 2021. It is now read-only.

Commit

Permalink
Switch to new streaming API for JSON decoding - much cleaner.
Browse files Browse the repository at this point in the history
+ Documentation updates.
  • Loading branch information
klauspost committed Jan 21, 2015
1 parent 5ef2626 commit 6a47e13
Show file tree
Hide file tree
Showing 17 changed files with 86 additions and 5,111 deletions.
2 changes: 1 addition & 1 deletion adgangsadressse.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type AdgangsAdresse struct {
Region Region `json:"region"` // Regionen som adressen er beliggende i. Beregnes udfra adgangspunktet og regionsinddelingerne fra DAGI
Retskreds Retskreds `json:"retskreds"` // Retskredsen som adressen er beliggende i. Beregnes udfra adgangspunktet og retskredsinddelingerne fra DAGI
Sogn Sogn `json:"sogn"` // Sognet som adressen er beliggende i. Beregnes udfra adgangspunktet og sogneinddelingerne fra DAGI
Status int `json:"status"` //Adressens status, som modtaget fra BBR. "1" angiver en endelig adresse og "3" angiver en foreløbig adresse". Adresser med status "2" eller "4" er ikke med i DAWA.
Status int `json:"status"` // Adressens status, som modtaget fra BBR. "1" angiver en endelig adresse og "3" angiver en foreløbig adresse". Adresser med status "2" eller "4" er ikke med i DAWA.
SupplerendeBynavn string `json:"supplerendebynavn"` // Et supplerende bynavn – typisk landsbyens navn – eller andet lokalt stednavn, der er fastsat af kommunen for at præcisere adressens beliggenhed indenfor postnummeret.
Vejstykke VejstykkeRef `json:"vejstykke"` // Vejstykket som adressen er knyttet til.
Zone string `json:"zone"` // Hvilken zone adressen ligger i. "Byzone", "Sommerhusområde" eller "Landzone". Beregnes udfra adgangspunktet og zoneinddelingerne fra PlansystemDK
Expand Down
2 changes: 1 addition & 1 deletion awstime.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"time"
)

// Since this is not a standard encoded field, we must create out own type.
// Since date/time is not a standard encoded field, we must create out own type.
type AwsTime time.Time

var location *time.Location
Expand Down
19 changes: 19 additions & 0 deletions dawa.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// The dawa package can be used to de-serialize structures received from "Danmarks Adressers Web API (DAWA)" (Addresses of Denmark Web API).
//
// This package allows to de-serialize JSON responses from the web api into typed structs.
// The package also allows importing JSON or CSV downloads from the official web page.
// See the /examples folder for more information.
//
// Package home: https://github.com/klauspost/dawa
//
// Information abou the format and download/API options, see http://dawa.aws.dk/
//
// Description text in Danish:
//
// Danmarks Adressers Web API (DAWA) udstiller data og funktionalitet vedrørende Danmarks adresser, adgangsadresser, vejnavne samt postnumre.
// DAWA anvendes til etablering af adressefunktionalitet i it-systemer. Målgruppen for nærværende website er udviklere, som ønsker at indbygge adressefunktionalitet i deres it-systemer.
package dawa

// modify JSONStrictFieldCheck to return an error on unknown fields on JSON import.
// If true, return an error if a map in the stream has a key which does not map to any field; else read and discard the key and value in the stream and proceed to the next.
var JSONStrictFieldCheck = true
2 changes: 1 addition & 1 deletion examples/adgangs-adresser-json.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
log.Fatal(err)
}

iter, err := aws.ImportAdgangsAdresserJSON(file)
iter, err := dawa.ImportAdgangsAdresserJSON(file)
if err != nil {
log.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion examples/adgangsadresser-csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
log.Fatal(err)
}

iter, err := aws.ImportAdgangsAdresserCSV(file)
iter, err := dawa.ImportAdgangsAdresserCSV(file)
if err != nil {
log.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion examples/adgangsadresser-json.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
log.Fatal(err)
}

iter, err := aws.ImportAdgangsAdresserJSON(file)
iter, err := dawa.ImportAdgangsAdresserJSON(file)
if err != nil {
log.Fatal(err)
}
Expand Down
2 changes: 1 addition & 1 deletion examples/adresser-csv.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
log.Fatal(err)
}

iter, err := aws.ImportAdresserCSV(file)
iter, err := dawa.ImportAdresserCSV(file)
if err != nil {
log.Fatal(err)
}
Expand Down
7 changes: 5 additions & 2 deletions examples/postnumre-json.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
log.Fatal(err)
}

iter, err := aws.ImportPostnumreJSON(file)
iter, err := dawa.ImportPostnumreJSON(file)
if err != nil {
log.Fatal(err)
}
Expand All @@ -30,7 +30,10 @@ func main() {
if err != nil {
log.Fatal(err)
}
n++
if a == nil {
panic("empty")
}
log.Printf("Entry:%#v\n", a)
n++
}
}
File renamed without changes.
5 changes: 4 additions & 1 deletion examples/vejstykker-json.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func main() {
log.Fatal(err)
}

iter, err := aws.ImportVejstykkerJSON(file)
iter, err := dawa.ImportVejstykkerJSON(file)
if err != nil {
log.Fatal(err)
}
Expand All @@ -30,6 +30,9 @@ func main() {
if err != nil {
log.Fatal(err)
}
if a == nil {
panic("empty")
}
n++
log.Printf("Entry:%#v\n", a)
}
Expand Down
6 changes: 6 additions & 0 deletions generate.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
package dawa

//go:generate codecgen -o values.generated.go postnummer.go awstime.go adresse.go adgangsadressse.go vejstykke.go

// Using this will speed up decoding about 20%
// To use, run this in the current directory:
//
// go get "github.com/ugorji/go/codec/codecgen"
// go generate
25 changes: 0 additions & 25 deletions helpers.go

This file was deleted.

47 changes: 12 additions & 35 deletions import-adgangsadresser.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,47 +129,24 @@ func ImportAdgangsAdresserCSV(in io.Reader) (*AdgangsAdresseIter, error) {
return ret, nil
}

// ImportAdresserJSON will import "adresser" from a JSON input, supplied to the reader.
// An iterator will be returned that return all addresses.
// ImportAdgangsAdresserJSON will import "adgangsadresser" from a JSON input, supplied to the reader.
// An iterator will be returned that return all items.
func ImportAdgangsAdresserJSON(in io.Reader) (*AdgangsAdresseIter, error) {
reader := bufio.NewReader(in)
// Skip until after '['
_, err := reader.ReadBytes('[')
if err != nil {
return nil, err
var h codec.JsonHandle
h.DecodeOptions.ErrorIfNoField = JSONStrictFieldCheck
// use a buffered reader for efficiency
if _, ok := in.(io.ByteScanner); !ok {
in = bufio.NewReader(in)
}
// Start decoder
ret := &AdgangsAdresseIter{a: make(chan AdgangsAdresse, 100)}
go func() {
defer close(ret.a)
var h codec.JsonHandle
h.ErrorIfNoField = true
for {
var dec *codec.Decoder = codec.NewDecoder(reader, &h)
a := AdgangsAdresse{}
if err := dec.Decode(&a); err != nil {
ret.err = err
return
}
ret.a <- a

// Skip comma
if b, err := readByteSkippingSpace(reader); err != nil {
ret.err = err
return
} else {
switch b {
case ',':
continue
case ']':
ret.err = io.EOF
return
default:
panic("Invalid character in JSON data: " + string([]byte{b}))
}
}

var dec *codec.Decoder = codec.NewDecoder(in, &h)
ret.err = dec.Decode(&ret.a)
if ret.err == nil {
ret.err = io.EOF
}
}()

return ret, nil
}
44 changes: 10 additions & 34 deletions import-adresser.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,45 +154,21 @@ func ImportAdresserCSV(in io.Reader) (*AdresseIter, error) {
// ImportAdresserJSON will import "adresser" from a JSON input, supplied to the reader.
// An iterator will be returned that return all addresses.
func ImportAdresserJSON(in io.Reader) (*AdresseIter, error) {
reader := bufio.NewReader(in)

//Skip until after '['
_, err := reader.ReadBytes('[')
if err != nil {
return nil, err
var h codec.JsonHandle
h.DecodeOptions.ErrorIfNoField = JSONStrictFieldCheck
// use a buffered reader for efficiency
if _, ok := in.(io.ByteScanner); !ok {
in = bufio.NewReader(in)
}
// Start decoder
ret := &AdresseIter{a: make(chan Adresse, 100)}
go func() {
defer close(ret.a)
var h codec.JsonHandle
h.ErrorIfNoField = true
for {
var dec *codec.Decoder = codec.NewDecoder(reader, &h)
a := Adresse{}
if err := dec.Decode(&a); err != nil {
ret.err = err
return
}
ret.a <- a

// Skip comma
if b, err := readByteSkippingSpace(reader); err != nil {
ret.err = err
return
} else {
switch b {
case ',':
continue
case ']':
ret.err = io.EOF
return
default:
panic("Invalid character in JSON data: " + string([]byte{b}))
}
}

var dec *codec.Decoder = codec.NewDecoder(in, &h)
ret.err = dec.Decode(&ret.a)
if ret.err == nil {
ret.err = io.EOF
}
}()

return ret, nil
}
47 changes: 12 additions & 35 deletions import-postnumre.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,47 +23,24 @@ func (a *PostnummerIter) Next() (*Postnummer, error) {
return nil, a.err
}

// ImportPostnummerrJSON will import "adresser" from a JSON input, supplied to the reader.
// An iterator will be returned that return all addresses.
// ImportPostnumreJSON will import "postnumre" from a JSON input, supplied to the reader.
// An iterator will be returned that return all items.
func ImportPostnumreJSON(in io.Reader) (*PostnummerIter, error) {
reader := bufio.NewReader(in)
// Skip until after '['
_, err := reader.ReadBytes('[')
if err != nil {
return nil, err
var h codec.JsonHandle
h.DecodeOptions.ErrorIfNoField = JSONStrictFieldCheck
// use a buffered reader for efficiency
if _, ok := in.(io.ByteScanner); !ok {
in = bufio.NewReader(in)
}
// Start decoder
ret := &PostnummerIter{a: make(chan Postnummer, 100)}
go func() {
defer close(ret.a)
var h codec.JsonHandle
h.ErrorIfNoField = true
for {
var dec *codec.Decoder = codec.NewDecoder(reader, &h)
a := Postnummer{}
if err := dec.Decode(&a); err != nil {
ret.err = err
return
}
ret.a <- a

// Skip comma
if b, err := readByteSkippingSpace(reader); err != nil {
ret.err = err
return
} else {
switch b {
case ',':
continue
case ']':
ret.err = io.EOF
return
default:
panic("Invalid character in JSON data: " + string([]byte{b}))
}
}

var dec *codec.Decoder = codec.NewDecoder(in, &h)
ret.err = dec.Decode(&ret.a)
if ret.err == nil {
ret.err = io.EOF
}
}()

return ret, nil
}
47 changes: 12 additions & 35 deletions import-vejstykker.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,47 +23,24 @@ func (a *VejstykkeIter) Next() (*Vejstykke, error) {
return nil, a.err
}

// ImportVejstykkerJSON will import "adresser" from a JSON input, supplied to the reader.
// An iterator will be returned that return all addresses.
// ImportVejstykkerJSON will import "vejstykker" from a JSON input, supplied to the reader.
// An iterator will be returned that return all items.
func ImportVejstykkerJSON(in io.Reader) (*VejstykkeIter, error) {
reader := bufio.NewReader(in)
// Skip until after '['
_, err := reader.ReadBytes('[')
if err != nil {
return nil, err
var h codec.JsonHandle
h.DecodeOptions.ErrorIfNoField = JSONStrictFieldCheck
// use a buffered reader for efficiency
if _, ok := in.(io.ByteScanner); !ok {
in = bufio.NewReader(in)
}
// Start decoder
ret := &VejstykkeIter{a: make(chan Vejstykke, 100)}
go func() {
defer close(ret.a)
var h codec.JsonHandle
h.ErrorIfNoField = true
for {
var dec *codec.Decoder = codec.NewDecoder(reader, &h)
a := Vejstykke{}
if err := dec.Decode(&a); err != nil {
ret.err = err
return
}
ret.a <- a

// Skip comma
if b, err := readByteSkippingSpace(reader); err != nil {
ret.err = err
return
} else {
switch b {
case ',':
continue
case ']':
ret.err = io.EOF
return
default:
panic("Invalid character in JSON data: " + string([]byte{b}))
}
}

var dec *codec.Decoder = codec.NewDecoder(in, &h)
ret.err = dec.Decode(&ret.a)
if ret.err == nil {
ret.err = io.EOF
}
}()

return ret, nil
}
Loading

0 comments on commit 6a47e13

Please sign in to comment.