• R/O
  • SSH
  • HTTPS

hamigaki: 提交


Commit MetaInfo

修訂1613 (tree)
時間2008-04-25 23:33:31
作者hamigaki

Log Message

supported to read UTF-8 for pax

Change Summary

差異

--- hamigaki/trunk/hamigaki/archivers/detail/tar_ex_header.hpp (revision 1612)
+++ hamigaki/trunk/hamigaki/archivers/detail/tar_ex_header.hpp (revision 1613)
@@ -1,6 +1,6 @@
11 // tar_ex_header.hpp: extended tar header
22
3-// Copyright Takeshi Mouri 2006, 2007.
3+// Copyright Takeshi Mouri 2006-2008.
44 // Distributed under the Boost Software License, Version 1.0.
55 // (See accompanying file LICENSE_1_0.txt or copy at
66 // http://www.boost.org/LICENSE_1_0.txt)
@@ -18,9 +18,13 @@
1818
1919 namespace hamigaki { namespace archivers { namespace detail {
2020
21+template<class Path>
2122 struct tar_ex_header
2223 {
23- boost::filesystem::path path;
24+ typedef Path path_type;
25+ typedef typename Path::string_type string_type;
26+
27+ Path path;
2428 boost::optional<boost::intmax_t> uid;
2529 boost::optional<boost::intmax_t> gid;
2630 boost::optional<boost::uintmax_t> file_size;
@@ -27,10 +31,10 @@
2731 boost::optional<filesystem::timestamp> modified_time;
2832 boost::optional<filesystem::timestamp> access_time;
2933 boost::optional<filesystem::timestamp> change_time;
30- boost::filesystem::path link_path;
31- std::string user_name;
32- std::string group_name;
33- std::string comment;
34+ Path link_path;
35+ string_type user_name;
36+ string_type group_name;
37+ string_type comment;
3438 };
3539
3640 } } } // End namespaces detail, archivers, hamigaki.
--- hamigaki/trunk/hamigaki/archivers/detail/tar_file_source_impl.hpp (revision 1612)
+++ hamigaki/trunk/hamigaki/archivers/detail/tar_file_source_impl.hpp (revision 1613)
@@ -20,6 +20,64 @@
2020
2121 namespace hamigaki { namespace archivers { namespace tar_detail {
2222
23+template<class String>
24+inline String from_tar_string(const std::string& s)
25+{
26+ return s;
27+}
28+
29+template<class String>
30+inline String from_pax_string(const std::string& s)
31+{
32+ return charset::to_code_page(charset::from_utf8(s), 0, "_");
33+}
34+
35+template<class Path>
36+inline tar::basic_header<Path> to_wide(const tar::header& head)
37+{
38+ return head;
39+}
40+
41+#if !defined(BOOST_FILESYSTEM_NARROW_ONLY)
42+template<>
43+inline std::wstring from_tar_string<std::wstring>(const std::string& s)
44+{
45+ return charset::from_code_page(s, 0);
46+}
47+
48+template<>
49+inline std::wstring from_pax_string<std::wstring>(const std::string& s)
50+{
51+ return charset::from_utf8(s);
52+}
53+
54+template<>
55+inline tar::wheader to_wide<boost::filesystem::wpath>(const tar::header& head)
56+{
57+ tar::wheader tmp;
58+
59+ tmp.path = tar_detail::from_tar_string<std::wstring>(head.path.string());
60+ tmp.permissions = head.permissions;
61+ tmp.uid = head.uid;
62+ tmp.gid = head.gid;
63+ tmp.file_size = head.file_size;
64+ tmp.modified_time = head.modified_time;
65+ tmp.access_time = head.access_time;
66+ tmp.change_time = head.change_time;
67+ tmp.type_flag = head.type_flag;
68+ tmp.link_path =
69+ tar_detail::from_tar_string<std::wstring>(head.link_path.string());
70+ tmp.format = head.format;
71+ tmp.user_name = charset::from_code_page(head.user_name, 0);
72+ tmp.group_name = charset::from_code_page(head.group_name, 0);
73+ tmp.dev_major = head.dev_major;
74+ tmp.dev_minor = head.dev_minor;
75+ tmp.comment = charset::from_code_page(head.comment, 0);
76+
77+ return tmp;
78+}
79+#endif
80+
2381 inline boost::uint32_t decode_nsec(const char* beg, const char* end)
2482 {
2583 std::string buf(beg, end);
@@ -65,13 +123,18 @@
65123
66124 namespace hamigaki { namespace archivers { namespace detail {
67125
68-template<class Source, class Path=boost::filesystem::path>
126+template<class Source, class Path>
69127 class basic_tar_file_source_impl
70128 {
71129 private:
72130 typedef detail::basic_ustar_file_source_impl<Source> ustar_type;
131+ typedef detail::tar_ex_header<Path> tar_ex_header;
73132
74133 public:
134+ typedef Path path_type;
135+ typedef typename Path::string_type string_type;
136+ typedef tar::basic_header<Path> header_type;
137+
75138 explicit basic_tar_file_source_impl(const Source& src)
76139 : ustar_(src), is_pax_(false)
77140 {
@@ -82,7 +145,7 @@
82145 if (!ustar_.next_entry())
83146 return false;
84147
85- header_ = ustar_.header();
148+ header_ = tar_detail::to_wide<Path>(ustar_.header());
86149
87150 if (header_.type_flag == tar::type_flag::global)
88151 {
@@ -91,7 +154,7 @@
91154 if (!ustar_.next_entry())
92155 throw boost::iostreams::detail::bad_read();
93156
94- header_ = ustar_.header();
157+ header_ = tar_detail::to_wide<Path>(ustar_.header());
95158 is_pax_ = true;
96159 }
97160
@@ -105,7 +168,7 @@
105168 if (!ustar_.next_entry())
106169 throw boost::iostreams::detail::bad_read();
107170
108- header_ = ustar_.header();
171+ header_ = tar_detail::to_wide<Path>(ustar_.header());
109172 is_pax = true;
110173 }
111174
@@ -119,7 +182,7 @@
119182 if (!ustar_.next_entry())
120183 throw boost::iostreams::detail::bad_read();
121184
122- header_ = ustar_.header();
185+ header_ = tar_detail::to_wide<Path>(ustar_.header());
123186 }
124187
125188 if (is_pax)
@@ -161,7 +224,7 @@
161224 return true;
162225 }
163226
164- tar::header header() const
227+ header_type header() const
165228 {
166229 return header_;
167230 }
@@ -173,11 +236,11 @@
173236
174237 private:
175238 ustar_type ustar_;
176- tar::header header_;
239+ header_type header_;
177240 tar_ex_header global_;
178241 bool is_pax_;
179242
180- boost::filesystem::path read_long_link()
243+ Path read_long_link()
181244 {
182245 std::string buf;
183246
@@ -188,7 +251,7 @@
188251 if (!buf.empty() && (*(buf.rbegin()) == '\0'))
189252 buf.resize(buf.size()-1);
190253
191- return buf;
254+ return tar_detail::from_tar_string<string_type>(buf);
192255 }
193256
194257 void read_extended_header(tar_ex_header& ext)
@@ -224,7 +287,7 @@
224287 const char* end = beg + (size - 1);
225288
226289 if (key == "path")
227- ext.path = beg;
290+ ext.path = tar_detail::from_pax_string<string_type>(beg);
228291 else if (key == "uid")
229292 ext.uid = hamigaki::from_dec<boost::intmax_t>(beg, end);
230293 else if (key == "gid")
@@ -238,13 +301,13 @@
238301 else if (key == "ctime")
239302 ext.change_time = tar_detail::to_timestamp(beg, end);
240303 else if (key == "linkpath")
241- ext.link_path = beg;
304+ ext.link_path = tar_detail::from_pax_string<string_type>(beg);
242305 else if (key == "uname")
243- ext.user_name = beg;
306+ ext.user_name = tar_detail::from_pax_string<string_type>(beg);
244307 else if (key == "gname")
245- ext.group_name = beg;
308+ ext.group_name = tar_detail::from_pax_string<string_type>(beg);
246309 else if (key == "comment")
247- ext.comment = beg;
310+ ext.comment = tar_detail::from_pax_string<string_type>(beg);
248311 }
249312 }
250313 };
--- hamigaki/trunk/hamigaki/archivers/tar_file.hpp (revision 1612)
+++ hamigaki/trunk/hamigaki/archivers/tar_file.hpp (revision 1613)
@@ -17,11 +17,11 @@
1717
1818 namespace hamigaki { namespace archivers {
1919
20-template<class Source>
20+template<class Source, class Path=boost::filesystem::path>
2121 class basic_tar_file_source
2222 {
2323 private:
24- typedef detail::basic_tar_file_source_impl<Source> impl_type;
24+ typedef detail::basic_tar_file_source_impl<Source,Path> impl_type;
2525
2626 public:
2727 typedef char char_type;
@@ -31,7 +31,8 @@
3131 , boost::iostreams::device_tag
3232 {};
3333
34- typedef tar::header header_type;
34+ typedef Path path_type;
35+ typedef tar::basic_header<Path> header_type;
3536
3637 explicit basic_tar_file_source(const Source& src)
3738 : pimpl_(new impl_type(src))
@@ -43,7 +44,7 @@
4344 return pimpl_->next_entry();
4445 }
4546
46- tar::header header() const
47+ header_type header() const
4748 {
4849 return pimpl_->header();
4950 }
@@ -67,6 +68,7 @@
6768 , boost::iostreams::device_tag
6869 {};
6970
71+ typedef boost::filesystem::path path_type;
7072 typedef tar::header header_type;
7173
7274 explicit tar_file_source(const std::string& filename)
@@ -195,6 +197,43 @@
195197 };
196198
197199 #if !defined(BOOST_FILESYSTEM_NARROW_ONLY)
200+class wtar_file_source
201+{
202+public:
203+ typedef char char_type;
204+
205+ struct category
206+ : boost::iostreams::input
207+ , boost::iostreams::device_tag
208+ {};
209+
210+ typedef boost::filesystem::wpath path_type;
211+ typedef tar::wheader header_type;
212+
213+ explicit wtar_file_source(const std::string& filename)
214+ : impl_(iostreams::file_source(filename, BOOST_IOS::binary))
215+ {
216+ }
217+
218+ bool next_entry()
219+ {
220+ return impl_.next_entry();
221+ }
222+
223+ tar::wheader header() const
224+ {
225+ return impl_.header();
226+ }
227+
228+ std::streamsize read(char* s, std::streamsize n)
229+ {
230+ return impl_.read(s, n);
231+ }
232+
233+private:
234+ basic_tar_file_source<iostreams::file_source,path_type> impl_;
235+};
236+
198237 class wtar_file_sink
199238 {
200239 public:
Show on old repository browser