File: mmap.h

package info (click to toggle)
nsis 3.08-3%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 12,952 kB
  • sloc: cpp: 38,735; ansic: 27,199; python: 1,352; asm: 712; xml: 409; pascal: 215; makefile: 211; javascript: 67
file content (244 lines) | stat: -rwxr-xr-x 6,817 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*
 * mmap.h
 * 
 * This file is a part of NSIS.
 * 
 * Copyright (C) 1999-2021 Nullsoft and Contributors
 * 
 * Licensed under the zlib/libpng license (the "License");
 * you may not use this file except in compliance with the License.
 * 
 * Licence details can be found in the file COPYING.
 * 
 * This software is provided 'as-is', without any express or implied
 * warranty.
 *
 * Unicode support by Jim Park -- 08/13/2007
 */

#ifndef __MMAP_H_
#define __MMAP_H_

#include "Platform.h"
#include "growbuf.h"

#ifndef _WIN32
#include <cstdio> // for FILE*
#include <fstream> // (some systems have FILE* in here)
#endif

class IMMap
{
  public:
    virtual void resize(int newlen)=0;
    virtual int  getsize() const=0;
    virtual void *get(int offset, int size) const=0;
    virtual void *get(int offset, int *size) const=0;
    virtual void *getmore(int offset, int size) const=0;
    virtual void release()=0;
    virtual void release(void *view, int size)=0;
    virtual void clear()=0;
    virtual void setro(BOOL bRO)=0;
    virtual void flush(int num)=0;
    virtual ~IMMap() {}
};

class MMapFile : public IMMap
{
  private: // don't copy instances
    MMapFile(const MMapFile&);
    void operator=(const MMapFile&);

  public:
    MMapFile();
    virtual ~MMapFile();

    /**
     * Closes the memory map and the file handle.
     */
    void clear();

    /**
     * Set read-only.
     * @param bRO Boolean value to set read-only.
     */
    void setro(BOOL bRO);

    /**
     * Creates the memory mapping object of the file with a mapping size.
     *
     * @param hFile The handle to the opened file.
     * @param dwSize The size of the memory mapped object.  You cannot set
     * this value to zero like with CreateFileMapping() because it will
     * immediately return.  Most likely, you want to set it to the size
     * of the file unless you want to only map a part of the file on
     * purpose.
     * @return Returns 1 on success, 0 on failure.
     */
#ifdef _WIN32
    int  setfile(HANDLE hFile, DWORD dwSize);
#else
    int  setfile(int hFile, DWORD dwSize);
#endif

   /**
    * Resize the memory mapping of the file.  Used when the filesize has
    * changed.  When setfile has not been called previously, then it will
    * create a temporary file and use it to create a memory map.  This is
    * what's used by MMapBuf to create a Memory Mapped Buffer.
    * 
    * @param newsize The new size of the file.  Limited to 32-bits.
    */
    void resize(int newsize);

    /**
     * Size of the memory map object.
     */
    int  getsize() const;

    /**
     * Set the memory map to a particular offset in the file and return the
     * memory mapped pointer to it.  Internally it may have to align to a
     * certain page size.
     * 
     * @param offset The offset from the beginning of the file.
     * @param size The size of the memory map window.
     */
    void *get(int offset, int size) const;

    /**
     * Set the memory map to a particular offset in the file and return the
     * memory mapped pointer to it.  Internally it may have to align to a
     * certain page size.
     * 
     * @param offset The offset from the beginning of the file.
     * @param sizep [in/out] The size of the memory map window.  (In non-Win32
     * systems, the new size is written back out.)
     */
    void *get(int offset, int *sizep) const;

    /**
     * This function sets memory map and just hands you the pointer and
     * it expects you to manage it.  So you need to call release(pView, size)
     * yourself or you will leak memory.
     *
     * Warning: This breaks encapsulation.  The user should probably just
     * create a new map.
     *
     * @param offset The offset from the beginning of the file.
     * @param size The size of the memory map window.
     */
    void *getmore(int offset, int size) const;

    /**
     * Releases the memory map currently being used.  Calls UnMapViewOfFile().
     */
    void release();

    /**
     * Releases the memory map pointed to by pView.  In Win32 systems
     * eventually calls UnmapViewOfFile().  Interestingly, the function
     * tries to align the pointer value back to the beginning of the
     * paged memory which is necessary because of the way get() works.
     *
     * This looks like it should only be used in conjunction with
     * getmore().  Otherwise, just call release().
     *
     * @param pView The pointer to somewhere in a MemMapped object.
     * @param size The size of the object.  Used only in non-Win32 systems.
     */
    void release(void *pView, int size);

    /**
     * Flushes the contents of the current memory map to disk.  Set size to 0
     * if you want to flush everything.
     *
     * @param num The number of bytes to flush.  0 for everything.
     */
    void flush(int num);

  private:
#ifdef _WIN32
    HANDLE m_hFile, m_hFileMap;
#else
    FILE *m_hFile;
    int m_hFileDesc;
    mutable int m_iMappedSize;
#endif
    mutable void *m_pView;
    mutable int m_iSize;
    BOOL m_bReadOnly;
    BOOL m_bTempHandle;

    static int m_iAllocationGranularity;
};

class MMapFake : public IMMap
{
  private: // don't copy instances
    MMapFake(const MMapFake&);
    void operator=(const MMapFake&);
  public:
    MMapFake();

    void set(const char *pMem, int iSize);
    int  getsize() const;
    void *get(int offset, int size) const;
    void *get(int offset, int *size) const;
    void *getmore(int offset, int size) const;

    void resize(int n);
    void release();
    void release(void *p, int size);
    void clear();
    void setro(BOOL b);
    void flush(BOOL b);

  private:
    const char *m_pMem;
    int m_iSize;
};

/**
 * A data structure that can be used to create a scratch file to do
 * work in.  When it's smaller than 16mb, it's all in memory using the
 * GrowBuf class.  But when it gets biggered than 16mb, then it uses
 * the MMapFile class to create a memory map to a temporary file and
 * then uses it.  This reduces memory overhead of the installer.
 *
 * This is sort of our virtual memory manager.
 */
class MMapBuf : public IGrowBuf, public IMMap
{
  private: // don't copy instances
    MMapBuf(const MMapBuf&);
    void operator=(const MMapBuf&);

  public:
    MMapBuf();
    virtual ~MMapBuf();

    int  add(const void *data, int len);
    void setro(BOOL bRO);
    void resize(int newlen);
    int  getsize() const;
    int  getlen() const;
    void *get() const;
    void *get(int offset, int *sizep) const;
    void *get(int offset, int size) const;
    void *getmore(int offset, int size) const;
    void release();
    void release(void *pView, int size);
    void clear();
    void flush(int num);

  private:
    GrowBuf m_gb;
    MMapFile m_fm;

    int m_gb_u;
    int m_alloc, m_used;
};

#endif//__MMAP_H_