u_stream_wd.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  *
00026  **************************************************************************/
00027 
00033 #include "pipe/p_config.h"
00034 
00035 #if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
00036 
00037 #include <windows.h>
00038 #include <winddi.h>
00039 
00040 #include "util/u_memory.h"
00041 #include "util/u_string.h"
00042 
00043 #include "u_stream.h"
00044 
00045 
00046 #define MAP_FILE_SIZE (4*1024*1024)
00047 
00048 
00049 struct util_stream 
00050 {
00051    char filename[MAX_PATH + 1];
00052    WCHAR wFileName[MAX_PATH + 1];
00053    boolean growable;
00054    size_t map_size;
00055    ULONG_PTR iFile;
00056    char *pMap;
00057    size_t written;
00058    unsigned suffix;
00059 };
00060 
00061 
00062 static INLINE boolean
00063 util_stream_map(struct util_stream *stream)
00064 {
00065    ULONG BytesInUnicodeString;
00066    static char filename[MAX_PATH + 1];
00067    unsigned filename_len;
00068 
00069    if(stream->growable)
00070       filename_len = util_snprintf(filename,
00071                                    sizeof(filename),
00072                                    "%s.%04x",
00073                                    stream->filename,
00074                                    stream->suffix++);
00075    else
00076       filename_len = util_snprintf(filename,
00077                                    sizeof(filename),
00078                                    "%s",
00079                                    stream->filename);
00080 
00081    EngMultiByteToUnicodeN(
00082          stream->wFileName,
00083          sizeof(stream->wFileName),
00084          &BytesInUnicodeString,
00085          filename,
00086          filename_len);
00087    
00088    stream->pMap = EngMapFile(stream->wFileName, stream->map_size, &stream->iFile);
00089    if(!stream->pMap)
00090       return FALSE;
00091    
00092    memset(stream->pMap, 0, stream->map_size);
00093    stream->written = 0;
00094    
00095    return TRUE;
00096 }
00097 
00098 
00099 static INLINE void
00100 util_stream_unmap(struct util_stream *stream)
00101 {
00102    EngUnmapFile(stream->iFile);
00103    if(stream->written < stream->map_size) {
00104       /* Truncate file size */
00105       stream->pMap = EngMapFile(stream->wFileName, stream->written, &stream->iFile);
00106       if(stream->pMap)
00107          EngUnmapFile(stream->iFile);
00108    }
00109    
00110    stream->pMap = NULL;
00111 }
00112 
00113 
00114 static INLINE void
00115 util_stream_full_qualified_filename(char *dst, size_t size, const char *src)
00116 {
00117    boolean need_drive, need_root;
00118    
00119    if((('A' <= src[0] && src[0] <= 'Z') || ('a' <= src[0] && src[0] <= 'z')) && src[1] == ':') {
00120       need_drive = FALSE;
00121       need_root = src[2] == '\\' ? FALSE : TRUE;
00122    }
00123    else {
00124       need_drive = TRUE;
00125       need_root = src[0] == '\\' ? FALSE : TRUE;
00126    }
00127    
00128    util_snprintf(dst, size, 
00129                  "\\??\\%s%s%s",
00130                  need_drive ? "C:" : "",
00131                  need_root ? "\\" : "",
00132                  src);
00133 }
00134 
00135 
00136 struct util_stream *
00137 util_stream_create(const char *filename, size_t max_size)
00138 {
00139    struct util_stream *stream;
00140    
00141    stream = CALLOC_STRUCT(util_stream);
00142    if(!stream)
00143       goto error1;
00144    
00145    util_stream_full_qualified_filename(stream->filename,
00146                                        sizeof(stream->filename),
00147                                        filename);
00148    
00149    if(max_size) {
00150       stream->growable = FALSE;
00151       stream->map_size = max_size;
00152    }
00153    else {
00154       stream->growable = TRUE;
00155       stream->map_size = MAP_FILE_SIZE;
00156    }
00157    
00158    if(!util_stream_map(stream))
00159       goto error2;
00160    
00161    return stream;
00162    
00163 error2:
00164    FREE(stream);
00165 error1:
00166    return NULL;
00167 }
00168 
00169 
00170 static INLINE void
00171 util_stream_copy(struct util_stream *stream, const char *data, size_t size)
00172 {
00173    assert(stream->written + size <= stream->map_size);
00174    memcpy(stream->pMap + stream->written, data, size);
00175    stream->written += size;
00176 }
00177 
00178 
00179 boolean
00180 util_stream_write(struct util_stream *stream, const void *data, size_t size)
00181 {
00182    if(!stream)
00183       return FALSE;
00184    
00185    if(!stream->pMap)
00186       return FALSE;
00187    
00188    while(stream->written + size > stream->map_size) {
00189       size_t step = stream->map_size - stream->written;
00190       util_stream_copy(stream, data, step);
00191       data = (const char *)data + step;
00192       size -= step;
00193       
00194       util_stream_unmap(stream);
00195       if(!stream->growable || !util_stream_map(stream))
00196          return FALSE;
00197    }
00198 
00199    util_stream_copy(stream, data, size);
00200    
00201    return TRUE;
00202 }
00203 
00204 
00205 void
00206 util_stream_flush(struct util_stream *stream) 
00207 {
00208    (void)stream;
00209 }
00210 
00211 
00212 void
00213 util_stream_close(struct util_stream *stream) 
00214 {
00215    if(!stream)
00216       return;
00217    
00218    util_stream_unmap(stream);
00219 
00220    FREE(stream);
00221 }
00222 
00223 
00224 #endif

Generated on Tue Sep 29 06:25:15 2009 for Gallium3D by  doxygen 1.5.4