source: XMLIO_V2/external/src/POCO/Foundation/FileStream_WIN32.hpp @ 80

Last change on this file since 80 was 80, checked in by ymipsl, 14 years ago

ajout lib externe

File size: 5.6 KB
Line 
1//
2// FileStream.cpp
3//
4// $Id: //poco/1.3/Foundation/src/FileStream_WIN32.cpp#5 $
5//
6// Library: Foundation
7// Package: Streams
8// Module:  FileStream
9//
10// Copyright (c) 2007, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// Permission is hereby granted, free of charge, to any person or organization
14// obtaining a copy of the software and accompanying documentation covered by
15// this license (the "Software") to use, reproduce, display, distribute,
16// execute, and transmit the Software, and to prepare derivative works of the
17// Software, and to permit third-parties to whom the Software is furnished to
18// do so, all subject to the following:
19//
20// The copyright notices in the Software and this entire statement, including
21// the above license grant, this restriction and the following disclaimer,
22// must be included in all copies of the Software, in whole or in part, and
23// all derivative works of the Software, unless such copies or derivative
24// works are solely in the form of machine-executable object code generated by
25// a source language processor.
26//
27// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33// DEALINGS IN THE SOFTWARE.
34//
35
36
37#include <Poco/FileStream.h>
38#include <Poco/File.h>
39#include <Poco/Exception.h>
40#if defined (POCO_WIN32_UTF8)
41#include <Poco/UnicodeConverter.h>
42#endif
43
44
45namespace Poco {
46
47
48FileStreamBuf::FileStreamBuf():
49        BufferedBidirectionalStreamBuf(BUFFER_SIZE, std::ios::in | std::ios::out),
50        _handle(INVALID_HANDLE_VALUE),
51        _pos(0)
52{
53}
54
55
56FileStreamBuf::~FileStreamBuf()
57{
58        close();
59}
60
61
62void FileStreamBuf::open(const std::string& path, std::ios::openmode mode)
63{
64        poco_assert (_handle == INVALID_HANDLE_VALUE);
65
66        _path = path;
67        setMode(mode);
68
69        DWORD access = 0;
70        if (mode & std::ios::in)
71                access |= GENERIC_READ;
72        if (mode & std::ios::out)
73                access |= GENERIC_WRITE;
74
75        DWORD shareMode = FILE_SHARE_READ;
76        if (!(mode & std::ios::out))
77                shareMode |= FILE_SHARE_WRITE;
78               
79        DWORD creationDisp = OPEN_EXISTING;
80        if (mode & std::ios::trunc)
81                creationDisp = CREATE_ALWAYS;
82        else if (mode & std::ios::out)
83                creationDisp = OPEN_ALWAYS;
84
85        DWORD flags = FILE_ATTRIBUTE_NORMAL;
86       
87#if defined (POCO_WIN32_UTF8)
88        std::wstring utf16Path;
89        UnicodeConverter::toUTF16(path, utf16Path);
90        _handle = CreateFileW(utf16Path.c_str(), access, shareMode, NULL, creationDisp, flags, NULL);
91#else
92        _handle = CreateFileA(path.c_str(), access, shareMode, NULL, creationDisp, flags, NULL);
93#endif
94
95        if (_handle == INVALID_HANDLE_VALUE)
96                File::handleLastError(_path);
97               
98        if ((mode & std::ios::ate) || (mode & std::ios::app))
99                seekoff(0, std::ios::end, mode);
100}
101
102
103int FileStreamBuf::readFromDevice(char* buffer, std::streamsize length)
104{
105        if (INVALID_HANDLE_VALUE == _handle || !(getMode() & std::ios::in))
106                return -1;
107
108        if (getMode() & std::ios::out)
109                sync();
110       
111        DWORD bytesRead(0);
112        BOOL rc = ReadFile(_handle, buffer, static_cast<DWORD>(length), &bytesRead, NULL);
113        if (rc == 0)
114                File::handleLastError(_path);
115
116        _pos += bytesRead;
117
118        return static_cast<int>(bytesRead);
119}
120
121
122int FileStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
123{
124        if (INVALID_HANDLE_VALUE == _handle || !(getMode() & std::ios::out))
125                return -1;
126
127        if (getMode() & std::ios::app)
128        {
129                LARGE_INTEGER li;
130                li.QuadPart = 0;
131                li.LowPart  = SetFilePointer(_handle, li.LowPart, &li.HighPart, FILE_END);
132                if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
133                        File::handleLastError(_path);
134                _pos = li.QuadPart;
135        }
136
137        DWORD bytesWritten(0);
138        BOOL rc = WriteFile(_handle, buffer, static_cast<DWORD>(length), &bytesWritten, NULL);
139        if (rc == 0)
140                File::handleLastError(_path);
141               
142        _pos += bytesWritten;
143
144        return static_cast<int>(bytesWritten);
145}
146
147
148bool FileStreamBuf::close()
149{
150        bool success = true;
151        if (_handle != INVALID_HANDLE_VALUE)
152        {
153                try
154                {
155                        if (getMode() & std::ios::out)
156                                sync();
157                }
158                catch (...)
159                {
160                        success = false;
161                }
162                CloseHandle(_handle);
163                _handle = INVALID_HANDLE_VALUE;
164        }
165        return success;
166}
167
168
169std::streampos FileStreamBuf::seekoff(std::streamoff off, std::ios::seekdir dir, std::ios::openmode mode)
170{
171        if (INVALID_HANDLE_VALUE == _handle || !(getMode() & mode))
172                return -1;
173       
174        if (getMode() & std::ios::out)
175                sync();
176
177        std::streamoff adj;
178        if (mode & std::ios::in)
179                adj = static_cast<std::streamoff>(egptr() - gptr());
180        else
181                adj = 0;
182
183        resetBuffers();
184
185        DWORD offset = FILE_BEGIN;
186        if (dir == std::ios::cur)
187        {
188                offset = FILE_CURRENT;
189                off -= adj;
190        }
191        else if (dir == std::ios::end)
192        {
193                offset = FILE_END;
194        }
195       
196        LARGE_INTEGER li;
197        li.QuadPart = off;
198        li.LowPart  = SetFilePointer(_handle, li.LowPart, &li.HighPart, offset);
199
200        if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
201                File::handleLastError(_path);
202        _pos = li.QuadPart;
203        return std::streampos(static_cast<std::streamoff>(_pos));
204}
205
206
207std::streampos FileStreamBuf::seekpos(std::streampos pos, std::ios::openmode mode)
208{
209        if (INVALID_HANDLE_VALUE == _handle || !(getMode() & mode))
210                return -1;
211
212        if (getMode() & std::ios::out)
213                sync();
214
215        resetBuffers();
216
217        LARGE_INTEGER li;
218        li.QuadPart = pos;
219        li.LowPart  = SetFilePointer(_handle, li.LowPart, &li.HighPart, FILE_BEGIN);
220
221        if (li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
222                File::handleLastError(_path);
223        _pos = li.QuadPart;
224        return std::streampos(static_cast<std::streamoff>(_pos));
225}
226
227
228} // namespace Poco
Note: See TracBrowser for help on using the repository browser.