File: writer.cpp

package info (click to toggle)
nsis 3.06.1-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 12,468 kB
  • sloc: cpp: 37,707; ansic: 26,911; python: 1,344; asm: 712; xml: 409; pascal: 215; makefile: 207; javascript: 67
file content (139 lines) | stat: -rwxr-xr-x 3,227 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
/*
 * writer.cpp
 * 
 * This file is a part of NSIS.
 * 
 * Copyright (C) 1999-2020 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
 */

#include "exehead/config.h"
#include "writer.h"
#include "growbuf.h"
#include "util.h"
#include <string.h>
#include <stdlib.h>
#include <stdexcept>
#include "tchar.h"

void writer_sink::write_byte(const unsigned char b)
{
  write_data(&b, 1);
}

void writer_sink::write_short(const short s)
{
  short fs = FIX_ENDIAN_INT16(s);
  write_data(&fs, sizeof(short));
}

void writer_sink::write_int(const int i)
{
  int fi = FIX_ENDIAN_INT32(i);
  write_data(&fi, sizeof(int));
}
void writer_sink::write_int64(const INT64 i)
{
  INT64 fi = FIX_ENDIAN_INT64(i);
  write_data(&fi, sizeof(INT64));
}

void writer_sink::write_int_array(const int i[], const size_t len)
{
  for (size_t l = 0; l < len; l++)
  {
    write_int(i[l]);
  }
}

// size in this case is the length of the string to write.
void writer_sink::write_string(const TCHAR *s, size_t size)
{
#ifdef _UNICODE
  if (m_ti.is_unicode())
  {
    bool strEnd = false;
    TCHAR ch = L'\0';
    for (; size ; size--)
    {
      if (!strEnd)
      {
        ch = *s++;
        if (ch == _T('\0'))
          strEnd = true;
      }
      write_short(ch);
    }
  }
  else
  {
    char *wb = new char[size];
    memset(wb, 0, size);
    WideCharToMultiByte(CP_ACP, 0, s, -1, wb, (int)size, NULL, NULL);
    write_data(wb, size);
    delete [] wb;
 }
#else
  //TODO: Why does this allocate memory? It could just write the string and a manual zero character?
  char *wb = new char[size];
  memset(wb, 0, size);
  strncpy(wb, s, size);
  write_data(wb, size);
  delete [] wb;
#endif
}

void writer_sink::write_growbuf(const IGrowBuf *b)
{
  write_data(b->get(), b->getlen());
}

namespace hlp {
  template<class T> static inline bool issigned() { return T(-1) < T(0); }
  template<class T> static inline bool issigned(const T&t) { return issigned<T>(); }
}

void growbuf_writer_sink::write_data(const void *data, const size_t size)
{
  // TODO: Replace all of this with a simple call when GrowBuf is changed to use size_t
  if (sizeof(size) == sizeof(sink_type::size_type) && hlp::issigned(size) == hlp::issigned<sink_type::size_type>())
  {
    m_buf->add(data, truncate_cast(sink_type::size_type, size));
  }
  else
  {
    size_t left = size;
    sink_type::size_type cbmaxadd = INT_MAX, cb;
    for (char *p = (char *) data; left; p += cb, left -= cb)
    {
      cb = left >= (size_t) cbmaxadd ? cbmaxadd : (sink_type::size_type) left;
      m_buf->add(p, cb);
    }
  }
}

void file_writer_sink::write_data(const void *data, const size_t size)
{
  if (fwrite(data, 1, size, m_fp) != size)
  {
    throw std::runtime_error("error writing");
  }
}

#ifdef NSIS_CONFIG_CRC_SUPPORT
#include "crc32.h"

void crc_writer_sink::write_data(const void *data, const size_t size)
{
  *m_crc = CRC32(*m_crc, (const unsigned char *) data, size);
}
#endif