Class: FormatParser::JSONParser::Validator
- Inherits:
-
Object
- Object
- FormatParser::JSONParser::Validator
- Defined in:
- lib/parsers/json_parser/validator.rb
Overview
This class checks whether a given file is a valid JSON file. The validation process DOES NOT assemble an object with the contents of the JSON file in memory, Instead, it implements a simple state-machine-like that digests the contents of the file while traversing the hierarchy of nodes in the document.
Although this is based on the IETF standard (www.rfc-editor.org/rfc/rfc8259), it does cut a few corners for the sake of simplicity. For instance, instead of validating Numbers, “true”, “false” and “null” tokens, it supports a type called Literal to hold generic sequences of characters. This decision makes the implementation simpler while being a good-enough approach to identify JSON files.
There is also a cap. Large files are not read all the way through. Instead, if the beginning of file is JSON-compliant, it is assumed that the file is a JSON file.
Defined Under Namespace
Classes: JSONParserError
Constant Summary collapse
- MAX_SAMPLE_SIZE =
1024
- MAX_LITERAL_SIZE =
much larger then necessary.
30
- ESCAPE_CHAR =
"\\"
- WHITESPACE_CHARS =
[" ", "\t", "\n", "\r"]
- ENDING_VALUE_CHARS =
[",", "]", "}"]
- LITERALS_CHAR_TEMPLATE =
any alphanumeric, “+”, “-” and “.”
/\w|[+\-.]/
Instance Method Summary collapse
-
#initialize(io) ⇒ Validator
constructor
A new instance of Validator.
- #stats(node_type) ⇒ Object
- #validate ⇒ Object
Constructor Details
#initialize(io) ⇒ Validator
Returns a new instance of Validator.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/parsers/json_parser/validator.rb', line 26 def initialize(io) @io = io @current_node = nil # :object, :array, :string, :literal @parent_nodes = [] @current_state = :awaiting_root_node @escape_next = false @current_literal_size = 0 @pos = 0 @all_parsers = {} @execution_stats = { array: 0, object: 0, literal: 0, string: 0 } setup_transitions end |
Instance Method Details
#stats(node_type) ⇒ Object
68 69 70 |
# File 'lib/parsers/json_parser/validator.rb', line 68 def stats(node_type) @execution_stats[node_type] end |
#validate ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/parsers/json_parser/validator.rb', line 47 def validate char_reader = FormatParser::UTF8Reader.new(@io) while (c = char_reader.read_char) @pos += 1 parse_char c # Halt validation if the sampling limit is reached. if @pos >= MAX_SAMPLE_SIZE raise JSONParserError, "Invalid JSON file" if @current_state == :awaiting_root_node return false end end # Raising error in case the EOF is reached earlier than expected raise JSONParserError, "Incomplete JSON file" if @current_state != :closed true rescue FormatParser::UTF8Reader::UTF8CharReaderError raise JSONParserError, "Invalid UTF-8 character" end |