<commit_before>/*
 * ALURE  OpenAL utility library
 * Copyright (C) 2009 by <NAME>.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * Or go to http://www.gnu.org/copyleft/lgpl.html
 */

/* Title: File I/O */

#include "config.h"

#include "main.h"

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <iostream>

#ifndef O_BINARY
#define O_BINARY 0
#endif

MemStreamBuf::int_type MemStreamBuf::underflow()
{
    if(gptr() == egptr())
    {
        char_type *data = (char_type*)memInfo.Data;
        setg(data, data + memInfo.Pos, data + memInfo.Length);
        memInfo.Pos = memInfo.Length;
    }
    if(gptr() == egptr())
        return traits_type::eof();
    return (*gptr())&0xFF;
}

MemStreamBuf::pos_type MemStreamBuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode)
{
    if((mode&std::ios_base::out))
        return traits_type::eof();

    pos_type pos;
    switch(whence)
    {
        case std::ios_base::beg:
            pos = pos_type(offset);
            break;
        case std::ios_base::cur:
            pos = pos_type(memInfo.Pos) - pos_type(egptr()-gptr());
            pos += offset;
            break;
        case std::ios_base::end:
            pos = memInfo.Length + pos_type(offset);
            break;
        default:
            return traits_type::eof();
    }

    return seekpos(pos, mode);
}

MemStreamBuf::pos_type MemStreamBuf::seekpos(pos_type pos, std::ios_base::openmode mode)
{
    if((mode&std::ios_base::out))
        return traits_type::eof();

    if(pos < 0 || pos > pos_type(memInfo.Length) || pos != pos_type(size_t(pos)))
        return traits_type::eof();
    memInfo.Pos = pos;

    setg(0, 0, 0);
    return pos;
}


int FileStreamBuf::underflow()
{
    if(usrFile && gptr() == egptr())
    {
        ALsizei amt = fio.read(usrFile, reinterpret_cast<ALubyte*>(&buffer[0]), sizeof(buffer));
        if(amt >= 0) setg(buffer, buffer, buffer+amt);
    }
    if(gptr() == egptr())
        return traits_type::eof();
    return (*gptr())&0xFF;
}

FileStreamBuf::pos_type FileStreamBuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode)
{
    if(!usrFile || (mode&std::ios_base::out))
        return traits_type::eof();

    pos_type pos;
    switch(whence)
    {
        case std::ios_base::beg:
            pos = pos_type(fio.seek(usrFile, offset, SEEK_SET));
            break;

        case std::ios_base::cur:
            offset -= off_type(egptr()-gptr());
            pos = pos_type(fio.seek(usrFile, offset, SEEK_CUR));
            break;

        case std::ios_base::end:
            pos = pos_type(fio.seek(usrFile, offset, SEEK_END));
            break;

        default:
            pos = traits_type::eof();
    }
    if(pos >= 0)
        setg(0, 0, 0);
    return pos;
}

FileStreamBuf::pos_type FileStreamBuf::seekpos(pos_type pos, std::ios_base::openmode mode)
{
    if(pos != pos_type(off_type(pos)))
        return traits_type::eof();
    return seekoff(off_type(pos), std::ios_base::beg, mode);
}


static void *open_wrap(const char *filename, ALuint mode)
{
    if(mode != 0)
        return NULL;

    return fopen(filename, "rb");
}

static void close_wrap(void *user_data)
{
    FILE *f = (FILE*)user_data;
    fclose(f);
}

ALsizei read_wrap(void *user_data, ALubyte *buf, ALuint bytes)
{
    FILE *f = (FILE*)user_data;
    return fread(buf, 1, bytes, f);
}

ALsizei write_wrap(void *user_data, const ALubyte *buf, ALuint bytes)
{
    FILE *f = (FILE*)user_data;
    return fwrite(buf, 1, bytes, f);
}

alureInt64 seek_wrap(void *user_data, alureInt64 offset, int whence)
{
    FILE *f = (FILE*)user_data;
#ifdef HAVE_FSEEKO
    if(offset != (off_t)offset)
        return -1;
    return fseeko(f, offset, whence);
#else
    if(offset != (long)offset)
        return -1;
    return fseek(f, offset, whence);
#endif
}

UserFuncs Funcs = {
    open_wrap,
    close_wrap,
    read_wrap,
    write_wrap,
    seek_wrap
};

extern "C" {

/* Function: alureSetIOCallbacks
 *
 * Provides callbacks for alternative methods to handle file I/O. Passing NULL
 * for all callbacks is a valid way to revert to normal I/O, otherwise they
 * must all be specified. Changing the callbacks will not affect open files
 * (they will continue using the callbacks that were set at the time they were
 * opened).
 *
 * Parameters:
 * open - This callback is called to open the named file. The given mode is the
 *        access rights the open file should have. Currently, this will always
 *        be 0 for read-only (applications should check this to make sure, as
 *        future versions may pass other values for other modes). Upon success,
 *        a non-NULL handle must be returned which will be used as a unique<commit_msg>Correct the return value of the default seek callback<commit_after>/*
 * ALURE  OpenAL utility library
 * Copyright (C) 2009 by <NAME>.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 * Or go to http://www.gnu.org/copyleft/lgpl.html
 */

/* Title: File I/O */

#include "config.h"

#include "main.h"

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <iostream>

#ifndef O_BINARY
#define O_BINARY 0
#endif

MemStreamBuf::int_type MemStreamBuf::underflow()
{
    if(gptr() == egptr())
    {
        char_type *data = (char_type*)memInfo.Data;
        setg(data, data + memInfo.Pos, data + memInfo.Length);
        memInfo.Pos = memInfo.Length;
    }
    if(gptr() == egptr())
        return traits_type::eof();
    return (*gptr())&0xFF;
}

MemStreamBuf::pos_type MemStreamBuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode)
{
    if((mode&std::ios_base::out))
        return traits_type::eof();

    pos_type pos;
    switch(whence)
    {
        case std::ios_base::beg:
            pos = pos_type(offset);
            break;
        case std::ios_base::cur:
            pos = pos_type(memInfo.Pos) - pos_type(egptr()-gptr());
            pos += offset;
            break;
        case std::ios_base::end:
            pos = memInfo.Length + pos_type(offset);
            break;
        default:
            return traits_type::eof();
    }

    return seekpos(pos, mode);
}

MemStreamBuf::pos_type MemStreamBuf::seekpos(pos_type pos, std::ios_base::openmode mode)
{
    if((mode&std::ios_base::out))
        return traits_type::eof();

    if(pos < 0 || pos > pos_type(memInfo.Length) || pos != pos_type(size_t(pos)))
        return traits_type::eof();
    memInfo.Pos = pos;

    setg(0, 0, 0);
    return pos;
}


int FileStreamBuf::underflow()
{
    if(usrFile && gptr() == egptr())
    {
        ALsizei amt = fio.read(usrFile, reinterpret_cast<ALubyte*>(&buffer[0]), sizeof(buffer));
        if(amt >= 0) setg(buffer, buffer, buffer+amt);
    }
    if(gptr() == egptr())
        return traits_type::eof();
    return (*gptr())&0xFF;
}

FileStreamBuf::pos_type FileStreamBuf::seekoff(off_type offset, std::ios_base::seekdir whence, std::ios_base::openmode mode)
{
    if(!usrFile || (mode&std::ios_base::out))
        return traits_type::eof();

    pos_type pos;
    switch(whence)
    {
        case std::ios_base::beg:
            pos = pos_type(fio.seek(usrFile, offset, SEEK_SET));
            break;

        case std::ios_base::cur:
            offset -= off_type(egptr()-gptr());
            pos = pos_type(fio.seek(usrFile, offset, SEEK_CUR));
            break;

        case std::ios_base::end:
            pos = pos_type(fio.seek(usrFile, offset, SEEK_END));
            break;

        default:
            pos = traits_type::eof();
    }
    if(pos >= 0)
        setg(0, 0, 0);
    return pos;
}

FileStreamBuf::pos_type FileStreamBuf::seekpos(pos_type pos, std::ios_base::openmode mode)
{
    if(pos != pos_type(off_type(pos)))
        return traits_type::eof();
    return seekoff(off_type(pos), std::ios_base::beg, mode);
}


static void *open_wrap(const char *filename, ALuint mode)
{
    if(mode != 0)
        return NULL;

    return fopen(filename, "rb");
}

static void close_wrap(void *user_data)
{
    FILE *f = (FILE*)user_data;
    fclose(f);
}

ALsizei read_wrap(void *user_data, ALubyte *buf, ALuint bytes)
{
    FILE *f = (FILE*)user_data;
    return fread(buf, 1, bytes, f);
}

ALsizei write_wrap(void *user_data, const ALubyte *buf, ALuint bytes)
{
    FILE *f = (FILE*)user_data;
    return fwrite(buf, 1, bytes, f);
}

alureInt64 seek_wrap(void *user_data, alureInt64 offset, int whence)
{
    FILE *f = (FILE*)user_data;
#ifdef HAVE_FSEEKO
    if(offset != (off_t)offset || fseeko(f, offset, whence) != 0)
        return -1;
    return ftello(f);
#else
    if(offset != (long)offset || fseek(f, offset, whence) != 0)
        return -1;
    return ftell(f);
#endif
}

UserFuncs Funcs = {
    open_wrap,
    close_wrap,
    read_wrap,
    write_wrap,
    seek_wrap
};

extern "C" {

/* Function: alureSetIOCallbacks
 *
 * Provides callbacks for alternative methods to handle file I/O. Passing NULL
 * for all callbacks is a valid way to revert to normal I/O, otherwise they
 * must all be specified. Changing the callbacks will not affect open files
 * (they will continue using the callbacks that were set at the time they were
 * opened).
 *
 * Parameters:
 * open - This callback is called to open the named file. The given mode is the
 *        access rights the open file should have. Currently, this will always
 *        be 0 for read-only (applications should check this to make sure, as
 *        future versions may pass other values for other modes). Upon success,
 *        a non-NULL handle must be returned which will be used as a unique
{'fraction_non_alphanumeric': 0.12399747679553032, 'fraction_numerical': 0.0073893845183382895, 'mean_word_length': 3.0488872674206493, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '179873', 'n_tokens_mistral': 3730, 'n_tokens_neox': 3622, 'n_words': 1063}