std::basic_...buf::seekoff(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::basic_filebuf::seekoff β€” the C++ Standard Library's glow-up guide πŸŽ€

Okay bestie, so this one is from the C++ Standard Library (iconic lineage fr), and it's the page about std::basic_filebuf::seekoff. Yes the title in the manpage has those cute little dots in it (std::basic_...buf::seekoff) because that's how the header folds long names β€” the actual thing we're talking about all page is std::basic_filebuf::seekoff. πŸ¦‹


✨ NAME ✨

std::basic_filebuf::seekoff β€” and that's it, that's the name, that's the function, that's the whole vibe. πŸ’–


✨ Synopsis ✨

It's protected, it's virtual, and she has defaults:

protected:

virtual pos_type seekoff( off_type off,
                          std::ios_base::seekdir dir,
                          std::ios_base::openmode which =
std::ios_base::in |
    std::ios_base::out );

✨ DESCRIPTION ✨ (the main character section πŸ‘‘)

So what does she do? She repositions the file pointer, if possible, to the position that corresponds to exactly off characters from the beginning, end, or current position of the file β€” depending on the value of dir. That's the whole job, and she does it, periodt. ⭐

Now the vibe checks she can fail, in order:

  • If the associated file is not open (is_open() == false), she fails immediately. No file, no service, no notes. πŸ’€
  • If the multibyte character encoding is state-dependent (codecvt::encoding() returned -1) or variable-length (codecvt::encoding() returned 0) and the offset off is not 0, she fails immediately β€” because this function cannot determine the number of bytes that correspond to off characters. Like, she literally cannot do the math for you, bestie. πŸ™ˆ
  • If dir is not std::basic_ios::cur or the offset off is not 0, and the most recent operation done on this filebuf object was output (that is, either the put buffer is not empty, or the most recently called function was overflow()), then she calls std::codecvt::unshift to determine the unshift sequence necessary, and writes that sequence to the file by calling overflow(). Close the loop before you move, queen. πŸŽ€

Then she converts the argument dir to a value whence of type int like this:

  • std::basic_ios::beg β†’ SEEK_SET
  • std::basic_ios::end β†’ SEEK_END
  • std::basic_ios::cur β†’ SEEK_CUR

Then, if the character encoding is fixed-width (codecvt::encoding() returns some positive number width), she moves the file pointer as if by std::fseek(file, width*off, whence).

Otherwise, she moves the file pointer as if by std::fseek(file, 0, whence).

And the openmode argument? It's required by the base class function signature, but it's usually ignored β€” because std::basic_filebuf maintains only one file position. One file, one position, one girl. πŸ’…


✨ Parameters ✨ (feed her the right info πŸ“)

  • off β€” relative position to set the position indicator to.
  • dir β€” defines the base position to apply the relative offset to. It can be one of the following constants:
    • beg β€” the beginning of a stream
    • end β€” the ending of a stream
    • cur β€” the current position of stream position indicator
  • which β€” defines which of the input and/or output sequences to affect. It can be one or a combination of the following constants:
    • in β€” affect the input sequence
    • out β€” affect the output sequence

✨ Return value ✨

A newly constructed object of type pos_type which stores the resulting file position, or pos_type(off_type(-1)) on failure. (That's the sad ending, but at least it's a specified sad ending.) 😭


✨ Notes ✨

seekoff() is called by std::basic_streambuf::pubseekoff, which is called by std::basic_istream::seekg, std::basic_ostream::seekp, std::basic_istream::tellg, and std::basic_ostream::tellp. So like, she's the popular one everyone invites to the function call. 🌈


✨ Example ✨

// Run this code

#include <fstream>
#include <iostream>
#include <locale>

template<typename CharT>
int get_encoding(const std::basic_istream<CharT>& stream)
{
    using Facet = std::codecvt<CharT, char, std::mbstate_t>;
    return std::use_facet<Facet>(stream.getloc()).encoding();
}

int main()
{
    // prepare a 10-byte file holding 4 characters ("zΓŸζ°΄π„‹") in UTF-8
    std::ofstream("text.txt") <<
"\x7a\xc3\x9f\xe6\xb0\xb4\xf0\x9d\x84\x8b";

    // open using a non-converting encoding
    std::ifstream f1("text.txt");
    std::cout << "f1's locale's encoding() returns "
              << get_encoding(f1) << '\n'
              << "pubseekoff(3, beg) returns "
              << f1.rdbuf()->pubseekoff(3, std::ios_base::beg) << '\n'
              << "pubseekoff(0, end) returns "
              << f1.rdbuf()->pubseekoff(0, std::ios_base::end) << '\n';

    // open using UTF-8
    std::wifstream f2("text.txt");
    f2.imbue(std::locale("en_US.UTF-8"));
    std::cout << "f2's locale's encoding() returns "
              << get_encoding(f2) << '\n'
              << "pubseekoff(3, beg) returns "
              << f2.rdbuf()->pubseekoff(3, std::ios_base::beg) << '\n'
              << "pubseekoff(0, end) returns "
              << f2.rdbuf()->pubseekoff(0, std::ios_base::end) << '\n';
}

Output πŸ’–

f1's locale's encoding() returns 1
pubseekoff(3, beg) returns 3
pubseekoff(0, end) returns 10
f2's locale's encoding() returns 0
pubseekoff(3, beg) returns -1
pubseekoff(0, end) returns 10

Notice f2 ate that -1 for pubseekoff(3, beg) β€” that's the variable-length encoding situation from up top doing its thing, and honestly? She warned you. 🫢


✨ Defect reports ✨

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

  • LWG 55 β€” applied to C++98. Behavior as published: seekoff returned an undefined invalid stream position on failure. Correct behavior: pos_type(off_type(-1)) is returned on failure. Miss Girl got a proper failure value, we love a retroactive glow-up. ✨

✨ See also ✨

  • pubseekoff β€” invokes seekoff() (public member function of std::basic_streambuf<CharT,Traits>)
  • seekpos β€” repositions the file position, using absolute addressing ([virtual] virtual protected member function)
  • fseek β€” moves the file position indicator to a specific location in a file (function)

Okay that's the whole page, no cap, not a single option left behind πŸ’œ Big shout to cppreference.com, version dated 2024.06.10 β€” and this little std::basic_...buf::seekoff(3) sign-off is officially out, mwah πŸ’…πŸŽ€πŸŒΈ

πŸ“¦ where this page comes from