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