تمرین: تجزیه Protobuf
در این تمرین، شما یک تجزیهکننده برای رمزگذاری باینری پروتوباف خواهید ساخت. نگران نباشید، این کار سادهتر از آن است که به نظر میرسد! این الگو نشاندهنده یک الگوی رایج در تجزیه دادهها است که شامل عبور برشهای داده است. دادههای اصلی هرگز کپی نمیشوند.
تجزیه کامل یک پیام پروتوباف نیاز به دانستن تایپهای این فیلدها دارد که بر اساس شمارههای فیلد ایندکس شدهاند. این اطلاعات معمولاً در یک فایل proto
ارائه میشود. در این تمرین، ما این اطلاعات را به صورت عبارات match
در توابعی که برای هر فیلد فراخوانی میشوند، کدگذاری خواهیم کرد.
ما از پروتوباف زیر استفاده خواهیم کرد:
message PhoneNumber {
optional string number = 1;
optional string type = 2;
}
message Person {
optional string name = 1;
optional int32 id = 2;
repeated PhoneNumber phones = 3;
}
یک پیام پروتوباف به عنوان مجموعهای از فیلدها، یکی پس از دیگری، کدگذاری میشود. هر فیلد به صورت یک “تگ” به همراه مقدار آن پیادهسازی شده است. تگ شامل شماره فیلد (مانند 2
برای فیلد id
در پیام Person
) و wire type است که نحوه تعیین بار را از جریان بایت مشخص میکند.
اعداد، از جمله تگ، با استفاده از کدگذاری با طول متغیر به نام VARINT نمایندگی میشوند. خوشبختانه، تابع parse_varint
برای شما تعریف شده است. کد داده شده همچنین بازخوانیهایی برای مدیریت فیلدهای Person
و PhoneNumber
و تجزیه یک پیام به مجموعهای از فراخوانیها به آن بازخوانیها را تعریف میکند.
برای شما باقیمانده است که تابع parse_field
و ویژگی ProtoMessage
را برای Person
و PhoneNumber
پیادهسازی کنید.
Speaker Notes
This slide and its sub-slides should take about 30 minutes.
- در این تمرین موارد مختلفی وجود دارد که ممکن است تجزیه protobuf با شکست مواجه شود، مثلاً اگر بخواهید یک
i32
را هنگامی که کمتر از ۴ بایت در بافر داده باقیمانده است، تجزیه کنید. در کد Rust معمولاً این را با استفاده ازResult
مدیریت میکنیم، اما برای سادگی در این تمرین، اگر با هرگونه خطا مواجه شویم، به جای آن که باResult
برخورد کنیم، برنامه را متوقف خواهیم کرد. در روز چهارم، به بررسی دقیقتر مدیریت خطا در Rust خواهیم پرداخت.