files.go raw

   1  package mxj
   2  
   3  import (
   4  	"fmt"
   5  	"io"
   6  	"os"
   7  )
   8  
   9  type Maps []Map
  10  
  11  func NewMaps() Maps {
  12  	return make(Maps, 0)
  13  }
  14  
  15  type MapRaw struct {
  16  	M Map
  17  	R []byte
  18  }
  19  
  20  // NewMapsFromXmlFile - creates an array from a file of JSON values.
  21  func NewMapsFromJsonFile(name string) (Maps, error) {
  22  	fi, err := os.Stat(name)
  23  	if err != nil {
  24  		return nil, err
  25  	}
  26  	if !fi.Mode().IsRegular() {
  27  		return nil, fmt.Errorf("file %s is not a regular file", name)
  28  	}
  29  
  30  	fh, err := os.Open(name)
  31  	if err != nil {
  32  		return nil, err
  33  	}
  34  	defer fh.Close()
  35  
  36  	am := make([]Map, 0)
  37  	for {
  38  		m, raw, err := NewMapJsonReaderRaw(fh)
  39  		if err != nil && err != io.EOF {
  40  			return am, fmt.Errorf("error: %s - reading: %s", err.Error(), string(raw))
  41  		}
  42  		if len(m) > 0 {
  43  			am = append(am, m)
  44  		}
  45  		if err == io.EOF {
  46  			break
  47  		}
  48  	}
  49  	return am, nil
  50  }
  51  
  52  // ReadMapsFromJsonFileRaw - creates an array of MapRaw from a file of JSON values.
  53  func NewMapsFromJsonFileRaw(name string) ([]MapRaw, error) {
  54  	fi, err := os.Stat(name)
  55  	if err != nil {
  56  		return nil, err
  57  	}
  58  	if !fi.Mode().IsRegular() {
  59  		return nil, fmt.Errorf("file %s is not a regular file", name)
  60  	}
  61  
  62  	fh, err := os.Open(name)
  63  	if err != nil {
  64  		return nil, err
  65  	}
  66  	defer fh.Close()
  67  
  68  	am := make([]MapRaw, 0)
  69  	for {
  70  		mr := new(MapRaw)
  71  		mr.M, mr.R, err = NewMapJsonReaderRaw(fh)
  72  		if err != nil && err != io.EOF {
  73  			return am, fmt.Errorf("error: %s - reading: %s", err.Error(), string(mr.R))
  74  		}
  75  		if len(mr.M) > 0 {
  76  			am = append(am, *mr)
  77  		}
  78  		if err == io.EOF {
  79  			break
  80  		}
  81  	}
  82  	return am, nil
  83  }
  84  
  85  // NewMapsFromXmlFile - creates an array from a file of XML values.
  86  func NewMapsFromXmlFile(name string) (Maps, error) {
  87  	fi, err := os.Stat(name)
  88  	if err != nil {
  89  		return nil, err
  90  	}
  91  	if !fi.Mode().IsRegular() {
  92  		return nil, fmt.Errorf("file %s is not a regular file", name)
  93  	}
  94  
  95  	fh, err := os.Open(name)
  96  	if err != nil {
  97  		return nil, err
  98  	}
  99  	defer fh.Close()
 100  
 101  	am := make([]Map, 0)
 102  	for {
 103  		m, raw, err := NewMapXmlReaderRaw(fh)
 104  		if err != nil && err != io.EOF {
 105  			return am, fmt.Errorf("error: %s - reading: %s", err.Error(), string(raw))
 106  		}
 107  		if len(m) > 0 {
 108  			am = append(am, m)
 109  		}
 110  		if err == io.EOF {
 111  			break
 112  		}
 113  	}
 114  	return am, nil
 115  }
 116  
 117  // NewMapsFromXmlFileRaw - creates an array of MapRaw from a file of XML values.
 118  // NOTE: the slice with the raw XML is clean with no extra capacity - unlike NewMapXmlReaderRaw().
 119  // It is slow at parsing a file from disk and is intended for relatively small utility files.
 120  func NewMapsFromXmlFileRaw(name string) ([]MapRaw, error) {
 121  	fi, err := os.Stat(name)
 122  	if err != nil {
 123  		return nil, err
 124  	}
 125  	if !fi.Mode().IsRegular() {
 126  		return nil, fmt.Errorf("file %s is not a regular file", name)
 127  	}
 128  
 129  	fh, err := os.Open(name)
 130  	if err != nil {
 131  		return nil, err
 132  	}
 133  	defer fh.Close()
 134  
 135  	am := make([]MapRaw, 0)
 136  	for {
 137  		mr := new(MapRaw)
 138  		mr.M, mr.R, err = NewMapXmlReaderRaw(fh)
 139  		if err != nil && err != io.EOF {
 140  			return am, fmt.Errorf("error: %s - reading: %s", err.Error(), string(mr.R))
 141  		}
 142  		if len(mr.M) > 0 {
 143  			am = append(am, *mr)
 144  		}
 145  		if err == io.EOF {
 146  			break
 147  		}
 148  	}
 149  	return am, nil
 150  }
 151  
 152  // ------------------------ Maps writing -------------------------
 153  // These are handy-dandy methods for dumping configuration data, etc.
 154  
 155  // JsonString - analogous to mv.Json()
 156  func (mvs Maps) JsonString(safeEncoding ...bool) (string, error) {
 157  	var s string
 158  	for _, v := range mvs {
 159  		j, err := v.Json()
 160  		if err != nil {
 161  			return s, err
 162  		}
 163  		s += string(j)
 164  	}
 165  	return s, nil
 166  }
 167  
 168  // JsonStringIndent - analogous to mv.JsonIndent()
 169  func (mvs Maps) JsonStringIndent(prefix, indent string, safeEncoding ...bool) (string, error) {
 170  	var s string
 171  	var haveFirst bool
 172  	for _, v := range mvs {
 173  		j, err := v.JsonIndent(prefix, indent)
 174  		if err != nil {
 175  			return s, err
 176  		}
 177  		if haveFirst {
 178  			s += "\n"
 179  		} else {
 180  			haveFirst = true
 181  		}
 182  		s += string(j)
 183  	}
 184  	return s, nil
 185  }
 186  
 187  // XmlString - analogous to mv.Xml()
 188  func (mvs Maps) XmlString() (string, error) {
 189  	var s string
 190  	for _, v := range mvs {
 191  		x, err := v.Xml()
 192  		if err != nil {
 193  			return s, err
 194  		}
 195  		s += string(x)
 196  	}
 197  	return s, nil
 198  }
 199  
 200  // XmlStringIndent - analogous to mv.XmlIndent()
 201  func (mvs Maps) XmlStringIndent(prefix, indent string) (string, error) {
 202  	var s string
 203  	for _, v := range mvs {
 204  		x, err := v.XmlIndent(prefix, indent)
 205  		if err != nil {
 206  			return s, err
 207  		}
 208  		s += string(x)
 209  	}
 210  	return s, nil
 211  }
 212  
 213  // JsonFile - write Maps to named file as JSON
 214  // Note: the file will be created, if necessary; if it exists it will be truncated.
 215  // If you need to append to a file, open it and use JsonWriter method.
 216  func (mvs Maps) JsonFile(file string, safeEncoding ...bool) error {
 217  	var encoding bool
 218  	if len(safeEncoding) == 1 {
 219  		encoding = safeEncoding[0]
 220  	}
 221  	s, err := mvs.JsonString(encoding)
 222  	if err != nil {
 223  		return err
 224  	}
 225  	fh, err := os.Create(file)
 226  	if err != nil {
 227  		return err
 228  	}
 229  	defer fh.Close()
 230  	fh.WriteString(s)
 231  	return nil
 232  }
 233  
 234  // JsonFileIndent - write Maps to named file as pretty JSON
 235  // Note: the file will be created, if necessary; if it exists it will be truncated.
 236  // If you need to append to a file, open it and use JsonIndentWriter method.
 237  func (mvs Maps) JsonFileIndent(file, prefix, indent string, safeEncoding ...bool) error {
 238  	var encoding bool
 239  	if len(safeEncoding) == 1 {
 240  		encoding = safeEncoding[0]
 241  	}
 242  	s, err := mvs.JsonStringIndent(prefix, indent, encoding)
 243  	if err != nil {
 244  		return err
 245  	}
 246  	fh, err := os.Create(file)
 247  	if err != nil {
 248  		return err
 249  	}
 250  	defer fh.Close()
 251  	fh.WriteString(s)
 252  	return nil
 253  }
 254  
 255  // XmlFile - write Maps to named file as XML
 256  // Note: the file will be created, if necessary; if it exists it will be truncated.
 257  // If you need to append to a file, open it and use XmlWriter method.
 258  func (mvs Maps) XmlFile(file string) error {
 259  	s, err := mvs.XmlString()
 260  	if err != nil {
 261  		return err
 262  	}
 263  	fh, err := os.Create(file)
 264  	if err != nil {
 265  		return err
 266  	}
 267  	defer fh.Close()
 268  	fh.WriteString(s)
 269  	return nil
 270  }
 271  
 272  // XmlFileIndent - write Maps to named file as pretty XML
 273  // Note: the file will be created,if necessary; if it exists it will be truncated.
 274  // If you need to append to a file, open it and use XmlIndentWriter method.
 275  func (mvs Maps) XmlFileIndent(file, prefix, indent string) error {
 276  	s, err := mvs.XmlStringIndent(prefix, indent)
 277  	if err != nil {
 278  		return err
 279  	}
 280  	fh, err := os.Create(file)
 281  	if err != nil {
 282  		return err
 283  	}
 284  	defer fh.Close()
 285  	fh.WriteString(s)
 286  	return nil
 287  }
 288