file.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package po
  5. import (
  6. "bytes"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "sort"
  11. )
  12. // File represents an PO File.
  13. //
  14. // See http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html
  15. type File struct {
  16. MimeHeader Header
  17. Messages []Message
  18. }
  19. // Load loads a named po file.
  20. func Load(name string) (*File, error) {
  21. data, err := ioutil.ReadFile(name)
  22. if err != nil {
  23. return nil, err
  24. }
  25. return LoadData(data)
  26. }
  27. // LoadData loads po file format data.
  28. func LoadData(data []byte) (*File, error) {
  29. r := newLineReader(string(data))
  30. var file File
  31. for {
  32. var msg Message
  33. if err := msg.readPoEntry(r); err != nil {
  34. if err == io.EOF {
  35. return &file, nil
  36. }
  37. return nil, err
  38. }
  39. if msg.MsgId == "" {
  40. file.MimeHeader.parseHeader(&msg)
  41. continue
  42. }
  43. file.Messages = append(file.Messages, msg)
  44. }
  45. }
  46. // Save saves a po file.
  47. func (f *File) Save(name string) error {
  48. return ioutil.WriteFile(name, []byte(f.String()), 0666)
  49. }
  50. // Save returns a po file format data.
  51. func (f *File) Data() []byte {
  52. // sort the massge as ReferenceFile/ReferenceLine field
  53. var messages []Message
  54. messages = append(messages, f.Messages...)
  55. sort.Sort(byMessages(messages))
  56. var buf bytes.Buffer
  57. fmt.Fprintf(&buf, "%s\n", f.MimeHeader.String())
  58. for i := 0; i < len(messages); i++ {
  59. fmt.Fprintf(&buf, "%s\n", messages[i].String())
  60. }
  61. return buf.Bytes()
  62. }
  63. // String returns the po format file string.
  64. func (f *File) String() string {
  65. return string(f.Data())
  66. }