summaryrefslogtreecommitdiffstats
path: root/pdf/pdfium/pdfium_api_string_buffer_adapter.h
blob: 7b45cbe36a800f63a2b7acd5ed0600dc26509064 (plain)
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
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PDF_PDFIUM_PDFIUM_API_STRING_BUFFER_ADAPTER_H_
#define PDF_PDFIUM_PDFIUM_API_STRING_BUFFER_ADAPTER_H_

#include <stddef.h>

#include "base/macros.h"
#include "base/numerics/safe_math.h"

namespace chrome_pdf {

// Helper to deal with the fact that many PDFium APIs write the null-terminator
// into string buffers that are passed to them, but the PDF plugin likes to pass
// in std::strings / base::string16s, where one should not count on the internal
// string buffers to be null-terminated.

template <class StringType>
class PDFiumAPIStringBufferAdapter {
 public:
  // |str| is the string to write into.
  // |expected_size| is the number of characters the PDFium API will write,
  // including the null-terminator. It should be at least 1.
  // |check_expected_size| whether to check the actual number of characters
  // written into |str| against |expected_size| when calling Close().
  PDFiumAPIStringBufferAdapter(StringType* str,
                               size_t expected_size,
                               bool check_expected_size);
  ~PDFiumAPIStringBufferAdapter();

  // Returns a pointer to |str_|'s buffer. The buffer's size is large enough to
  // hold |expected_size_| + 1 characters, so the PDFium API that uses the
  // pointer has space to write a null-terminator.
  void* GetData();

  // Resizes |str_| to |actual_size| - 1 characters, thereby removing the extra
  // null-terminator. This must be called prior to the adapter's destruction.
  // The pointer returned by GetData() should be considered invalid.
  void Close(size_t actual_size);

  template <typename IntType>
  void Close(IntType actual_size) {
    base::CheckedNumeric<size_t> unsigned_size = actual_size;
    Close(unsigned_size.ValueOrDie());
  }

 private:
  StringType* const str_;
  void* const data_;
  const size_t expected_size_;
  const bool check_expected_size_;
  bool is_closed_;

  DISALLOW_COPY_AND_ASSIGN(PDFiumAPIStringBufferAdapter);
};

// Helper to deal with the fact that many PDFium APIs write the null-terminator
// into string buffers that are passed to them, but the PDF plugin likes to pass
// in std::strings / base::string16s, where one should not count on the internal
// string buffers to be null-terminated. This version is suitable for APIs that
// work in terms of number of bytes instead of the number of characters.
template <class StringType>
class PDFiumAPIStringBufferSizeInBytesAdapter {
 public:
  // |str| is the string to write into.
  // |expected_size| is the number of bytes the PDFium API will write,
  // including the null-terminator. It should be at least the size of a
  // character in bytes.
  // |check_expected_size| whether to check the actual number of bytes
  // written into |str| against |expected_size| when calling Close().
  PDFiumAPIStringBufferSizeInBytesAdapter(StringType* str,
                                          size_t expected_size,
                                          bool check_expected_size);
  ~PDFiumAPIStringBufferSizeInBytesAdapter();

  // Returns a pointer to |str_|'s buffer. The buffer's size is large enough to
  // hold |expected_size_| + sizeof(StringType::value_type) bytes, so the PDFium
  // API that uses the pointer has space to write a null-terminator.
  void* GetData();

  // Resizes |str_| to |actual_size| - sizeof(StringType::value_type) bytes,
  // thereby removing the extra null-terminator. This must be called prior to
  // the adapter's destruction. The pointer returned by GetData() should be
  // considered invalid.
  void Close(size_t actual_size);

  template <typename IntType>
  void Close(IntType actual_size) {
    base::CheckedNumeric<size_t> unsigned_size = actual_size;
    Close(unsigned_size.ValueOrDie());
  }

 private:
  PDFiumAPIStringBufferAdapter<StringType> adapter_;
};

}  // namespace chrome_pdf

#endif  // PDF_PDFIUM_PDFIUM_API_STRING_BUFFER_ADAPTER_H_