duangsuse::Echo
719 subscribers
4.28K photos
130 videos
583 files
6.49K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
https://github.com/duangsuse/AXMLEdit/issues/2

其实这玩意都快把我的眼睛看瞎了,这种代码... 不必要的复杂性... emmmm...

StartTagChunk startChunk = StartTagChunk.createChunk(name, attCount, -1, attribute);
// 构造一个新的 chunk 之后, 开始写入
if (isNotAppTag(tagName)) {
ChunkParser.xmlStruct.byteSrc = Utils.insertByte(ChunkParser.xmlStruct.byteSrc, subTagChunkOffsets, startChunk.getChunkBytes());
subTagChunkOffsets += startChunk.getChunkBytes().length;
} else {
ChunkParser.xmlStruct.byteSrc = Utils.insertByte(ChunkParser.xmlStruct.byteSrc, subAppTagChunkOffset, startChunk.getChunkBytes());
subAppTagChunkOffset += startChunk.getChunkBytes().length;
}

这都是啥辣鸡代码 #Java

https://github.com/duangsuse/AXMLEdit/blob/master/src/main/java/cn/wjdiankong/axmledit/helper/AXmlEditor.java#L84

前面使用的算法大概是:

XmlPull 标签开始:
size tagName = makeStrPoolRef(parser.getName())
int count = parser.getAttrCount()
byte[count * 20] attrbytes
for (int i : count)
size uri= makeStrPoolRef(prefixStr)
int[] type = getAttrType(attrValue[i])
String[] attrName = attrName[i].split()

int aname = attrName[1]
int avalue = attrValue[i]
int atype = type[0]
int adata = type[1]

AttrData data(uri, aname, avalue, atype, adata)
attrbytes = bytecat(attrbytes, data.bytes, i * data.len)

为啥非得建立这么多 byte 数组?难道不能用 OutputStream 吗?

TagStart:
int tagName = axml.strPoolRef(parser.getName())
final int count = parser.getAttrCount()
for (int i : count)
String attr_name = attrName[i].split()
int[] attr_type = toAttrType(attrValue[i])

int aname = attr_name[1], avalue = attrValue[i], atype = type[0], adata = type[1];

new AttrData(uriRef, aname ,avalue, atype, adata).writes(axml)

如果有不能立刻写的数据,那就保存好晚点结束生成的时候再写,比如 string pool...
为什么要不断去手算偏移量... 能流式就不要不断去做乘除法
duangsuse::Echo
停,现在是 DJson 的设计时间。今天暂时只来设计。 #Java Json 是什么呢? json.org Json 里可以有这些类型的『数据』 DJson 称之为『Type』,都可能为 null(为了方便,和 JSON 定义相称) ObjectJ<Type> ArrayJ<Type> String Number Boolean DJson 应该继承于一个 Text ParserCombinator 库,此库应该接受这些参数类型的 Constructor java.io.DataInput j…
Parser<String> stringP() {
return () -> { charP('"'); manyConcat(jsonCharP()); charP('"'); }
}

Parser<Character> jsonCharP() {
return () -> {
return maybe(sequence(charP('\\'), jsonEscapeP()),
all(notElement("\"\\"), element(range(0x0020, 0x10ffff))));
};
}

Parser<Character> jsonEscapeP() {
return () -> {
return maybe(element("\"/\\bnrt"), sequence(charP("u"), repeats(4, hexCharP())));
};
}

Parser<Character> hexCharP() {
return () -> {
return maybe(digitP(), element(range("a", "f")), element(range("A", "F")));
};
}

Parser<Character> digitP() {
return () -> {
return maybe(charP('0'), element(range('1', '9')));
};
}
我得再去考虑一下 Parser 应该怎么抽象,然后 DJson 就可以使用这种 combinator 风格的 parser 库了

@FunctionalInterface
interface Parser<? extends R> {
@Nullable R match(TextReadStream reader);
}

🤔 charP 是什么呢? 一个 Parser<Character>, 就是说它的匹配结果是 Character

.... 不应该接受任何的额外参数,所以不如这么说:

@FunctionalInterface
interface Parser<? extends R> {
@Nullable R match();
}

class MyParser extemds TextCombinator {
Parser<Character> charP(char x) {
return () -> { return getChar() == x ? getChar() : null; }
}

Parser<Void> helloP() {
return () -> {
sequence(charP("h"), charP("e"), charP("l"), charP("l"), charP("o"));
return null;
};
}

Parser<Integer> manyHelloP() {
return () -> {
ManyMatch hellos = many(helloP());
return hellos.length
};
}
}

这样就可以了

MyParser parser = new MyParser(System.in);
System.out.println(parser.manyHelloP());

hellohellohellohello
...

处理 EOF:

sequence 里默认一个一个 match,EOF 则直接不 match,使用 eofP 来匹配结束吧...(说说而已,我觉得应该专门使用一种方式)
mustSequence 里可以提供一个函数来指示错误信息,Unexpected EOF

比如一个简单的语法结构:

<def> <name> <(> { arg } <)> <=> <value>

就是:

mustSequence(
keywordP(DEF), ws(),
nameP(), ws(),
parenLP(),
many(argP()),
parenRP(), ws(),
eqP(),
valueP()
).except((n) -> switch (n) {
case 0: return expect("def keyword");
case 2: return expect("variable name");
case 4: return expect("(");
case 6: return expect(")");
case 8: return expect("=");
case 9: return expect("variable value");
})

假设用户只输入了

def a

就 EOF 了,实际上最后一个状态是 ws(), 倒数第二个是 definitionP
这样,mustSequence 就可以给出错误信息:
duangsuse::Echo
我得再去考虑一下 Parser 应该怎么抽象,然后 DJson 就可以使用这种 combinator 风格的 parser 库了 @FunctionalInterface interface Parser<? extends R> { @Nullable R match(TextReadStream reader); } 🤔 charP 是什么呢? 一个 Parser<Character>, 就是说它的匹配结果是 Character .... 不应该接受任何的额外参数,所以不如这么说: @Fu…
@FunctionalInterface
interface Parser<R> {
@Nullable <? extends R> match();
}

@FunctionalInterface
interface Matcher<R> {
@Nullable boolean matches(<? super R> value);
}

所以提供的 parser combinator 方法都有

Parser<R> satisfy(Matcher<Character> predicate);
charP

SequenceParser<R> maySequence(Parser<R> parsers...);
SequenceParser<R> sequence(Parser<R> parsers...);

all
maybe
sequenceFilterConcat
exclusiveOr
not

repeats

some
many
manyConcat

element
notElement
range

看看这道题

Regex 子集的

data RegExp
= Normal Char
-- ^ A character that is not in "()*|."
| Any
-- ^ Any character
| ZeroOrMore RegExp
-- ^ Zero or more occurances of the same regexp
| Or RegExp RegExp
-- ^ A choice between 2 regexps
| Str [RegExp]
-- ^ A sequence of regexps.

Normal 就是 charP
Any 没有默认定义,但是可以这么写
Parser<Character> any() { return satisfy((x) -> true); }

ZeroOrMore 就是 many
Or 就是 maybe
Str 就是 sequence

这个 Parser 也可以用来解析 Regex 所能解析的东西:

"ab*" -> sequence(charP("a"), many(charP("b")))
"(ab)+" -> some(sequence(charP("a"), charP("b")))
"(a.*)|(bb)" ->
maybe(
sequence(charP('a'), many(any())),
sequence(charP('b'), charP('b'))))
草,没时间写了
#backend #java 🤔 异步拖长了,用消息队列(
... 那客户端一定要同步查询也得 keep 一大堆 alive 的 HTTP connection...

说到底是 GitHub 连接慢了?emmm
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (YuutaW 鱼塔)
仔细观察了日志,发现日志从 28% 到结尾均有各种 Vertx Thread Blocked 异常,从 5s ~ 12s 不等。同时在 Arrays#copyOf、vertx-blocked-thread-checker 线程、OkHttp ConnectionPool 线程、vert.x-eventloop-thread-0 等地方均发生 OOM 异常。
其实只需要做前端的工作的.. #Android #net
Forwarded from YuutaW 鱼塔
理解 SS 源码困难(
辣鸡。 #security #web 连 XXS 都不防
我们这里也搞过,后来我强行卸了硬盘保护系统... 结果辣鸡 BIOS 只能从 PCI 启动,电脑坏了... 后来老师拆了还原卡又重装了保护系统... 所以我只能 VM #School
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (YuutaW 鱼塔)
雾草 学校电脑 🐮🍺,从 U 盘启动需要管理员密码 🌚
#freedom 总算能用了.... 蓐羊毛翻墙日益艰难?🌚🐕
https://github.com/RikkaApps/Riru/tree/master/riru-core/jni/main
#C 欸我真想写一篇分析的... 可惜自己事情又多
很想学学写 C++,虽然我不是真正意义上不会 C++... 只是 C++ 模板和 constexpr 函数式编程比其他不常用一些而已了。
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
顺便一说,DJson 希望有泛型的 ObjectJ<T extends Type> 什么的其实是希望可以这样: 😫 DJson .fromString("{a:1}") .into(new ObjectJ<Number>()) .doParse(); 然后假设这么干可以边解析边检查类型( 但是... 其实 Java 没有真泛型,是泛型擦除实现的泛型... 没有办法拿到 T 的 java.lang.Class<T> 实例... 我开始是想 interface 里也能为类指定 static 方法限定的...…
那个,突然想到如果能拿到 instance 的话是可以使用 Object#getClass() 拿到 Class 的,而 T.getClass() 就不存在,Java 里类就是类对象就是对象,要不然就是静态方法了,不过那就不能编译期检查的(其实可能希望能利用泛型检查)。
上面的是说错了(
duangsuse::Echo
@FunctionalInterface interface Parser<R> { @Nullable <? extends R> match(); } @FunctionalInterface interface Matcher<R> { @Nullable boolean matches(<? super R> value); } 所以提供的 parser combinator 方法都有 Parser<R> satisfy(Matcher<Character> predicate); charP…
顺便说说 #fix #Java

  @Nullable boolean matches(<? super R> value);

这一句是错的,应该改成,属于我不熟悉泛型语法...

@Nullable <T super R> boolean matches(T value);