|  | 
          1楼
          巨大八爪鱼
          2016-1-25 11:37
          
          
            class Testattr_accessor :param1
 end
 
 $ob = Test.new
 $ob.param1 = "c";
 #p $ob
 
 #$file = File.open("object.dat", "wb")
 #Marshal.dump($ob, $file)
 #$file.close
 
 $file = File.open("number.dat", "wb")
 
 # 所有的整数数据都以0x040869开头,其中0x69是字符'i',也就是int的首字母
 #Marshal.dump(0, $file) # 04 08 69 00
 #Marshal.dump(1, $file) # 04 08 69 06, 1 = 0x06 - 0x05
 #Marshal.dump(2, $file) # 04 08 69 07, 2 = 0x07 - 0x05
 #Marshal.dump(120, $file) # 04 08 69 7D
 #Marshal.dump(122, $file) # 04 08 69 7F, 122 = 0x7F - 0x05
 
 #Marshal.dump(123, $file) # 04 08 69 01 7B, 123 = 0x7B
 #Marshal.dump(124, $file) # 04 08 69 01 7C
 #Marshal.dump(125, $file) # 04 08 69 01 7D
 #Marshal.dump(255, $file) # 04 08 69 01 FF, 255 = 0xFF
 #Marshal.dump(256, $file) # 04 08 69 02 00 01, 256 = 0x0100
 #Marshal.dump(257, $file) # 04 08 69 02 01 01, 257 = 0x0101
 #Marshal.dump(270, $file) # 04 08 69 02 0E 01, 270 = 0x010E
 #Marshal.dump(0xABCD, $file) # 04 08 69 02 CD AB
 #Marshal.dump(0xFFFF, $file) # 04 08 69 02 FF FF
 #Marshal.dump(0x10000, $file) # 04 08 69 03 00 00 01
 #Marshal.dump(0xABCDEF, $file) # 04 08 69 03 EF CD AB
 #Marshal.dump(0xFFFFFF, $file) # 04 08 69 03 FF FF FF
 
 #Marshal.dump(0x1000000, $file) # 04 08 69 04 00 00 00 01
 #Marshal.dump(0x2000000, $file) # 04 08 69 04 00 00 00 02
 #Marshal.dump(0xFFFFFFF, $file) # 04 08 69 04 FF FF FF 0F
 #Marshal.dump(0x10000000, $file) # 04 08 69 04 00 00 00 10
 #Marshal.dump(0x3FFFFFFF, $file) # 04 08 69 04 FF FF FF 3F
 
 #Marshal.dump(-1, $file) # 04 08 69 FA
 #Marshal.dump(-2, $file) # 04 08 69 F9
 #Marshal.dump(-3, $file) # 04 08 69 F8
 #Marshal.dump(-4, $file) # 04 08 69 F7
 #Marshal.dump(-5, $file) # 04 08 69 F6
 #Marshal.dump(-6, $file) # 04 08 69 F5
 #Marshal.dump(-122, $file) # 04 08 69 81
 #Marshal.dump(-123, $file) # 04 08 69 80
 #Marshal.dump(-124, $file) # 04 08 69 FF 84
 #Marshal.dump(-125, $file) # 04 08 69 FF 83
 
 # 从0x40000000开始是long型,也就是1073741824
 #Marshal.dump(0x40000000, $file) # 04 08 6C 2B 07 00 00 00 40
 #Marshal.dump(0xFFFFFFFF, $file) # 04 08 6C 2B 07 FF FF FF FF
 #Marshal.dump(0xABCDEF12, $file) # 04 08 6C(l) 2B(+) 07 12 EF CD AB
 
 
 $file.close
 
 exit
 
 已经把正int整数型的结构研究完了,现在在研究负int整数型。
 
 | 
    
      |  | 
          3楼
          巨大八爪鱼
          2016-1-25 11:44
          
          
            最开头的04 08表示的就是Marshal的版本号4.8 | 
    
      |  | 
          5楼
          巨大八爪鱼
          2016-1-26 10:03
          
          
            其实,在Ruby的官方网站里下载的源码包里面就有marshal.c,而且版本是4.8 | 
    
      |  | 
          7楼
          巨大八爪鱼
          2016-1-26 10:32
          
          
            static voidw_long(long x, struct dump_arg *arg)
 {
 char buf[sizeof(long)+1];
 int i;
 
 #if SIZEOF_LONG > 4
 if (!(RSHIFT(x, 31) == 0 || RSHIFT(x, 31) == -1)) {
 /* big long does not fit in 4 bytes */
 rb_raise(rb_eTypeError, "long too big to dump");
 }
 #endif
 
 if (x == 0) {
 w_byte(0, arg);
 return;
 }
 if (0 < x && x < 123) {
 w_byte((char)(x + 5), arg);
 return;
 }
 if (-124 < x && x < 0) {
 w_byte((char)((x - 5)&0xff), arg);
 return;
 }
 for (i=1;i<(int)sizeof(long)+1;i++) {
 buf[i] = (char)(x & 0xff);
 x = RSHIFT(x,8);
 if (x == 0) {
 buf[0] = i;
 break;
 }
 if (x == -1) {
 buf[0] = -i;
 break;
 }
 }
 w_nbyte(buf, i+1, arg);
 }
 
 这就是Marshal中dump整数的方法!
 
 | 
    
      |  | 
          8楼
          巨大八爪鱼
          2016-1-26 13:08
          
          
            int RubyMarshal::WriteLong(long num){
 char data[sizeof(long) + 1];
 int count = 1;
 int i;
 if (num == 0)
 data[0] = 0;
 else if (num > 0 && num < 123)
 data[0] = (char)(num + 5);
 else if (num > -124 && num < 0)
 data[0] = (char)((num - 5) & 0xff);
 else
 {
 for (i = 1; i < sizeof(long) + 1; i++)
 {
 data[i] = (char)(num & 0xff);
 num >>= 8;
 if (num == 0)
 {
 data[0] = i;
 break;
 }
 else if (num == -1)
 {
 data[0] = -i;
 break;
 }
 }
 count += i;
 }
 filestream->write(data, count);
 return count;
 }
 | 
    
      |  | 
          9楼
          巨大八爪鱼
          2016-1-26 16:48
          
          
            #include "StdAfx.h"#include "RubyMarshal.h"
 
 using namespace std;
 
 RubyMarshal::RubyMarshal(ostream *stream) : filestream(stream)
 {
 }
 
 
 RubyMarshal::~RubyMarshal(void)
 {
 }
 
 int RubyMarshal::BeginArray(int length)
 {
 filestream->put(TYPE_ARRAY);
 return WriteLong(length) + 1;
 }
 
 int RubyMarshal::BeginHash(int length, bool hasDefValue)
 {
 if (hasDefValue)
 filestream->put(TYPE_HASH_DEF);
 else
 filestream->put(TYPE_HASH);
 return WriteLong(length) + 1;
 }
 
 int RubyMarshal::WriteBool(bool value)
 {
 if (value)
 filestream->put(TYPE_TRUE);
 else
 filestream->put(TYPE_FALSE);
 return 1;
 }
 
 int RubyMarshal::WriteFixnum(long num)
 {
 filestream->put(TYPE_FIXNUM);
 return WriteLong(num) + 1;
 }
 
 int RubyMarshal::WriteHeader(void)
 {
 char header[] = {MARSHAL_MAJOR, MARSHAL_MINOR};
 filestream->write(header, sizeof(header));
 return sizeof(header);
 }
 
 int RubyMarshal::WriteLong(long num)
 {
 char data[sizeof(long) + 1];
 int count = 1;
 int i;
 if (num == 0)
 data[0] = 0;
 else if (num > 0 && num < 123)
 data[0] = (char)(num + 5);
 else if (num > -124 && num < 0)
 data[0] = (char)((num - 5) & 0xff);
 else
 {
 for (i = 1; i < sizeof(long) + 1; i++)
 {
 data[i] = (char)(num & 0xff);
 num >>= 8;
 if (num == 0)
 {
 data[0] = i;
 break;
 }
 else if (num == -1)
 {
 data[0] = -i;
 break;
 }
 }
 count += i;
 }
 filestream->write(data, count);
 return count;
 }
 
 int RubyMarshal::WriteNil(void)
 {
 filestream->put(TYPE_NIL);
 return 1;
 }
 
 int RubyMarshal::WriteRegexp(char *pStr)
 {
 int start = 0, end;
 int len = strlen(pStr);
 int count = 2;
 if (pStr[0] == '/')
 start = 1;
 for (end = len - 1; pStr[end] != '/' && end >= 0; end--);
 if (end <= start)
 end = len;
 int regLen = end - start;
 filestream->put(TYPE_REGEXP);
 count += WriteLong(regLen);
 filestream->write(pStr + start, regLen);
 count += regLen;
 
 char flag = 0;
 for (pStr += end + 1; *pStr != '\0'; pStr++)
 {
 switch (*pStr)
 {
 case 'i':
 flag |= ONIG_OPTION_IGNORECASE;
 break;
 case 'm':
 flag |= ONIG_OPTION_MULTILINE;
 break;
 case 'x':
 flag |= ONIG_OPTION_EXTEND;
 break;
 }
 }
 filestream->put(flag);
 return count;
 }
 
 int RubyMarshal::WriteString(char *pStr)
 {
 return WriteString(TYPE_STRING, pStr);
 }
 
 int RubyMarshal::WriteString(char type, char *pStr)
 {
 int len = strlen(pStr);
 filestream->put(type);
 int count = WriteLong(len);
 filestream->write(pStr, len);
 count += len + 1;
 return count;
 }
 
 int RubyMarshal::WriteSymbol(char *pStr)
 {
 return WriteString(TYPE_SYMBOL, pStr);
 }
 | 
    
      |  | 
          10楼
          巨大八爪鱼
          2016-1-26 16:48
          
          
            #include "stdafx.h"#include "RubyMarshal.h"
 
 using namespace std;
 
 int _tmain(int argc, _TCHAR* argv[])
 {
 ofstream file("example.rxdata", ios::binary);
 RubyMarshal rms(&file);
 rms.WriteHeader();
 /*rms.BeginArray(4);
 rms.WriteFixnum(-23489);
 rms.WriteString("Do you want anything to drink?\nA cup of milk, please.");
 
 rms.BeginArray(4);
 rms.WriteBool(true);
 rms.WriteBool(false);
 rms.WriteNil();*/
 cout << rms.WriteRegexp("/^here$/mi") << endl;
 
 /*rms.BeginHash(2);
 rms.WriteBool(false);
 rms.WriteString("test");
 rms.WriteString("haha");
 rms.WriteSymbol("sys");*/
 
 file.close();
 
 ifstream file2("example.rxdata", ios::binary);
 char list[] = "0123456789ABCDEF";
 char ch;
 int i;
 for (i = 0; ch = file2.get(), !file2.eof(); i++)
 {
 cout << list[ch >> 4 & 0x0f] << list[ch & 0x0f] << ' ';
 if ((i + 1) % 16 == 8)
 cout << ' ';
 if ((i + 1) % 16 == 0)
 {
 i = -1;
 cout << endl;
 }
 }
 cout << endl;
 file2.close();
 system("pause");
 return 0;
 }
 
 
 |