2017-02-16 11 views
1

Для отправки сложных объектов JSON/JavaScript в двоичные файлы на C++ через провод, я использую протокольные буферы. В наши дни существует поддержка native protobuf для Node.js, поэтому я не использую никаких других привязок.Буферы протокола записи/чтения

// Set maximum execution time of binary to equal the 
// remainder of processing time, minus a second to allow 
// for parsing. 
var timeLimit = context.getRemainingTimeInMillis() - 1000; 

// Check if meta parameters are given in the request. 
// Assign default values if they are not. 
var model = new protocols.Model(); 

// Sort the resolutions. 
function descending(a, b) { 
    if (a.width > b.width) { 
     return -1; 
    } else if (a.width < b.width) { 
     return 1; 
    } 
    return 0; 
} 

// Construct image objects. 
var images = request.images.map(function(image) { 
    // Perform the sort. 
    image.resolutions.sort(descending); 

    // Create an image protobuffer. 
    var imageProto = new protocols.Model.Image(); 

    // Assign the original's resolution to the image. 
    imageProto.setWidth(image.resolutions[0].width); 
    imageProto.setHeight(image.resolutions[0].height); 

    // Return the result. 
    return imageProto; 
}); 

// Construct flag enumeration references. 
var flags = request.flags.map(function(flag) { 
    return protocols.Model.Flag[flag]; 
}); 

// Assign request properties to protobuf. 
model.setImagesList  (images             ); 
model.setFlagsList  (flags              ); 
model.setMinNoOfPages (request.minNoOfPages ? request.minNoOfPages : 1  ); 
model.setMaxNoOfPages (request.maxNoOfPages ? request.maxNoOfPages : 1  ); 
model.setMaxPerPage  (request.maxPerPage  ? request.maxPerPage : 5  ); 
model.setPageWidth  (request.pageWidth  ? request.pageWidth  : 3508  ); 
model.setPageHeight  (request.pageHeight  ? request.pageHeight : 2480  ); 
model.setTimeLimit  (request.timeLimit  ? request.timeLimit  : timeLimit); 
model.setBorderWidth (request.borderWidth ? request.borderWidth : 0  ); 
model.setMinDim   (request.minDim   ? request.minDim  : 0  ); 

// This is where things go wrong. 
var serialized = model.serializeBinary(); 
fs.writeFileSync('model.pb', serialized); 
var read = fs.readFileSync('model.pb'), 
    model2 = protocols.Model.deserializeBinary(read); 

console.log(model.toObject()); 
console.log(model2.toObject()); 

Выше приведен фрагмент кода, на котором я застрял. Мне удалось составить сообщение Protobuf:

syntax = "proto3"; 

package layout; 

message Model { 

    enum Flag { 
     FILL_PAGE = 0; 
     BORDERS = 1; 
    } 

    message Image { 
     int32 width = 1; 
     int32 height = 2; 
    } 

    repeated Flag flags = 1; 
    repeated Image images = 2; 

    string avoid_layout = 3; 
    int32 min_no_of_pages = 4; 
    int32 max_no_of_pages = 5; 
    int32 max_per_page = 6; 
    int32 page_width = 7; 
    int32 page_height = 8; 
    int32 time_limit = 9; 
    int32 border_width = 10; 
    int32 min_dim = 11; 
} 

Однако документация на поддержку JavaScript для Protobuf минимальна (https://developers.google.com/protocol-buffers/docs/reference/javascript-generated#message), и я не могу понять, как я могу читать мои сообщения в файл, а затем прочитать их снова , Может кто-нибудь объяснить мне, как это сделать?

Я представляю решение некоторые вариации на последних строках моего кода, но в настоящее время я получаю эту ошибку:

AssertionError: Failure: Type not convertible to Uint8Array. 
+1

Какая кодовая строка? Я думаю, 'model2 = protocols.Model.deserializeBinary (read)'? –

+0

Да, эта строка вызывает ошибку. – Arthelais

+1

Каков результат 'read instanceof Uint8Array'? Если false, какую версию 'node' вы используете? –

ответ

1

Вы, вероятно, свидетелями какой-то неясный случай узла Buffer не признается Uint8Array. Я нашел relevant issue report. Поэтому попробуйте применить тип с помощью

protocols.Model.deserializeBinary(new Uint8Array(read)); 

или replacing the constructor. Это предложение особенно похоже на ваше - оно также читает двоичный файл.

Смежные вопросы