1 //===-- Implementation of fopencookie -------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "src/stdio/fopencookie.h"
10 #include "src/__support/CPP/new.h"
11 #include "src/__support/File/file.h"
17 namespace __llvm_libc
{
21 class CookieFile
: public __llvm_libc::File
{
23 cookie_io_functions_t ops
;
25 static FileIOResult
cookie_write(File
*f
, const void *data
, size_t size
);
26 static FileIOResult
cookie_read(File
*f
, void *data
, size_t size
);
27 static ErrorOr
<long> cookie_seek(File
*f
, long offset
, int whence
);
28 static int cookie_close(File
*f
);
29 static int cookie_flush(File
*);
32 CookieFile(void *c
, cookie_io_functions_t cops
, uint8_t *buffer
,
33 size_t bufsize
, File::ModeFlags mode
)
34 : File(&cookie_write
, &cookie_read
, &CookieFile::cookie_seek
,
35 &cookie_close
, &cookie_flush
, &cleanup_file
<CookieFile
>, buffer
,
36 bufsize
, 0 /* default buffering mode */,
37 true /* File owns buffer */, mode
),
38 cookie(c
), ops(cops
) {}
41 FileIOResult
CookieFile::cookie_write(File
*f
, const void *data
, size_t size
) {
42 auto cookie_file
= reinterpret_cast<CookieFile
*>(f
);
43 if (cookie_file
->ops
.write
== nullptr)
45 return cookie_file
->ops
.write(cookie_file
->cookie
,
46 reinterpret_cast<const char *>(data
), size
);
49 FileIOResult
CookieFile::cookie_read(File
*f
, void *data
, size_t size
) {
50 auto cookie_file
= reinterpret_cast<CookieFile
*>(f
);
51 if (cookie_file
->ops
.read
== nullptr)
53 return cookie_file
->ops
.read(cookie_file
->cookie
,
54 reinterpret_cast<char *>(data
), size
);
57 ErrorOr
<long> CookieFile::cookie_seek(File
*f
, long offset
, int whence
) {
58 auto cookie_file
= reinterpret_cast<CookieFile
*>(f
);
59 if (cookie_file
->ops
.seek
== nullptr) {
62 off64_t offset64
= offset
;
63 int result
= cookie_file
->ops
.seek(cookie_file
->cookie
, &offset64
, whence
);
70 int CookieFile::cookie_close(File
*f
) {
71 auto cookie_file
= reinterpret_cast<CookieFile
*>(f
);
72 if (cookie_file
->ops
.close
== nullptr)
74 return cookie_file
->ops
.close(cookie_file
->cookie
);
77 int CookieFile::cookie_flush(File
*) { return 0; }
79 } // anonymous namespace
81 LLVM_LIBC_FUNCTION(::FILE *, fopencookie
,
82 (void *cookie
, const char *mode
,
83 cookie_io_functions_t ops
)) {
87 buffer
= new (ac
) uint8_t[File::DEFAULT_BUFFER_SIZE
];
92 auto *file
= new (ac
) CookieFile(
93 cookie
, ops
, buffer
, File::DEFAULT_BUFFER_SIZE
, File::mode_flags(mode
));
96 return reinterpret_cast<::FILE *>(file
);
99 } // namespace __llvm_libc