Tho*_*ann 6 macos objective-c nscoding ios nsarchiving
对于数据恢复程序,我需要能够从NSArchiver编写的文件中提取值+类型,而无需访问Apple的CF/NS框架.
OS X file命令报告以下文件:
NeXT/Apple typedstream data, little endian, version 4, system 1000
Run Code Online (Sandbox Code Playgroud)
是否有关于如何编码这些文件的文档,或者是否有人提出可以解析它们的代码?
以下是此类数据的示例(也可:可下载):
04 0B 73 74 72 65 61 6D 74 79 70 65 64 81 E8 03 ..streamtyped...
84 01 40 84 84 84 12 4E 53 41 74 74 72 69 62 75 ..@....NSAttribu
74 65 64 53 74 72 69 6E 67 00 84 84 08 4E 53 4F tedString....NSO
62 6A 65 63 74 00 85 92 84 84 84 08 4E 53 53 74 bject.......NSSt
72 69 6E 67 01 94 84 01 2B 06 46 65 73 6B 65 72 ring....+.Fesker
86 84 02 69 49 01 06 92 84 84 84 0C 4E 53 44 69 ...iI.......NSDi
63 74 69 6F 6E 61 72 79 00 94 84 01 69 01 92 84 ctionary....i...
96 96 1D 5F 5F 6B 49 4D 4D 65 73 73 61 67 65 50 ...__kIMMessageP
61 72 74 41 74 74 72 69 62 75 74 65 4E 61 6D 65 artAttributeName
86 92 84 84 84 08 4E 53 4E 75 6D 62 65 72 00 84 ......NSNumber..
84 07 4E 53 56 61 6C 75 65 00 94 84 01 2A 84 99 ..NSValue....*..
99 00 86 86 86 .....
Run Code Online (Sandbox Code Playgroud)
这包含NSAttributedString.我有类似的例子,包含NSMutableAttributedStrings等,但最终都解析为NSAttributedStrings,我喜欢获取文本.我不关心其余的,但我需要知道它是否有效.
我目前的解决方案是使用NSUnarchiver,假设我总是应该在那里找到NSAttributedString,获取它的第一个元素并读取它的文本,然后从中重新创建一个存档,看它是否与原始数据相同.如果我收到异常或其他存档,我认为存档已损坏或无效:
NSData *data = [[NSData alloc] initWithBytesNoCopy:dataPtr length:dataLen freeWhenDone:false];
NSUnarchiver *a = NULL;
// The algorithm simply assumes that the data contains a NSAttributedString, retrieves it,
// and then recreates the NSArchived version from it in order to tell its size.
@try {
a = [[NSUnarchiver alloc] initForReadingWithData:data];
NSAttributedString *s = [a decodeObject];
// re-encode the string item so we can tell its length
NSData *d = [NSArchiver archivedDataWithRootObject:s];
if ([d isEqualTo:[data subdataWithRange:NSMakeRange(0,d.length)]]) {
lenOut = (int) d.length;
okay = true; // -> lenOut is valid, though textOut might still fail, see @catch below
textOut = [s.string cStringUsingEncoding:NSUTF8StringEncoding];
} else {
// oops, we don't get back what we had as input, so let's better not consider this valid
}
} @catch (NSException *e) {
// data is invalid
}
Run Code Online (Sandbox Code Playgroud)
但是,上面的代码有几个问题:
*** mmap(size=18446744071608111104) failed (error code=12) *** error: can't allocate region *** set a breakpoint in malloc_error_break to debug我提交了一个关于此的错误报告,因为"无法修复",很遗憾).因此,我需要自定义代码来解码这些类型的档案.我看了几个,但无法理解它使用的代码.显然,有长度字段和类型字段,显然类型在0x81到0x86范围内.此外,前16个字节是标题,包括偏移14-15的系统代码(0x03E8 = 1000).
我也想知道源代码是否在某些旧的NeXT源或曾经存在的Windows版本中可用,但我会在哪里找到它?(注意:我被引导到GNUstep源代码("core.20131003.tar.bz2"),我在其中找到了它的NSUnarchiver源代码,但该代码显然是从1998年开始使用它自己的编码,但这并不理解这个" streamtyped"编码.)
虽然我不知道格式的任何文档,但您可以通过查看较旧的Darwin(或OpenStep)版本的公共源代码来查找您要查找的信息.
例如,看一下旧darwin发行版镜像中可用typedstream文件的实现.typedstream.mobjc-1.tar.gz
此源代码应该能够读/写typedstream.请务必在使用时确认Apple的许可证.
看一下 Cocotron 的NSArchiver和的开源实现NSUnarchiver:
https://code.google.com/p/cocotron/source/browse/Foundation/NSArchiver.m https://code.google.com/p/cocotron/source/browse/Foundation/NSUnarchiver.m
| 归档时间: |
|
| 查看次数: |
1493 次 |
| 最近记录: |