1// Copyright (c) 2012 - Cloud Instruments Co., Ltd.
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this
9//    list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright notice,
11//    this list of conditions and the following disclaimer in the documentation
12//    and/or other materials provided with the distribution.
13//
14// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25package seelog
26
27import (
28	"fmt"
29	"io"
30	"os"
31	"path/filepath"
32)
33
34// fileWriter is used to write to a file.
35type fileWriter struct {
36	innerWriter io.WriteCloser
37	fileName    string
38}
39
40// Creates a new file and a corresponding writer. Returns error, if the file couldn't be created.
41func NewFileWriter(fileName string) (writer *fileWriter, err error) {
42	newWriter := new(fileWriter)
43	newWriter.fileName = fileName
44
45	return newWriter, nil
46}
47
48func (fw *fileWriter) Close() error {
49	if fw.innerWriter != nil {
50		err := fw.innerWriter.Close()
51		if err != nil {
52			return err
53		}
54		fw.innerWriter = nil
55	}
56	return nil
57}
58
59// Create folder and file on WriteLog/Write first call
60func (fw *fileWriter) Write(bytes []byte) (n int, err error) {
61	if fw.innerWriter == nil {
62		if err := fw.createFile(); err != nil {
63			return 0, err
64		}
65	}
66	return fw.innerWriter.Write(bytes)
67}
68
69func (fw *fileWriter) createFile() error {
70	folder, _ := filepath.Split(fw.fileName)
71	var err error
72
73	if 0 != len(folder) {
74		err = os.MkdirAll(folder, defaultDirectoryPermissions)
75		if err != nil {
76			return err
77		}
78	}
79
80	// If exists
81	fw.innerWriter, err = os.OpenFile(fw.fileName, os.O_WRONLY|os.O_APPEND|os.O_CREATE, defaultFilePermissions)
82
83	if err != nil {
84		return err
85	}
86
87	return nil
88}
89
90func (fw *fileWriter) String() string {
91	return fmt.Sprintf("File writer: %s", fw.fileName)
92}
93