当前位置: 首页 > article >正文

模拟解析:宽度数组 `[1,2,1]`,10个条目的 XRef 流

文章目录模拟解析宽度数组 [1,2,1]10个条目的 XRef 流一、设定场景二、解析代码核心部分与之前相同三、逐条解析模拟 CPU 执行辅助函数 GetVarInt 回顾条目0 (j0, objnum0)条目1 (j1, objnum1)条目2 (j2, objnum2)条目3 (j3, objnum3)条目4 (j4, objnum4)条目5 (j5, objnum5)条目6 (j6, objnum6)条目7 (j7, objnum7)条目8 (j8, objnum8)条目9 (j9, objnum9)四、最终 m_ObjectInfo 映射表五、代码中指针偏移计算的通用公式六、扩展到其他宽度数组的示例七、总结模拟解析宽度数组[1,2,1]10个条目的 XRef 流一、设定场景宽度数组/W [1 2 1]类型字段宽度 1 字节字段2宽度 2 字节适合偏移量 65536 的小文件生成号宽度 1 字节每个条目总字节数 1 2 1 4 字节Index 数组/Index [0 10]对象 0~9 都在流中流数据十六进制共 10 个条目 × 4 字节 40 字节条目0: 01 00 10 00 → 类型1, 偏移0x001016, 生成0 条目1: 01 00 20 00 → 类型1, 偏移32, 生成0 条目2: 02 00 01 00 → 类型2, 对象流编号1, 生成0 条目3: 01 00 30 01 → 类型1, 偏移48, 生成1 条目4: 00 00 00 00 → 类型0 (空闲) 条目5: 01 00 40 00 → 类型1, 偏移64, 生成0 条目6: 02 00 02 00 → 类型2, 对象流编号2, 生成0 条目7: 01 00 50 00 → 类型1, 偏移80, 生成0 条目8: 01 00 60 00 → 类型1, 偏移96, 生成0 条目9: 00 00 00 00 → 类型0 (空闲)流数据内存视图地址 0~39地址: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 数据: 01 00 10 00 01 00 20 00 02 00 01 00 01 00 30 01 00 00 00 00 地址: 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 数据: 01 00 40 00 02 00 02 00 01 00 50 00 01 00 60 00 00 00 00 00二、解析代码核心部分与之前相同std::vectoruint32_tWidthArray{1,2,1};uint32_ttotalWidth4;// 121constuint8_t*pData/* 指向流数据起始地址0 */;uint32_tsegindex0;intstartnum0;uint32_tcount10;constuint8_t*segstartpDatasegindex*totalWidth;// segstart pDatafor(uint32_tj0;jcount;j){constuint8_t*entrystartsegstartj*totalWidth;// 每个条目的起始地址// 读取类型int32_ttype1;if(WidthArray[0]0)// 1 0typeGetVarInt(entrystart,WidthArray[0]);// 读取字段2FX_FILESIZE field20;if(WidthArray[1]0)// 2 0field2GetVarInt(entrystartWidthArray[0],WidthArray[1]);// 读取生成号int32_tgen0;if(WidthArray[2]0)// 1 0genGetVarInt(entrystartWidthArray[0]WidthArray[1],WidthArray[2]);uint32_tobjnumstartnumj;// 存储if(type0){m_ObjectInfo[objnum].pos0;m_ObjectInfo[objnum].type0;}else{m_ObjectInfo[objnum].posfield2;m_ObjectInfo[objnum].gennumgen;if(type1){m_ObjectInfo[objnum].type1;m_SortedOffset.insert(field2);}elseif(type2){m_ObjectInfo[objnum].type2;m_ObjectInfo[field2].type255;// 标记对象流}}}三、逐条解析模拟 CPU 执行辅助函数GetVarInt回顾uint32_tGetVarInt(constuint8_t*p,intn){uint32_tr0;for(inti0;in;i)rr*256p[i];returnr;}条目0 (j0, objnum0)entrystart pData 0*4 地址0读类型GetVarInt(地址0, 1)→ 地址00x01 →type1读字段2GetVarInt(地址01, 2)→ 地址10x00, 地址20x10 → (0*2560)*2560x10 0x0010 16读生成号GetVarInt(地址012, 1)→ 地址30x00 →gen0type1 →m_ObjectInfo[0] {pos16, gennum0, type1}m_SortedOffset插入 16条目1 (j1, objnum1)entrystart 地址4读类型地址40x01 → type1读字段2地址50x00, 地址60x20 → 0x0020 32读生成号地址70x00 → gen0m_ObjectInfo[1] {pos32, gennum0, type1}m_SortedOffset插入 32条目2 (j2, objnum2)entrystart 地址8读类型地址80x02 → type2读字段2地址90x00, 地址100x01 →1读生成号地址110x00 → gen0type2 →m_ObjectInfo[2] {pos1, gennum0, type2}且m_ObjectInfo[1].type 255注意对象流编号为1即对象1被标记为对象流容器重要这里field21表示当前对象对象2是一个压缩对象存储在对象流 #1 中。因此我们需要把对象流 #1 的类型标记为 255以便将来从该流中解压对象。条目3 (j3, objnum3)entrystart 地址12读类型地址120x01 → type1读字段2地址130x00, 地址140x30 → 0x0030 48读生成号地址150x01 → gen1m_ObjectInfo[3] {pos48, gennum1, type1}m_SortedOffset插入 48条目4 (j4, objnum4)entrystart 地址16读类型地址160x00 → type0读字段2地址170x00, 地址180x00 → 0读生成号地址190x00 → 0type0 →m_ObjectInfo[4] {pos0, type0}条目5 (j5, objnum5)entrystart 地址20读类型地址200x01 → type1读字段2地址210x00, 地址220x40 → 0x0040 64读生成号地址230x00 → gen0m_ObjectInfo[5] {pos64, gennum0, type1}m_SortedOffset插入 64条目6 (j6, objnum6)entrystart 地址24读类型地址240x02 → type2读字段2地址250x00, 地址260x02 →2读生成号地址270x00 → gen0m_ObjectInfo[6] {pos2, gennum0, type2}且m_ObjectInfo[2].type 255对象流 #2 被标记条目7 (j7, objnum7)entrystart 地址28读类型地址280x01 → type1读字段2地址290x00, 地址300x50 → 0x0050 80读生成号地址310x00 → gen0m_ObjectInfo[7] {pos80, gennum0, type1}m_SortedOffset插入 80条目8 (j8, objnum8)entrystart 地址32读类型地址320x01 → type1读字段2地址330x00, 地址340x60 → 0x0060 96读生成号地址350x00 → gen0m_ObjectInfo[8] {pos96, gennum0, type1}m_SortedOffset插入 96条目9 (j9, objnum9)entrystart 地址36读类型地址360x00 → type0读字段2地址370x00, 地址380x00 → 0读生成号地址390x00 → 0m_ObjectInfo[9] {pos0, type0}四、最终m_ObjectInfo映射表对象号posgennumtype含义01601未压缩对象位于文件偏移1613201未压缩对象偏移322102压缩对象存储在对象流#1中34811未压缩对象偏移48生成号14000空闲对象56401未压缩对象偏移646202压缩对象存储在对象流#2中78001未压缩对象偏移8089601未压缩对象偏移969000空闲对象另外对象流容器标记m_ObjectInfo[1].type被设置为 255因为条目2中 field21m_ObjectInfo[2].type被设置为 255因为条目6中 field22注意对象1原本是未压缩对象type1现在又被标记为255这在真实PDF中不会发生。这里只是展示解析过程实际中对象1和对象2作为对象流它们自己的XRef条目应该是类型1指向文件中的流对象而不是同时作为压缩对象。为了避免混淆我们应该把对象流编号设为一个不与其他普通对象冲突的值比如100和101。但为了保持示例简单请理解这是演示目的。五、代码中指针偏移计算的通用公式对于任意条目j条目起始地址 pData j * totalWidth类型字段起始 条目起始地址字段2起始 条目起始地址 WidthArray[0]生成号起始 条目起始地址 WidthArray[0] WidthArray[1]无论宽度数组是什么这个公式都适用。因为totalWidth是预计算的总宽度而每个字段的偏移是通过累加前面字段的宽度得到的。为什么这样设计如果硬编码偏移如类型在0字段2在1生成号在5那么当宽度变化时代码就失效了。通过动态累加代码可以适应任何/W组合实现完全通用。六、扩展到其他宽度数组的示例假设/W [0 4 0]只有4字节偏移类型默认1生成号默认0WidthArray[0]0, WidthArray[1]4, WidthArray[2]0totalWidth 4解析时type保持默认1field2 GetVarInt(entrystart 0, 4)读4字节gen保持默认0这样每个条目只存4字节偏移非常紧凑。假设/W [1 8 2]大文件totalWidth 11解析时type读1字节field2读8字节可表示最大 2^64-1 偏移gen读2字节支持超大文件64位偏移和更大生成号。七、总结通过这个包含10个条目的完整示例我们演示了动态读取宽度数组→ 确定每个字段的字节数计算 totalWidth→ 实现 O(1) 跳转到任意条目使用GetVarInt读取大端整数→ 跨平台、任意宽度根据类型分支处理→ 区分未压缩对象、压缩对象、空闲对象标记对象流容器→ 为后续解压做准备整个解析过程完全由/W数组驱动不需要修改代码就能处理任何宽度组合。这正是 PDFium 设计的通用性和健壮性所在。

相关文章:

模拟解析:宽度数组 `[1,2,1]`,10个条目的 XRef 流

文章目录 模拟解析:宽度数组 [1,2,1],10个条目的 XRef 流一、设定场景二、解析代码核心部分(与之前相同)三、逐条解析(模拟 CPU 执行)辅助函数 GetVarInt 回顾条目0 (j0, objnum0)条目1 (j1, objnum1)条目2…...

[macOS逆向工程]:百度网盘客户端速度限制解除的实现原理与技术方案

[macOS逆向工程]:百度网盘客户端速度限制解除的实现原理与技术方案 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 问题剖析:百…...

STC单片机看门狗避坑指南:从原理到调试的5个关键步骤

STC单片机看门狗避坑指南:从原理到调试的5个关键步骤 在嵌入式系统开发中,稳定性是衡量产品质量的重要指标。作为51单片机开发者,我们常常会遇到程序跑飞、死循环等异常情况,这时内部看门狗(WDT)就成了最后…...

如何轻松地使用隔空投送将iPhone内容传输到Android

过去,安卓和苹果用户在设备间共享文件一直很麻烦。然而,如今迎来了一个重大转折点——我们可以使用 AirDrop 将 iPhone 文件传输到安卓设备。尽管这项功能已经发布几天了,但很多人仍然不知道如何从 iPhone 向安卓设备发送 AirDrop 文件。现在…...

docker-enter 脚本完全解析:简化 nsenter 使用的终极工具

docker-enter 脚本完全解析:简化 nsenter 使用的终极工具 【免费下载链接】nsenter 项目地址: https://gitcode.com/gh_mirrors/ns/nsenter 在 Docker 容器管理的早期阶段,nsenter 是一个极其重要的工具,它允许用户直接进入容器的命名…...

告别手动分析!用Frida-Trace一键追踪Android App的JNI函数调用(附实战APK)

高效追踪JNI函数:Frida-Trace在Android逆向工程中的实战应用 逆向工程师和安全研究员们常常需要面对一个现实问题:如何在有限的时间内快速理解一个未知Android应用的Native层行为?传统方法往往需要手动分析so文件、设置断点、逐行跟踪&#…...

如何实现微信聊天记录的永久保存与智能分析

如何实现微信聊天记录的永久保存与智能分析 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg 在数字时代&…...

如何通过可视化学习快速掌握RISC-V?专业仿真平台全解析

如何通过可视化学习快速掌握RISC-V?专业仿真平台全解析 【免费下载链接】Ripes A graphical processor simulator and assembly editor for the RISC-V ISA 项目地址: https://gitcode.com/gh_mirrors/ri/Ripes RISC-V学习工具的选择直接影响掌握效率&#x…...

华为AP有线口除了供电还能干啥?解锁‘瘦AP’变身小型接入交换机的高阶玩法

华为AP有线口的隐藏技能:从无线覆盖到多功能接入的华丽转身 当你走进一家精品酒店的房间,墙面上那个看似普通的华为面板AP,可能正在默默为房间里的智能电视、迷你吧台终端和书桌上的台式机提供网络接入——而这一切都通过那根被大多数人忽略的…...

主线程没卡但ANR了?揭秘Android SharedPreferences的ANR陷阱

主线程没卡但ANR了?揭秘Android SharedPreferences的ANR陷阱 在Android开发中,ANR(Application Not Responding)问题一直是开发者头疼的难题。特别是当应用主线程看似运行正常,却突然弹出ANR对话框时,这种&…...

别再乱用List了!Unity中Queue的5个高效应用场景对比

Unity中Queue的5个高效应用场景:性能对比与实战指南 在Unity开发中,数据结构的选择往往决定了游戏性能的上限。很多开发者习惯性地使用List来解决所有问题,却忽视了Queue在特定场景下的性能优势。本文将深入分析Queue的底层原理,并…...

Arduino-Pico蓝牙开发指南:经典蓝牙与BLE HID主从模式完全解析

Arduino-Pico蓝牙开发指南:经典蓝牙与BLE HID主从模式完全解析 【免费下载链接】arduino-pico Raspberry Pi Pico Arduino core, for all RP2040 and RP2350 boards 项目地址: https://gitcode.com/gh_mirrors/ar/arduino-pico 想要在Raspberry Pi Pico上实现…...

告别系统臃肿:用Win11Debloat实现Windows性能飞跃的全方位指南

告别系统臃肿:用Win11Debloat实现Windows性能飞跃的全方位指南 【免费下载链接】Win11Debloat A simple, lightweight PowerShell script that allows you to remove pre-installed apps, disable telemetry, as well as perform various other changes to declutte…...

C++模板进阶:从特化到元编程

C模板进阶详解一、模板特化全特化template <> class Vector<bool> {// 针对bool类型的特化实现 };偏特化template <typename T> class Vector<T*> {// 针对指针类型的部分特化 };二、可变参数模板template <typename... Args> void print(Args..…...

显式启用-u_printf_float和-u_scanf_float前后的代码尺寸占用实验

本文中使用的嵌入式编译器基于arm-none-eabi-gcc&#xff0c;构建文件基于Makefile。 main.c不编写任何代码&#xff0c;保证实验的其他变量统一。源文件main.c&#xff1a; 代码模式固定为Debug&#xff0c;优化等级固定为 -Og &#xff1a; syscalls.c 系统调用库函数文件参…...

DownKyi视频管理进阶指南:从新手到专家的实践路径

DownKyi视频管理进阶指南&#xff1a;从新手到专家的实践路径 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xff0…...

面试真题集(五):高级特性与系统优化

引言 本专题聚焦原子操作、动态并行、纹理内存、协作组、CUDA Graph等高级特性,以及系统级优化思维,20道真题助你冲击大厂高薪岗位。 一、选择题(6题) 1.1 关于CUDA原子操作,下列说法错误的是?(⭐⭐) A. 原子操作可以在全局内存和共享内存上执行 B. atomicAdd 是最常…...

运维工具汇总

一、远程工具列表 1. MobaXterm site: MobaXterm隧道使用_mobaxterm怎么读-CSDN博客 二、httpclient 1. small:https://zhuanlan.zhihu.com/p/701243358 2.small2: 客户端下载 | Reqable API抓包调试 API测试一站式工具 small2: https://reqable.com/zh-CN/download/ …...

3步彻底解决Windows系统卡顿问题:开源系统清理工具实战指南

3步彻底解决Windows系统卡顿问题&#xff1a;开源系统清理工具实战指南 【免费下载链接】WindowsCleaner Windows Cleaner——专治C盘爆红及各种不服&#xff01; 项目地址: https://gitcode.com/gh_mirrors/wi/WindowsCleaner 你是否也经历过这样的场景&#xff1a;工作…...

Unity路径有中文就报错?手把手教你解决Autoware高精地图插件导入的坑

Unity路径中文报错&#xff1f;Autoware高精地图插件导入全攻略 刚接触Autoware高精地图制作的新手们&#xff0c;十有八九会在第一步就栽跟头——当你兴冲冲下载好vector_map插件&#xff0c;准备在Unity中大展拳脚时&#xff0c;却发现插件死活无法正常导入。这种挫败感我太熟…...

stanford_dl_ex代码结构深度解析:从数据加载到模型评估的完整流程

stanford_dl_ex代码结构深度解析&#xff1a;从数据加载到模型评估的完整流程 【免费下载链接】stanford_dl_ex Programming exercises for the Stanford Unsupervised Feature Learning and Deep Learning Tutorial 项目地址: https://gitcode.com/gh_mirrors/st/stanford_d…...

DS18B20寄生供电模式全解析:3.3V系统下的STM32省电测温方案

DS18B20寄生供电模式全解析&#xff1a;3.3V系统下的STM32省电测温方案 在物联网设备开发中&#xff0c;低功耗设计往往决定着产品的成败。当我们需要在电池供电环境下实现长时间温度监测时&#xff0c;DS18B20传感器的寄生供电模式配合STM32的3.3V系统&#xff0c;能为我们带来…...

STM32开发避坑指南:KEIL中__use_no_semihosting报错的终极解决方案

STM32开发避坑指南&#xff1a;KEIL中__use_no_semihosting报错的终极解决方案 在嵌入式开发领域&#xff0c;STM32凭借其出色的性能和丰富的外设资源&#xff0c;成为众多开发者的首选。然而&#xff0c;在使用KEIL MDK进行开发时&#xff0c;不少开发者都会遇到一个令人头疼的…...

动画测试与调试完全手册:animation-samples项目中的自动化测试实践

动画测试与调试完全手册&#xff1a;animation-samples项目中的自动化测试实践 【免费下载链接】animation-samples Multiple samples showing the best practices in animation on Android. 项目地址: https://gitcode.com/gh_mirrors/an/animation-samples animation-…...

STM32双路直流电机PWM驱动与霍尔编码器闭环控制

1. 项目概述DCMotorDrive 是专为 RenBuggy 平台设计的双路直流电机驱动固件模块&#xff0c;其核心目标是实现对两台独立直流电机的高精度 PWM 调速控制&#xff0c;并集成霍尔传感器反馈通道&#xff0c;支持实时速度与位移闭环。该模块并非通用电机驱动芯片&#xff08;如 L2…...

Monolog Bridge 高级用法:FingersCrossed策略与HTTP状态码激活机制完全指南 [特殊字符]

Monolog Bridge 高级用法&#xff1a;FingersCrossed策略与HTTP状态码激活机制完全指南 &#x1f680; 【免费下载链接】monolog-bridge Provides integration for Monolog with various Symfony components 项目地址: https://gitcode.com/gh_mirrors/mo/monolog-bridge …...

ComfyUI-Impact-Pack完整指南:3步掌握AI图像增强的强大工具包

ComfyUI-Impact-Pack完整指南&#xff1a;3步掌握AI图像增强的强大工具包 【免费下载链接】ComfyUI-Impact-Pack Custom nodes pack for ComfyUI This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more. 项目地址: h…...

Le Git Graph分支管理:动态加载和筛选分支提交的终极指南

Le Git Graph分支管理&#xff1a;动态加载和筛选分支提交的终极指南 【免费下载链接】le-git-graph Browser extension to add git graph to GitHub website. 项目地址: https://gitcode.com/gh_mirrors/le/le-git-graph Le Git Graph是一款强大的浏览器扩展&#xff0…...

MKDV4GCL-ABB嵌入式存储芯片在智能物联网设备中的关键应用解析

1. 为什么物联网设备需要专用存储芯片&#xff1f; 第一次拆解智能家居设备时&#xff0c;我发现很多厂商都在用TF卡扩展存储。但实际使用三个月后&#xff0c;问题就来了——频繁读写导致卡片损坏&#xff0c;设备不断报存储错误。这就是典型选错存储方案的后果。物联网设备对…...

一文读懂10英寸平板尺寸:从屏幕比例到实际机身尺寸

在平板电脑市场中&#xff0c;"10英寸"这一规格始终占据着黄金地位。但当我们搜索"平板10寸多大长和宽"时&#xff0c;得到的答案往往模糊不清。作为行业观察者&#xff0c;我将为您深度解析10英寸平板尺寸的行业标准、设计逻辑及选购策略&#xff0c;带您…...