This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
# V=0 quiet, V=1 verbose. other values don't work.
|
||||
V = 0
|
||||
V0 = $(V:0=)
|
||||
Q1 = $(V:1=)
|
||||
Q = $(Q1:0=@)
|
||||
ECHO1 = $(V:1=@ :)
|
||||
ECHO = $(ECHO1:0=@ echo)
|
||||
NULLCMD = :
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
srcdir = .
|
||||
topdir = /usr/include/ruby-3.2.0
|
||||
hdrdir = $(topdir)
|
||||
arch_hdrdir = /usr/include/x86_64-linux-gnu/ruby-3.2.0
|
||||
PATH_SEPARATOR = :
|
||||
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
|
||||
prefix = $(DESTDIR)/usr
|
||||
rubysitearchprefix = $(sitearchlibdir)/$(RUBY_BASE_NAME)
|
||||
rubyarchprefix = $(archlibdir)/$(RUBY_BASE_NAME)
|
||||
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
|
||||
exec_prefix = $(prefix)
|
||||
vendorarchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/vendor_ruby
|
||||
sitearchhdrdir = $(sitearchincludedir)/$(RUBY_VERSION_NAME)/site_ruby
|
||||
rubyarchhdrdir = $(archincludedir)/$(RUBY_VERSION_NAME)
|
||||
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
|
||||
sitehdrdir = $(rubyhdrdir)/site_ruby
|
||||
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
|
||||
vendorarchdir = $(rubysitearchprefix)/vendor_ruby/$(ruby_version)
|
||||
vendorlibdir = $(vendordir)/$(ruby_version)
|
||||
vendordir = $(rubylibprefix)/vendor_ruby
|
||||
sitearchdir = $(DESTDIR)/usr/local/lib/x86_64-linux-gnu/site_ruby
|
||||
sitelibdir = $(sitedir)/$(ruby_version)
|
||||
sitedir = $(DESTDIR)/usr/local/lib/site_ruby
|
||||
rubyarchdir = $(rubyarchprefix)/$(ruby_version)
|
||||
rubylibdir = $(rubylibprefix)/$(ruby_version)
|
||||
sitearchincludedir = $(includedir)/$(sitearch)
|
||||
archincludedir = $(includedir)/$(arch)
|
||||
sitearchlibdir = $(libdir)/$(sitearch)
|
||||
archlibdir = $(libdir)/$(arch)
|
||||
ridir = $(datarootdir)/$(RI_BASE_NAME)
|
||||
mandir = $(datarootdir)/man
|
||||
localedir = $(datarootdir)/locale
|
||||
libdir = $(exec_prefix)/lib
|
||||
psdir = $(docdir)
|
||||
pdfdir = $(docdir)
|
||||
dvidir = $(docdir)
|
||||
htmldir = $(docdir)
|
||||
infodir = $(datarootdir)/info
|
||||
docdir = $(datarootdir)/doc/$(PACKAGE)
|
||||
oldincludedir = $(DESTDIR)/usr/include
|
||||
includedir = $(prefix)/include
|
||||
runstatedir = $(DESTDIR)/var/run
|
||||
localstatedir = $(DESTDIR)/var
|
||||
sharedstatedir = $(prefix)/com
|
||||
sysconfdir = $(DESTDIR)/etc
|
||||
datadir = $(datarootdir)
|
||||
datarootdir = $(prefix)/share
|
||||
libexecdir = $(exec_prefix)/libexec
|
||||
sbindir = $(exec_prefix)/sbin
|
||||
bindir = $(exec_prefix)/bin
|
||||
archdir = $(rubyarchdir)
|
||||
|
||||
|
||||
CC_WRAPPER =
|
||||
CC = x86_64-linux-gnu-gcc
|
||||
CXX = x86_64-linux-gnu-g++
|
||||
LIBRUBY = $(LIBRUBY_SO)
|
||||
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
||||
LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME)
|
||||
LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static $(MAINLIBS)
|
||||
empty =
|
||||
OUTFLAG = -o $(empty)
|
||||
COUTFLAG = -o $(empty)
|
||||
CSRCFLAG = $(empty)
|
||||
|
||||
RUBY_EXTCONF_H =
|
||||
cflags = $(optflags) $(debugflags) $(warnflags)
|
||||
cxxflags =
|
||||
optflags = -O3 -fno-fast-math
|
||||
debugflags = -ggdb3
|
||||
warnflags = -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wmisleading-indentation -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wundef
|
||||
cppflags =
|
||||
CCDLFLAGS = -fPIC
|
||||
CFLAGS = $(CCDLFLAGS) -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.8 -fPIC $(ARCH_FLAG)
|
||||
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
||||
DEFS =
|
||||
CPPFLAGS = -DBUILD_FOR_RUBY -DOS_UNIX -Wdate-time -D_FORTIFY_SOURCE=3 $(DEFS) $(cppflags)
|
||||
CXXFLAGS = $(CCDLFLAGS) -g -O2 -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -ffile-prefix-map=BUILDDIR=. -fstack-protector-strong -fstack-clash-protection -Wformat -Werror=format-security -fcf-protection -fdebug-prefix-map=BUILDDIR=/usr/src/ruby3.2-3.2.3-1ubuntu0.24.04.8 $(ARCH_FLAG)
|
||||
ldflags = -L. -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fstack-protector-strong -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed
|
||||
dldflags = -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now
|
||||
ARCH_FLAG =
|
||||
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
|
||||
LDSHARED = $(CXX) -shared
|
||||
LDSHAREDXX = $(CXX) -shared
|
||||
AR = x86_64-linux-gnu-gcc-ar
|
||||
EXEEXT =
|
||||
|
||||
RUBY_INSTALL_NAME = $(RUBY_BASE_NAME)3.2
|
||||
RUBY_SO_NAME = ruby-3.2
|
||||
RUBYW_INSTALL_NAME =
|
||||
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
|
||||
RUBYW_BASE_NAME = rubyw
|
||||
RUBY_BASE_NAME = ruby
|
||||
|
||||
arch = x86_64-linux-gnu
|
||||
sitearch = $(arch)
|
||||
ruby_version = 3.2.0
|
||||
ruby = $(bindir)/$(RUBY_BASE_NAME)3.2
|
||||
RUBY = $(ruby)
|
||||
BUILTRUBY = $(bindir)/$(RUBY_BASE_NAME)3.2
|
||||
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/backward.h $(hdrdir)/ruby/ruby.h $(hdrdir)/ruby/defines.h $(hdrdir)/ruby/missing.h $(hdrdir)/ruby/intern.h $(hdrdir)/ruby/st.h $(hdrdir)/ruby/subst.h $(arch_hdrdir)/ruby/config.h
|
||||
|
||||
RM = rm -f
|
||||
RM_RF = rm -fr
|
||||
RMDIRS = rmdir --ignore-fail-on-non-empty -p
|
||||
MAKEDIRS = /bin/mkdir -p
|
||||
INSTALL = /usr/bin/install -c
|
||||
INSTALL_PROG = $(INSTALL) -m 0755
|
||||
INSTALL_DATA = $(INSTALL) -m 644
|
||||
COPY = cp
|
||||
TOUCH = exit >
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
preload =
|
||||
libpath = . $(archlibdir)
|
||||
LIBPATH = -L. -L$(archlibdir)
|
||||
DEFFILE =
|
||||
|
||||
CLEANFILES = mkmf.log
|
||||
DISTCLEANFILES =
|
||||
DISTCLEANDIRS =
|
||||
|
||||
extout =
|
||||
extout_prefix =
|
||||
target_prefix =
|
||||
LOCAL_LIBS =
|
||||
LIBS = $(LIBRUBYARG_SHARED) -lm -lpthread -lc
|
||||
ORIG_SRCS = mapper.cpp rubymain.cpp
|
||||
SRCS = $(ORIG_SRCS)
|
||||
OBJS = mapper.o rubymain.o
|
||||
HDRS = $(srcdir)/mapper.h
|
||||
LOCAL_HDRS =
|
||||
TARGET = fastfilereaderext
|
||||
TARGET_NAME = fastfilereaderext
|
||||
TARGET_ENTRY = Init_$(TARGET_NAME)
|
||||
DLLIB = $(TARGET).so
|
||||
EXTSTATIC =
|
||||
STATIC_LIB =
|
||||
|
||||
TIMESTAMP_DIR = .
|
||||
BINDIR = $(bindir)
|
||||
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
||||
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
||||
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
||||
HDRDIR = $(sitehdrdir)$(target_prefix)
|
||||
ARCHHDRDIR = $(sitearchhdrdir)$(target_prefix)
|
||||
TARGET_SO_DIR =
|
||||
TARGET_SO = $(TARGET_SO_DIR)$(DLLIB)
|
||||
CLEANLIBS = $(TARGET_SO) false
|
||||
CLEANOBJS = $(OBJS) *.bak
|
||||
TARGET_SO_DIR_TIMESTAMP = $(TIMESTAMP_DIR)/.sitearchdir.time
|
||||
|
||||
all: $(DLLIB)
|
||||
static: $(STATIC_LIB)
|
||||
.PHONY: all install static install-so install-rb
|
||||
.PHONY: clean clean-so clean-static clean-rb
|
||||
|
||||
clean-static::
|
||||
clean-rb-default::
|
||||
clean-rb::
|
||||
clean-so::
|
||||
clean: clean-so clean-static clean-rb-default clean-rb
|
||||
-$(Q)$(RM_RF) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
|
||||
|
||||
distclean-rb-default::
|
||||
distclean-rb::
|
||||
distclean-so::
|
||||
distclean-static::
|
||||
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
|
||||
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
||||
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
||||
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
|
||||
|
||||
realclean: distclean
|
||||
install: install-so install-rb
|
||||
|
||||
install-so: $(DLLIB) $(TARGET_SO_DIR_TIMESTAMP)
|
||||
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
||||
clean-static::
|
||||
-$(Q)$(RM) $(STATIC_LIB)
|
||||
install-rb: pre-install-rb do-install-rb install-rb-default
|
||||
install-rb-default: pre-install-rb-default do-install-rb-default
|
||||
pre-install-rb: Makefile
|
||||
pre-install-rb-default: Makefile
|
||||
do-install-rb:
|
||||
do-install-rb-default:
|
||||
pre-install-rb-default:
|
||||
@$(NULLCMD)
|
||||
$(TARGET_SO_DIR_TIMESTAMP):
|
||||
$(Q) $(MAKEDIRS) $(@D) $(RUBYARCHDIR)
|
||||
$(Q) $(TOUCH) $@
|
||||
|
||||
site-install: site-install-so site-install-rb
|
||||
site-install-so: install-so
|
||||
site-install-rb: install-rb
|
||||
|
||||
.SUFFIXES: .c .m .cc .mm .cxx .cpp .o .S
|
||||
|
||||
.cc.o:
|
||||
$(ECHO) compiling $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
||||
|
||||
.cc.S:
|
||||
$(ECHO) translating $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
||||
|
||||
.mm.o:
|
||||
$(ECHO) compiling $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
||||
|
||||
.mm.S:
|
||||
$(ECHO) translating $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
||||
|
||||
.cxx.o:
|
||||
$(ECHO) compiling $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
||||
|
||||
.cxx.S:
|
||||
$(ECHO) translating $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
||||
|
||||
.cpp.o:
|
||||
$(ECHO) compiling $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
||||
|
||||
.cpp.S:
|
||||
$(ECHO) translating $(<)
|
||||
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
||||
|
||||
.c.o:
|
||||
$(ECHO) compiling $(<)
|
||||
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
||||
|
||||
.c.S:
|
||||
$(ECHO) translating $(<)
|
||||
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
||||
|
||||
.m.o:
|
||||
$(ECHO) compiling $(<)
|
||||
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $(CSRCFLAG)$<
|
||||
|
||||
.m.S:
|
||||
$(ECHO) translating $(<)
|
||||
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -S $(CSRCFLAG)$<
|
||||
|
||||
$(TARGET_SO): $(OBJS) Makefile
|
||||
$(ECHO) linking shared-object $(DLLIB)
|
||||
-$(Q)$(RM) $(@)
|
||||
$(Q) $(LDSHAREDXX) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
||||
|
||||
|
||||
|
||||
$(OBJS): $(HDRS) $(ruby_headers)
|
||||
@@ -0,0 +1,109 @@
|
||||
require 'mkmf'
|
||||
|
||||
def check_libs libs = [], fatal = false
|
||||
libs.all? { |lib| have_library(lib) || (abort("could not find library: #{lib}") if fatal) }
|
||||
end
|
||||
|
||||
def check_heads heads = [], fatal = false
|
||||
heads.all? { |head| have_header(head) || (abort("could not find header: #{head}") if fatal)}
|
||||
end
|
||||
|
||||
def add_define(name)
|
||||
$defs.push("-D#{name}")
|
||||
end
|
||||
|
||||
# Eager check devs tools
|
||||
have_devel? if respond_to?(:have_devel?)
|
||||
|
||||
add_define 'BUILD_FOR_RUBY'
|
||||
|
||||
# Minor platform details between *nix and Windows:
|
||||
|
||||
if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
|
||||
GNU_CHAIN = ENV['CROSS_COMPILING'] || $1 == 'mingw'
|
||||
OS_WIN32 = true
|
||||
add_define "OS_WIN32"
|
||||
else
|
||||
GNU_CHAIN = true
|
||||
OS_UNIX = true
|
||||
add_define 'OS_UNIX'
|
||||
end
|
||||
|
||||
# Adjust number of file descriptors (FD) on Windows
|
||||
|
||||
if RbConfig::CONFIG["host_os"] =~ /mingw/
|
||||
found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
|
||||
any? { |v| v.include?("FD_SETSIZE") }
|
||||
|
||||
add_define "FD_SETSIZE=32767" unless found
|
||||
end
|
||||
|
||||
# Main platform invariances:
|
||||
|
||||
case RUBY_PLATFORM
|
||||
when /mswin32/, /mingw32/, /bccwin32/
|
||||
check_heads(%w[windows.h winsock.h], true)
|
||||
check_libs(%w[kernel32 rpcrt4 gdi32], true)
|
||||
|
||||
if GNU_CHAIN
|
||||
CONFIG['LDSHAREDXX'] = "$(CXX) -shared -static-libgcc -static-libstdc++"
|
||||
else
|
||||
$defs.push "-EHs"
|
||||
$defs.push "-GR"
|
||||
end
|
||||
|
||||
when /solaris/
|
||||
add_define 'OS_SOLARIS8'
|
||||
check_libs(%w[nsl socket], true)
|
||||
|
||||
if CONFIG['CC'] == 'cc' && (
|
||||
`cc -flags 2>&1` =~ /Sun/ || # detect SUNWspro compiler
|
||||
`cc -V 2>&1` =~ /Sun/ # detect Solaris Studio compiler
|
||||
)
|
||||
# SUN CHAIN
|
||||
add_define 'CC_SUNWspro'
|
||||
$preload = ["\nCXX = CC"] # hack a CXX= line into the makefile
|
||||
$CFLAGS = CONFIG['CFLAGS'] = "-KPIC"
|
||||
CONFIG['CCDLFLAGS'] = "-KPIC"
|
||||
CONFIG['LDSHARED'] = "$(CXX) -G -KPIC -lCstd"
|
||||
CONFIG['LDSHAREDXX'] = "$(CXX) -G -KPIC -lCstd"
|
||||
else
|
||||
# GNU CHAIN
|
||||
# on Unix we need a g++ link, not gcc.
|
||||
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
||||
end
|
||||
|
||||
when /openbsd/
|
||||
# OpenBSD branch contributed by Guillaume Sellier.
|
||||
|
||||
# on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs
|
||||
CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC"
|
||||
CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC"
|
||||
|
||||
when /darwin/
|
||||
# on Unix we need a g++ link, not gcc.
|
||||
# Ff line contributed by Daniel Harple.
|
||||
CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
|
||||
|
||||
when /linux/
|
||||
# on Unix we need a g++ link, not gcc.
|
||||
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
||||
|
||||
when /aix/
|
||||
CONFIG['LDSHARED'] = "$(CXX) -Wl,-bstatic -Wl,-bdynamic -Wl,-G -Wl,-brtl"
|
||||
|
||||
when /cygwin/
|
||||
# For rubies built with Cygwin, CXX may be set to CC, which is just
|
||||
# a wrapper for gcc.
|
||||
# This will compile, but it will not link to the C++ std library.
|
||||
# Explicitly set CXX to use g++.
|
||||
CONFIG['CXX'] = "g++"
|
||||
# on Unix we need a g++ link, not gcc.
|
||||
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
||||
|
||||
else
|
||||
# on Unix we need a g++ link, not gcc.
|
||||
CONFIG['LDSHARED'] = "$(CXX) -shared"
|
||||
end
|
||||
|
||||
create_makefile "fastfilereaderext"
|
||||
@@ -0,0 +1,214 @@
|
||||
/*****************************************************************************
|
||||
|
||||
$Id: mapper.cpp 4527 2007-07-04 10:21:34Z francis $
|
||||
|
||||
File: mapper.cpp
|
||||
Date: 02Jul07
|
||||
|
||||
Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved.
|
||||
Gmail: garbagecat10
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of either: 1) the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version; or 2) Ruby's License.
|
||||
|
||||
See the file COPYING for complete licensing information.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// UNIX implementation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#ifdef OS_UNIX
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "mapper.h"
|
||||
|
||||
/******************
|
||||
Mapper_t::Mapper_t
|
||||
******************/
|
||||
|
||||
Mapper_t::Mapper_t (const std::string &filename)
|
||||
{
|
||||
/* We ASSUME we can open the file.
|
||||
* (More precisely, we assume someone else checked before we got here.)
|
||||
*/
|
||||
|
||||
Fd = open (filename.c_str(), O_RDONLY);
|
||||
if (Fd < 0)
|
||||
throw std::runtime_error (strerror (errno));
|
||||
|
||||
struct stat st;
|
||||
if (fstat (Fd, &st))
|
||||
throw std::runtime_error (strerror (errno));
|
||||
FileSize = st.st_size;
|
||||
|
||||
#ifdef OS_WIN32
|
||||
MapPoint = (char*) mmap (0, FileSize, PROT_READ, MAP_SHARED, Fd, 0);
|
||||
#else
|
||||
MapPoint = (const char*) mmap (0, FileSize, PROT_READ, MAP_SHARED, Fd, 0);
|
||||
#endif
|
||||
if (MapPoint == MAP_FAILED)
|
||||
throw std::runtime_error (strerror (errno));
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
Mapper_t::~Mapper_t
|
||||
*******************/
|
||||
|
||||
Mapper_t::~Mapper_t()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
Mapper_t::Close
|
||||
***************/
|
||||
|
||||
void Mapper_t::Close()
|
||||
{
|
||||
// Can be called multiple times.
|
||||
// Calls to GetChunk are invalid after a call to Close.
|
||||
if (MapPoint) {
|
||||
#ifdef CC_SUNWspro
|
||||
// TODO: The void * cast works fine on Solaris 11, but
|
||||
// I don't know at what point that changed from older Solaris.
|
||||
munmap ((char*)MapPoint, FileSize);
|
||||
#else
|
||||
munmap ((void*)MapPoint, FileSize);
|
||||
#endif
|
||||
MapPoint = NULL;
|
||||
}
|
||||
if (Fd >= 0) {
|
||||
close (Fd);
|
||||
Fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/******************
|
||||
Mapper_t::GetChunk
|
||||
******************/
|
||||
|
||||
const char *Mapper_t::GetChunk (unsigned start)
|
||||
{
|
||||
return MapPoint + start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // OS_UNIX
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// WINDOWS implementation
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef OS_WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "mapper.h"
|
||||
|
||||
/******************
|
||||
Mapper_t::Mapper_t
|
||||
******************/
|
||||
|
||||
Mapper_t::Mapper_t (const std::string &filename)
|
||||
{
|
||||
/* We ASSUME we can open the file.
|
||||
* (More precisely, we assume someone else checked before we got here.)
|
||||
*/
|
||||
|
||||
hFile = INVALID_HANDLE_VALUE;
|
||||
hMapping = NULL;
|
||||
MapPoint = NULL;
|
||||
FileSize = 0;
|
||||
|
||||
hFile = CreateFile (filename.c_str(), GENERIC_READ|GENERIC_WRITE, FILE_SHARE_DELETE|FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
throw std::runtime_error ("File not found");
|
||||
|
||||
BY_HANDLE_FILE_INFORMATION i;
|
||||
if (GetFileInformationByHandle (hFile, &i))
|
||||
FileSize = i.nFileSizeLow;
|
||||
|
||||
hMapping = CreateFileMapping (hFile, NULL, PAGE_READWRITE, 0, 0, NULL);
|
||||
if (!hMapping)
|
||||
throw std::runtime_error ("File not mapped");
|
||||
|
||||
#ifdef OS_WIN32
|
||||
MapPoint = (char*) MapViewOfFile (hMapping, FILE_MAP_WRITE, 0, 0, 0);
|
||||
#else
|
||||
MapPoint = (const char*) MapViewOfFile (hMapping, FILE_MAP_WRITE, 0, 0, 0);
|
||||
#endif
|
||||
if (!MapPoint)
|
||||
throw std::runtime_error ("Mappoint not read");
|
||||
}
|
||||
|
||||
|
||||
/*******************
|
||||
Mapper_t::~Mapper_t
|
||||
*******************/
|
||||
|
||||
Mapper_t::~Mapper_t()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
/***************
|
||||
Mapper_t::Close
|
||||
***************/
|
||||
|
||||
void Mapper_t::Close()
|
||||
{
|
||||
// Can be called multiple times.
|
||||
// Calls to GetChunk are invalid after a call to Close.
|
||||
if (MapPoint) {
|
||||
UnmapViewOfFile (MapPoint);
|
||||
MapPoint = NULL;
|
||||
}
|
||||
if (hMapping != NULL) {
|
||||
CloseHandle (hMapping);
|
||||
hMapping = NULL;
|
||||
}
|
||||
if (hFile != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle (hFile);
|
||||
hFile = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************
|
||||
Mapper_t::GetChunk
|
||||
******************/
|
||||
|
||||
const char *Mapper_t::GetChunk (unsigned start)
|
||||
{
|
||||
return MapPoint + start;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // OS_WINDOWS
|
||||
@@ -0,0 +1,59 @@
|
||||
/*****************************************************************************
|
||||
|
||||
$Id: mapper.h 4529 2007-07-04 11:32:22Z francis $
|
||||
|
||||
File: mapper.h
|
||||
Date: 02Jul07
|
||||
|
||||
Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved.
|
||||
Gmail: garbagecat10
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of either: 1) the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version; or 2) Ruby's License.
|
||||
|
||||
See the file COPYING for complete licensing information.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef __Mapper__H_
|
||||
#define __Mapper__H_
|
||||
|
||||
|
||||
/**************
|
||||
class Mapper_t
|
||||
**************/
|
||||
|
||||
class Mapper_t
|
||||
{
|
||||
public:
|
||||
Mapper_t (const std::string&);
|
||||
virtual ~Mapper_t();
|
||||
|
||||
const char *GetChunk (unsigned);
|
||||
void Close();
|
||||
size_t GetFileSize() {return FileSize;}
|
||||
|
||||
private:
|
||||
size_t FileSize;
|
||||
|
||||
#ifdef OS_UNIX
|
||||
private:
|
||||
int Fd;
|
||||
const char *MapPoint;
|
||||
#endif // OS_UNIX
|
||||
|
||||
#ifdef OS_WIN32
|
||||
private:
|
||||
HANDLE hFile;
|
||||
HANDLE hMapping;
|
||||
char *MapPoint;
|
||||
#endif // OS_WIN32
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __Mapper__H_
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*****************************************************************************
|
||||
|
||||
$Id: rubymain.cpp 4529 2007-07-04 11:32:22Z francis $
|
||||
|
||||
File: rubymain.cpp
|
||||
Date: 02Jul07
|
||||
|
||||
Copyright (C) 2007 by Francis Cianfrocca. All Rights Reserved.
|
||||
Gmail: garbagecat10
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of either: 1) the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version; or 2) Ruby's License.
|
||||
|
||||
See the file COPYING for complete licensing information.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <ruby.h>
|
||||
#include "mapper.h"
|
||||
|
||||
static VALUE EmModule;
|
||||
static VALUE FastFileReader;
|
||||
static VALUE Mapper;
|
||||
|
||||
|
||||
|
||||
/*********
|
||||
mapper_dt
|
||||
*********/
|
||||
|
||||
static void mapper_dt (void *ptr)
|
||||
{
|
||||
if (ptr)
|
||||
delete (Mapper_t*) ptr;
|
||||
}
|
||||
|
||||
/**********
|
||||
mapper_new
|
||||
**********/
|
||||
|
||||
static VALUE mapper_new (VALUE self, VALUE filename)
|
||||
{
|
||||
Mapper_t *m = new Mapper_t (StringValueCStr (filename));
|
||||
if (!m)
|
||||
rb_raise (rb_eStandardError, "No Mapper Object");
|
||||
VALUE v = Data_Wrap_Struct (Mapper, 0, mapper_dt, (void*)m);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
mapper_get_chunk
|
||||
****************/
|
||||
|
||||
static VALUE mapper_get_chunk (VALUE self, VALUE start, VALUE length)
|
||||
{
|
||||
Mapper_t *m = NULL;
|
||||
Data_Get_Struct (self, Mapper_t, m);
|
||||
if (!m)
|
||||
rb_raise (rb_eStandardError, "No Mapper Object");
|
||||
|
||||
// TODO, what if some moron sends us a negative start value?
|
||||
unsigned _start = NUM2INT (start);
|
||||
unsigned _length = NUM2INT (length);
|
||||
if ((_start + _length) > m->GetFileSize())
|
||||
rb_raise (rb_eStandardError, "Mapper Range Error");
|
||||
|
||||
const char *chunk = m->GetChunk (_start);
|
||||
if (!chunk)
|
||||
rb_raise (rb_eStandardError, "No Mapper Chunk");
|
||||
return rb_str_new (chunk, _length);
|
||||
}
|
||||
|
||||
/************
|
||||
mapper_close
|
||||
************/
|
||||
|
||||
static VALUE mapper_close (VALUE self)
|
||||
{
|
||||
Mapper_t *m = NULL;
|
||||
Data_Get_Struct (self, Mapper_t, m);
|
||||
if (!m)
|
||||
rb_raise (rb_eStandardError, "No Mapper Object");
|
||||
m->Close();
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
/***********
|
||||
mapper_size
|
||||
***********/
|
||||
|
||||
static VALUE mapper_size (VALUE self)
|
||||
{
|
||||
Mapper_t *m = NULL;
|
||||
Data_Get_Struct (self, Mapper_t, m);
|
||||
if (!m)
|
||||
rb_raise (rb_eStandardError, "No Mapper Object");
|
||||
return INT2NUM (m->GetFileSize());
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
Init_fastfilereaderext
|
||||
**********************/
|
||||
|
||||
extern "C" void Init_fastfilereaderext()
|
||||
{
|
||||
EmModule = rb_define_module ("EventMachine");
|
||||
FastFileReader = rb_define_class_under (EmModule, "FastFileReader", rb_cObject);
|
||||
Mapper = rb_define_class_under (FastFileReader, "Mapper", rb_cObject);
|
||||
|
||||
rb_define_module_function (Mapper, "new", (VALUE(*)(...))mapper_new, 1);
|
||||
rb_define_method (Mapper, "size", (VALUE(*)(...))mapper_size, 0);
|
||||
rb_define_method (Mapper, "close", (VALUE(*)(...))mapper_close, 0);
|
||||
rb_define_method (Mapper, "get_chunk", (VALUE(*)(...))mapper_get_chunk, 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user