blob: 1f99acf83003871f68cf3209560b97d7b552f89e [file] [log] [blame]
// Copyright 2019 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef LIBIPP_IPP_PARSER_H_
#define LIBIPP_IPP_PARSER_H_
#include <cstdint>
#include <list>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "ipp_attribute.h"
#include "ipp_base.h"
#include "ipp_frame.h"
namespace ipp {
// forward declarations
class Collection;
class Package;
struct RawAttribute;
struct RawCollection;
enum ErrorCode {
kAttributeNameIsEmpty,
kAttributeNameIsTooLong,
kAttributeNameDoesNotBeginWithLowercaseLetter,
kAttributeNameContainsIncorrectCharacters
};
class Parser {
public:
// Constructor, both parameters must not be nullptr. |frame| is used as
// internal buffer to store intermediate form of parsed data. All spotted
// issues are logged to |log| (by push_back()).
Parser(Frame* frame, std::vector<Log>* log) : frame_(frame), errors_(log) {}
// Parses data from given buffer and saves it to internal buffer.
bool ReadFrameFromBuffer(const uint8_t* ptr, const uint8_t* const buf_end);
// Interpret the content from internal buffer and store it in |package|.
// If |log_unknown_values| is set then all attributes unknown in |package|
// are reported to the log.
bool SaveFrameToPackage(bool log_unknown_values, Package* package);
// Resets the state of the object to initial state. It does not modify
// objects provided in the constructor (|frame| and |log|).
void ResetContent();
private:
// Copy/move/assign constructors/operators are forbidden.
Parser(const Parser&) = delete;
Parser(Parser&&) = delete;
Parser& operator=(const Parser&) = delete;
Parser& operator=(Parser&&) = delete;
// Methods for adding entries to the log.
void LogScannerError(const std::string& message, const uint8_t* position);
void LogParserError(ErrorCode error_code);
void LogParserError(
const std::string& message,
std::string action = "This is critical error, parsing was cancelled.");
void LogParserWarning(const std::string& message);
void LogParserNewElement();
// Reads single tag_name_value from the buffer (ptr is updated) and append it
// to the parameter. Returns false <=> error occurred.
bool ReadTNVsFromBuffer(const uint8_t** ptr,
const uint8_t* const end_buf,
std::list<TagNameValue>*);
// Parser helpers.
bool ParseRawValue(int coll_level,
const TagNameValue& tnv,
std::list<TagNameValue>* data_chunks,
RawAttribute* attr);
bool ParseRawCollection(int coll_level,
std::list<TagNameValue>* data_chunks,
RawCollection* coll);
bool ParseRawGroup(std::list<TagNameValue>* data_chunks, RawCollection* coll);
bool DecodeCollection(RawCollection* raw, Collection* coll);
// Helper for parsing individual values.
void LoadAttrValue(Attribute* attr,
size_t index,
const std::vector<uint8_t>& buf,
uint8_t tag);
// Internal buffer.
Frame* frame_;
// Internal log: all errors & warnings are logged here.
std::vector<Log>* errors_;
// Temporary copies of begin/end pointers of the current buffer.
const uint8_t* buffer_begin_ = nullptr;
const uint8_t* buffer_end_ = nullptr;
// This is a path to group/attribute being processed currently by the parser.
// Each segment contains a name and a flag (true/false). When the flag is
// set to true then notices about direct offspring unknown attributes are
// added to the log with LogParserNewElement(...) method. When false, this
// method has no effect for offspring attributes.
std::vector<std::pair<std::string, bool>> parser_context_;
};
} // namespace ipp
#endif // LIBIPP_IPP_PARSER_H_