 |
Exiv2
|
27 #include "exiv2lib_export.h"
37 #ifndef EXV_XPATH_MEMIO
38 #define EXV_XPATH_MEMIO 0
83 virtual int open() = 0;
92 virtual int close() = 0;
102 virtual long write(
const byte* data,
long wcount) = 0;
112 virtual long write(
BasicIo& src) = 0;
120 virtual int putb(
byte data) = 0;
131 virtual DataBuf read(
long rcount) = 0;
144 virtual long read(
byte* buf,
long rcount) = 0;
151 virtual int getb() = 0;
165 virtual void transfer(
BasicIo& src) = 0;
174 #if defined(_MSC_VER)
175 virtual int seek(int64_t offset, Position pos) = 0;
177 virtual int seek(
long offset, Position pos) = 0;
189 virtual byte* mmap(
bool isWriteable =
false) =0;
196 virtual int munmap() =0;
207 virtual long tell()
const = 0;
213 virtual size_t size()
const = 0;
215 virtual bool isopen()
const = 0;
217 virtual int error()
const = 0;
219 virtual bool eof()
const = 0;
226 #ifdef EXV_UNICODE_PATH
231 virtual std::wstring wpath()
const =0;
253 BasicIo() : bigBlock_(NULL) {};
276 void close() {
if (bio_.isopen()) bio_.close(); }
307 #ifdef EXV_UNICODE_PATH
313 FileIo(
const std::wstring& wpath);
359 virtual long write(
const byte* data,
long wcount);
369 virtual long write(
BasicIo& src);
377 virtual int putb(
byte data);
388 virtual DataBuf read(
long rcount);
401 virtual long read(
byte* buf,
long rcount);
427 virtual void transfer(
BasicIo& src);
436 #if defined(_MSC_VER)
437 virtual int seek(int64_t offset,
Position pos);
439 virtual int seek(
long offset,
Position pos);
452 virtual byte* mmap(
bool isWriteable =
false);
460 virtual int munmap();
465 #ifdef EXV_UNICODE_PATH
471 virtual void setPath(
const std::wstring& wpath);
481 virtual long tell()
const;
488 virtual size_t size()
const;
490 virtual bool isopen()
const;
492 virtual int error()
const;
494 virtual bool eof()
const;
497 #ifdef EXV_UNICODE_PATH
502 virtual std::wstring wpath()
const;
512 virtual void populateFakeData();
524 std::auto_ptr<Impl> p_;
554 MemIo(
const byte* data,
long size);
583 virtual long write(
const byte* data,
long wcount);
594 virtual long write(
BasicIo& src);
602 virtual int putb(
byte data);
613 virtual DataBuf read(
long rcount);
626 virtual long read(
byte* buf,
long rcount);
649 virtual void transfer(
BasicIo& src);
658 #if defined(_MSC_VER)
659 virtual int seek(int64_t offset,
Position pos);
661 virtual int seek(
long offset,
Position pos);
671 virtual byte* mmap(
bool =
false);
672 virtual int munmap();
681 virtual long tell()
const;
687 virtual size_t size()
const;
689 virtual bool isopen()
const;
691 virtual int error()
const;
693 virtual bool eof()
const;
696 #ifdef EXV_UNICODE_PATH
701 virtual std::wstring wpath()
const;
711 virtual void populateFakeData();
724 std::auto_ptr<Impl> p_;
738 #ifdef EXV_UNICODE_PATH
744 XPathIo(
const std::wstring& wpath);
778 #ifdef EXV_UNICODE_PATH
784 XPathIo(
const std::wstring& wOrgPathpath);
796 virtual void transfer(
BasicIo& src);
809 #ifdef EXV_UNICODE_PATH
815 static std::string writeDataToFile(
const std::wstring& wOrgPath);
861 virtual long write(
const byte* data,
long wcount);
876 virtual long write(
BasicIo& src);
882 virtual int putb(
byte data);
895 virtual DataBuf read(
long rcount);
910 virtual long read(
byte* buf,
long rcount);
934 virtual void transfer(
BasicIo& src);
943 #if defined(_MSC_VER)
944 virtual int seek(int64_t offset,
Position pos);
946 virtual int seek(
long offset,
Position pos);
952 virtual byte* mmap(
bool =
false);
957 virtual int munmap();
965 virtual long tell()
const;
971 virtual size_t size()
const;
973 virtual bool isopen()
const;
975 virtual int error()
const;
977 virtual bool eof()
const;
980 #ifdef EXV_UNICODE_PATH
985 virtual std::wstring wpath()
const;
995 virtual void populateFakeData();
1029 #ifdef EXV_UNICODE_PATH
1035 HttpIo(
const std::wstring& wurl,
size_t blockSize = 1024);
1059 class EXIV2API CurlIo :
public RemoteIo {
1072 CurlIo(
const std::string& url,
size_t blockSize = 0);
1073 #ifdef EXV_UNICODE_PATH
1079 CurlIo(
const std::wstring& wurl,
size_t blockSize = 0);
1086 long write(
const byte* data,
long wcount);
1096 CurlIo(CurlIo& rhs);
1098 CurlIo& operator=(
const CurlIo& rhs);
1115 class EXIV2LIB_DEPRECATED_EXPORT SshIo :
public RemoteIo {
1128 SshIo(
const std::string& url,
size_t blockSize = 1024);
1129 #ifdef EXV_UNICODE_PATH
1135 SshIo(
const std::wstring& wurl,
size_t blockSize = 1024);
1143 SshIo& operator=(
const SshIo& rhs);
1164 #ifdef EXV_UNICODE_PATH
1169 EXIV2API DataBuf
readFile(
const std::wstring& wpath);
1177 #ifdef EXV_UNICODE_PATH
1182 EXIV2API
long writeFile(
const DataBuf& buf,
const std::wstring& wpath);
1190 #ifdef EXV_UNICODE_PATH
1197 const std::wstring& replace);
1203 EXIV2API
size_t curlWriter(
char* data,
size_t size,
size_t nmemb,
std::string* writerData);
1206 #endif // #ifndef BASICIO_HPP_
Internal Pimpl structure of class MemIo.
Definition: basicio.cpp:1054
bool isMalloced_
Was the buffer allocated?
Definition: basicio.cpp:1064
virtual int open()=0
Open the IO source using the default access mode. The default mode should allow for reading and writi...
Provides binary IO on blocks of memory by implementing the BasicIo interface. A copy-on-write impleme...
Definition: basicio.hpp:540
std::string Port
URL port.
Definition: futils.hpp:197
virtual bool isopen() const =0
Returns true if the IO source is open, otherwise false.
virtual int getb()
Read one byte from the memory block. The IO position is advanced by one byte.
Definition: basicio.cpp:1393
std::string openMode_
File open mode.
Definition: basicio.cpp:110
virtual int close()
Reset the IO position to the start. It does not release the data.
Definition: basicio.cpp:1741
virtual int error() const =0
Returns 0 if the IO source is in a valid state, otherwise nonzero.
byte * pData_
Pointer to the buffer, 0 if none has been allocated.
Definition: types.hpp:269
void populate(byte *source, size_t num)
Populate the block.
Definition: basicio.cpp:1124
byte * pMappedArea_
Pointer to the memory-mapped area.
Definition: basicio.cpp:118
virtual int error() const
Always returns 0.
Definition: basicio.cpp:1995
static const std::string GEN_FILE_EXT
The extension of the generated file which is created when getting input data to add or modify the met...
Definition: basicio.hpp:772
virtual byte * mmap(bool isWriteable=false)
Map the file into the process's address space. The file must be open before mmap() is called....
Definition: basicio.cpp:412
Provides binary file IO by implementing the BasicIo interface.
Definition: basicio.hpp:296
EXIV2API int http(Exiv2::Dictionary &request, Exiv2::Dictionary &response, std::string &errors)
execute an HTTP request
Definition: http.cpp:189
virtual int open()
Connect to the remote server, get the size of the remote file and allocate the array of blocksMap.
Definition: basicio.cpp:1707
virtual int seek(long offset, Position pos)
Move the current IO position.
Definition: basicio.cpp:1933
Utility class that closes a BasicIo instance upon destruction. Meant to be used as a stack variable i...
Definition: basicio.hpp:264
Position
Seek starting positions.
Definition: basicio.hpp:61
virtual DataBuf read(long rcount)
Read data from the file. Reading starts at the current file position and the position is advanced by ...
Definition: basicio.cpp:992
virtual size_t size() const
Get the current memory buffer size in bytes.
Definition: basicio.cpp:1985
long size_
Size of the memory area.
Definition: basicio.cpp:1062
virtual long tell() const
Get the current file position.
Definition: basicio.cpp:928
virtual long getFileLength()=0
Get the length (in bytes) of the remote file.
virtual byte * mmap(bool=false)
Not support.
Definition: basicio.cpp:1953
#define EXV_DEBUG
Shorthand to create a temp debug log message object and return its ostringstream.
Definition: error.hpp:144
Protocol protocol_
the protocol of url
Definition: basicio.cpp:1607
virtual void getDataByRange(long lowBlock, long highBlock, std::string &response)=0
Get the data by range.
EXIV2API bool fileExists(const std::string &path, bool ct=false)
Test if a file exists.
Definition: futils.cpp:311
bool eof_
EOF indicator.
Definition: basicio.cpp:1606
bool isWriteable_
Can the mapped area be written to?
Definition: basicio.cpp:121
Type definitions for Exiv2 and related functionality.
OpMode
Mode of operation.
Definition: basicio.cpp:99
virtual int munmap()
Remove a mapping established with mmap(). If the mapped area is writeable, this ensures that changes ...
Definition: basicio.cpp:378
Utility class provides the block mapping to the part of data. This avoids allocating a single contigu...
Definition: basicio.cpp:1101
~BlockMap()
Destructor. Releases all managed memory.
Definition: basicio.cpp:1113
virtual void populateFakeData()
Mark all the bNone blocks to bKnow. This avoids allocating memory for parts of the file that contain ...
Definition: basicio.cpp:2017
virtual int getb()
Read one byte from the memory blocks. The IO position is advanced by one byte. If the memory block is...
Definition: basicio.cpp:1890
Dictionary::const_iterator Dictionary_i
typedef for Dictionary iterator
Definition: datasets.hpp:372
EXV_WARN_UNUSED_RESULT std::pair< byte *, long > release()
Release ownership of the buffer to the caller. Returns the buffer as a data pointer and size pair,...
Definition: types.cpp:172
virtual ~FileIo()
Destructor. Flushes and closes an open file.
Definition: basicio.cpp:373
virtual void transfer(BasicIo &src)
Clear the memory block and then transfer data from the src BasicIo object into a new block of memory.
Definition: basicio.cpp:1237
std::string Path
URL file path.
Definition: futils.hpp:194
long getFileLength()
Get the length (in bytes) of the remote file.
Definition: basicio.cpp:2092
long idx_
Index into the memory area.
Definition: basicio.cpp:1061
nlink_t st_nlink
Number of hard links (broken on Windows, see winNumberOfLinks())
Definition: basicio.cpp:128
virtual int error() const
Always returns 0.
Definition: basicio.cpp:1402
virtual int seek(long offset, Position pos)
Move the current IO position.
Definition: basicio.cpp:1314
std::string path_
(Standard) path
Definition: basicio.cpp:105
void getDataByRange(long lowBlock, long highBlock, std::string &response)
Get the data by range.
Definition: basicio.cpp:2110
virtual bool isopen() const
Always returns true.
Definition: basicio.cpp:1365
EXIV2API long writeFile(const DataBuf &buf, const std::string &path)
Write DataBuf buf to file path.
Definition: basicio.cpp:2701
void markKnown(size_t num)
Change the status to bKnow. bKnow blocks do not contain the data, but they keep the size of data....
Definition: basicio.cpp:1138
EXIV2API std::string strError()
Return a system error message and the error code (errno). See strerror(3).
Definition: futils.cpp:356
Impl * p_
Pointer to implementation.
Definition: basicio.hpp:1007
Provides the http read/write access for the RemoteIo.
Definition: basicio.hpp:1015
virtual int getb()
Read one byte from the file. The file position is advanced by one byte.
Definition: basicio.cpp:1011
virtual long tell() const
Get the current IO position.
Definition: basicio.cpp:1980
std::string path_
(Standard) path
Definition: basicio.cpp:1597
virtual void writeRemote(const byte *data, size_t size, long from, long to)=0
Submit the data to the remote machine. The data replace a part of the remote file....
MemIo()
Default constructor that results in an empty object.
Definition: basicio.cpp:1209
virtual int putb(byte data)
Not support.
Definition: basicio.cpp:1839
EXIV2API std::string ReplaceStringInPlace(std::string subject, const std::string &search, const std::string &replace)
replace each substring of the subject that matches the given search string with the given replacement...
Definition: basicio.cpp:2721
Impl()
Default constructor.
Definition: basicio.cpp:1077
#define EXV_MAX(a, b)
Simple common max macro.
Definition: types.hpp:83
size_t size_
The file size.
Definition: basicio.cpp:1603
long idx_
Index into the memory area.
Definition: basicio.cpp:1604
virtual int putb(byte data)
Write one byte to the file. The file position is advanced by one byte.
Definition: basicio.cpp:883
EXIV2API DataBuf readFile(const std::string &path)
Read file path into a DataBuf, which is returned.
Definition: basicio.cpp:2663
static std::string writeDataToFile(const std::string &orgPath)
Read the data from stdin/data uri path and write them to the file.
Definition: basicio.cpp:1520
byte * bigBlock_
this is allocated and populated by mmap()
Definition: basicio.hpp:246
XPathIo(const std::string &orgPath)
Default constructor that reads data from stdin/data uri path and writes them to the temp file.
Definition: basicio.cpp:1485
int stat(StructStat &buf) const
stat wrapper for internal use
Definition: basicio.cpp:237
Internal Pimpl structure of class FileIo.
Definition: basicio.cpp:89
virtual bool eof() const
Returns true if the IO position has reached the end, otherwise false.
Definition: basicio.cpp:2000
size_t blockSize_
Size of the block memory.
Definition: basicio.cpp:1601
virtual void transfer(BasicIo &src)
Remove the contents of the file and then transfer data from the src BasicIo object into the empty fil...
Definition: basicio.cpp:1906
void writeRemote(const byte *data, size_t size, long from, long to)
Submit the data to the remote machine. The data replace a part of the remote file....
Definition: basicio.cpp:2132
EXIV2API std::string getEnv(int env_var)
Return the value of environmental variable.
Definition: futils.cpp:74
virtual int close()=0
Close the IO source. After closing a BasicIo instance can not be read or written. Closing flushes any...
virtual ~MemIo()
Destructor. Releases all managed memory.
Definition: basicio.cpp:1219
virtual size_t size() const
Flush any buffered writes and get the current file size in bytes.
Definition: basicio.cpp:934
std::string stringFormat(const char *format,...)
format a string in the pattern of sprintf .
Definition: image_int.cpp:32
virtual int open()
Open the file using using the default access mode of "rb". This method can also be used to "reopen" a...
Definition: basicio.cpp:952
virtual ~RemoteIo()
Destructor. Releases all managed memory.
Definition: basicio.cpp:1699
int switchMode(OpMode opMode)
Switch to a new access mode, reopening the file if needed. Optimized to only reopen the file when it ...
Definition: basicio.cpp:181
uint8_t byte
1 byte unsigned integer type.
Definition: types.hpp:105
virtual void setPath(const std::string &path)
close the file source and set a new path.
Definition: basicio.cpp:552
virtual int error() const
Returns 0 if the file is in a valid state, otherwise nonzero.
Definition: basicio.cpp:1018
Provides remote binary file IO by implementing the BasicIo interface. This is an abstract class....
Definition: basicio.hpp:832
void reserve(long wcount)
Reserve memory.
Definition: basicio.cpp:1171
HttpIo(const std::string &url, size_t blockSize=1024)
Constructor that accepts the http URL on which IO will be performed. The constructor does not open th...
Definition: basicio.cpp:2182
virtual ~BasicIo()
Destructor.
Definition: basicio.cpp:84
byte * data_
Pointer to the start of the memory area.
Definition: basicio.cpp:1060
virtual ~Impl()
Destructor. Releases all managed memory.
Definition: basicio.cpp:1695
EXIV2API Protocol fileProtocol(const std::string &path)
Return the protocol of the path.
Definition: futils.cpp:261
BasicIo & bio_
The BasicIo reference.
Definition: basicio.hpp:282
Internal Pimpl abstract structure of class RemoteIo.
Definition: basicio.cpp:1585
Utility class containing a character array. All it does is to take care of memory allocation and dele...
Definition: types.hpp:204
static const std::string TEMP_FILE_EXT
The extension of the temporary file which is created when getting input data to read metadata....
Definition: basicio.hpp:767
void alloc(long size)
Allocate a data buffer of at least the given size. Note that if the requested size is less than the c...
Definition: types.cpp:161
virtual void transfer(BasicIo &src)
Change the name of the temp file and make it untemporary before calling the method of superclass File...
Definition: basicio.cpp:1504
virtual DataBuf read(long rcount)
Read data from the memory blocks. Reading starts at the current IO position and the position is advan...
Definition: basicio.cpp:1844
long size_
The current size of the buffer.
Definition: types.hpp:271
static Uri EXIV2API Parse(const std::string &uri)
Parse the input URL to the protocol, host, path, username, password.
Definition: futils.cpp:395
virtual bool eof() const =0
Returns true if the IO position has reached the end, otherwise false.
virtual bool isopen() const
Returns true if the memory area is allocated.
Definition: basicio.cpp:1990
virtual void populateFakeData()
Mark all the bNone blocks to bKnow. This avoids allocating memory for parts of the file that contain ...
Definition: basicio.cpp:1424
mode_t st_mode
Permissions.
Definition: basicio.cpp:126
virtual DataBuf read(long rcount)=0
Read data from the IO source. Reading starts at the current IO position and the position is advanced ...
Protocol
the collection of protocols.
Definition: futils.hpp:46
void copyXattrFrom(const FileIo &src)
copy extended attributes (xattr) from another file
Definition: basicio.cpp:277
BlockMap * blocksMap_
An array contains all blocksMap.
Definition: basicio.cpp:1602
XMP property and type information. References: XMP Specification from Adobe (Property descriptions c...
Provides classes and functions to encode and decode Exif and Iptc data. The libexiv2 API consists of ...
Definition: asfvideo.hpp:36
Simple struct stat wrapper for internal use.
Definition: basicio.cpp:124
virtual long write(const byte *data, long wcount)
Not support this method.
Definition: basicio.cpp:1757
EXIV2API long base64decode(const char *in, char *out, size_t out_size)
Decode base64 data and put the resulting string in out.
Definition: futils.cpp:216
FileIo(const std::string &path)
Constructor that accepts the file path on which IO will be performed. The constructor does not open t...
Definition: basicio.cpp:361
virtual std::string path() const =0
Return the path to the IO resource. Often used to form comprehensive error messages where only a Basi...
Exiv2::Uri hostInfo_
the host information extracted from the path
Definition: basicio.cpp:2037
virtual ~XPathIo()
Destructor. Releases all managed memory and removes the temp file.
Definition: basicio.cpp:1497
virtual int seek(long offset, Position pos)
Move the current file position.
Definition: basicio.cpp:910
#define EXV_MIN(a, b)
Simple common min macro.
Definition: types.hpp:81
Impl(const std::string &path, size_t blockSize)
Constructor.
Definition: basicio.cpp:1649
HttpIo & operator=(const HttpIo &rhs)
Assignment operator.
OpMode opMode_
File open mode.
Definition: basicio.cpp:112
virtual int close()
Does nothing on MemIo objects.
Definition: basicio.cpp:1370
Impl(const std::string &path)
Constructor.
Definition: basicio.cpp:155
#define EXV_WARNING
Shorthand for a temp warning log message object and return its ostringstream.
Definition: error.hpp:148
virtual void populateFakeData()
Mark all the bNone blocks to bKnow. This avoids allocating memory for parts of the file that contain ...
Definition: basicio.hpp:241
virtual int putb(byte data)
Write one byte to the memory block. The IO position is advanced by one byte.
Definition: basicio.cpp:1282
virtual size_t size() const =0
Get the current size of the IO source in bytes.
@ time
IPTC time type.
Definition: types.hpp:149
EXIV2API int base64encode(const void *data_buf, size_t dataLength, char *result, size_t resultSize)
Encode in base64 the data in data_buf and put the resulting string in result.
Definition: futils.cpp:142
blockType_e
the status of the block.
Definition: basicio.cpp:1104
virtual size_t populateBlocks(size_t lowBlock, size_t highBlock)
Get the data from the remote machine and write them to the memory blocks.
Definition: basicio.cpp:1662
virtual std::string path() const
Returns a dummy path, indicating that memory access is used.
Definition: basicio.cpp:1412
virtual std::string path() const
Returns the URL of the file.
Definition: basicio.cpp:2005
virtual long tell() const
Get the current IO position.
Definition: basicio.cpp:1348
virtual ~IoCloser()
Destructor, closes the BasicIo reference.
Definition: basicio.hpp:271
HttpImpl(const std::string &path, size_t blockSize)
Constructor.
Definition: basicio.cpp:2075
std::auto_ptr< BasicIo > AutoPtr
BasicIo auto_ptr type.
Definition: basicio.hpp:58
Provides binary IO for the data from stdin and data uri path.
Definition: basicio.hpp:761
std::string Host
URL host.
Definition: futils.hpp:196
BasicError< char > Error
Error class used for exceptions (std::string based)
Definition: error.hpp:323
virtual bool isopen() const
Returns true if the file is open, otherwise false.
Definition: basicio.cpp:976
virtual byte * mmap(bool=false)
Allow direct access to the underlying data buffer. The buffer is not protected against write access i...
Definition: basicio.cpp:1338
uint32_t totalRead_
bytes requested from host
Definition: basicio.cpp:1608
virtual std::string path() const
Returns the path of the file.
Definition: basicio.cpp:1028
bool isMalloced_
Is the mapped area allocated?
Definition: basicio.cpp:120
virtual long write(const byte *data, long wcount)
Write data to the memory block. If needed, the size of the internal memory block is expanded....
Definition: basicio.cpp:1226
bool isMalloced_
Was the blocksMap_ allocated?
Definition: basicio.cpp:1605
virtual int munmap()
Remove a mapping established with mmap(). If the mapped area is writeable, this ensures that changes ...
Definition: basicio.cpp:1343
static void EXIV2API Decode(Uri &uri)
Decode the url components.
Definition: futils.cpp:386
@ string
IPTC string type.
Definition: types.hpp:147
std::map< std::string, std::string > Dictionary
typedef for string:string map
Definition: datasets.hpp:364
virtual void populateFakeData()
Mark all the bNone blocks to bKnow. This avoids allocating memory for parts of the file that contain ...
Definition: basicio.cpp:1049
off_t st_size
Size.
Definition: basicio.cpp:127
FILE * fp_
File stream pointer.
Definition: basicio.cpp:111
long sizeAlloced_
Size of the allocated buffer.
Definition: basicio.cpp:1063
virtual size_t size() const
Get the current memory buffer size in bytes.
Definition: basicio.cpp:1353
virtual int seek(long offset, Position pos)=0
Move the current IO position.
Internal Pimpl structure of class HttpIo.
Definition: basicio.cpp:2029
IPTC dataset and type information.
An interface for simple binary IO.
Definition: basicio.hpp:55
virtual int close()
Flush and unwritten data and close the file . It is safe to call close on an already closed instance.
Definition: basicio.cpp:981
size_t mappedLength_
Size of the memory-mapped area.
Definition: basicio.cpp:119
int open(const std::string &mode)
Open the file using using the specified mode.
Definition: basicio.cpp:958
virtual long write(const byte *data, long wcount)
Write data to the file. The file position is advanced by the number of bytes written.
Definition: basicio.cpp:579
virtual bool eof() const
Returns true if the IO position has reached the end, otherwise false.
Definition: basicio.cpp:1407
virtual void transfer(BasicIo &src)
Remove the contents of the file and then transfer data from the src BasicIo object into the empty fil...
Definition: basicio.cpp:609
virtual bool eof() const
Returns true if the file position has reached the end, otherwise false.
Definition: basicio.cpp:1023
Basic file utility functions required by Exiv2.
virtual int munmap()
Not support.
Definition: basicio.cpp:1975
virtual DataBuf read(long rcount)
Read data from the memory block. Reading starts at the current IO position and the position is advanc...
Definition: basicio.cpp:1375
std::string Protocol
URL protocol.
Definition: futils.hpp:195
Error class for exceptions, log message class.
virtual int open()
Memory IO is always open for reading and writing. This method therefore only resets the IO position t...
Definition: basicio.cpp:1358
bool eof_
EOF indicator.
Definition: basicio.cpp:1065
A container for URL components. It also provides the method to parse a URL to get the protocol,...
Definition: futils.hpp:189
EXIV2API std::string urlencode(const char *str)
Encode the input url.
Definition: futils.cpp:94