duangsuse::Echo
一个『迷你』编程语言,我们称它为 面包(Bread) 🍞 (跑) 我希望它能类似 DropScript 一样作为面向对象的 JVM 语言,不过同时我觉得必须把它和优秀(划掉,没有单独编译期的语言不是好语言)的 DropScript 划清界限(删除)其实所谓界限不过是 pattern matcing 和 OOP、infixl/infixr、module 等等 而已... 它支持这些数据类型,一门强类型自动推导语言: Str (字符串) Num (双精度浮点) Rat (大有理数) Bool (布耳值) I8…
上面的,我最后还是只能抱怨一下自己的缓慢,和做最后一点能做的事...
1. AXMLSerializer,我正在写(格式从这个 axmlparser 里学中,也看到了它用一个 Binary Data Reader 帮助类很好用,可惜 Delegate 类全是余赘代码),顺手学了一下 POM 模型一些比较入门的东西
== POM 模型我设置的属性(基本 Maven Center 里都能看到的):
Group, ArtifictId, VersionName
PomURL, PomName, PomDescription, PomPackaging
DevName, DevId
ScmUrl, ScmDevConn, ScmConn
LicenceURL, LicenceName, LicenceDist
2. 支持 lambda calculus 的计算器,我真的很想体验一下 Unicode 语法(跑
1+1
1+2*3
(9-3)*2+1
10/1
1.1*100
0xabcdef
10e1
-4
(-4)+1
nand = λa b. ¬(a ∧ b)
xor = λa. λb. a∨b ∧ nand(a)(b)
1. AXMLSerializer,我正在写(格式从这个 axmlparser 里学中,也看到了它用一个 Binary Data Reader 帮助类很好用,可惜 Delegate 类全是余赘代码),顺手学了一下 POM 模型一些比较入门的东西
== POM 模型我设置的属性(基本 Maven Center 里都能看到的):
Group, ArtifictId, VersionName
PomURL, PomName, PomDescription, PomPackaging
DevName, DevId
ScmUrl, ScmDevConn, ScmConn
LicenceURL, LicenceName, LicenceDist
2. 支持 lambda calculus 的计算器,我真的很想体验一下 Unicode 语法(跑
1+1
1+2*3
(9-3)*2+1
10/1
1.1*100
0xabcdef
10e1
-4
(-4)+1
nand = λa b. ¬(a ∧ b)
xor = λa. λb. a∨b ∧ nand(a)(b)
GitHub
shazam/axmlparser
An updated version of AXMLParser, compatible with aapt2 - shazam/axmlparser
duangsuse::Echo
顺手发点截图 #elec #PL #blog #cs
体验了 EPL(懒得检查表达式了)、Fritzing(这个玩意是用来进行嵌入式设计的,当然你也可以理解为开发板编程什么的,可以画原理图、建面包版和写串口通讯代码)
因为打印了很多博文的缘故,已经开始手动处理网页来尽可能压榨一面 A4 纸的信息量
因为打印了很多博文的缘故,已经开始手动处理网页来尽可能压榨一面 A4 纸的信息量
R 大 09 年就那么大佬了,难怪现在我都看不见他一样了... 这世界有代沟啊
duangsuse::Echo
htmlPrint.zip
Agda 的 coinductive record 么... 我还没学会,emmm。
Agda 环境我还没建立,到时候建立了会发一些简单的证明帮助大家入门。
Agda 环境我还没建立,到时候建立了会发一些简单的证明帮助大家入门。
duangsuse::Echo
立即 公开维护(
AXMLParser parser = new AXMLParser(apkFileInputStream);
int eventType = parser.getType();
while (eventType != AXMLParser.END_DOCUMENT) {
String parserName = parser.getName();
boolean isManifest = "manifest".equals(parserName);
[...]
eventType = parser.next();
}
这个原来的玩意是用流模式的...我也打算这么做,当然也会提供扫描整个文档的辅助方法
这种方式也被 LLVM Cookbook 里的 TOY 语言 Lexer 采用(get_token() 函数从输入流扫描,然后返回词条类型,业务代码判断词条类型访问相应静态变量拿信息)
就作为 Iterable 吧,因为我觉得这种方式(eventType + static field 存储 AXML 结构信息)不够面向对象,反而能嗅出点过程式的端倪。
换句话说,我觉得我应该这样封装:
val parser = AxmlSerializer.Reader(axmlFileInputStream)虽然这样会导致它不够『底层』以至于不是所有 xmlparser 可以处理的文档它都可以处理,但我还是觉得... 不错
for (node in parser.treeIterator) {
when (node is AxmlTag && node.tag == "manifest") {
// [...]
}
}
不过... 其实鱼和熊掌可以兼得,先做一个流处理最底层的 AxmlSequencer,再在上面封装 AxmlSerializer.Reader 不就好了吗?
流处理,最下面是 Binary 数据的 Reader (Extension),提供最底层的二进制格式 DataView
中间一层是文件大格式的 Scanner (Reader),扫描 AXML 『大体』的文件格式(Chunk)
最顶端一层提供 AxmlTree 流接口和帮助函数,每次需要新 node 时就看看自己的缓冲区里有没有剩下的对象可供返回(数据指针移动)
如果没有了,向底层 ask 新的 chunck,拆分,入队,否则返回已经扫描出来的对象
val treeIterator: Iterator<AxmlNode>
get() = asIterator()
fun asIterator(): AxmlNodeIterator<AxmlNode> {
return /* 实现 next 和 hasNext,如果队列为空则从 Sequencer 里读取下一块,拆分,存到 NodeIterator 的队列里,否则返回出队元素 */
}
duangsuse::Echo
AXMLParser parser = new AXMLParser(apkFileInputStream); int eventType = parser.getType(); while (eventType != AXMLParser.END_DOCUMENT) { String parserName = parser.getName(); boolean isManifest = "manifest".equals(parserName); [...] eventType…
https://github.com/duangsuse/AxmlSerializer/wiki/Binary-Serialization-%E7%B1%BB%E8%A6%81%E6%8F%90%E4%BE%9B%E7%9A%84%E6%88%90%E5%91%98%E5%92%8C%E6%96%B9%E6%B3%95%E6%93%8D%E4%BD%9C#binary-serializatoin
我正在准备分析手头上的资料总结出『后面』的文件格式,等我验证规范有效之后,就会开始写一个二进制序列化类库,使用这个线性字节流结构提取式类库解决 AxmlSerializer 的问题
新的库有糖能够使得文件格式的表达更具定义式风格,避免了使用旧式的 byte array 一大堆算偏移量、提取字节数组组装某种数值、裁切子序列的操作(一些不嫌麻烦的库现在依然选择这种方式)
🤔
AAPT2 AXML 文件格式的总结,将在这里讨论
为了方便快速了解格式详情,会使用弱类型的『脚本语言』Ruby 进行 STDIN IO 解析 AXML 文件基础结构。
我正在准备分析手头上的资料总结出『后面』的文件格式,等我验证规范有效之后,就会开始写一个二进制序列化类库,使用这个线性字节流结构提取式类库解决 AxmlSerializer 的问题
新的库有糖能够使得文件格式的表达更具定义式风格,避免了使用旧式的 byte array 一大堆算偏移量、提取字节数组组装某种数值、裁切子序列的操作(一些不嫌麻烦的库现在依然选择这种方式)
@ByteStruct这样对于简单的结构体,在 parser 里面调用
class ResChunkHeader {
@Type(Unsigned16) ChunkType type;
@Type(Unsigned32) long size;
}
reader.readStruct(ResChunkHeader.class) 就可以了🤔
AAPT2 AXML 文件格式的总结,将在这里讨论
为了方便快速了解格式详情,会使用弱类型的『脚本语言』Ruby 进行 STDIN IO 解析 AXML 文件基础结构。
GitHub
Binary Serialization 类要提供的成员和方法操作
Android AAPT2-compatible AXML Binary XML format parser/generator - duangsuse-valid-projects/AxmlSerializer
duangsuse::Echo
简单的思路,虽然写了我很久 🤔...
其实有个大小端的问题... 虽然 AXML 作为一种二进制文件格式并不复杂(没有添加 alignment、不需要搞基流定位)
但是还是要求以小端格式存取,至少好像是 String Pool 必须这样 🤔
emmm... 唉
但是还是要求以小端格式存取,至少好像是 String Pool 必须这样 🤔
emmm... 唉
duangsuse::Echo
AndroidManifest.xml
以下是基于这个文件和 https://gist.github.com/duangsuse/3ae94e339eb188fa4ec8a87b6e105331 分析出来确认有效的文件结构:
当然还有 https://github.com/aosp-mirror/platform_frameworks_base/tree/pie-release/tools/aapt2
AAPT2
https://github.com/aosp-mirror/platform_frameworks_base/blob/pie-release/tools/aapt2/cmd/Dump.cpp#L79
当然还有 https://github.com/aosp-mirror/platform_frameworks_base/tree/pie-release/tools/aapt2
AAPT2
https://github.com/aosp-mirror/platform_frameworks_base/blob/pie-release/tools/aapt2/cmd/Dump.cpp#L79
Gist
手把手教你解析AXML - CSDN https://blog.csdn.net/beyond702/article/details/51830108
手把手教你解析AXML - CSDN https://blog.csdn.net/beyond702/article/details/51830108 - csdn-beyond702-51830108.md
乘着 Telegram 还能够连上赶快
== BinaryDataReader 的必须基础操作,我所希望的
+ skipNBytes(n)
+ readNBytes(n)
+ readU8 / readI8
+ readU16 / readI16
+ readU32 / readI32
+ readU64 / readI64
+ readCStr / readXPrefixStr
+ readNX
+ skipX
+ checkX
和 java 的 DataInputStream 相比,它缺少:
+ readUTF
+ readLine
+ readFully <1 overloads>
+ read Float/Double/Char/Boolean
它实现了 ExtDataInput 扩展类的
+ skipInt(skipX)
+ readIntArray(readNX)
+ skipCheckX(checkX)
+ skipBytes(skipNBytes)(更努力地跳过这些字节,或者说坚持一定要跳过而不因为被打断而终止,定义如下)
因为没有必要(只是处理二进制数据)。
== BinaryDataReader 的必须基础操作,我所希望的
+ skipNBytes(n)
+ readNBytes(n)
+ readU8 / readI8
+ readU16 / readI16
+ readU32 / readI32
+ readU64 / readI64
+ readCStr / readXPrefixStr
+ readNX
+ skipX
+ checkX
和 java 的 DataInputStream 相比,它缺少:
+ readUTF
+ readLine
+ readFully <1 overloads>
+ read Float/Double/Char/Boolean
它实现了 ExtDataInput 扩展类的
+ skipInt(skipX)
+ readIntArray(readNX)
+ skipCheckX(checkX)
+ skipBytes(skipNBytes)(更努力地跳过这些字节,或者说坚持一定要跳过而不因为被打断而终止,定义如下)
proc int skipNBytes(int n) {
int skipped = 0, now;
while skipped < n AND now = super.skipBytes(n - skipped) >0 { total += now; }
return skipped;
}
+ readNullEndedString (readCStr)因为没有必要(只是处理二进制数据)。
duangsuse::Echo
以下是基于这个文件和 https://gist.github.com/duangsuse/3ae94e339eb188fa4ec8a87b6e105331 分析出来确认有效的文件结构: 当然还有 https://github.com/aosp-mirror/platform_frameworks_base/tree/pie-release/tools/aapt2 AAPT2 https://github.com/aosp-mirror/platform_frameworks_base/blob/pie…
首先:AXMLParser 它怎么看 AXML 文件格式:
Axml -> little-endian
int 0x00080003 (其实这种定义是不足够健壮的,它利用了 Top Chunk 的性质,硬编码了 Chunk Type 和 Chunk Header Length)
int chunkSize
StringBlock strb
StringBlock -> little-endian
skipCheckChunkTypeInt(CHUNK_STRINGPOOL_TYPE, CHUNK_NULL_TYPE)
int chunkSize
int stringCount
int styleCount
int flags
int stringsOffset
int stylesOffset
prop isUTF8 = flags & 0x00000100
int[stringCount] stringOffsets
prop stringOwns = [stringCount; -1]
if styleCount != 0 then int[styleCount] styleOffsets
prop size = if styleCount != 0 then stylesOffset else chunkSize end - stringsOffset
byte[size] strings
strings = readFully
if stylesOffset != 0 then
prop size = (chunkSize - stylesOffset)
styles = int[size / 4]
prop remaining = size % 4
if remaining >= 1 then while remaining-- >0 do skipByte
Axml -> little-endian
int 0x00080003 (其实这种定义是不足够健壮的,它利用了 Top Chunk 的性质,硬编码了 Chunk Type 和 Chunk Header Length)
int chunkSize
StringBlock strb
StringBlock -> little-endian
skipCheckChunkTypeInt(CHUNK_STRINGPOOL_TYPE, CHUNK_NULL_TYPE)
int chunkSize
int stringCount
int styleCount
int flags
int stringsOffset
int stylesOffset
prop isUTF8 = flags & 0x00000100
int[stringCount] stringOffsets
prop stringOwns = [stringCount; -1]
if styleCount != 0 then int[styleCount] styleOffsets
prop size = if styleCount != 0 then stylesOffset else chunkSize end - stringsOffset
byte[size] strings
strings = readFully
if stylesOffset != 0 then
prop size = (chunkSize - stylesOffset)
styles = int[size / 4]
prop remaining = size % 4
if remaining >= 1 then while remaining-- >0 do skipByte