目前共有15篇帖子。 內容轉換:不轉換▼
 
點擊 回復
623 14
今天上午,我开始研究rxdata文件的数据结构
一派護法 十九級
1樓 發表于:2016-1-25 11:37

class Test
  attr_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整数型。
一派護法 十九級
2樓 發表于:2016-1-25 11:38

http://bbs.66rpg.com/thread-139590-1-1.html
这里有rxdata数据结构的教程
一派護法 十九級
3樓 發表于:2016-1-25 11:44

最开头的04 08表示的就是Marshal的版本号4.8
一派護法 十九級
4樓 發表于:2016-1-26 09:44

marshal.c的下载地址:
http://www.opensource.apple.com/source/ruby/ruby-18/ruby/marshal.c
2楼的链接中就翻译了部分其中的注释
一派護法 十九級
5樓 發表于:2016-1-26 10:03

其实,在Ruby的官方网站里下载的源码包里面就有marshal.c,而且版本是4.8
一派護法 十九級
6樓 發表于:2016-1-26 10:03

一派護法 十九級
7樓 發表于:2016-1-26 10:32

static void
w_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;
}

一派護法 十九級
11樓 發表于:2016-1-26 18:20

扩展模块:
    rms.BeginExtended("Math");
    rms.BeginObject("A", 2);
    rms.BeginMember("b");
    rms.WriteString("space");
    rms.BeginMember("a");
    rms.WriteString("time");

Ruby代码:
class A
  attr_accessor :a
  attr_accessor :b
end

ax = A.new
ax.a = "time"
ax.b = "space"
file = File.open("../extended2.rxdata", "wb")
Marshal.dump(ax.extend(Math), file)
file.close
一派護法 十九級
12樓 發表于:2016-1-26 18:23

C++:
rms.BeginExtended("Math");
rms.WriteString("rest");

Ruby:
"rest".extend(Math)
一派護法 十九級
13樓 發表于:2016-1-26 20:56

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.BeginHash(2, true);
    rms.WriteBool(false);
    rms.WriteString("test");
    rms.WriteString("haha");
    rms.WriteSymbol("sym");
    rms.WriteString("Default Value");

    rms.BeginArray(6);
    rms.WriteBool(true);
    rms.WriteBool(false);
    rms.WriteNil();
    rms.WriteRegexp("/^here$/mi");
    rms.WriteSymbol("sym2");
    rms.WriteSymLink(1);*/

    /*rms.BeginObject("A", 2);
    rms.BeginMember("b");
    rms.BeginArray(2);
    rms.WriteModule("Math");
    rms.WriteNil();
    rms.BeginMember("a");
    rms.WriteRegexp("/./im");*/
    //rms.WriteClass("A");

    /*rms.BeginExtended("Math");
    rms.WriteString("rest");*/
    /*rms.BeginObject("A", 2);
    rms.BeginMember("b");
    rms.WriteString("space");
    rms.BeginMember("a");
    rms.WriteString("time");*/
    //cout << rms.WriteBignum(-2015104222256789012) << endl;
    cout << rms.WriteFloat(-3.14159265358979323846) << endl;

    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;
一派護法 十九級
14樓 發表于:2016-1-29 13:47

今天上午,我開始研究如何用php讀取rxdata文件。
一派護法 十九級
15樓 發表于:2016-8-22 23:16

最近,我正忙于制作Rxdata查看器

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
(快捷鍵:Ctrl+Enter)
 

本帖信息

點擊數:623 回複數:14
評論數: ?
作者: 巨大八爪鱼
最後回復:巨大八爪鱼
最後回復時間:2016-8-22 23:16
 
©2010-2024 Arslanbar Ver2.0
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。