1 /*
2  *
3  *   Copyright (C) 2012-2018 by C.H. Huang
4  *   plushuang.tw@gmail.com
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2.1 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  *  ---
21  *
22  *  In addition, as a special exception, the copyright holders give
23  *  permission to link the code of portions of this program with the
24  *  OpenSSL library under certain conditions as described in each
25  *  individual source file, and distribute linked combinations
26  *  including the two.
27  *  You must obey the GNU Lesser General Public License in all respects
28  *  for all of the code used other than OpenSSL.  If you modify
29  *  file(s) with this exception, you may extend this exception to your
30  *  version of the file(s), but you are not obligated to do so.  If you
31  *  do not wish to do so, delete this exception statement from your
32  *  version.  If you delete this exception statement from all source
33  *  files in the program, then also delete it here.
34  *
35  */
36 
37 #include <UgStdio.h>
38 #include <UgDefine.h>
39 #include <UgJsonFile.h>
40 
41 static int  buffer_to_fd (UgBuffer* buffer);
42 
ug_json_file_new(int buffer_size)43 UgJsonFile*  ug_json_file_new (int buffer_size)
44 {
45 	UgJsonFile*  jfile;
46 
47 	if (buffer_size == 0)
48 		buffer_size = 4096;
49 
50 	if (buffer_size == 0)
51 		jfile = ug_malloc (sizeof (UgJsonFile));
52 	else
53 		jfile = ug_malloc (sizeof (UgJsonFile) + sizeof (char) * buffer_size - 1);
54 
55 	jfile->fd = -1;
56 	jfile->n_bytes = buffer_size;
57 	ug_json_init (&jfile->json);
58 	return jfile;
59 }
60 
ug_json_file_free(UgJsonFile * jfile)61 void  ug_json_file_free (UgJsonFile* jfile)
62 {
63 	if (jfile->fd != -1)
64 		ug_close (jfile->fd);
65 	ug_json_final (&jfile->json);
66 	ug_free (jfile);
67 }
68 
ug_json_file_begin_parse(UgJsonFile * jfile,const char * path)69 int   ug_json_file_begin_parse (UgJsonFile* jfile, const char* path)
70 {
71 	int  fd;
72 
73 //	fd = open (path, O_RDONLY, 0);
74 	fd = ug_open (path, UG_O_RDONLY | UG_O_TEXT, 0);
75 	if (fd == -1)
76 		return FALSE;
77 
78 	return ug_json_file_begin_parse_fd (jfile, fd);
79 }
80 
ug_json_file_begin_write(UgJsonFile * jfile,const char * path,UgJsonFormat format)81 int   ug_json_file_begin_write (UgJsonFile* jfile, const char* path, UgJsonFormat format)
82 {
83 	int  fd;
84 
85 //	fd = open (path, O_CREAT | O_WRONLY | O_TRUNC,
86 //			S_IREAD | S_IWRITE | S_IRGRP | S_IROTH);
87 	fd = ug_open (path, UG_O_CREAT | UG_O_WRONLY | UG_O_TRUNC | UG_O_TEXT,
88 			UG_S_IREAD | UG_S_IWRITE | UG_S_IRGRP | UG_S_IROTH);
89 	if (fd == -1)
90 		return FALSE;
91 
92 	return ug_json_file_begin_write_fd (jfile, fd, format);
93 }
94 
ug_json_file_begin_parse_fd(UgJsonFile * jfile,int fd)95 int   ug_json_file_begin_parse_fd (UgJsonFile* jfile, int fd)
96 {
97 	jfile->fd = fd;
98 	// ready to parse
99 	ug_json_begin_parse (&jfile->json);
100 	return TRUE;
101 }
102 
ug_json_file_begin_write_fd(UgJsonFile * jfile,int fd,UgJsonFormat format)103 int   ug_json_file_begin_write_fd (UgJsonFile* jfile, int fd, UgJsonFormat format)
104 {
105 	jfile->fd = fd;
106 	// init UgBuffer for writer
107 	ug_buffer_init_external (&jfile->buffer, jfile->bytes, jfile->n_bytes);
108 	jfile->buffer.data = (void*)(uintptr_t) jfile->fd;
109 	jfile->buffer.more = buffer_to_fd;
110 	// ready to write
111 	ug_json_begin_write (&jfile->json, format, &jfile->buffer);
112 	return TRUE;
113 }
114 
ug_json_file_end_parse(UgJsonFile * jfile)115 UgJsonError   ug_json_file_end_parse (UgJsonFile* jfile)
116 {
117 	UgJsonError  error;
118 	int          len;
119 
120 	do {
121 		len = ug_read (jfile->fd, &jfile->bytes, jfile->n_bytes);
122 		error = ug_json_parse (&jfile->json, jfile->bytes, len);
123 		if (error < 0)
124 			goto exit;
125 	} while (len > 0);
126 
127 	error = ug_json_end_parse (&jfile->json);
128 exit:
129 	ug_close (jfile->fd);
130 	jfile->fd = -1;
131 	return error;
132 }
133 
ug_json_file_end_write(UgJsonFile * jfile)134 void  ug_json_file_end_write (UgJsonFile* jfile)
135 {
136 	ug_json_end_write (&jfile->json);
137 	ug_buffer_clear (&jfile->buffer, FALSE);
138 	ug_write (jfile->fd, "\n\n", 2);
139 
140 	// close() doesn't call fsync()
141 	// If you want to avoid delayed write, call fsync() before close()
142 	ug_sync (jfile->fd);
143 
144 	ug_close (jfile->fd);
145 	jfile->fd = -1;
146 }
147 
148 // ----------------------------------------------------------------------------
149 // static function for ug_json_file_save
150 
151 // UgBufferFunc
buffer_to_fd(UgBuffer * buffer)152 static int  buffer_to_fd (UgBuffer* buffer)
153 {
154 	int     fd;
155 
156 	fd = (uintptr_t)buffer->data;
157 	ug_write (fd, buffer->beg, ug_buffer_length (buffer));
158 	buffer->cur = buffer->beg;
159 	return 0;
160 }
161 
162 
163