summaryrefslogtreecommitdiff
path: root/ruby_1_8_6/ext/dl/sample
diff options
context:
space:
mode:
Diffstat (limited to 'ruby_1_8_6/ext/dl/sample')
-rw-r--r--ruby_1_8_6/ext/dl/sample/c++sample.C35
-rw-r--r--ruby_1_8_6/ext/dl/sample/c++sample.rb60
-rw-r--r--ruby_1_8_6/ext/dl/sample/drives.rb70
-rw-r--r--ruby_1_8_6/ext/dl/sample/getch.rb5
-rw-r--r--ruby_1_8_6/ext/dl/sample/libc.rb69
-rw-r--r--ruby_1_8_6/ext/dl/sample/msgbox.rb19
-rw-r--r--ruby_1_8_6/ext/dl/sample/msgbox2.rb18
-rw-r--r--ruby_1_8_6/ext/dl/sample/stream.rb87
8 files changed, 363 insertions, 0 deletions
diff --git a/ruby_1_8_6/ext/dl/sample/c++sample.C b/ruby_1_8_6/ext/dl/sample/c++sample.C
new file mode 100644
index 0000000000..d083d337a7
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/c++sample.C
@@ -0,0 +1,35 @@
+#include <stdio.h>
+
+class Person {
+private:
+ const char *name;
+ int age;
+
+public:
+ Person(const char *name, int age);
+ const char * get_name();
+ int get_age();
+ void set_age(int i);
+};
+
+Person::Person(const char *name, int age)
+ : name(name), age(age)
+{
+ /* empty */
+}
+
+const char *
+Person::get_name()
+{
+ return name;
+}
+
+int
+Person::get_age(){
+ return age;
+}
+
+void
+Person::set_age(int i){
+ age = i;
+}
diff --git a/ruby_1_8_6/ext/dl/sample/c++sample.rb b/ruby_1_8_6/ext/dl/sample/c++sample.rb
new file mode 100644
index 0000000000..29887df845
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/c++sample.rb
@@ -0,0 +1,60 @@
+=begin
+ This script shows how to deal with C++ classes using Ruby/DL.
+ You must build a dynamic loadable library using "c++sample.C"
+ to run this script as follows:
+ $ g++ -o libsample.so -shared c++sample.C
+=end
+
+require 'dl'
+require 'dl/import'
+require 'dl/struct'
+
+# Give a name of dynamic loadable library
+LIBNAME = ARGV[0] || "libsample.so"
+
+class Person
+ module Core
+ extend DL::Importable
+
+ dlload LIBNAME
+
+ # mangled symbol names
+ extern "void __6PersonPCci(void *, const char *, int)"
+ extern "const char *get_name__6Person(void *)"
+ extern "int get_age__6Person(void *)"
+ extern "void set_age__6Personi(void *, int)"
+
+ Data = struct [
+ "char *name",
+ "int age",
+ ]
+ end
+
+ def initialize(name, age)
+ @ptr = Core::Data.alloc
+ Core::__6PersonPCci(@ptr, name, age)
+ end
+
+ def get_name()
+ str = Core::get_name__6Person(@ptr)
+ if( str )
+ str.to_s
+ else
+ nil
+ end
+ end
+
+ def get_age()
+ Core::get_age__6Person(@ptr)
+ end
+
+ def set_age(age)
+ Core::set_age__6Personi(@ptr, age)
+ end
+end
+
+obj = Person.new("ttate", 1)
+p obj.get_name()
+p obj.get_age()
+obj.set_age(10)
+p obj.get_age()
diff --git a/ruby_1_8_6/ext/dl/sample/drives.rb b/ruby_1_8_6/ext/dl/sample/drives.rb
new file mode 100644
index 0000000000..8a590404b1
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/drives.rb
@@ -0,0 +1,70 @@
+# -*- ruby -*-
+# drives.rb -- find existing drives and show the drive type.
+
+require 'dl'
+require 'dl/import'
+
+module Kernel32
+ extend DL::Importable
+
+ dlload "kernel32"
+
+ extern "long GetLogicalDrives()"
+ extern "int GetDriveType(char*)"
+ extern "long GetDiskFreeSpace(char*, long ref, long ref, long ref, long ref)"
+end
+
+include Kernel32
+
+buff = Kernel32.getLogicalDrives()
+
+i = 0
+ds = []
+while( i < 26 )
+ mask = (1 << i)
+ if( buff & mask > 0 )
+ ds.push((65+i).chr)
+ end
+ i += 1
+end
+
+=begin
+From the cygwin's /usr/include/w32api/winbase.h:
+#define DRIVE_UNKNOWN 0
+#define DRIVE_NO_ROOT_DIR 1
+#define DRIVE_REMOVABLE 2
+#define DRIVE_FIXED 3
+#define DRIVE_REMOTE 4
+#define DRIVE_CDROM 5
+#define DRIVE_RAMDISK 6
+=end
+
+types = [
+ "unknown",
+ "no root dir",
+ "Removable",
+ "Fixed",
+ "Remote",
+ "CDROM",
+ "RAM",
+]
+print("Drive : Type (Free Space/Available Space)\n")
+ds.each{|d|
+ t = Kernel32.getDriveType(d + ":\\")
+ Kernel32.getDiskFreeSpace(d + ":\\", 0, 0, 0, 0)
+ _,sec_per_clus,byte_per_sec,free_clus,total_clus = Kernel32._args_
+ fbytes = sec_per_clus * byte_per_sec * free_clus
+ tbytes = sec_per_clus * byte_per_sec * total_clus
+ unit = "B"
+ if( fbytes > 1024 && tbytes > 1024 )
+ fbytes = fbytes / 1024
+ tbytes = tbytes / 1024
+ unit = "K"
+ end
+ if( fbytes > 1024 && tbytes > 1024 )
+ fbytes = fbytes / 1024
+ tbytes = tbytes / 1024
+ unit = "M"
+ end
+ print("#{d} : #{types[t]} (#{fbytes} #{unit}/#{tbytes} #{unit})\n")
+}
diff --git a/ruby_1_8_6/ext/dl/sample/getch.rb b/ruby_1_8_6/ext/dl/sample/getch.rb
new file mode 100644
index 0000000000..3f7261c979
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/getch.rb
@@ -0,0 +1,5 @@
+require 'dl'
+
+crtdll = DL::dlopen("crtdll")
+getch = crtdll['_getch', 'L']
+print(getch.call, "\n")
diff --git a/ruby_1_8_6/ext/dl/sample/libc.rb b/ruby_1_8_6/ext/dl/sample/libc.rb
new file mode 100644
index 0000000000..a1f6fbe543
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/libc.rb
@@ -0,0 +1,69 @@
+require "dl/import"
+require "dl/struct"
+
+module LIBC
+ extend DL::Importable
+
+ begin
+ dlload "libc.so.6"
+ rescue
+ dlload "libc.so.5"
+ end
+
+ extern "int atoi(char*)"
+ extern "ibool isdigit(int)"
+ extern "int gettimeofday(struct timeval *, struct timezone *)"
+ extern "char* strcat(char*, char*)"
+ extern "FILE* fopen(char*, char*)"
+ extern "int fclose(FILE*)"
+ extern "int fgetc(FILE*)"
+ extern "int strlen(char*)"
+ extern "void qsort(void*, int, int, void*)"
+
+ def str_qsort(ary, comp)
+ len = ary.length
+ r,rs = qsort(ary, len, DL.sizeof('P'), comp)
+ return rs[0].to_a('S', len)
+ end
+
+ Timeval = struct [
+ "long tv_sec",
+ "long tv_usec",
+ ]
+
+ Timezone = struct [
+ "int tz_minuteswest",
+ "int tz_dsttime",
+ ]
+
+ def my_compare(ptr1, ptr2)
+ ptr1.ptr.to_s <=> ptr2.ptr.to_s
+ end
+ COMPARE = callback("int my_compare(char**, char**)")
+end
+
+
+$cb1 = DL.callback('IPP'){|ptr1, ptr2|
+ str1 = ptr1.ptr.to_s
+ str2 = ptr2.ptr.to_s
+ str1 <=> str2
+}
+
+p LIBC.atoi("10")
+
+p LIBC.isdigit(?1)
+
+p LIBC.isdigit(?a)
+
+p LIBC.strcat("a", "b")
+
+ary = ["a","c","b"]
+ptr = ary.to_ptr
+LIBC.qsort(ptr, ary.length, DL.sizeof('P'), LIBC::COMPARE)
+p ptr.to_a('S', ary.length)
+
+tv = LIBC::Timeval.malloc
+tz = LIBC::Timezone.malloc
+LIBC.gettimeofday(tv, tz)
+
+p Time.at(tv.tv_sec)
diff --git a/ruby_1_8_6/ext/dl/sample/msgbox.rb b/ruby_1_8_6/ext/dl/sample/msgbox.rb
new file mode 100644
index 0000000000..091e646091
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/msgbox.rb
@@ -0,0 +1,19 @@
+# This script works on Windows.
+
+require 'dl'
+
+User32 = DL.dlopen("user32")
+Kernel32 = DL.dlopen("kernel32")
+
+MB_OK = 0
+MB_OKCANCEL = 1
+
+message_box = User32['MessageBoxA', 'ILSSI']
+r,rs = message_box.call(0, 'ok?', 'error', MB_OKCANCEL)
+
+case r
+when 1
+ print("OK!\n")
+when 2
+ print("Cancel!\n")
+end
diff --git a/ruby_1_8_6/ext/dl/sample/msgbox2.rb b/ruby_1_8_6/ext/dl/sample/msgbox2.rb
new file mode 100644
index 0000000000..e49846cc5e
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/msgbox2.rb
@@ -0,0 +1,18 @@
+# This script works on Windows.
+
+require 'dl/win32'
+
+MB_OK = 0
+MB_OKCANCEL = 1
+
+message_box = Win32API.new("user32",'MessageBoxA', 'ISSI', 'I')
+r = message_box.call(0, 'ok?', 'error', MB_OKCANCEL)
+
+case r
+when 1
+ print("OK!\n")
+when 2
+ print("Cancel!\n")
+else
+ p r
+end
diff --git a/ruby_1_8_6/ext/dl/sample/stream.rb b/ruby_1_8_6/ext/dl/sample/stream.rb
new file mode 100644
index 0000000000..179836999d
--- /dev/null
+++ b/ruby_1_8_6/ext/dl/sample/stream.rb
@@ -0,0 +1,87 @@
+# -*- ruby -*-
+# Display a file name and stream names of a file with those size.
+
+require 'dl'
+require 'dl/import'
+
+module NTFS
+ extend DL::Importable
+
+ dlload "kernel32.dll"
+
+ OPEN_EXISTING = 3
+ GENERIC_READ = 0x80000000
+ BACKUP_DATA = 0x00000001
+ BACKUP_ALTERNATE_DATA = 0x00000004
+ FILE_SHARE_READ = 0x00000001
+ FILE_FLAG_BACKUP_SEMANTICS = 0x02000000
+
+ typealias "LPSECURITY_ATTRIBUTES", "void*"
+
+ extern "BOOL BackupRead(HANDLE, PBYTE, DWORD, PDWORD, BOOL, BOOL, PVOID)"
+ extern "BOOL BackupSeek(HANDLE, DWORD, DWORD, PDWORD, PDWORD, PVOID)"
+ extern "BOOL CloseHandle(HANDLE)"
+ extern "HANDLE CreateFile(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES,
+ DWORD, DWORD, HANDLE)"
+
+ module_function
+
+ def streams(filename)
+ status = []
+ h = createFile(filename,GENERIC_READ,FILE_SHARE_READ,nil,
+ OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0)
+ if( h != 0 )
+ begin
+ # allocate the memory for backup data used in backupRead().
+ data = DL.malloc(DL.sizeof("L5"))
+ data.struct!("LLLLL", :id, :attrs, :size_low, :size_high, :name_size)
+
+ # allocate memories for references to long values used in backupRead().
+ context = DL.malloc(DL.sizeof("L"))
+ lval = DL.malloc(DL.sizeof("L"))
+
+ while( backupRead(h, data, data.size, lval, false, false, context) )
+ size = data[:size_low] + (data[:size_high] << (DL.sizeof("I") * 8))
+ case data[:id]
+ when BACKUP_ALTERNATE_DATA
+ stream_name = DL.malloc(data[:name_size])
+ backupRead(h, stream_name, stream_name.size,
+ lval, false, false, context)
+ name = stream_name[0, stream_name.size]
+ name.tr!("\000","")
+ if( name =~ /^:(.*?):.*$/ )
+ status.push([$1,size])
+ end
+ when BACKUP_DATA
+ status.push([nil,size])
+ else
+ raise(RuntimeError, "unknown data type #{data[:id]}.")
+ end
+ l1 = DL.malloc(DL.sizeof("L"))
+ l2 = DL.malloc(DL.sizeof("L"))
+ if( !backupSeek(h, data[:size_low], data[:size_high], l1, l2, context) )
+ break
+ end
+ end
+ ensure
+ backupRead(h, nil, 0, lval, true, false, context)
+ closeHandle(h)
+ end
+ return status
+ else
+ raise(RuntimeError, "can't open #{filename}.\n")
+ end
+ end
+end
+
+ARGV.each{|filename|
+ if( File.exist?(filename) )
+ NTFS.streams(filename).each{|name,size|
+ if( name )
+ print("#{filename}:#{name}\t#{size}bytes\n")
+ else
+ print("#{filename}\t#{size}bytes\n")
+ end
+ }
+ end
+}