diff options
Diffstat (limited to 'ruby_1_8_6/ext/digest/digest.c')
-rw-r--r-- | ruby_1_8_6/ext/digest/digest.c | 642 |
1 files changed, 0 insertions, 642 deletions
diff --git a/ruby_1_8_6/ext/digest/digest.c b/ruby_1_8_6/ext/digest/digest.c deleted file mode 100644 index 0b910e8c47..0000000000 --- a/ruby_1_8_6/ext/digest/digest.c +++ /dev/null @@ -1,642 +0,0 @@ -/************************************************ - - digest.c - - - $Author$ - created at: Fri May 25 08:57:27 JST 2001 - - Copyright (C) 1995-2001 Yukihiro Matsumoto - Copyright (C) 2001-2006 Akinori MUSHA - - $RoughId: digest.c,v 1.16 2001/07/13 15:38:27 knu Exp $ - $Id$ - -************************************************/ - -#include "digest.h" - -static VALUE rb_mDigest; -static VALUE rb_mDigest_Instance; -static VALUE rb_cDigest_Class; -static VALUE rb_cDigest_Base; - -static ID id_reset, id_update, id_finish, id_digest, id_hexdigest, id_digest_length; -static ID id_metadata; - -RUBY_EXTERN void Init_digest_base(void); - -/* - * Document-module: Digest - * - * This module provides a framework for message digest libraries. - */ - -static VALUE -hexencode_str_new(VALUE str_digest) -{ - char *digest; - size_t digest_len; - int i; - VALUE str; - char *p; - static const char hex[] = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - 'a', 'b', 'c', 'd', 'e', 'f' - }; - - StringValue(str_digest); - digest = RSTRING_PTR(str_digest); - digest_len = RSTRING_LEN(str_digest); - - if (LONG_MAX / 2 < digest_len) { - rb_raise(rb_eRuntimeError, "digest string too long"); - } - - str = rb_str_new(0, digest_len * 2); - - for (i = 0, p = RSTRING_PTR(str); i < digest_len; i++) { - unsigned char byte = digest[i]; - - p[i + i] = hex[byte >> 4]; - p[i + i + 1] = hex[byte & 0x0f]; - } - - return str; -} - -/* - * call-seq: - * Digest.hexencode(string) -> hexencoded_string - * - * Generates a hex-encoded version of a given _string_. - */ -static VALUE -rb_digest_s_hexencode(VALUE klass, VALUE str) -{ - return hexencode_str_new(str); -} - -/* - * Document-module: Digest::Instance - * - * This module provides instance methods for a digest implementation - * object to calculate message digest values. - */ - -/* - * call-seq: - * digest_obj.update(string) -> digest_obj - * digest_obj << string -> digest_obj - * - * Updates the digest using a given _string_ and returns self. - * - * The update() method and the left-shift operator are overridden by - * each implementation subclass. (One should be an alias for the - * other) - */ -static VALUE -rb_digest_instance_update(VALUE self, VALUE str) -{ - rb_raise(rb_eRuntimeError, "%s does not implement update()", RSTRING_PTR(rb_inspect(self))); -} - -/* - * call-seq: - * digest_obj.instance_eval { finish } -> digest_obj - * - * Finishes the digest and returns the resulting hash value. - * - * This method is overridden by each implementation subclass and often - * made private, because some of those subclasses may leave internal - * data uninitialized. Do not call this method from outside. Use - * #digest!() instead, which ensures that internal data be reset for - * security reasons. - */ -static VALUE -rb_digest_instance_finish(VALUE self) -{ - rb_raise(rb_eRuntimeError, "%s does not implement finish()", RSTRING_PTR(rb_inspect(self))); -} - -/* - * call-seq: - * digest_obj.reset -> digest_obj - * - * Resets the digest to the initial state and returns self. - * - * This method is overridden by each implementation subclass. - */ -static VALUE -rb_digest_instance_reset(VALUE self) -{ - rb_raise(rb_eRuntimeError, "%s does not implement reset()", RSTRING_PTR(rb_inspect(self))); -} - -/* - * call-seq: - * digest_obj.new -> another_digest_obj - * - * Returns a new, initialized copy of the digest object. Equivalent - * to digest_obj.clone().reset(). - */ -static VALUE -rb_digest_instance_new(VALUE self) -{ - VALUE clone = rb_obj_clone(self); - rb_funcall(clone, id_reset, 0); - return clone; -} - -/* - * call-seq: - * digest_obj.digest -> string - * digest_obj.digest(string) -> string - * - * If none is given, returns the resulting hash value of the digest, - * keeping the digest's state. - * - * If a _string_ is given, returns the hash value for the given - * _string_, resetting the digest to the initial state before and - * after the process. - */ -static VALUE -rb_digest_instance_digest(int argc, VALUE *argv, VALUE self) -{ - VALUE str, value; - - if (rb_scan_args(argc, argv, "01", &str) > 0) { - rb_funcall(self, id_reset, 0); - rb_funcall(self, id_update, 1, str); - value = rb_funcall(self, id_finish, 0); - rb_funcall(self, id_reset, 0); - } else { - VALUE clone = rb_obj_clone(self); - - value = rb_funcall(clone, id_finish, 0); - rb_funcall(clone, id_reset, 0); - } - - return value; -} - -/* - * call-seq: - * digest_obj.digest! -> string - * - * Returns the resulting hash value and resets the digest to the - * initial state. - */ -static VALUE -rb_digest_instance_digest_bang(VALUE self) -{ - VALUE value = rb_funcall(self, id_finish, 0); - rb_funcall(self, id_reset, 0); - - return value; -} - -/* - * call-seq: - * digest_obj.hexdigest -> string - * digest_obj.hexdigest(string) -> string - * - * If none is given, returns the resulting hash value of the digest in - * a hex-encoded form, keeping the digest's state. - * - * If a _string_ is given, returns the hash value for the given - * _string_ in a hex-encoded form, resetting the digest to the initial - * state before and after the process. - */ -static VALUE -rb_digest_instance_hexdigest(int argc, VALUE *argv, VALUE self) -{ - VALUE str, value; - - if (rb_scan_args(argc, argv, "01", &str) > 0) { - rb_funcall(self, id_reset, 0); - rb_funcall(self, id_update, 1, str); - value = rb_funcall(self, id_finish, 0); - rb_funcall(self, id_reset, 0); - } else { - VALUE clone = rb_obj_clone(self); - - value = rb_funcall(clone, id_finish, 0); - rb_funcall(clone, id_reset, 0); - } - - return hexencode_str_new(value); -} - -/* - * call-seq: - * digest_obj.hexdigest! -> string - * - * Returns the resulting hash value and resets the digest to the - * initial state. - */ -static VALUE -rb_digest_instance_hexdigest_bang(VALUE self) -{ - VALUE value = rb_funcall(self, id_finish, 0); - rb_funcall(self, id_reset, 0); - - return hexencode_str_new(value); -} - -/* - * call-seq: - * digest_obj.to_s -> string - * - * Returns digest_obj.hexdigest(). - */ -static VALUE -rb_digest_instance_to_s(VALUE self) -{ - return rb_funcall(self, id_hexdigest, 0); -} - -/* - * call-seq: - * digest_obj.inspect -> string - * - * Creates a printable version of the digest object. - */ -static VALUE -rb_digest_instance_inspect(VALUE self) -{ - VALUE str; - size_t digest_len = 32; /* about this size at least */ - char *cname; - - cname = rb_obj_classname(self); - - /* #<Digest::ClassName: xxxxx...xxxx> */ - str = rb_str_buf_new(2 + strlen(cname) + 2 + digest_len * 2 + 1); - rb_str_buf_cat2(str, "#<"); - rb_str_buf_cat2(str, cname); - rb_str_buf_cat2(str, ": "); - rb_str_buf_append(str, rb_digest_instance_hexdigest(0, 0, self)); - rb_str_buf_cat2(str, ">"); - return str; -} - -/* - * call-seq: - * digest_obj == another_digest_obj -> boolean - * digest_obj == string -> boolean - * - * If a string is given, checks whether it is equal to the hex-encoded - * hash value of the digest object. If another digest instance is - * given, checks whether they have the same hash value. Otherwise - * returns false. - */ -static VALUE -rb_digest_instance_equal(VALUE self, VALUE other) -{ - VALUE str1, str2; - - if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) { - str1 = rb_digest_instance_digest(0, 0, self); - str2 = rb_digest_instance_digest(0, 0, other); - } else { - str1 = rb_digest_instance_to_s(self); - str2 = other; - } - - /* never blindly assume that subclass methods return strings */ - StringValue(str1); - StringValue(str2); - - if (RSTRING_LEN(str1) == RSTRING_LEN(str2) && - rb_str_cmp(str1, str2) == 0) { - return Qtrue; - } - return Qfalse; -} - -/* - * call-seq: - * digest_obj.digest_length -> integer - * - * Returns the length of the hash value of the digest. - * - * This method should be overridden by each implementation subclass. - * If not, digest_obj.digest().length() is returned. - */ -static VALUE -rb_digest_instance_digest_length(VALUE self) -{ - /* subclasses really should redefine this method */ - VALUE digest = rb_digest_instance_digest(0, 0, self); - - /* never blindly assume that #digest() returns a string */ - StringValue(digest); - return INT2NUM(RSTRING_LEN(digest)); -} - -/* - * call-seq: - * digest_obj.length -> integer - * digest_obj.size -> integer - * - * Returns digest_obj.digest_length(). - */ -static VALUE -rb_digest_instance_length(VALUE self) -{ - return rb_funcall(self, id_digest_length, 0); -} - -/* - * call-seq: - * digest_obj.block_length -> integer - * - * Returns the block length of the digest. - * - * This method is overridden by each implementation subclass. - */ -static VALUE -rb_digest_instance_block_length(VALUE self) -{ - rb_raise(rb_eRuntimeError, "%s does not implement block_length()", RSTRING_PTR(rb_inspect(self))); -} - -/* - * Document-class: Digest::Class - * - * This module stands as a base class for digest implementation - * classes. - */ - -/* - * call-seq: - * Digest::Class.digest(string, *parameters) -> hash_string - * - * Returns the hash value of a given _string_. This is equivalent to - * Digest::Class.new(*parameters).digest(string), where extra - * _parameters_, if any, are passed through to the constructor and the - * _string_ is passed to #digest(). - */ -static VALUE -rb_digest_class_s_digest(int argc, VALUE *argv, VALUE klass) -{ - VALUE str; - volatile VALUE obj; - - if (argc < 1) { - rb_raise(rb_eArgError, "no data given"); - } - - str = *argv++; - argc--; - - StringValue(str); - - obj = rb_obj_alloc(klass); - rb_obj_call_init(obj, argc, argv); - - return rb_funcall(obj, id_digest, 1, str); -} - -/* - * call-seq: - * Digest::Class.hexdigest(string[, ...]) -> hash_string - * - * Returns the hex-encoded hash value of a given _string_. This is - * almost equivalent to - * Digest.hexencode(Digest::Class.new(*parameters).digest(string)). - */ -static VALUE -rb_digest_class_s_hexdigest(int argc, VALUE *argv, VALUE klass) -{ - return hexencode_str_new(rb_funcall2(klass, id_digest, argc, argv)); -} - -/* - * Document-class: Digest::Base - * - * This abstract class provides a common interface to message digest - * implementation classes written in C. - */ - -static rb_digest_metadata_t * -get_digest_base_metadata(VALUE klass) -{ - VALUE p; - VALUE obj; - rb_digest_metadata_t *algo; - - for (p = klass; p; p = RCLASS(p)->super) { - if (rb_ivar_defined(p, id_metadata)) { - obj = rb_ivar_get(p, id_metadata); - break; - } - } - - if (!p) - rb_raise(rb_eRuntimeError, "Digest::Base cannot be directly inherited in Ruby"); - - Data_Get_Struct(obj, rb_digest_metadata_t, algo); - - switch (algo->api_version) { - case 2: - break; - - /* - * put conversion here if possible when API is updated - */ - - default: - rb_raise(rb_eRuntimeError, "Incompatible digest API version"); - } - - return algo; -} - -static VALUE -rb_digest_base_alloc(VALUE klass) -{ - rb_digest_metadata_t *algo; - VALUE obj; - void *pctx; - - if (klass == rb_cDigest_Base) { - rb_raise(rb_eNotImpError, "Digest::Base is an abstract class"); - } - - algo = get_digest_base_metadata(klass); - - pctx = xmalloc(algo->ctx_size); - algo->init_func(pctx); - - obj = Data_Wrap_Struct(klass, 0, free, pctx); - - return obj; -} - -/* :nodoc: */ -static VALUE -rb_digest_base_copy(VALUE copy, VALUE obj) -{ - rb_digest_metadata_t *algo; - void *pctx1, *pctx2; - - if (copy == obj) return copy; - - rb_check_frozen(copy); - - algo = get_digest_base_metadata(rb_obj_class(copy)); - - Data_Get_Struct(obj, void, pctx1); - Data_Get_Struct(copy, void, pctx2); - memcpy(pctx2, pctx1, algo->ctx_size); - - return copy; -} - -/* :nodoc: */ -static VALUE -rb_digest_base_reset(VALUE self) -{ - rb_digest_metadata_t *algo; - void *pctx; - - algo = get_digest_base_metadata(rb_obj_class(self)); - - Data_Get_Struct(self, void, pctx); - - algo->init_func(pctx); - - return self; -} - -/* :nodoc: */ -static VALUE -rb_digest_base_update(VALUE self, VALUE str) -{ - rb_digest_metadata_t *algo; - void *pctx; - - algo = get_digest_base_metadata(rb_obj_class(self)); - - Data_Get_Struct(self, void, pctx); - - StringValue(str); - algo->update_func(pctx, (unsigned char *)RSTRING_PTR(str), RSTRING_LEN(str)); - - return self; -} - -/* :nodoc: */ -static VALUE -rb_digest_base_finish(VALUE self) -{ - rb_digest_metadata_t *algo; - void *pctx; - VALUE str; - - algo = get_digest_base_metadata(rb_obj_class(self)); - - Data_Get_Struct(self, void, pctx); - - str = rb_str_new(0, algo->digest_len); - algo->finish_func(pctx, (unsigned char *)RSTRING_PTR(str)); - - /* avoid potential coredump caused by use of a finished context */ - algo->init_func(pctx); - - return str; -} - -/* :nodoc: */ -static VALUE -rb_digest_base_digest_length(VALUE self) -{ - rb_digest_metadata_t *algo; - - algo = get_digest_base_metadata(rb_obj_class(self)); - - return INT2NUM(algo->digest_len); -} - -/* :nodoc: */ -static VALUE -rb_digest_base_block_length(VALUE self) -{ - rb_digest_metadata_t *algo; - - algo = get_digest_base_metadata(rb_obj_class(self)); - - return INT2NUM(algo->block_len); -} - -void -Init_digest(void) -{ - id_reset = rb_intern("reset"); - id_update = rb_intern("update"); - id_finish = rb_intern("finish"); - id_digest = rb_intern("digest"); - id_hexdigest = rb_intern("hexdigest"); - id_digest_length = rb_intern("digest_length"); - - /* - * module Digest - */ - rb_mDigest = rb_define_module("Digest"); - - /* module functions */ - rb_define_module_function(rb_mDigest, "hexencode", rb_digest_s_hexencode, 1); - - /* - * module Digest::Instance - */ - rb_mDigest_Instance = rb_define_module_under(rb_mDigest, "Instance"); - - /* instance methods that should be overridden */ - rb_define_method(rb_mDigest_Instance, "update", rb_digest_instance_update, 1); - rb_define_method(rb_mDigest_Instance, "<<", rb_digest_instance_update, 1); - rb_define_private_method(rb_mDigest_Instance, "finish", rb_digest_instance_finish, 0); - rb_define_method(rb_mDigest_Instance, "reset", rb_digest_instance_reset, 0); - rb_define_method(rb_mDigest_Instance, "digest_length", rb_digest_instance_digest_length, 0); - rb_define_method(rb_mDigest_Instance, "block_length", rb_digest_instance_block_length, 0); - - /* instance methods that may be overridden */ - rb_define_method(rb_mDigest_Instance, "==", rb_digest_instance_equal, 1); - rb_define_method(rb_mDigest_Instance, "inspect", rb_digest_instance_inspect, 0); - - /* instance methods that need not usually be overridden */ - rb_define_method(rb_mDigest_Instance, "new", rb_digest_instance_new, 0); - rb_define_method(rb_mDigest_Instance, "digest", rb_digest_instance_digest, -1); - rb_define_method(rb_mDigest_Instance, "digest!", rb_digest_instance_digest_bang, 0); - rb_define_method(rb_mDigest_Instance, "hexdigest", rb_digest_instance_hexdigest, -1); - rb_define_method(rb_mDigest_Instance, "hexdigest!", rb_digest_instance_hexdigest_bang, 0); - rb_define_method(rb_mDigest_Instance, "to_s", rb_digest_instance_to_s, 0); - rb_define_method(rb_mDigest_Instance, "length", rb_digest_instance_length, 0); - rb_define_method(rb_mDigest_Instance, "size", rb_digest_instance_length, 0); - - /* - * class Digest::Class - */ - rb_cDigest_Class = rb_define_class_under(rb_mDigest, "Class", rb_cObject); - rb_include_module(rb_cDigest_Class, rb_mDigest_Instance); - - /* class methods */ - rb_define_singleton_method(rb_cDigest_Class, "digest", rb_digest_class_s_digest, -1); - rb_define_singleton_method(rb_cDigest_Class, "hexdigest", rb_digest_class_s_hexdigest, -1); - - id_metadata = rb_intern("metadata"); - - /* class Digest::Base < Digest::Class */ - rb_cDigest_Base = rb_define_class_under(rb_mDigest, "Base", rb_cDigest_Class); - - rb_define_alloc_func(rb_cDigest_Base, rb_digest_base_alloc); - - rb_define_method(rb_cDigest_Base, "initialize_copy", rb_digest_base_copy, 1); - rb_define_method(rb_cDigest_Base, "reset", rb_digest_base_reset, 0); - rb_define_method(rb_cDigest_Base, "update", rb_digest_base_update, 1); - rb_define_method(rb_cDigest_Base, "<<", rb_digest_base_update, 1); - rb_define_private_method(rb_cDigest_Base, "finish", rb_digest_base_finish, 0); - rb_define_method(rb_cDigest_Base, "digest_length", rb_digest_base_digest_length, 0); - rb_define_method(rb_cDigest_Base, "block_length", rb_digest_base_block_length, 0); -} |