<?php
/**
 * Tiny in-memory stand-in for a file resource, used by Shieldforge_Geo and
 * Shieldforge_Asn when their on-disk inflated-cache directory isn't writable.
 * Wraps a string buffer with a seek/read interface that mirrors fseek()/fread(),
 * so the same binary-search code can run against either a real file handle or
 * this in-memory buffer without branching at every call site.
 *
 * @package Brainwerk Security Suite
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Shieldforge_Mem_Handle {

    /** @var string */
    private $data;

    /** @var int */
    private $pos = 0;

    public function __construct( $data ) {
        $this->data = $data;
    }

    /** Seek to a byte offset, whether $h is a Shieldforge_Mem_Handle or a file resource. */
    public static function seek( $h, $pos ) {
        if ( $h instanceof self ) {
            $h->pos = $pos;
        } else {
            fseek( $h, $pos );
        }
    }

    /** Read $len bytes, whether $h is a Shieldforge_Mem_Handle or a file resource. */
    public static function read( $h, $len ) {
        if ( $h instanceof self ) {
            $out       = substr( $h->data, $h->pos, $len );
            $h->pos   += $len;
            return $out;
        }
        return (string) fread( $h, $len ); // phpcs:ignore WordPress.WP.AlternativeFunctions
    }

    /** Close $h if it's a real file resource; no-op for the in-memory case. */
    public static function close( $h ) {
        if ( is_resource( $h ) ) {
            fclose( $h ); // phpcs:ignore WordPress.WP.AlternativeFunctions
        }
    }
}
