blob: 86e68d0e5d5c794f9938891c72202a597f04ec7a [file]
// Copyright 2013 Frank Schroeder. All rights reserved. MIT licensed.
package properties
import (
"fmt"
"io"
"io/ioutil"
"unicode/utf8"
)
type Properties struct {
m map[string]string
}
// Reads bytes fully and parses them as ISO-8859-1.
func NewProperties(r io.Reader) (*Properties, error) {
buf, err := ioutil.ReadAll(r)
if err != nil {
return nil, err
}
return NewPropertiesFromString(toUtf8(buf))
}
func NewPropertiesFromISO8859_1(buf []byte) (*Properties, error) {
return newParser().Parse(toUtf8(buf))
}
// Java properties spec says that .properties files must be ISO-8859-1
// encoded. Therefore, we first convert them to UTF-8 and then parse them.
func NewPropertiesFromString(input string) (*Properties, error) {
if err := isISO8859_1(input); err != nil {
return nil, err
}
return newParser().Parse(input)
}
// returns the value for the given key
func (p *Properties) Get(key string) (value string, ok bool) {
value, ok = p.m[key]
return value, ok
}
// sets the property key = value and returns the previous value if exists or an empty string
func (p *Properties) Set(key, value string) (prevValue string) {
prevValue, ok := p.m[key]
if !ok {
prevValue = ""
}
p.m[key] = value
return prevValue
}
// returns the number of keys
func (p *Properties) Len() int {
return len(p.m)
}
// taken from
// http://stackoverflow.com/questions/13510458/golang-convert-iso8859-1-to-utf8
func toUtf8(iso8859_1_buf []byte) string {
buf := make([]rune, len(iso8859_1_buf))
for i, b := range iso8859_1_buf {
buf[i] = rune(b)
}
return string(buf)
}
func isISO8859_1(s string) error {
for i := 0; i < len(s); i++ {
r, w := utf8.DecodeRuneInString(s[i:])
if w > 1 || r > 255 {
return fmt.Errorf("invalid ISO-8859-1 input. %s", s)
}
}
return nil
}