calabash-android 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES.txt +1 -0
- data/Gemfile +4 -0
- data/LICENSE +8 -0
- data/Rakefile +2 -0
- data/bin/calabash-android +42 -0
- data/bin/calabash-android-build.rb +37 -0
- data/bin/calabash-android-generate.rb +26 -0
- data/bin/calabash-android-helpers.rb +71 -0
- data/bin/calabash-android-run.rb +18 -0
- data/bin/calabash-android-setup.rb +392 -0
- data/calabash-android.gemspec +23 -0
- data/doc/calabash-android-help.txt +21 -0
- data/epl-v10.html +261 -0
- data/features-skeleton/.irbrc +16 -0
- data/features-skeleton/irb_android.sh +2 -0
- data/features-skeleton/my_first.feature +5 -0
- data/features-skeleton/step_definitions/calabash_steps.rb +1 -0
- data/features-skeleton/support/app_installation_hooks.rb +26 -0
- data/features-skeleton/support/app_life_cycle_hooks.rb +28 -0
- data/features-skeleton/support/env.rb +1 -0
- data/features-skeleton/support/hooks.rb +18 -0
- data/lib/calabash-android.rb +2 -0
- data/lib/calabash-android/calabash_steps.rb +18 -0
- data/lib/calabash-android/canned_steps.md +239 -0
- data/lib/calabash-android/color_helper.rb +13 -0
- data/lib/calabash-android/cucumber.rb +9 -0
- data/lib/calabash-android/lib/screenShotTaker.jar +0 -0
- data/lib/calabash-android/management/adb.rb +11 -0
- data/lib/calabash-android/management/app_installation.rb +21 -0
- data/lib/calabash-android/operations.rb +283 -0
- data/lib/calabash-android/steps/additions_manual_steps.rb +11 -0
- data/lib/calabash-android/steps/app_steps.rb +10 -0
- data/lib/calabash-android/steps/assert_steps.rb +32 -0
- data/lib/calabash-android/steps/check_box_steps.rb +3 -0
- data/lib/calabash-android/steps/context_menu_steps.rb +12 -0
- data/lib/calabash-android/steps/date_picker_steps.rb +8 -0
- data/lib/calabash-android/steps/enter_text_steps.rb +21 -0
- data/lib/calabash-android/steps/location_steps.rb +19 -0
- data/lib/calabash-android/steps/navigation_steps.rb +27 -0
- data/lib/calabash-android/steps/press_button_steps.rb +35 -0
- data/lib/calabash-android/steps/progress_steps.rb +49 -0
- data/lib/calabash-android/steps/rotation_steps.rb +8 -0
- data/lib/calabash-android/steps/screenshot_steps.rb +11 -0
- data/lib/calabash-android/steps/spinner_steps.rb +3 -0
- data/lib/calabash-android/steps/time_picker_steps.rb +8 -0
- data/lib/calabash-android/version.rb +6 -0
- data/test-server/AndroidManifest.xml +13 -0
- data/test-server/build.xml +192 -0
- data/test-server/calabash-js/src/calabash.js +125 -0
- data/test-server/calabash-js/src/set_text.js +132 -0
- data/test-server/instrumentation-backend/.classpath +10 -0
- data/test-server/instrumentation-backend/.project +33 -0
- data/test-server/instrumentation-backend/.settings/org.eclipse.jdt.core.prefs +12 -0
- data/test-server/instrumentation-backend/AndroidManifest.xml +15 -0
- data/test-server/instrumentation-backend/assets/foo.bar +0 -0
- data/test-server/instrumentation-backend/gen/com/lesspainful/simpleui/test/R.java +23 -0
- data/test-server/instrumentation-backend/libs/robotium-solo-2.5.jar +0 -0
- data/test-server/instrumentation-backend/project.properties +11 -0
- data/test-server/instrumentation-backend/res/drawable-hdpi/ic_launcher.png +0 -0
- data/test-server/instrumentation-backend/res/drawable-ldpi/ic_launcher.png +0 -0
- data/test-server/instrumentation-backend/res/drawable-mdpi/ic_launcher.png +0 -0
- data/test-server/instrumentation-backend/res/layout/main.xml +12 -0
- data/test-server/instrumentation-backend/res/values/strings.xml +7 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Command.java +48 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/InstrumentationBackend.java +196 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +64 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/TestHelpers.java +136 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/Action.java +11 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/Actions.java +113 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/NullAction.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/PressButtonNumber.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/PressButtonText.java +27 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/PressImageButtonNumber.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/button/WaitForButton.java +47 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/checkbox/ToggleCheckboxNumber.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressText.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressTextAndSelectFromMenuById.java +26 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressTextAndSelectFromMenuByIndex.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/contextmenu/LongPressTextAndSelectFromMenuByText.java +26 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/ClickOnScreen.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/gestures/Swipe.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/helpers/ListActions.java +26 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/LongPressListItems.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/list/PressListItems.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/location/FakeGPSLocation.java +79 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/scrolling/ScrollDown.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/scrolling/ScrollUp.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/DownKey.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/GoBack.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/PressMenu.java +26 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/softkey/SelectFromMenuByText.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/spinner/SelectSpinnerItemByContentDescription.java +43 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertText.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/AssertTextOfSpecificTextViewByContentDescription.java +32 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextByIndex.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClearTextFieldByContentDescription.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/ClickOnText.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextByContentDescription.java +32 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/text/EnterTextByIndex.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetDateByContentDescription.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetDateByIndex.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetTimeByContentDescription.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/time/SetTimeByIndex.java +26 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/ClickOnViewById.java +63 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/LongPressOnViewById.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/Press.java +89 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/WaitForViewById.java +41 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/Wait.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForDialogClose.java +21 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForProgress.java +47 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForScreen.java +49 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/wait/WaitForText.java +26 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/CalabashChromeClient.java +109 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpBodyHtml.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/DumpHtml.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/EnterTextByCssSelector.java +99 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/PressByCssSelector.java +43 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Query.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/QueryHelper.java +99 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/ScrollTo.java +74 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetPropertyByCssSelector.java +43 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/SetText.java +50 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/webview/Touch.java +44 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/Base64Variant.java +413 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/Base64Variants.java +90 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/FormatSchema.java +29 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonEncoding.java +47 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonFactory.java +937 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonGenerationException.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonGenerator.java +1197 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonLocation.java +141 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonNode.java +879 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonParseException.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonParser.java +1434 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonProcessingException.java +80 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonStreamContext.java +122 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/JsonToken.java +161 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/ObjectCodec.java +157 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/PrettyPrinter.java +166 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/SerializableString.java +54 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/Version.java +90 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/Versioned.java +20 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JacksonAnnotation.java +20 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonAnyGetter.java +25 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonAnySetter.java +24 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonAutoDetect.java +148 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonBackReference.java +41 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonCreator.java +19 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonGetter.java +35 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonIgnore.java +57 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonIgnoreProperties.java +48 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonIgnoreType.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonManagedReference.java +41 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonMethod.java +90 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonProperty.java +38 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonPropertyOrder.java +46 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonRawValue.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonSetter.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonSubTypes.java +44 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonTypeInfo.java +236 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonTypeName.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonUnwrapped.java +76 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonValue.java +46 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/JsonWriteNullProperties.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/annotate/package-info.java +16 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/format/DataFormatDetector.java +176 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/format/DataFormatMatcher.java +117 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/format/InputAccessor.java +130 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/format/MatchStrength.java +64 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/format/package-info.java +8 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/ByteSourceBootstrapper.java +518 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/DefaultPrettyPrinter.java +13 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/Indenter.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/JsonGeneratorBase.java +570 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/JsonNumericParserBase.java +20 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/JsonParserBase.java +1067 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/JsonParserMinimalBase.java +539 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/JsonReadContext.java +188 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/JsonWriteContext.java +178 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/ReaderBasedParser.java +1815 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/ReaderBasedParserBase.java +228 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/StreamBasedParserBase.java +197 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/Utf8Generator.java +1757 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/Utf8StreamParser.java +2966 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/WriterBasedGenerator.java +1815 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/impl/package-info.java +6 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/BaseReader.java +117 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/CharacterEscapes.java +73 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/IOContext.java +239 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/InputDecorator.java +67 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/JsonStringEncoder.java +408 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/MergedStream.java +145 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/NumberInput.java +303 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/NumberOutput.java +398 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/OutputDecorator.java +40 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/SegmentedStringWriter.java +104 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/SerializedString.java +114 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/UTF32Reader.java +214 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/UTF8Writer.java +387 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/io/package.html +4 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/AbstractTypeResolver.java +63 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/AnnotationIntrospector.java +1485 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/BeanDescription.java +171 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/BeanProperty.java +123 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/BeanPropertyDefinition.java +66 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ClassIntrospector.java +117 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ContextualDeserializer.java +38 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ContextualKeyDeserializer.java +33 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ContextualSerializer.java +38 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/DeserializationConfig.java +926 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/DeserializationContext.java +262 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/DeserializationProblemHandler.java +56 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/DeserializerFactory.java +356 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/DeserializerProvider.java +185 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/Deserializers.java +339 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/HandlerInstantiator.java +115 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/InjectableValues.java +85 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/JsonDeserializer.java +166 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/JsonMappingException.java +335 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/JsonSerializable.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/JsonSerializableWithType.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/JsonSerializer.java +138 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/KeyDeserializer.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/KeyDeserializers.java +21 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/MapperConfig.java +1154 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/MappingIterator.java +190 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/MappingJsonFactory.java +81 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/Module.java +255 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ObjectMapper.java +2885 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ObjectReader.java +958 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ObjectWriter.java +554 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/PropertyNamingStrategy.java +258 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ResolvableDeserializer.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ResolvableSerializer.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/RuntimeJsonMappingException.java +21 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/SerializationConfig.java +1041 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/SerializerFactory.java +198 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/SerializerProvider.java +552 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/Serializers.java +137 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/TypeDeserializer.java +118 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/TypeSerializer.java +164 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JacksonInject.java +30 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JacksonStdImpl.java +25 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonCachable.java +32 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonDeserialize.java +109 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonFilter.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonRootName.java +29 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonSerialize.java +216 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonTypeIdResolver.java +35 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonTypeResolver.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonValueInstantiator.java +26 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/JsonView.java +37 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/NoClass.java +19 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/annotate/package-info.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/AbstractDeserializer.java +102 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/ArrayDeserializer.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/ArrayDeserializers.java +11 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/BasicDeserializerFactory.java +894 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/BeanDeserializer.java +1537 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/BeanDeserializerBuilder.java +277 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/BeanDeserializerFactory.java +1474 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/BeanDeserializerModifier.java +58 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/CollectionDeserializer.java +47 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/ContainerDeserializer.java +14 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/CustomDeserializerFactory.java +227 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/DateDeserializer.java +9 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/EnumDeserializer.java +15 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/EnumResolver.java +17 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/FromStringDeserializer.java +13 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/JsonNodeDeserializer.java +54 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/MapDeserializer.java +44 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/SettableAnyProperty.java +177 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/SettableBeanProperty.java +827 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/StdDeserializationContext.java +326 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/StdDeserializer.java +94 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/StdDeserializerProvider.java +494 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/StdDeserializers.java +119 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/StdKeyDeserializer.java +12 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/StdKeyDeserializers.java +11 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/StdScalarDeserializer.java +13 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/ThrowableDeserializer.java +13 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/UntypedObjectDeserializer.java +9 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/ValueInstantiator.java +280 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/ValueInstantiators.java +52 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/BeanPropertyMap.java +257 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/CreatorCollector.java +141 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/CreatorProperty.java +152 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/ExternalTypeHandler.java +173 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/PropertyBasedCreator.java +117 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/PropertyValue.java +117 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/PropertyValueBuffer.java +102 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/UnwrappedPropertyHandler.java +41 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/ValueInjector.java +45 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/impl/package-info.java +9 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/package-info.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/AtomicBooleanDeserializer.java +22 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/AtomicReferenceDeserializer.java +47 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/CalendarDeserializer.java +47 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/ClassDeserializer.java +49 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/CollectionDeserializer.java +265 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/ContainerDeserializerBase.java +37 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/DateDeserializer.java +30 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/EnumDeserializer.java +139 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/EnumMapDeserializer.java +90 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/EnumSetDeserializer.java +89 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/FromStringDeserializer.java +265 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/JavaTypeDeserializer.java +38 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/JsonNodeDeserializer.java +314 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/MapDeserializer.java +412 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/ObjectArrayDeserializer.java +201 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/PrimitiveArrayDeserializers.java +583 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/StdDeserializer.java +1136 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/StdKeyDeserializer.java +340 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/StdKeyDeserializers.java +108 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/StdScalarDeserializer.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/StdValueInstantiator.java +392 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/StringCollectionDeserializer.java +227 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/StringDeserializer.java +55 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/ThrowableDeserializer.java +164 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/TimestampDeserializer.java +30 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/TokenBufferDeserializer.java +36 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/UntypedObjectDeserializer.java +248 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/deser/std/package-info.java +15 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/exc/UnrecognizedPropertyException.java +75 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ext/CoreXMLDeserializers.java +114 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ext/CoreXMLSerializers.java +72 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ext/DOMDeserializer.java +65 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ext/OptionalHandlerFactory.java +217 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ext/package-info.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/Annotated.java +85 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedClass.java +980 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedConstructor.java +143 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedField.java +119 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedMember.java +56 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedMethod.java +188 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedMethodMap.java +85 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedParameter.java +191 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotatedWithParams.java +195 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/AnnotationMap.java +101 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/BasicBeanDescription.java +615 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/BasicClassIntrospector.java +364 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/JacksonAnnotationIntrospector.java +813 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/MemberKey.java +83 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/MethodFilter.java +12 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/NopAnnotationIntrospector.java +209 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/POJOPropertiesCollector.java +713 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/POJOPropertyBuilder.java +648 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/VisibilityChecker.java +424 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/introspect/package-info.java +12 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/NamedType.java +53 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/SubtypeResolver.java +39 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/TypeIdResolver.java +74 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/TypeResolverBuilder.java +151 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsArrayTypeDeserializer.java +126 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsArrayTypeSerializer.java +110 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsExternalTypeDeserializer.java +37 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsExternalTypeSerializer.java +129 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsPropertyTypeDeserializer.java +191 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsPropertyTypeSerializer.java +69 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsWrapperTypeDeserializer.java +103 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/AsWrapperTypeSerializer.java +121 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/ClassNameIdResolver.java +138 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/MinimalClassNameIdResolver.java +66 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/StdSubtypeResolver.java +151 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/StdTypeResolverBuilder.java +202 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/TypeDeserializerBase.java +154 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/TypeIdResolverBase.java +37 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/TypeNameIdResolver.java +154 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/TypeSerializerBase.java +31 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/impl/package-info.java +9 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/jsontype/package-info.java +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/module/SimpleAbstractTypeResolver.java +86 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/module/SimpleDeserializers.java +130 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/module/SimpleKeyDeserializers.java +59 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/module/SimpleModule.java +265 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/module/SimpleSerializers.java +206 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/module/SimpleValueInstantiators.java +45 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/module/package-info.java +16 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/package-info.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/AnyGetterWriter.java +48 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/ArraySerializers.java +7 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/BasicSerializerFactory.java +806 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/BeanPropertyFilter.java +30 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/BeanPropertyWriter.java +512 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/BeanSerializer.java +126 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/BeanSerializerBuilder.java +140 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/BeanSerializerFactory.java +780 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/BeanSerializerModifier.java +95 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/ContainerSerializers.java +8 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/CustomSerializerFactory.java +293 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/EnumSerializer.java +17 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/FilterProvider.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/FilteredBeanPropertyWriter.java +96 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/JdkSerializers.java +11 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/MapSerializer.java +58 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/PropertyBuilder.java +372 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/ScalarSerializerBase.java +18 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/SerializerBase.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/StdKeySerializer.java +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/StdSerializerProvider.java +852 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/StdSerializers.java +372 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/ToStringSerializer.java +14 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/FailingSerializer.java +43 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/JsonSerializerMap.java +93 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/PropertySerializerMap.java +231 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/ReadOnlyClassToSerializerMap.java +73 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/SerializerCache.java +304 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/SimpleBeanPropertyFilter.java +109 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/SimpleFilterProvider.java +114 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/UnknownSerializer.java +54 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/UnwrappingBeanPropertyWriter.java +99 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/UnwrappingBeanSerializer.java +76 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/impl/package-info.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/package-info.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/AsArraySerializerBase.java +185 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/BeanSerializerBase.java +340 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/CalendarSerializer.java +43 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/CollectionSerializer.java +113 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/ContainerSerializerBase.java +51 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/DateSerializer.java +42 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/EnumMapSerializer.java +218 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/EnumSerializer.java +84 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/EnumSetSerializer.java +47 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/IndexedStringListSerializer.java +116 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/InetAddressSerializer.java +51 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/IterableSerializer.java +63 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/JsonValueSerializer.java +233 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/MapSerializer.java +422 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/NonTypedScalarSerializerBase.java +34 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/NullSerializer.java +38 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/ObjectArraySerializer.java +281 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/RawSerializer.java +52 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/ScalarSerializerBase.java +52 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/SerializableSerializer.java +99 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/SerializableWithTypeSerializer.java +90 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/SerializerBase.java +184 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StaticListSerializerBase.java +46 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StdArraySerializers.java +476 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StdContainerSerializers.java +249 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StdJdkSerializers.java +195 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StdKeySerializer.java +43 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StdKeySerializers.java +95 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StringCollectionSerializer.java +119 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/StringSerializer.java +36 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/TimeZoneSerializer.java +38 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/ToStringSerializer.java +73 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/ser/std/TokenBufferSerializer.java +66 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/ArrayType.java +260 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/ClassKey.java +94 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/CollectionLikeType.java +204 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/CollectionType.java +94 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/HierarchicType.java +88 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/MapLikeType.java +265 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/MapType.java +146 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/SimpleType.java +250 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/TypeBase.java +148 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/TypeBindings.java +351 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/TypeFactory.java +1165 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/TypeModifier.java +38 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/TypeParser.java +134 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/type/package-info.java +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/Annotations.java +23 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/ArrayBuilders.java +293 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/BeanUtil.java +260 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/ClassUtil.java +645 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/Comparators.java +48 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/EnumResolver.java +108 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/EnumValues.java +82 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/ISO8601DateFormat.java +52 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/ISO8601Utils.java +230 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/JSONPObject.java +105 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/JSONWrappedObject.java +117 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/LRUMap.java +28 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/LinkedNode.java +45 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/Named.java +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/ObjectBuffer.java +257 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/PrimitiveArrayBuilder.java +180 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/Provider.java +21 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/RootNameLookup.java +54 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/StdDateFormat.java +348 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/map/util/package-info.java +4 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/ArrayNode.java +758 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/BaseJsonNode.java +122 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/BigIntegerNode.java +104 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/BinaryNode.java +136 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/BooleanNode.java +84 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/ContainerNode.java +185 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/DecimalNode.java +96 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/DoubleNode.java +106 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/IntNode.java +122 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/JsonNodeFactory.java +222 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/LongNode.java +99 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/MissingNode.java +97 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/NodeCursor.java +222 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/NullNode.java +58 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/NumericNode.java +72 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/ObjectNode.java +696 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/POJONode.java +145 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/TextNode.java +299 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/TreeTraversingParser.java +383 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/ValueNode.java +58 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/node/package-info.java +8 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/package-info.java +30 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/schema/JsonSchema.java +82 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/schema/JsonSerializableSchema.java +46 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/schema/SchemaAware.java +25 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/schema/package-info.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/BytesToNameCanonicalizer.java +969 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/CharsToNameCanonicalizer.java +578 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/Name.java +50 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/Name1.java +44 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/Name2.java +40 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/Name3.java +39 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/NameN.java +68 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/sym/package-info.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/type/JavaType.java +503 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/type/TypeReference.java +60 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/type/package-info.java +8 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/BufferRecycler.java +109 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/ByteArrayBuilder.java +294 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/CharTypes.java +237 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/DefaultPrettyPrinter.java +282 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/InternCache.java +49 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/JsonGeneratorDelegate.java +273 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/JsonParserDelegate.java +251 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/JsonParserSequence.java +150 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/MinimalPrettyPrinter.java +152 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/TextBuffer.java +707 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/TokenBuffer.java +1233 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/VersionUtil.java +79 -0
- data/test-server/instrumentation-backend/src/sh/calaba/org/codehaus/jackson/util/package-info.java +4 -0
- metadata +619 -0
|
@@ -0,0 +1,2966 @@
|
|
|
1
|
+
package sh.calaba.org.codehaus.jackson.impl;
|
|
2
|
+
|
|
3
|
+
import java.io.*;
|
|
4
|
+
|
|
5
|
+
import sh.calaba.org.codehaus.jackson.*;
|
|
6
|
+
import sh.calaba.org.codehaus.jackson.io.IOContext;
|
|
7
|
+
import sh.calaba.org.codehaus.jackson.sym.*;
|
|
8
|
+
import sh.calaba.org.codehaus.jackson.util.*;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This is a concrete implementation of {@link JsonParser}, which is
|
|
12
|
+
* based on a {@link java.io.InputStream} as the input source.
|
|
13
|
+
*/
|
|
14
|
+
public final class Utf8StreamParser
|
|
15
|
+
extends JsonParserBase
|
|
16
|
+
{
|
|
17
|
+
final static byte BYTE_LF = (byte) '\n';
|
|
18
|
+
|
|
19
|
+
private final static int[] sInputCodesUtf8 = CharTypes.getInputCodeUtf8();
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Latin1 encoding is not supported, but we do use 8-bit subset for
|
|
23
|
+
* pre-processing task, to simplify first pass, keep it fast.
|
|
24
|
+
*/
|
|
25
|
+
private final static int[] sInputCodesLatin1 = CharTypes.getInputCodeLatin1();
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
/**********************************************************
|
|
29
|
+
/* Configuration
|
|
30
|
+
/**********************************************************
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Codec used for data binding when (if) requested; typically full
|
|
35
|
+
* <code>ObjectMapper</code>, but that abstract is not part of core
|
|
36
|
+
* package.
|
|
37
|
+
*/
|
|
38
|
+
protected ObjectCodec _objectCodec;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Symbol table that contains field names encountered so far
|
|
42
|
+
*/
|
|
43
|
+
final protected BytesToNameCanonicalizer _symbols;
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
/**********************************************************
|
|
47
|
+
/* Parsing state
|
|
48
|
+
/**********************************************************
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Temporary buffer used for name parsing.
|
|
53
|
+
*/
|
|
54
|
+
protected int[] _quadBuffer = new int[16];
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Flag that indicates that the current token has not yet
|
|
58
|
+
* been fully processed, and needs to be finished for
|
|
59
|
+
* some access (or skipped to obtain the next token)
|
|
60
|
+
*/
|
|
61
|
+
protected boolean _tokenIncomplete = false;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Temporary storage for partially parsed name bytes.
|
|
65
|
+
*/
|
|
66
|
+
private int _quad1;
|
|
67
|
+
|
|
68
|
+
/*
|
|
69
|
+
/**********************************************************
|
|
70
|
+
/* Input buffering (from former 'StreamBasedParserBase')
|
|
71
|
+
/**********************************************************
|
|
72
|
+
*/
|
|
73
|
+
|
|
74
|
+
protected InputStream _inputStream;
|
|
75
|
+
|
|
76
|
+
/*
|
|
77
|
+
/**********************************************************
|
|
78
|
+
/* Current input data
|
|
79
|
+
/**********************************************************
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Current buffer from which data is read; generally data is read into
|
|
84
|
+
* buffer from input source, but in some cases pre-loaded buffer
|
|
85
|
+
* is handed to the parser.
|
|
86
|
+
*/
|
|
87
|
+
protected byte[] _inputBuffer;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Flag that indicates whether the input buffer is recycable (and
|
|
91
|
+
* needs to be returned to recycler once we are done) or not.
|
|
92
|
+
*<p>
|
|
93
|
+
* If it is not, it also means that parser can NOT modify underlying
|
|
94
|
+
* buffer.
|
|
95
|
+
*/
|
|
96
|
+
protected boolean _bufferRecyclable;
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
/**********************************************************
|
|
100
|
+
/* Life-cycle
|
|
101
|
+
/**********************************************************
|
|
102
|
+
*/
|
|
103
|
+
|
|
104
|
+
public Utf8StreamParser(IOContext ctxt, int features, InputStream in,
|
|
105
|
+
ObjectCodec codec, BytesToNameCanonicalizer sym,
|
|
106
|
+
byte[] inputBuffer, int start, int end,
|
|
107
|
+
boolean bufferRecyclable)
|
|
108
|
+
{
|
|
109
|
+
super(ctxt, features);
|
|
110
|
+
_inputStream = in;
|
|
111
|
+
_objectCodec = codec;
|
|
112
|
+
_symbols = sym;
|
|
113
|
+
_inputBuffer = inputBuffer;
|
|
114
|
+
_inputPtr = start;
|
|
115
|
+
_inputEnd = end;
|
|
116
|
+
_bufferRecyclable = bufferRecyclable;
|
|
117
|
+
// 12-Mar-2010, tatus: Sanity check, related to [JACKSON-259]:
|
|
118
|
+
if (!JsonParser.Feature.CANONICALIZE_FIELD_NAMES.enabledIn(features)) {
|
|
119
|
+
// should never construct non-canonical UTF-8/byte parser (instead, use Reader)
|
|
120
|
+
_throwInternal();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
@Override
|
|
125
|
+
public ObjectCodec getCodec() {
|
|
126
|
+
return _objectCodec;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@Override
|
|
130
|
+
public void setCodec(ObjectCodec c) {
|
|
131
|
+
_objectCodec = c;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/*
|
|
135
|
+
/**********************************************************
|
|
136
|
+
/* Former StreamBasedParserBase methods
|
|
137
|
+
/**********************************************************
|
|
138
|
+
*/
|
|
139
|
+
|
|
140
|
+
@Override
|
|
141
|
+
public int releaseBuffered(OutputStream out) throws IOException
|
|
142
|
+
{
|
|
143
|
+
int count = _inputEnd - _inputPtr;
|
|
144
|
+
if (count < 1) {
|
|
145
|
+
return 0;
|
|
146
|
+
}
|
|
147
|
+
// let's just advance ptr to end
|
|
148
|
+
int origPtr = _inputPtr;
|
|
149
|
+
out.write(_inputBuffer, origPtr, count);
|
|
150
|
+
return count;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@Override
|
|
154
|
+
public Object getInputSource() {
|
|
155
|
+
return _inputStream;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/*
|
|
159
|
+
/**********************************************************
|
|
160
|
+
/* Low-level reading, other
|
|
161
|
+
/**********************************************************
|
|
162
|
+
*/
|
|
163
|
+
|
|
164
|
+
@Override
|
|
165
|
+
protected final boolean loadMore()
|
|
166
|
+
throws IOException
|
|
167
|
+
{
|
|
168
|
+
_currInputProcessed += _inputEnd;
|
|
169
|
+
_currInputRowStart -= _inputEnd;
|
|
170
|
+
|
|
171
|
+
if (_inputStream != null) {
|
|
172
|
+
int count = _inputStream.read(_inputBuffer, 0, _inputBuffer.length);
|
|
173
|
+
if (count > 0) {
|
|
174
|
+
_inputPtr = 0;
|
|
175
|
+
_inputEnd = count;
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
// End of input
|
|
179
|
+
_closeInput();
|
|
180
|
+
// Should never return 0, so let's fail
|
|
181
|
+
if (count == 0) {
|
|
182
|
+
throw new IOException("InputStream.read() returned 0 characters when trying to read "+_inputBuffer.length+" bytes");
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Helper method that will try to load at least specified number bytes in
|
|
190
|
+
* input buffer, possible moving existing data around if necessary
|
|
191
|
+
*
|
|
192
|
+
* @since 1.6
|
|
193
|
+
*/
|
|
194
|
+
protected final boolean _loadToHaveAtLeast(int minAvailable)
|
|
195
|
+
throws IOException
|
|
196
|
+
{
|
|
197
|
+
// No input stream, no leading (either we are closed, or have non-stream input source)
|
|
198
|
+
if (_inputStream == null) {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
// Need to move remaining data in front?
|
|
202
|
+
int amount = _inputEnd - _inputPtr;
|
|
203
|
+
if (amount > 0 && _inputPtr > 0) {
|
|
204
|
+
_currInputProcessed += _inputPtr;
|
|
205
|
+
_currInputRowStart -= _inputPtr;
|
|
206
|
+
System.arraycopy(_inputBuffer, _inputPtr, _inputBuffer, 0, amount);
|
|
207
|
+
_inputEnd = amount;
|
|
208
|
+
} else {
|
|
209
|
+
_inputEnd = 0;
|
|
210
|
+
}
|
|
211
|
+
_inputPtr = 0;
|
|
212
|
+
while (_inputEnd < minAvailable) {
|
|
213
|
+
int count = _inputStream.read(_inputBuffer, _inputEnd, _inputBuffer.length - _inputEnd);
|
|
214
|
+
if (count < 1) {
|
|
215
|
+
// End of input
|
|
216
|
+
_closeInput();
|
|
217
|
+
// Should never return 0, so let's fail
|
|
218
|
+
if (count == 0) {
|
|
219
|
+
throw new IOException("InputStream.read() returned 0 characters when trying to read "+amount+" bytes");
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
}
|
|
223
|
+
_inputEnd += count;
|
|
224
|
+
}
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@Override
|
|
229
|
+
protected void _closeInput() throws IOException
|
|
230
|
+
{
|
|
231
|
+
/* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close()
|
|
232
|
+
* on the underlying InputStream, unless we "own" it, or auto-closing
|
|
233
|
+
* feature is enabled.
|
|
234
|
+
*/
|
|
235
|
+
if (_inputStream != null) {
|
|
236
|
+
if (_ioContext.isResourceManaged() || isEnabled(Feature.AUTO_CLOSE_SOURCE)) {
|
|
237
|
+
_inputStream.close();
|
|
238
|
+
}
|
|
239
|
+
_inputStream = null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Method called to release internal buffers owned by the base
|
|
245
|
+
* reader. This may be called along with {@link #_closeInput} (for
|
|
246
|
+
* example, when explicitly closing this reader instance), or
|
|
247
|
+
* separately (if need be).
|
|
248
|
+
*/
|
|
249
|
+
@Override
|
|
250
|
+
protected void _releaseBuffers() throws IOException
|
|
251
|
+
{
|
|
252
|
+
super._releaseBuffers();
|
|
253
|
+
if (_bufferRecyclable) {
|
|
254
|
+
byte[] buf = _inputBuffer;
|
|
255
|
+
if (buf != null) {
|
|
256
|
+
_inputBuffer = null;
|
|
257
|
+
_ioContext.releaseReadIOBuffer(buf);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/*
|
|
263
|
+
/**********************************************************
|
|
264
|
+
/* Public API, data access
|
|
265
|
+
/**********************************************************
|
|
266
|
+
*/
|
|
267
|
+
|
|
268
|
+
@Override
|
|
269
|
+
public String getText()
|
|
270
|
+
throws IOException, JsonParseException
|
|
271
|
+
{
|
|
272
|
+
JsonToken t = _currToken;
|
|
273
|
+
if (t == JsonToken.VALUE_STRING) {
|
|
274
|
+
if (_tokenIncomplete) {
|
|
275
|
+
_tokenIncomplete = false;
|
|
276
|
+
_finishString(); // only strings can be incomplete
|
|
277
|
+
}
|
|
278
|
+
return _textBuffer.contentsAsString();
|
|
279
|
+
}
|
|
280
|
+
return _getText2(t);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
protected final String _getText2(JsonToken t)
|
|
284
|
+
{
|
|
285
|
+
if (t == null) {
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
switch (t) {
|
|
289
|
+
case FIELD_NAME:
|
|
290
|
+
return _parsingContext.getCurrentName();
|
|
291
|
+
|
|
292
|
+
case VALUE_STRING:
|
|
293
|
+
// fall through
|
|
294
|
+
case VALUE_NUMBER_INT:
|
|
295
|
+
case VALUE_NUMBER_FLOAT:
|
|
296
|
+
return _textBuffer.contentsAsString();
|
|
297
|
+
}
|
|
298
|
+
return t.asString();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
@Override
|
|
302
|
+
public char[] getTextCharacters()
|
|
303
|
+
throws IOException, JsonParseException
|
|
304
|
+
{
|
|
305
|
+
if (_currToken != null) { // null only before/after document
|
|
306
|
+
switch (_currToken) {
|
|
307
|
+
|
|
308
|
+
case FIELD_NAME:
|
|
309
|
+
if (!_nameCopied) {
|
|
310
|
+
String name = _parsingContext.getCurrentName();
|
|
311
|
+
int nameLen = name.length();
|
|
312
|
+
if (_nameCopyBuffer == null) {
|
|
313
|
+
_nameCopyBuffer = _ioContext.allocNameCopyBuffer(nameLen);
|
|
314
|
+
} else if (_nameCopyBuffer.length < nameLen) {
|
|
315
|
+
_nameCopyBuffer = new char[nameLen];
|
|
316
|
+
}
|
|
317
|
+
name.getChars(0, nameLen, _nameCopyBuffer, 0);
|
|
318
|
+
_nameCopied = true;
|
|
319
|
+
}
|
|
320
|
+
return _nameCopyBuffer;
|
|
321
|
+
|
|
322
|
+
case VALUE_STRING:
|
|
323
|
+
if (_tokenIncomplete) {
|
|
324
|
+
_tokenIncomplete = false;
|
|
325
|
+
_finishString(); // only strings can be incomplete
|
|
326
|
+
}
|
|
327
|
+
// fall through
|
|
328
|
+
case VALUE_NUMBER_INT:
|
|
329
|
+
case VALUE_NUMBER_FLOAT:
|
|
330
|
+
return _textBuffer.getTextBuffer();
|
|
331
|
+
|
|
332
|
+
default:
|
|
333
|
+
return _currToken.asCharArray();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return null;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
@Override
|
|
340
|
+
public int getTextLength()
|
|
341
|
+
throws IOException, JsonParseException
|
|
342
|
+
{
|
|
343
|
+
if (_currToken != null) { // null only before/after document
|
|
344
|
+
switch (_currToken) {
|
|
345
|
+
|
|
346
|
+
case FIELD_NAME:
|
|
347
|
+
return _parsingContext.getCurrentName().length();
|
|
348
|
+
case VALUE_STRING:
|
|
349
|
+
if (_tokenIncomplete) {
|
|
350
|
+
_tokenIncomplete = false;
|
|
351
|
+
_finishString(); // only strings can be incomplete
|
|
352
|
+
}
|
|
353
|
+
// fall through
|
|
354
|
+
case VALUE_NUMBER_INT:
|
|
355
|
+
case VALUE_NUMBER_FLOAT:
|
|
356
|
+
return _textBuffer.size();
|
|
357
|
+
|
|
358
|
+
default:
|
|
359
|
+
return _currToken.asCharArray().length;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
return 0;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
@Override
|
|
366
|
+
public int getTextOffset() throws IOException, JsonParseException
|
|
367
|
+
{
|
|
368
|
+
// Most have offset of 0, only some may have other values:
|
|
369
|
+
if (_currToken != null) {
|
|
370
|
+
switch (_currToken) {
|
|
371
|
+
case FIELD_NAME:
|
|
372
|
+
return 0;
|
|
373
|
+
case VALUE_STRING:
|
|
374
|
+
if (_tokenIncomplete) {
|
|
375
|
+
_tokenIncomplete = false;
|
|
376
|
+
_finishString(); // only strings can be incomplete
|
|
377
|
+
}
|
|
378
|
+
// fall through
|
|
379
|
+
case VALUE_NUMBER_INT:
|
|
380
|
+
case VALUE_NUMBER_FLOAT:
|
|
381
|
+
return _textBuffer.getTextOffset();
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return 0;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
@Override
|
|
388
|
+
public byte[] getBinaryValue(Base64Variant b64variant)
|
|
389
|
+
throws IOException, JsonParseException
|
|
390
|
+
{
|
|
391
|
+
if (_currToken != JsonToken.VALUE_STRING &&
|
|
392
|
+
(_currToken != JsonToken.VALUE_EMBEDDED_OBJECT || _binaryValue == null)) {
|
|
393
|
+
_reportError("Current token ("+_currToken+") not VALUE_STRING or VALUE_EMBEDDED_OBJECT, can not access as binary");
|
|
394
|
+
}
|
|
395
|
+
/* To ensure that we won't see inconsistent data, better clear up
|
|
396
|
+
* state...
|
|
397
|
+
*/
|
|
398
|
+
if (_tokenIncomplete) {
|
|
399
|
+
try {
|
|
400
|
+
_binaryValue = _decodeBase64(b64variant);
|
|
401
|
+
} catch (IllegalArgumentException iae) {
|
|
402
|
+
throw _constructError("Failed to decode VALUE_STRING as base64 ("+b64variant+"): "+iae.getMessage());
|
|
403
|
+
}
|
|
404
|
+
/* let's clear incomplete only now; allows for accessing other
|
|
405
|
+
* textual content in error cases
|
|
406
|
+
*/
|
|
407
|
+
_tokenIncomplete = false;
|
|
408
|
+
} else { // may actually require conversion...
|
|
409
|
+
if (_binaryValue == null) {
|
|
410
|
+
ByteArrayBuilder builder = _getByteArrayBuilder();
|
|
411
|
+
_decodeBase64(getText(), builder, b64variant);
|
|
412
|
+
_binaryValue = builder.toByteArray();
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return _binaryValue;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/*
|
|
419
|
+
/**********************************************************
|
|
420
|
+
/* Public API, traversal, basic
|
|
421
|
+
/**********************************************************
|
|
422
|
+
*/
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* @return Next token from the stream, if any found, or null
|
|
426
|
+
* to indicate end-of-input
|
|
427
|
+
*/
|
|
428
|
+
@Override
|
|
429
|
+
public JsonToken nextToken()
|
|
430
|
+
throws IOException, JsonParseException
|
|
431
|
+
{
|
|
432
|
+
_numTypesValid = NR_UNKNOWN;
|
|
433
|
+
/* First: field names are special -- we will always tokenize
|
|
434
|
+
* (part of) value along with field name to simplify
|
|
435
|
+
* state handling. If so, can and need to use secondary token:
|
|
436
|
+
*/
|
|
437
|
+
if (_currToken == JsonToken.FIELD_NAME) {
|
|
438
|
+
return _nextAfterName();
|
|
439
|
+
}
|
|
440
|
+
if (_tokenIncomplete) {
|
|
441
|
+
_skipString(); // only strings can be partial
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
int i = _skipWSOrEnd();
|
|
445
|
+
if (i < 0) { // end-of-input
|
|
446
|
+
/* 19-Feb-2009, tatu: Should actually close/release things
|
|
447
|
+
* like input source, symbol table and recyclable buffers now.
|
|
448
|
+
*/
|
|
449
|
+
close();
|
|
450
|
+
return (_currToken = null);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* First, need to ensure we know the starting location of token
|
|
454
|
+
* after skipping leading white space
|
|
455
|
+
*/
|
|
456
|
+
_tokenInputTotal = _currInputProcessed + _inputPtr - 1;
|
|
457
|
+
_tokenInputRow = _currInputRow;
|
|
458
|
+
_tokenInputCol = _inputPtr - _currInputRowStart - 1;
|
|
459
|
+
|
|
460
|
+
// finally: clear any data retained so far
|
|
461
|
+
_binaryValue = null;
|
|
462
|
+
|
|
463
|
+
// Closing scope?
|
|
464
|
+
if (i == INT_RBRACKET) {
|
|
465
|
+
if (!_parsingContext.inArray()) {
|
|
466
|
+
_reportMismatchedEndMarker(i, '}');
|
|
467
|
+
}
|
|
468
|
+
_parsingContext = _parsingContext.getParent();
|
|
469
|
+
return (_currToken = JsonToken.END_ARRAY);
|
|
470
|
+
}
|
|
471
|
+
if (i == INT_RCURLY) {
|
|
472
|
+
if (!_parsingContext.inObject()) {
|
|
473
|
+
_reportMismatchedEndMarker(i, ']');
|
|
474
|
+
}
|
|
475
|
+
_parsingContext = _parsingContext.getParent();
|
|
476
|
+
return (_currToken = JsonToken.END_OBJECT);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Nope: do we then expect a comma?
|
|
480
|
+
if (_parsingContext.expectComma()) {
|
|
481
|
+
if (i != INT_COMMA) {
|
|
482
|
+
_reportUnexpectedChar(i, "was expecting comma to separate "+_parsingContext.getTypeDesc()+" entries");
|
|
483
|
+
}
|
|
484
|
+
i = _skipWS();
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
/* And should we now have a name? Always true for
|
|
488
|
+
* Object contexts, since the intermediate 'expect-value'
|
|
489
|
+
* state is never retained.
|
|
490
|
+
*/
|
|
491
|
+
if (!_parsingContext.inObject()) {
|
|
492
|
+
return _nextTokenNotInObject(i);
|
|
493
|
+
}
|
|
494
|
+
// So first parse the field name itself:
|
|
495
|
+
Name n = _parseFieldName(i);
|
|
496
|
+
_parsingContext.setCurrentName(n.getName());
|
|
497
|
+
_currToken = JsonToken.FIELD_NAME;
|
|
498
|
+
i = _skipWS();
|
|
499
|
+
if (i != INT_COLON) {
|
|
500
|
+
_reportUnexpectedChar(i, "was expecting a colon to separate field name and value");
|
|
501
|
+
}
|
|
502
|
+
i = _skipWS();
|
|
503
|
+
|
|
504
|
+
// Ok: we must have a value... what is it? Strings are very common, check first:
|
|
505
|
+
if (i == INT_QUOTE) {
|
|
506
|
+
_tokenIncomplete = true;
|
|
507
|
+
_nextToken = JsonToken.VALUE_STRING;
|
|
508
|
+
return _currToken;
|
|
509
|
+
}
|
|
510
|
+
JsonToken t;
|
|
511
|
+
|
|
512
|
+
switch (i) {
|
|
513
|
+
case INT_LBRACKET:
|
|
514
|
+
t = JsonToken.START_ARRAY;
|
|
515
|
+
break;
|
|
516
|
+
case INT_LCURLY:
|
|
517
|
+
t = JsonToken.START_OBJECT;
|
|
518
|
+
break;
|
|
519
|
+
case INT_RBRACKET:
|
|
520
|
+
case INT_RCURLY:
|
|
521
|
+
// Error: neither is valid at this point; valid closers have
|
|
522
|
+
// been handled earlier
|
|
523
|
+
_reportUnexpectedChar(i, "expected a value");
|
|
524
|
+
case INT_t:
|
|
525
|
+
_matchToken("true", 1);
|
|
526
|
+
t = JsonToken.VALUE_TRUE;
|
|
527
|
+
break;
|
|
528
|
+
case INT_f:
|
|
529
|
+
_matchToken("false", 1);
|
|
530
|
+
t = JsonToken.VALUE_FALSE;
|
|
531
|
+
break;
|
|
532
|
+
case INT_n:
|
|
533
|
+
_matchToken("null", 1);
|
|
534
|
+
t = JsonToken.VALUE_NULL;
|
|
535
|
+
break;
|
|
536
|
+
|
|
537
|
+
case INT_MINUS:
|
|
538
|
+
/* Should we have separate handling for plus? Although
|
|
539
|
+
* it is not allowed per se, it may be erroneously used,
|
|
540
|
+
* and could be indicate by a more specific error message.
|
|
541
|
+
*/
|
|
542
|
+
case INT_0:
|
|
543
|
+
case INT_1:
|
|
544
|
+
case INT_2:
|
|
545
|
+
case INT_3:
|
|
546
|
+
case INT_4:
|
|
547
|
+
case INT_5:
|
|
548
|
+
case INT_6:
|
|
549
|
+
case INT_7:
|
|
550
|
+
case INT_8:
|
|
551
|
+
case INT_9:
|
|
552
|
+
t = parseNumberText(i);
|
|
553
|
+
break;
|
|
554
|
+
default:
|
|
555
|
+
t = _handleUnexpectedValue(i);
|
|
556
|
+
}
|
|
557
|
+
_nextToken = t;
|
|
558
|
+
return _currToken;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
private final JsonToken _nextTokenNotInObject(int i)
|
|
562
|
+
throws IOException, JsonParseException
|
|
563
|
+
{
|
|
564
|
+
if (i == INT_QUOTE) {
|
|
565
|
+
_tokenIncomplete = true;
|
|
566
|
+
return (_currToken = JsonToken.VALUE_STRING);
|
|
567
|
+
}
|
|
568
|
+
switch (i) {
|
|
569
|
+
case INT_LBRACKET:
|
|
570
|
+
_parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol);
|
|
571
|
+
return (_currToken = JsonToken.START_ARRAY);
|
|
572
|
+
case INT_LCURLY:
|
|
573
|
+
_parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol);
|
|
574
|
+
return (_currToken = JsonToken.START_OBJECT);
|
|
575
|
+
case INT_RBRACKET:
|
|
576
|
+
case INT_RCURLY:
|
|
577
|
+
// Error: neither is valid at this point; valid closers have
|
|
578
|
+
// been handled earlier
|
|
579
|
+
_reportUnexpectedChar(i, "expected a value");
|
|
580
|
+
case INT_t:
|
|
581
|
+
_matchToken("true", 1);
|
|
582
|
+
return (_currToken = JsonToken.VALUE_TRUE);
|
|
583
|
+
case INT_f:
|
|
584
|
+
_matchToken("false", 1);
|
|
585
|
+
return (_currToken = JsonToken.VALUE_FALSE);
|
|
586
|
+
case INT_n:
|
|
587
|
+
_matchToken("null", 1);
|
|
588
|
+
return (_currToken = JsonToken.VALUE_NULL);
|
|
589
|
+
case INT_MINUS:
|
|
590
|
+
/* Should we have separate handling for plus? Although
|
|
591
|
+
* it is not allowed per se, it may be erroneously used,
|
|
592
|
+
* and could be indicate by a more specific error message.
|
|
593
|
+
*/
|
|
594
|
+
case INT_0:
|
|
595
|
+
case INT_1:
|
|
596
|
+
case INT_2:
|
|
597
|
+
case INT_3:
|
|
598
|
+
case INT_4:
|
|
599
|
+
case INT_5:
|
|
600
|
+
case INT_6:
|
|
601
|
+
case INT_7:
|
|
602
|
+
case INT_8:
|
|
603
|
+
case INT_9:
|
|
604
|
+
return (_currToken = parseNumberText(i));
|
|
605
|
+
}
|
|
606
|
+
return (_currToken = _handleUnexpectedValue(i));
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
private final JsonToken _nextAfterName()
|
|
610
|
+
{
|
|
611
|
+
_nameCopied = false; // need to invalidate if it was copied
|
|
612
|
+
JsonToken t = _nextToken;
|
|
613
|
+
_nextToken = null;
|
|
614
|
+
// Also: may need to start new context?
|
|
615
|
+
if (t == JsonToken.START_ARRAY) {
|
|
616
|
+
_parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol);
|
|
617
|
+
} else if (t == JsonToken.START_OBJECT) {
|
|
618
|
+
_parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol);
|
|
619
|
+
}
|
|
620
|
+
return (_currToken = t);
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
@Override
|
|
624
|
+
public void close() throws IOException
|
|
625
|
+
{
|
|
626
|
+
super.close();
|
|
627
|
+
// Merge found symbols, if any:
|
|
628
|
+
_symbols.release();
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/*
|
|
632
|
+
/**********************************************************
|
|
633
|
+
/* Public API, traversal, nextXxxValue/nextFieldName
|
|
634
|
+
/**********************************************************
|
|
635
|
+
*/
|
|
636
|
+
|
|
637
|
+
@Override
|
|
638
|
+
public boolean nextFieldName(SerializableString str)
|
|
639
|
+
throws IOException, JsonParseException
|
|
640
|
+
{
|
|
641
|
+
// // // Note: most of code below is copied from nextToken()
|
|
642
|
+
|
|
643
|
+
_numTypesValid = NR_UNKNOWN;
|
|
644
|
+
if (_currToken == JsonToken.FIELD_NAME) { // can't have name right after name
|
|
645
|
+
_nextAfterName();
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
if (_tokenIncomplete) {
|
|
649
|
+
_skipString();
|
|
650
|
+
}
|
|
651
|
+
int i = _skipWSOrEnd();
|
|
652
|
+
if (i < 0) { // end-of-input
|
|
653
|
+
close();
|
|
654
|
+
_currToken = null;
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
_tokenInputTotal = _currInputProcessed + _inputPtr - 1;
|
|
658
|
+
_tokenInputRow = _currInputRow;
|
|
659
|
+
_tokenInputCol = _inputPtr - _currInputRowStart - 1;
|
|
660
|
+
|
|
661
|
+
// finally: clear any data retained so far
|
|
662
|
+
_binaryValue = null;
|
|
663
|
+
|
|
664
|
+
// Closing scope?
|
|
665
|
+
if (i == INT_RBRACKET) {
|
|
666
|
+
if (!_parsingContext.inArray()) {
|
|
667
|
+
_reportMismatchedEndMarker(i, '}');
|
|
668
|
+
}
|
|
669
|
+
_parsingContext = _parsingContext.getParent();
|
|
670
|
+
_currToken = JsonToken.END_ARRAY;
|
|
671
|
+
return false;
|
|
672
|
+
}
|
|
673
|
+
if (i == INT_RCURLY) {
|
|
674
|
+
if (!_parsingContext.inObject()) {
|
|
675
|
+
_reportMismatchedEndMarker(i, ']');
|
|
676
|
+
}
|
|
677
|
+
_parsingContext = _parsingContext.getParent();
|
|
678
|
+
_currToken = JsonToken.END_OBJECT;
|
|
679
|
+
return false;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Nope: do we then expect a comma?
|
|
683
|
+
if (_parsingContext.expectComma()) {
|
|
684
|
+
if (i != INT_COMMA) {
|
|
685
|
+
_reportUnexpectedChar(i, "was expecting comma to separate "+_parsingContext.getTypeDesc()+" entries");
|
|
686
|
+
}
|
|
687
|
+
i = _skipWS();
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
if (!_parsingContext.inObject()) {
|
|
691
|
+
_nextTokenNotInObject(i);
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// // // This part differs, name parsing
|
|
696
|
+
if (i == INT_QUOTE) {
|
|
697
|
+
// when doing literal match, must consider escaping:
|
|
698
|
+
byte[] nameBytes = str.asQuotedUTF8();
|
|
699
|
+
final int len = nameBytes.length;
|
|
700
|
+
if ((_inputPtr + len) < _inputEnd) { // maybe...
|
|
701
|
+
// first check length match by
|
|
702
|
+
final int end = _inputPtr+len;
|
|
703
|
+
if (_inputBuffer[end] == INT_QUOTE) {
|
|
704
|
+
int offset = 0;
|
|
705
|
+
final int ptr = _inputPtr;
|
|
706
|
+
while (true) {
|
|
707
|
+
if (offset == len) { // yes, match!
|
|
708
|
+
_inputPtr = end+1; // skip current value first
|
|
709
|
+
// First part is simple; setting of name
|
|
710
|
+
_parsingContext.setCurrentName(str.getValue());
|
|
711
|
+
_currToken = JsonToken.FIELD_NAME;
|
|
712
|
+
// But then we also must handle following value etc
|
|
713
|
+
_isNextTokenNameYes();
|
|
714
|
+
return true;
|
|
715
|
+
}
|
|
716
|
+
if (nameBytes[offset] != _inputBuffer[ptr+offset]) {
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
719
|
+
++offset;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
_isNextTokenNameNo(i);
|
|
725
|
+
return false;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
private final void _isNextTokenNameYes()
|
|
729
|
+
throws IOException, JsonParseException
|
|
730
|
+
{
|
|
731
|
+
// very first thing: common case, colon, value, no white space
|
|
732
|
+
int i;
|
|
733
|
+
if (_inputPtr < _inputEnd && _inputBuffer[_inputPtr] == INT_COLON) { // fast case first
|
|
734
|
+
++_inputPtr;
|
|
735
|
+
i = _inputBuffer[_inputPtr++];
|
|
736
|
+
if (i == INT_QUOTE) {
|
|
737
|
+
_tokenIncomplete = true;
|
|
738
|
+
_nextToken = JsonToken.VALUE_STRING;
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
if (i == INT_LCURLY) {
|
|
742
|
+
_nextToken = JsonToken.START_OBJECT;
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
if (i == INT_LBRACKET) {
|
|
746
|
+
_nextToken = JsonToken.START_ARRAY;
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
i &= 0xFF;
|
|
750
|
+
if (i <= INT_SPACE || i == INT_SLASH) {
|
|
751
|
+
--_inputPtr;
|
|
752
|
+
i = _skipWS();
|
|
753
|
+
}
|
|
754
|
+
} else {
|
|
755
|
+
i = _skipColon();
|
|
756
|
+
}
|
|
757
|
+
switch (i) {
|
|
758
|
+
case INT_QUOTE:
|
|
759
|
+
_tokenIncomplete = true;
|
|
760
|
+
_nextToken = JsonToken.VALUE_STRING;
|
|
761
|
+
return;
|
|
762
|
+
case INT_LBRACKET:
|
|
763
|
+
_nextToken = JsonToken.START_ARRAY;
|
|
764
|
+
return;
|
|
765
|
+
case INT_LCURLY:
|
|
766
|
+
_nextToken = JsonToken.START_OBJECT;
|
|
767
|
+
return;
|
|
768
|
+
case INT_RBRACKET:
|
|
769
|
+
case INT_RCURLY:
|
|
770
|
+
_reportUnexpectedChar(i, "expected a value");
|
|
771
|
+
case INT_t:
|
|
772
|
+
_matchToken("true", 1);
|
|
773
|
+
_nextToken = JsonToken.VALUE_TRUE;
|
|
774
|
+
return;
|
|
775
|
+
case INT_f:
|
|
776
|
+
_matchToken("false", 1);
|
|
777
|
+
_nextToken = JsonToken.VALUE_FALSE;
|
|
778
|
+
return;
|
|
779
|
+
case INT_n:
|
|
780
|
+
_matchToken("null", 1);
|
|
781
|
+
_nextToken = JsonToken.VALUE_NULL;
|
|
782
|
+
return;
|
|
783
|
+
case INT_MINUS:
|
|
784
|
+
case INT_0:
|
|
785
|
+
case INT_1:
|
|
786
|
+
case INT_2:
|
|
787
|
+
case INT_3:
|
|
788
|
+
case INT_4:
|
|
789
|
+
case INT_5:
|
|
790
|
+
case INT_6:
|
|
791
|
+
case INT_7:
|
|
792
|
+
case INT_8:
|
|
793
|
+
case INT_9:
|
|
794
|
+
_nextToken = parseNumberText(i);
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
_nextToken = _handleUnexpectedValue(i);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
private final void _isNextTokenNameNo(int i)
|
|
801
|
+
throws IOException, JsonParseException
|
|
802
|
+
{
|
|
803
|
+
// // // and this is back to standard nextToken()
|
|
804
|
+
|
|
805
|
+
Name n = _parseFieldName(i);
|
|
806
|
+
_parsingContext.setCurrentName(n.getName());
|
|
807
|
+
_currToken = JsonToken.FIELD_NAME;
|
|
808
|
+
i = _skipWS();
|
|
809
|
+
if (i != INT_COLON) {
|
|
810
|
+
_reportUnexpectedChar(i, "was expecting a colon to separate field name and value");
|
|
811
|
+
}
|
|
812
|
+
i = _skipWS();
|
|
813
|
+
|
|
814
|
+
// Ok: we must have a value... what is it? Strings are very common, check first:
|
|
815
|
+
if (i == INT_QUOTE) {
|
|
816
|
+
_tokenIncomplete = true;
|
|
817
|
+
_nextToken = JsonToken.VALUE_STRING;
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
JsonToken t;
|
|
821
|
+
|
|
822
|
+
switch (i) {
|
|
823
|
+
case INT_LBRACKET:
|
|
824
|
+
t = JsonToken.START_ARRAY;
|
|
825
|
+
break;
|
|
826
|
+
case INT_LCURLY:
|
|
827
|
+
t = JsonToken.START_OBJECT;
|
|
828
|
+
break;
|
|
829
|
+
case INT_RBRACKET:
|
|
830
|
+
case INT_RCURLY:
|
|
831
|
+
_reportUnexpectedChar(i, "expected a value");
|
|
832
|
+
case INT_t:
|
|
833
|
+
_matchToken("true", 1);
|
|
834
|
+
t = JsonToken.VALUE_TRUE;
|
|
835
|
+
break;
|
|
836
|
+
case INT_f:
|
|
837
|
+
_matchToken("false", 1);
|
|
838
|
+
t = JsonToken.VALUE_FALSE;
|
|
839
|
+
break;
|
|
840
|
+
case INT_n:
|
|
841
|
+
_matchToken("null", 1);
|
|
842
|
+
t = JsonToken.VALUE_NULL;
|
|
843
|
+
break;
|
|
844
|
+
|
|
845
|
+
case INT_MINUS:
|
|
846
|
+
case INT_0:
|
|
847
|
+
case INT_1:
|
|
848
|
+
case INT_2:
|
|
849
|
+
case INT_3:
|
|
850
|
+
case INT_4:
|
|
851
|
+
case INT_5:
|
|
852
|
+
case INT_6:
|
|
853
|
+
case INT_7:
|
|
854
|
+
case INT_8:
|
|
855
|
+
case INT_9:
|
|
856
|
+
t = parseNumberText(i);
|
|
857
|
+
break;
|
|
858
|
+
default:
|
|
859
|
+
t = _handleUnexpectedValue(i);
|
|
860
|
+
}
|
|
861
|
+
_nextToken = t;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
@Override
|
|
865
|
+
public String nextTextValue()
|
|
866
|
+
throws IOException, JsonParseException
|
|
867
|
+
{
|
|
868
|
+
// two distinct cases; either got name and we know next type, or 'other'
|
|
869
|
+
if (_currToken == JsonToken.FIELD_NAME) { // mostly copied from '_nextAfterName'
|
|
870
|
+
_nameCopied = false;
|
|
871
|
+
JsonToken t = _nextToken;
|
|
872
|
+
_nextToken = null;
|
|
873
|
+
_currToken = t;
|
|
874
|
+
if (t == JsonToken.VALUE_STRING) {
|
|
875
|
+
if (_tokenIncomplete) {
|
|
876
|
+
_tokenIncomplete = false;
|
|
877
|
+
_finishString();
|
|
878
|
+
}
|
|
879
|
+
return _textBuffer.contentsAsString();
|
|
880
|
+
}
|
|
881
|
+
if (t == JsonToken.START_ARRAY) {
|
|
882
|
+
_parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol);
|
|
883
|
+
} else if (t == JsonToken.START_OBJECT) {
|
|
884
|
+
_parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol);
|
|
885
|
+
}
|
|
886
|
+
return null;
|
|
887
|
+
}
|
|
888
|
+
// !!! TODO: optimize this case as well
|
|
889
|
+
return (nextToken() == JsonToken.VALUE_STRING) ? getText() : null;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
@Override
|
|
893
|
+
public int nextIntValue(int defaultValue)
|
|
894
|
+
throws IOException, JsonParseException
|
|
895
|
+
{
|
|
896
|
+
// two distinct cases; either got name and we know next type, or 'other'
|
|
897
|
+
if (_currToken == JsonToken.FIELD_NAME) { // mostly copied from '_nextAfterName'
|
|
898
|
+
_nameCopied = false;
|
|
899
|
+
JsonToken t = _nextToken;
|
|
900
|
+
_nextToken = null;
|
|
901
|
+
_currToken = t;
|
|
902
|
+
if (t == JsonToken.VALUE_NUMBER_INT) {
|
|
903
|
+
return getIntValue();
|
|
904
|
+
}
|
|
905
|
+
if (t == JsonToken.START_ARRAY) {
|
|
906
|
+
_parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol);
|
|
907
|
+
} else if (t == JsonToken.START_OBJECT) {
|
|
908
|
+
_parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol);
|
|
909
|
+
}
|
|
910
|
+
return defaultValue;
|
|
911
|
+
}
|
|
912
|
+
// !!! TODO: optimize this case as well
|
|
913
|
+
return (nextToken() == JsonToken.VALUE_NUMBER_INT) ? getIntValue() : defaultValue;
|
|
914
|
+
}
|
|
915
|
+
|
|
916
|
+
@Override
|
|
917
|
+
public long nextLongValue(long defaultValue)
|
|
918
|
+
throws IOException, JsonParseException
|
|
919
|
+
{
|
|
920
|
+
// two distinct cases; either got name and we know next type, or 'other'
|
|
921
|
+
if (_currToken == JsonToken.FIELD_NAME) { // mostly copied from '_nextAfterName'
|
|
922
|
+
_nameCopied = false;
|
|
923
|
+
JsonToken t = _nextToken;
|
|
924
|
+
_nextToken = null;
|
|
925
|
+
_currToken = t;
|
|
926
|
+
if (t == JsonToken.VALUE_NUMBER_INT) {
|
|
927
|
+
return getLongValue();
|
|
928
|
+
}
|
|
929
|
+
if (t == JsonToken.START_ARRAY) {
|
|
930
|
+
_parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol);
|
|
931
|
+
} else if (t == JsonToken.START_OBJECT) {
|
|
932
|
+
_parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol);
|
|
933
|
+
}
|
|
934
|
+
return defaultValue;
|
|
935
|
+
}
|
|
936
|
+
// !!! TODO: optimize this case as well
|
|
937
|
+
return (nextToken() == JsonToken.VALUE_NUMBER_INT) ? getLongValue() : defaultValue;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
@Override
|
|
941
|
+
public Boolean nextBooleanValue()
|
|
942
|
+
throws IOException, JsonParseException
|
|
943
|
+
{
|
|
944
|
+
// two distinct cases; either got name and we know next type, or 'other'
|
|
945
|
+
if (_currToken == JsonToken.FIELD_NAME) { // mostly copied from '_nextAfterName'
|
|
946
|
+
_nameCopied = false;
|
|
947
|
+
JsonToken t = _nextToken;
|
|
948
|
+
_nextToken = null;
|
|
949
|
+
_currToken = t;
|
|
950
|
+
if (t == JsonToken.VALUE_TRUE) {
|
|
951
|
+
return Boolean.TRUE;
|
|
952
|
+
}
|
|
953
|
+
if (t == JsonToken.VALUE_FALSE) {
|
|
954
|
+
return Boolean.FALSE;
|
|
955
|
+
}
|
|
956
|
+
if (t == JsonToken.START_ARRAY) {
|
|
957
|
+
_parsingContext = _parsingContext.createChildArrayContext(_tokenInputRow, _tokenInputCol);
|
|
958
|
+
} else if (t == JsonToken.START_OBJECT) {
|
|
959
|
+
_parsingContext = _parsingContext.createChildObjectContext(_tokenInputRow, _tokenInputCol);
|
|
960
|
+
}
|
|
961
|
+
return null;
|
|
962
|
+
}
|
|
963
|
+
switch (nextToken()) {
|
|
964
|
+
case VALUE_TRUE:
|
|
965
|
+
return Boolean.TRUE;
|
|
966
|
+
case VALUE_FALSE:
|
|
967
|
+
return Boolean.FALSE;
|
|
968
|
+
}
|
|
969
|
+
return null;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
/*
|
|
973
|
+
/**********************************************************
|
|
974
|
+
/* Internal methods, number parsing
|
|
975
|
+
/* (note: in 1.6 and prior, part of "Utf8NumericParser"
|
|
976
|
+
/**********************************************************
|
|
977
|
+
*/
|
|
978
|
+
|
|
979
|
+
/**
|
|
980
|
+
* Initial parsing method for number values. It needs to be able
|
|
981
|
+
* to parse enough input to be able to determine whether the
|
|
982
|
+
* value is to be considered a simple integer value, or a more
|
|
983
|
+
* generic decimal value: latter of which needs to be expressed
|
|
984
|
+
* as a floating point number. The basic rule is that if the number
|
|
985
|
+
* has no fractional or exponential part, it is an integer; otherwise
|
|
986
|
+
* a floating point number.
|
|
987
|
+
*<p>
|
|
988
|
+
* Because much of input has to be processed in any case, no partial
|
|
989
|
+
* parsing is done: all input text will be stored for further
|
|
990
|
+
* processing. However, actual numeric value conversion will be
|
|
991
|
+
* deferred, since it is usually the most complicated and costliest
|
|
992
|
+
* part of processing.
|
|
993
|
+
*/
|
|
994
|
+
protected final JsonToken parseNumberText(int c)
|
|
995
|
+
throws IOException, JsonParseException
|
|
996
|
+
{
|
|
997
|
+
char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
|
|
998
|
+
int outPtr = 0;
|
|
999
|
+
boolean negative = (c == INT_MINUS);
|
|
1000
|
+
|
|
1001
|
+
// Need to prepend sign?
|
|
1002
|
+
if (negative) {
|
|
1003
|
+
outBuf[outPtr++] = '-';
|
|
1004
|
+
// Must have something after sign too
|
|
1005
|
+
if (_inputPtr >= _inputEnd) {
|
|
1006
|
+
loadMoreGuaranteed();
|
|
1007
|
+
}
|
|
1008
|
+
c = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
1009
|
+
// Note: must be followed by a digit
|
|
1010
|
+
if (c < INT_0 || c > INT_9) {
|
|
1011
|
+
return _handleInvalidNumberStart(c, true);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// One special case: if first char is 0, must not be followed by a digit
|
|
1016
|
+
if (c == INT_0) {
|
|
1017
|
+
c = _verifyNoLeadingZeroes();
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
// Ok: we can first just add digit we saw first:
|
|
1021
|
+
outBuf[outPtr++] = (char) c;
|
|
1022
|
+
int intLen = 1;
|
|
1023
|
+
|
|
1024
|
+
// And then figure out how far we can read without further checks:
|
|
1025
|
+
int end = _inputPtr + outBuf.length;
|
|
1026
|
+
if (end > _inputEnd) {
|
|
1027
|
+
end = _inputEnd;
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
// With this, we have a nice and tight loop:
|
|
1031
|
+
while (true) {
|
|
1032
|
+
if (_inputPtr >= end) {
|
|
1033
|
+
// Long enough to be split across boundary, so:
|
|
1034
|
+
return _parserNumber2(outBuf, outPtr, negative, intLen);
|
|
1035
|
+
}
|
|
1036
|
+
c = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
1037
|
+
if (c < INT_0 || c > INT_9) {
|
|
1038
|
+
break;
|
|
1039
|
+
}
|
|
1040
|
+
++intLen;
|
|
1041
|
+
outBuf[outPtr++] = (char) c;
|
|
1042
|
+
}
|
|
1043
|
+
if (c == '.' || c == 'e' || c == 'E') {
|
|
1044
|
+
return _parseFloatText(outBuf, outPtr, c, negative, intLen);
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
--_inputPtr; // to push back trailing char (comma etc)
|
|
1048
|
+
_textBuffer.setCurrentLength(outPtr);
|
|
1049
|
+
|
|
1050
|
+
// And there we have it!
|
|
1051
|
+
return resetInt(negative, intLen);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
/**
|
|
1055
|
+
* Method called to handle parsing when input is split across buffer boundary
|
|
1056
|
+
* (or output is longer than segment used to store it)
|
|
1057
|
+
*/
|
|
1058
|
+
private final JsonToken _parserNumber2(char[] outBuf, int outPtr, boolean negative,
|
|
1059
|
+
int intPartLength)
|
|
1060
|
+
throws IOException, JsonParseException
|
|
1061
|
+
{
|
|
1062
|
+
// Ok, parse the rest
|
|
1063
|
+
while (true) {
|
|
1064
|
+
if (_inputPtr >= _inputEnd && !loadMore()) {
|
|
1065
|
+
_textBuffer.setCurrentLength(outPtr);
|
|
1066
|
+
return resetInt(negative, intPartLength);
|
|
1067
|
+
}
|
|
1068
|
+
int c = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
1069
|
+
if (c > INT_9 || c < INT_0) {
|
|
1070
|
+
if (c == '.' || c == 'e' || c == 'E') {
|
|
1071
|
+
return _parseFloatText(outBuf, outPtr, c, negative, intPartLength);
|
|
1072
|
+
}
|
|
1073
|
+
break;
|
|
1074
|
+
}
|
|
1075
|
+
if (outPtr >= outBuf.length) {
|
|
1076
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1077
|
+
outPtr = 0;
|
|
1078
|
+
}
|
|
1079
|
+
outBuf[outPtr++] = (char) c;
|
|
1080
|
+
++intPartLength;
|
|
1081
|
+
}
|
|
1082
|
+
--_inputPtr; // to push back trailing char (comma etc)
|
|
1083
|
+
_textBuffer.setCurrentLength(outPtr);
|
|
1084
|
+
|
|
1085
|
+
// And there we have it!
|
|
1086
|
+
return resetInt(negative, intPartLength);
|
|
1087
|
+
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* Method called when we have seen one zero, and want to ensure
|
|
1092
|
+
* it is not followed by another
|
|
1093
|
+
*/
|
|
1094
|
+
private final int _verifyNoLeadingZeroes()
|
|
1095
|
+
throws IOException, JsonParseException
|
|
1096
|
+
{
|
|
1097
|
+
// Ok to have plain "0"
|
|
1098
|
+
if (_inputPtr >= _inputEnd && !loadMore()) {
|
|
1099
|
+
return INT_0;
|
|
1100
|
+
}
|
|
1101
|
+
int ch = _inputBuffer[_inputPtr] & 0xFF;
|
|
1102
|
+
// if not followed by a number (probably '.'); return zero as is, to be included
|
|
1103
|
+
if (ch < INT_0 || ch > INT_9) {
|
|
1104
|
+
return INT_0;
|
|
1105
|
+
}
|
|
1106
|
+
// [JACKSON-358]: we may want to allow them, after all...
|
|
1107
|
+
if (!isEnabled(Feature.ALLOW_NUMERIC_LEADING_ZEROS)) {
|
|
1108
|
+
reportInvalidNumber("Leading zeroes not allowed");
|
|
1109
|
+
}
|
|
1110
|
+
// if so, just need to skip either all zeroes (if followed by number); or all but one (if non-number)
|
|
1111
|
+
++_inputPtr; // Leading zero to be skipped
|
|
1112
|
+
if (ch == INT_0) {
|
|
1113
|
+
while (_inputPtr < _inputEnd || loadMore()) {
|
|
1114
|
+
ch = _inputBuffer[_inputPtr] & 0xFF;
|
|
1115
|
+
if (ch < INT_0 || ch > INT_9) { // followed by non-number; retain one zero
|
|
1116
|
+
return INT_0;
|
|
1117
|
+
}
|
|
1118
|
+
++_inputPtr; // skip previous zeroes
|
|
1119
|
+
if (ch != INT_0) { // followed by other number; return
|
|
1120
|
+
break;
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
return ch;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
private final JsonToken _parseFloatText(char[] outBuf, int outPtr, int c,
|
|
1128
|
+
boolean negative, int integerPartLength)
|
|
1129
|
+
throws IOException, JsonParseException
|
|
1130
|
+
{
|
|
1131
|
+
int fractLen = 0;
|
|
1132
|
+
boolean eof = false;
|
|
1133
|
+
|
|
1134
|
+
// And then see if we get other parts
|
|
1135
|
+
if (c == '.') { // yes, fraction
|
|
1136
|
+
outBuf[outPtr++] = (char) c;
|
|
1137
|
+
|
|
1138
|
+
fract_loop:
|
|
1139
|
+
while (true) {
|
|
1140
|
+
if (_inputPtr >= _inputEnd && !loadMore()) {
|
|
1141
|
+
eof = true;
|
|
1142
|
+
break fract_loop;
|
|
1143
|
+
}
|
|
1144
|
+
c = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
1145
|
+
if (c < INT_0 || c > INT_9) {
|
|
1146
|
+
break fract_loop;
|
|
1147
|
+
}
|
|
1148
|
+
++fractLen;
|
|
1149
|
+
if (outPtr >= outBuf.length) {
|
|
1150
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1151
|
+
outPtr = 0;
|
|
1152
|
+
}
|
|
1153
|
+
outBuf[outPtr++] = (char) c;
|
|
1154
|
+
}
|
|
1155
|
+
// must be followed by sequence of ints, one minimum
|
|
1156
|
+
if (fractLen == 0) {
|
|
1157
|
+
reportUnexpectedNumberChar(c, "Decimal point not followed by a digit");
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
int expLen = 0;
|
|
1162
|
+
if (c == 'e' || c == 'E') { // exponent?
|
|
1163
|
+
if (outPtr >= outBuf.length) {
|
|
1164
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1165
|
+
outPtr = 0;
|
|
1166
|
+
}
|
|
1167
|
+
outBuf[outPtr++] = (char) c;
|
|
1168
|
+
// Not optional, can require that we get one more char
|
|
1169
|
+
if (_inputPtr >= _inputEnd) {
|
|
1170
|
+
loadMoreGuaranteed();
|
|
1171
|
+
}
|
|
1172
|
+
c = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
1173
|
+
// Sign indicator?
|
|
1174
|
+
if (c == '-' || c == '+') {
|
|
1175
|
+
if (outPtr >= outBuf.length) {
|
|
1176
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1177
|
+
outPtr = 0;
|
|
1178
|
+
}
|
|
1179
|
+
outBuf[outPtr++] = (char) c;
|
|
1180
|
+
// Likewise, non optional:
|
|
1181
|
+
if (_inputPtr >= _inputEnd) {
|
|
1182
|
+
loadMoreGuaranteed();
|
|
1183
|
+
}
|
|
1184
|
+
c = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
exp_loop:
|
|
1188
|
+
while (c <= INT_9 && c >= INT_0) {
|
|
1189
|
+
++expLen;
|
|
1190
|
+
if (outPtr >= outBuf.length) {
|
|
1191
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1192
|
+
outPtr = 0;
|
|
1193
|
+
}
|
|
1194
|
+
outBuf[outPtr++] = (char) c;
|
|
1195
|
+
if (_inputPtr >= _inputEnd && !loadMore()) {
|
|
1196
|
+
eof = true;
|
|
1197
|
+
break exp_loop;
|
|
1198
|
+
}
|
|
1199
|
+
c = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
1200
|
+
}
|
|
1201
|
+
// must be followed by sequence of ints, one minimum
|
|
1202
|
+
if (expLen == 0) {
|
|
1203
|
+
reportUnexpectedNumberChar(c, "Exponent indicator not followed by a digit");
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
|
|
1207
|
+
// Ok; unless we hit end-of-input, need to push last char read back
|
|
1208
|
+
if (!eof) {
|
|
1209
|
+
--_inputPtr;
|
|
1210
|
+
}
|
|
1211
|
+
_textBuffer.setCurrentLength(outPtr);
|
|
1212
|
+
|
|
1213
|
+
// And there we have it!
|
|
1214
|
+
return resetFloat(negative, integerPartLength, fractLen, expLen);
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
/*
|
|
1218
|
+
/**********************************************************
|
|
1219
|
+
/* Internal methods, secondary parsing
|
|
1220
|
+
/**********************************************************
|
|
1221
|
+
*/
|
|
1222
|
+
|
|
1223
|
+
protected final Name _parseFieldName(int i)
|
|
1224
|
+
throws IOException, JsonParseException
|
|
1225
|
+
{
|
|
1226
|
+
if (i != INT_QUOTE) {
|
|
1227
|
+
return _handleUnusualFieldName(i);
|
|
1228
|
+
}
|
|
1229
|
+
// First: can we optimize out bounds checks?
|
|
1230
|
+
if ((_inputPtr + 9) > _inputEnd) { // Need 8 chars, plus one trailing (quote)
|
|
1231
|
+
return slowParseFieldName();
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
// If so, can also unroll loops nicely
|
|
1235
|
+
/* 25-Nov-2008, tatu: This may seem weird, but here we do
|
|
1236
|
+
* NOT want to worry about UTF-8 decoding. Rather, we'll
|
|
1237
|
+
* assume that part is ok (if not it will get caught
|
|
1238
|
+
* later on), and just handle quotes and backslashes here.
|
|
1239
|
+
*/
|
|
1240
|
+
final byte[] input = _inputBuffer;
|
|
1241
|
+
final int[] codes = sInputCodesLatin1;
|
|
1242
|
+
|
|
1243
|
+
int q = input[_inputPtr++] & 0xFF;
|
|
1244
|
+
|
|
1245
|
+
if (codes[q] == 0) {
|
|
1246
|
+
i = input[_inputPtr++] & 0xFF;
|
|
1247
|
+
if (codes[i] == 0) {
|
|
1248
|
+
q = (q << 8) | i;
|
|
1249
|
+
i = input[_inputPtr++] & 0xFF;
|
|
1250
|
+
if (codes[i] == 0) {
|
|
1251
|
+
q = (q << 8) | i;
|
|
1252
|
+
i = input[_inputPtr++] & 0xFF;
|
|
1253
|
+
if (codes[i] == 0) {
|
|
1254
|
+
q = (q << 8) | i;
|
|
1255
|
+
i = input[_inputPtr++] & 0xFF;
|
|
1256
|
+
if (codes[i] == 0) {
|
|
1257
|
+
_quad1 = q;
|
|
1258
|
+
return parseMediumFieldName(i, codes);
|
|
1259
|
+
}
|
|
1260
|
+
if (i == INT_QUOTE) { // one byte/char case or broken
|
|
1261
|
+
return findName(q, 4);
|
|
1262
|
+
}
|
|
1263
|
+
return parseFieldName(q, i, 4);
|
|
1264
|
+
}
|
|
1265
|
+
if (i == INT_QUOTE) { // one byte/char case or broken
|
|
1266
|
+
return findName(q, 3);
|
|
1267
|
+
}
|
|
1268
|
+
return parseFieldName(q, i, 3);
|
|
1269
|
+
}
|
|
1270
|
+
if (i == INT_QUOTE) { // one byte/char case or broken
|
|
1271
|
+
return findName(q, 2);
|
|
1272
|
+
}
|
|
1273
|
+
return parseFieldName(q, i, 2);
|
|
1274
|
+
}
|
|
1275
|
+
if (i == INT_QUOTE) { // one byte/char case or broken
|
|
1276
|
+
return findName(q, 1);
|
|
1277
|
+
}
|
|
1278
|
+
return parseFieldName(q, i, 1);
|
|
1279
|
+
}
|
|
1280
|
+
if (q == INT_QUOTE) { // special case, ""
|
|
1281
|
+
return BytesToNameCanonicalizer.getEmptyName();
|
|
1282
|
+
}
|
|
1283
|
+
return parseFieldName(0, q, 0); // quoting or invalid char
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1286
|
+
protected final Name parseMediumFieldName(int q2, final int[] codes)
|
|
1287
|
+
throws IOException, JsonParseException
|
|
1288
|
+
{
|
|
1289
|
+
// Ok, got 5 name bytes so far
|
|
1290
|
+
int i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1291
|
+
if (codes[i] != 0) {
|
|
1292
|
+
if (i == INT_QUOTE) { // 5 bytes
|
|
1293
|
+
return findName(_quad1, q2, 1);
|
|
1294
|
+
}
|
|
1295
|
+
return parseFieldName(_quad1, q2, i, 1); // quoting or invalid char
|
|
1296
|
+
}
|
|
1297
|
+
q2 = (q2 << 8) | i;
|
|
1298
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1299
|
+
if (codes[i] != 0) {
|
|
1300
|
+
if (i == INT_QUOTE) { // 6 bytes
|
|
1301
|
+
return findName(_quad1, q2, 2);
|
|
1302
|
+
}
|
|
1303
|
+
return parseFieldName(_quad1, q2, i, 2);
|
|
1304
|
+
}
|
|
1305
|
+
q2 = (q2 << 8) | i;
|
|
1306
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1307
|
+
if (codes[i] != 0) {
|
|
1308
|
+
if (i == INT_QUOTE) { // 7 bytes
|
|
1309
|
+
return findName(_quad1, q2, 3);
|
|
1310
|
+
}
|
|
1311
|
+
return parseFieldName(_quad1, q2, i, 3);
|
|
1312
|
+
}
|
|
1313
|
+
q2 = (q2 << 8) | i;
|
|
1314
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1315
|
+
if (codes[i] != 0) {
|
|
1316
|
+
if (i == INT_QUOTE) { // 8 bytes
|
|
1317
|
+
return findName(_quad1, q2, 4);
|
|
1318
|
+
}
|
|
1319
|
+
return parseFieldName(_quad1, q2, i, 4);
|
|
1320
|
+
}
|
|
1321
|
+
_quadBuffer[0] = _quad1;
|
|
1322
|
+
_quadBuffer[1] = q2;
|
|
1323
|
+
return parseLongFieldName(i);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
protected Name parseLongFieldName(int q)
|
|
1327
|
+
throws IOException, JsonParseException
|
|
1328
|
+
{
|
|
1329
|
+
// As explained above, will ignore UTF-8 encoding at this point
|
|
1330
|
+
final int[] codes = sInputCodesLatin1;
|
|
1331
|
+
int qlen = 2;
|
|
1332
|
+
|
|
1333
|
+
while (true) {
|
|
1334
|
+
/* Let's offline if we hit buffer boundary (otherwise would
|
|
1335
|
+
* need to [try to] align input, which is bit complicated
|
|
1336
|
+
* and may not always be possible)
|
|
1337
|
+
*/
|
|
1338
|
+
if ((_inputEnd - _inputPtr) < 4) {
|
|
1339
|
+
return parseEscapedFieldName(_quadBuffer, qlen, 0, q, 0);
|
|
1340
|
+
}
|
|
1341
|
+
// Otherwise can skip boundary checks for 4 bytes in loop
|
|
1342
|
+
|
|
1343
|
+
int i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1344
|
+
if (codes[i] != 0) {
|
|
1345
|
+
if (i == INT_QUOTE) {
|
|
1346
|
+
return findName(_quadBuffer, qlen, q, 1);
|
|
1347
|
+
}
|
|
1348
|
+
return parseEscapedFieldName(_quadBuffer, qlen, q, i, 1);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
q = (q << 8) | i;
|
|
1352
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1353
|
+
if (codes[i] != 0) {
|
|
1354
|
+
if (i == INT_QUOTE) {
|
|
1355
|
+
return findName(_quadBuffer, qlen, q, 2);
|
|
1356
|
+
}
|
|
1357
|
+
return parseEscapedFieldName(_quadBuffer, qlen, q, i, 2);
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
q = (q << 8) | i;
|
|
1361
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1362
|
+
if (codes[i] != 0) {
|
|
1363
|
+
if (i == INT_QUOTE) {
|
|
1364
|
+
return findName(_quadBuffer, qlen, q, 3);
|
|
1365
|
+
}
|
|
1366
|
+
return parseEscapedFieldName(_quadBuffer, qlen, q, i, 3);
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
q = (q << 8) | i;
|
|
1370
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1371
|
+
if (codes[i] != 0) {
|
|
1372
|
+
if (i == INT_QUOTE) {
|
|
1373
|
+
return findName(_quadBuffer, qlen, q, 4);
|
|
1374
|
+
}
|
|
1375
|
+
return parseEscapedFieldName(_quadBuffer, qlen, q, i, 4);
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// Nope, no end in sight. Need to grow quad array etc
|
|
1379
|
+
if (qlen >= _quadBuffer.length) {
|
|
1380
|
+
_quadBuffer = growArrayBy(_quadBuffer, qlen);
|
|
1381
|
+
}
|
|
1382
|
+
_quadBuffer[qlen++] = q;
|
|
1383
|
+
q = i;
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
/**
|
|
1388
|
+
* Method called when not even first 8 bytes are guaranteed
|
|
1389
|
+
* to come consequtively. Happens rarely, so this is offlined;
|
|
1390
|
+
* plus we'll also do full checks for escaping etc.
|
|
1391
|
+
*/
|
|
1392
|
+
protected Name slowParseFieldName()
|
|
1393
|
+
throws IOException, JsonParseException
|
|
1394
|
+
{
|
|
1395
|
+
if (_inputPtr >= _inputEnd) {
|
|
1396
|
+
if (!loadMore()) {
|
|
1397
|
+
_reportInvalidEOF(": was expecting closing '\"' for name");
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
int i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1401
|
+
if (i == INT_QUOTE) { // special case, ""
|
|
1402
|
+
return BytesToNameCanonicalizer.getEmptyName();
|
|
1403
|
+
}
|
|
1404
|
+
return parseEscapedFieldName(_quadBuffer, 0, 0, i, 0);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
private final Name parseFieldName(int q1, int ch, int lastQuadBytes)
|
|
1408
|
+
throws IOException, JsonParseException
|
|
1409
|
+
{
|
|
1410
|
+
return parseEscapedFieldName(_quadBuffer, 0, q1, ch, lastQuadBytes);
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
private final Name parseFieldName(int q1, int q2, int ch, int lastQuadBytes)
|
|
1414
|
+
throws IOException, JsonParseException
|
|
1415
|
+
{
|
|
1416
|
+
_quadBuffer[0] = q1;
|
|
1417
|
+
return parseEscapedFieldName(_quadBuffer, 1, q2, ch, lastQuadBytes);
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
/**
|
|
1421
|
+
* Slower parsing method which is generally branched to when
|
|
1422
|
+
* an escape sequence is detected (or alternatively for long
|
|
1423
|
+
* names, or ones crossing input buffer boundary). In any case,
|
|
1424
|
+
* needs to be able to handle more exceptional cases, gets
|
|
1425
|
+
* slower, and hance is offlined to a separate method.
|
|
1426
|
+
*/
|
|
1427
|
+
protected Name parseEscapedFieldName(int[] quads, int qlen, int currQuad, int ch,
|
|
1428
|
+
int currQuadBytes)
|
|
1429
|
+
throws IOException, JsonParseException
|
|
1430
|
+
{
|
|
1431
|
+
/* 25-Nov-2008, tatu: This may seem weird, but here we do
|
|
1432
|
+
* NOT want to worry about UTF-8 decoding. Rather, we'll
|
|
1433
|
+
* assume that part is ok (if not it will get caught
|
|
1434
|
+
* later on), and just handle quotes and backslashes here.
|
|
1435
|
+
*/
|
|
1436
|
+
final int[] codes = sInputCodesLatin1;
|
|
1437
|
+
|
|
1438
|
+
while (true) {
|
|
1439
|
+
if (codes[ch] != 0) {
|
|
1440
|
+
if (ch == INT_QUOTE) { // we are done
|
|
1441
|
+
break;
|
|
1442
|
+
}
|
|
1443
|
+
// Unquoted white space?
|
|
1444
|
+
if (ch != INT_BACKSLASH) {
|
|
1445
|
+
// As per [JACKSON-208], call can now return:
|
|
1446
|
+
_throwUnquotedSpace(ch, "name");
|
|
1447
|
+
} else {
|
|
1448
|
+
// Nope, escape sequence
|
|
1449
|
+
ch = _decodeEscaped();
|
|
1450
|
+
}
|
|
1451
|
+
/* Oh crap. May need to UTF-8 (re-)encode it, if it's
|
|
1452
|
+
* beyond 7-bit ascii. Gets pretty messy.
|
|
1453
|
+
* If this happens often, may want to use different name
|
|
1454
|
+
* canonicalization to avoid these hits.
|
|
1455
|
+
*/
|
|
1456
|
+
if (ch > 127) {
|
|
1457
|
+
// Ok, we'll need room for first byte right away
|
|
1458
|
+
if (currQuadBytes >= 4) {
|
|
1459
|
+
if (qlen >= quads.length) {
|
|
1460
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1461
|
+
}
|
|
1462
|
+
quads[qlen++] = currQuad;
|
|
1463
|
+
currQuad = 0;
|
|
1464
|
+
currQuadBytes = 0;
|
|
1465
|
+
}
|
|
1466
|
+
if (ch < 0x800) { // 2-byte
|
|
1467
|
+
currQuad = (currQuad << 8) | (0xc0 | (ch >> 6));
|
|
1468
|
+
++currQuadBytes;
|
|
1469
|
+
// Second byte gets output below:
|
|
1470
|
+
} else { // 3 bytes; no need to worry about surrogates here
|
|
1471
|
+
currQuad = (currQuad << 8) | (0xe0 | (ch >> 12));
|
|
1472
|
+
++currQuadBytes;
|
|
1473
|
+
// need room for middle byte?
|
|
1474
|
+
if (currQuadBytes >= 4) {
|
|
1475
|
+
if (qlen >= quads.length) {
|
|
1476
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1477
|
+
}
|
|
1478
|
+
quads[qlen++] = currQuad;
|
|
1479
|
+
currQuad = 0;
|
|
1480
|
+
currQuadBytes = 0;
|
|
1481
|
+
}
|
|
1482
|
+
currQuad = (currQuad << 8) | (0x80 | ((ch >> 6) & 0x3f));
|
|
1483
|
+
++currQuadBytes;
|
|
1484
|
+
}
|
|
1485
|
+
// And same last byte in both cases, gets output below:
|
|
1486
|
+
ch = 0x80 | (ch & 0x3f);
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
// Ok, we have one more byte to add at any rate:
|
|
1490
|
+
if (currQuadBytes < 4) {
|
|
1491
|
+
++currQuadBytes;
|
|
1492
|
+
currQuad = (currQuad << 8) | ch;
|
|
1493
|
+
} else {
|
|
1494
|
+
if (qlen >= quads.length) {
|
|
1495
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1496
|
+
}
|
|
1497
|
+
quads[qlen++] = currQuad;
|
|
1498
|
+
currQuad = ch;
|
|
1499
|
+
currQuadBytes = 1;
|
|
1500
|
+
}
|
|
1501
|
+
if (_inputPtr >= _inputEnd) {
|
|
1502
|
+
if (!loadMore()) {
|
|
1503
|
+
_reportInvalidEOF(" in field name");
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
ch = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
if (currQuadBytes > 0) {
|
|
1510
|
+
if (qlen >= quads.length) {
|
|
1511
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1512
|
+
}
|
|
1513
|
+
quads[qlen++] = currQuad;
|
|
1514
|
+
}
|
|
1515
|
+
Name name = _symbols.findName(quads, qlen);
|
|
1516
|
+
if (name == null) {
|
|
1517
|
+
name = addName(quads, qlen, currQuadBytes);
|
|
1518
|
+
}
|
|
1519
|
+
return name;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
/**
|
|
1523
|
+
* Method called when we see non-white space character other
|
|
1524
|
+
* than double quote, when expecting a field name.
|
|
1525
|
+
* In standard mode will just throw an expection; but
|
|
1526
|
+
* in non-standard modes may be able to parse name.
|
|
1527
|
+
*/
|
|
1528
|
+
protected final Name _handleUnusualFieldName(int ch)
|
|
1529
|
+
throws IOException, JsonParseException
|
|
1530
|
+
{
|
|
1531
|
+
// [JACKSON-173]: allow single quotes
|
|
1532
|
+
if (ch == INT_APOSTROPHE && isEnabled(Feature.ALLOW_SINGLE_QUOTES)) {
|
|
1533
|
+
return _parseApostropheFieldName();
|
|
1534
|
+
}
|
|
1535
|
+
// [JACKSON-69]: allow unquoted names if feature enabled:
|
|
1536
|
+
if (!isEnabled(Feature.ALLOW_UNQUOTED_FIELD_NAMES)) {
|
|
1537
|
+
_reportUnexpectedChar(ch, "was expecting double-quote to start field name");
|
|
1538
|
+
}
|
|
1539
|
+
/* Also: note that although we use a different table here,
|
|
1540
|
+
* it does NOT handle UTF-8 decoding. It'll just pass those
|
|
1541
|
+
* high-bit codes as acceptable for later decoding.
|
|
1542
|
+
*/
|
|
1543
|
+
final int[] codes = CharTypes.getInputCodeUtf8JsNames();
|
|
1544
|
+
// Also: must start with a valid character...
|
|
1545
|
+
if (codes[ch] != 0) {
|
|
1546
|
+
_reportUnexpectedChar(ch, "was expecting either valid name character (for unquoted name) or double-quote (for quoted) to start field name");
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
/* Ok, now; instead of ultra-optimizing parsing here (as with
|
|
1550
|
+
* regular JSON names), let's just use the generic "slow"
|
|
1551
|
+
* variant. Can measure its impact later on if need be
|
|
1552
|
+
*/
|
|
1553
|
+
int[] quads = _quadBuffer;
|
|
1554
|
+
int qlen = 0;
|
|
1555
|
+
int currQuad = 0;
|
|
1556
|
+
int currQuadBytes = 0;
|
|
1557
|
+
|
|
1558
|
+
while (true) {
|
|
1559
|
+
// Ok, we have one more byte to add at any rate:
|
|
1560
|
+
if (currQuadBytes < 4) {
|
|
1561
|
+
++currQuadBytes;
|
|
1562
|
+
currQuad = (currQuad << 8) | ch;
|
|
1563
|
+
} else {
|
|
1564
|
+
if (qlen >= quads.length) {
|
|
1565
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1566
|
+
}
|
|
1567
|
+
quads[qlen++] = currQuad;
|
|
1568
|
+
currQuad = ch;
|
|
1569
|
+
currQuadBytes = 1;
|
|
1570
|
+
}
|
|
1571
|
+
if (_inputPtr >= _inputEnd) {
|
|
1572
|
+
if (!loadMore()) {
|
|
1573
|
+
_reportInvalidEOF(" in field name");
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
ch = _inputBuffer[_inputPtr] & 0xFF;
|
|
1577
|
+
if (codes[ch] != 0) {
|
|
1578
|
+
break;
|
|
1579
|
+
}
|
|
1580
|
+
++_inputPtr;
|
|
1581
|
+
}
|
|
1582
|
+
|
|
1583
|
+
if (currQuadBytes > 0) {
|
|
1584
|
+
if (qlen >= quads.length) {
|
|
1585
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1586
|
+
}
|
|
1587
|
+
quads[qlen++] = currQuad;
|
|
1588
|
+
}
|
|
1589
|
+
Name name = _symbols.findName(quads, qlen);
|
|
1590
|
+
if (name == null) {
|
|
1591
|
+
name = addName(quads, qlen, currQuadBytes);
|
|
1592
|
+
}
|
|
1593
|
+
return name;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
/* Parsing to support [JACKSON-173]. Plenty of duplicated code;
|
|
1597
|
+
* main reason being to try to avoid slowing down fast path
|
|
1598
|
+
* for valid JSON -- more alternatives, more code, generally
|
|
1599
|
+
* bit slower execution.
|
|
1600
|
+
*/
|
|
1601
|
+
protected final Name _parseApostropheFieldName()
|
|
1602
|
+
throws IOException, JsonParseException
|
|
1603
|
+
{
|
|
1604
|
+
if (_inputPtr >= _inputEnd) {
|
|
1605
|
+
if (!loadMore()) {
|
|
1606
|
+
_reportInvalidEOF(": was expecting closing '\'' for name");
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
int ch = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1610
|
+
if (ch == INT_APOSTROPHE) { // special case, ''
|
|
1611
|
+
return BytesToNameCanonicalizer.getEmptyName();
|
|
1612
|
+
}
|
|
1613
|
+
int[] quads = _quadBuffer;
|
|
1614
|
+
int qlen = 0;
|
|
1615
|
+
int currQuad = 0;
|
|
1616
|
+
int currQuadBytes = 0;
|
|
1617
|
+
|
|
1618
|
+
// Copied from parseEscapedFieldName, with minor mods:
|
|
1619
|
+
|
|
1620
|
+
final int[] codes = sInputCodesLatin1;
|
|
1621
|
+
|
|
1622
|
+
while (true) {
|
|
1623
|
+
if (ch == INT_APOSTROPHE) {
|
|
1624
|
+
break;
|
|
1625
|
+
}
|
|
1626
|
+
// additional check to skip handling of double-quotes
|
|
1627
|
+
if (ch != INT_QUOTE && codes[ch] != 0) {
|
|
1628
|
+
if (ch != INT_BACKSLASH) {
|
|
1629
|
+
// Unquoted white space?
|
|
1630
|
+
// As per [JACKSON-208], call can now return:
|
|
1631
|
+
_throwUnquotedSpace(ch, "name");
|
|
1632
|
+
} else {
|
|
1633
|
+
// Nope, escape sequence
|
|
1634
|
+
ch = _decodeEscaped();
|
|
1635
|
+
}
|
|
1636
|
+
/* Oh crap. May need to UTF-8 (re-)encode it, if it's
|
|
1637
|
+
* beyond 7-bit ascii. Gets pretty messy.
|
|
1638
|
+
* If this happens often, may want to use different name
|
|
1639
|
+
* canonicalization to avoid these hits.
|
|
1640
|
+
*/
|
|
1641
|
+
if (ch > 127) {
|
|
1642
|
+
// Ok, we'll need room for first byte right away
|
|
1643
|
+
if (currQuadBytes >= 4) {
|
|
1644
|
+
if (qlen >= quads.length) {
|
|
1645
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1646
|
+
}
|
|
1647
|
+
quads[qlen++] = currQuad;
|
|
1648
|
+
currQuad = 0;
|
|
1649
|
+
currQuadBytes = 0;
|
|
1650
|
+
}
|
|
1651
|
+
if (ch < 0x800) { // 2-byte
|
|
1652
|
+
currQuad = (currQuad << 8) | (0xc0 | (ch >> 6));
|
|
1653
|
+
++currQuadBytes;
|
|
1654
|
+
// Second byte gets output below:
|
|
1655
|
+
} else { // 3 bytes; no need to worry about surrogates here
|
|
1656
|
+
currQuad = (currQuad << 8) | (0xe0 | (ch >> 12));
|
|
1657
|
+
++currQuadBytes;
|
|
1658
|
+
// need room for middle byte?
|
|
1659
|
+
if (currQuadBytes >= 4) {
|
|
1660
|
+
if (qlen >= quads.length) {
|
|
1661
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1662
|
+
}
|
|
1663
|
+
quads[qlen++] = currQuad;
|
|
1664
|
+
currQuad = 0;
|
|
1665
|
+
currQuadBytes = 0;
|
|
1666
|
+
}
|
|
1667
|
+
currQuad = (currQuad << 8) | (0x80 | ((ch >> 6) & 0x3f));
|
|
1668
|
+
++currQuadBytes;
|
|
1669
|
+
}
|
|
1670
|
+
// And same last byte in both cases, gets output below:
|
|
1671
|
+
ch = 0x80 | (ch & 0x3f);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
// Ok, we have one more byte to add at any rate:
|
|
1675
|
+
if (currQuadBytes < 4) {
|
|
1676
|
+
++currQuadBytes;
|
|
1677
|
+
currQuad = (currQuad << 8) | ch;
|
|
1678
|
+
} else {
|
|
1679
|
+
if (qlen >= quads.length) {
|
|
1680
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1681
|
+
}
|
|
1682
|
+
quads[qlen++] = currQuad;
|
|
1683
|
+
currQuad = ch;
|
|
1684
|
+
currQuadBytes = 1;
|
|
1685
|
+
}
|
|
1686
|
+
if (_inputPtr >= _inputEnd) {
|
|
1687
|
+
if (!loadMore()) {
|
|
1688
|
+
_reportInvalidEOF(" in field name");
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
ch = _inputBuffer[_inputPtr++] & 0xFF;
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
if (currQuadBytes > 0) {
|
|
1695
|
+
if (qlen >= quads.length) {
|
|
1696
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1697
|
+
}
|
|
1698
|
+
quads[qlen++] = currQuad;
|
|
1699
|
+
}
|
|
1700
|
+
Name name = _symbols.findName(quads, qlen);
|
|
1701
|
+
if (name == null) {
|
|
1702
|
+
name = addName(quads, qlen, currQuadBytes);
|
|
1703
|
+
}
|
|
1704
|
+
return name;
|
|
1705
|
+
}
|
|
1706
|
+
|
|
1707
|
+
/*
|
|
1708
|
+
/**********************************************************
|
|
1709
|
+
/* Internal methods, symbol (name) handling
|
|
1710
|
+
/**********************************************************
|
|
1711
|
+
*/
|
|
1712
|
+
|
|
1713
|
+
private final Name findName(int q1, int lastQuadBytes)
|
|
1714
|
+
throws JsonParseException
|
|
1715
|
+
{
|
|
1716
|
+
// Usually we'll find it from the canonical symbol table already
|
|
1717
|
+
Name name = _symbols.findName(q1);
|
|
1718
|
+
if (name != null) {
|
|
1719
|
+
return name;
|
|
1720
|
+
}
|
|
1721
|
+
// If not, more work. We'll need add stuff to buffer
|
|
1722
|
+
_quadBuffer[0] = q1;
|
|
1723
|
+
return addName(_quadBuffer, 1, lastQuadBytes);
|
|
1724
|
+
}
|
|
1725
|
+
|
|
1726
|
+
private final Name findName(int q1, int q2, int lastQuadBytes)
|
|
1727
|
+
throws JsonParseException
|
|
1728
|
+
{
|
|
1729
|
+
// Usually we'll find it from the canonical symbol table already
|
|
1730
|
+
Name name = _symbols.findName(q1, q2);
|
|
1731
|
+
if (name != null) {
|
|
1732
|
+
return name;
|
|
1733
|
+
}
|
|
1734
|
+
// If not, more work. We'll need add stuff to buffer
|
|
1735
|
+
_quadBuffer[0] = q1;
|
|
1736
|
+
_quadBuffer[1] = q2;
|
|
1737
|
+
return addName(_quadBuffer, 2, lastQuadBytes);
|
|
1738
|
+
}
|
|
1739
|
+
|
|
1740
|
+
private final Name findName(int[] quads, int qlen, int lastQuad, int lastQuadBytes)
|
|
1741
|
+
throws JsonParseException
|
|
1742
|
+
{
|
|
1743
|
+
if (qlen >= quads.length) {
|
|
1744
|
+
_quadBuffer = quads = growArrayBy(quads, quads.length);
|
|
1745
|
+
}
|
|
1746
|
+
quads[qlen++] = lastQuad;
|
|
1747
|
+
Name name = _symbols.findName(quads, qlen);
|
|
1748
|
+
if (name == null) {
|
|
1749
|
+
return addName(quads, qlen, lastQuadBytes);
|
|
1750
|
+
}
|
|
1751
|
+
return name;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
/**
|
|
1755
|
+
* This is the main workhorse method used when we take a symbol
|
|
1756
|
+
* table miss. It needs to demultiplex individual bytes, decode
|
|
1757
|
+
* multi-byte chars (if any), and then construct Name instance
|
|
1758
|
+
* and add it to the symbol table.
|
|
1759
|
+
*/
|
|
1760
|
+
private final Name addName(int[] quads, int qlen, int lastQuadBytes)
|
|
1761
|
+
throws JsonParseException
|
|
1762
|
+
{
|
|
1763
|
+
/* Ok: must decode UTF-8 chars. No other validation is
|
|
1764
|
+
* needed, since unescaping has been done earlier as necessary
|
|
1765
|
+
* (as well as error reporting for unescaped control chars)
|
|
1766
|
+
*/
|
|
1767
|
+
// 4 bytes per quad, except last one maybe less
|
|
1768
|
+
int byteLen = (qlen << 2) - 4 + lastQuadBytes;
|
|
1769
|
+
|
|
1770
|
+
/* And last one is not correctly aligned (leading zero bytes instead
|
|
1771
|
+
* need to shift a bit, instead of trailing). Only need to shift it
|
|
1772
|
+
* for UTF-8 decoding; need revert for storage (since key will not
|
|
1773
|
+
* be aligned, to optimize lookup speed)
|
|
1774
|
+
*/
|
|
1775
|
+
int lastQuad;
|
|
1776
|
+
|
|
1777
|
+
if (lastQuadBytes < 4) {
|
|
1778
|
+
lastQuad = quads[qlen-1];
|
|
1779
|
+
// 8/16/24 bit left shift
|
|
1780
|
+
quads[qlen-1] = (lastQuad << ((4 - lastQuadBytes) << 3));
|
|
1781
|
+
} else {
|
|
1782
|
+
lastQuad = 0;
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1785
|
+
// Need some working space, TextBuffer works well:
|
|
1786
|
+
char[] cbuf = _textBuffer.emptyAndGetCurrentSegment();
|
|
1787
|
+
int cix = 0;
|
|
1788
|
+
|
|
1789
|
+
for (int ix = 0; ix < byteLen; ) {
|
|
1790
|
+
int ch = quads[ix >> 2]; // current quad, need to shift+mask
|
|
1791
|
+
int byteIx = (ix & 3);
|
|
1792
|
+
ch = (ch >> ((3 - byteIx) << 3)) & 0xFF;
|
|
1793
|
+
++ix;
|
|
1794
|
+
|
|
1795
|
+
if (ch > 127) { // multi-byte
|
|
1796
|
+
int needed;
|
|
1797
|
+
if ((ch & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF)
|
|
1798
|
+
ch &= 0x1F;
|
|
1799
|
+
needed = 1;
|
|
1800
|
+
} else if ((ch & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF)
|
|
1801
|
+
ch &= 0x0F;
|
|
1802
|
+
needed = 2;
|
|
1803
|
+
} else if ((ch & 0xF8) == 0xF0) { // 4 bytes; double-char with surrogates and all...
|
|
1804
|
+
ch &= 0x07;
|
|
1805
|
+
needed = 3;
|
|
1806
|
+
} else { // 5- and 6-byte chars not valid xml chars
|
|
1807
|
+
_reportInvalidInitial(ch);
|
|
1808
|
+
needed = ch = 1; // never really gets this far
|
|
1809
|
+
}
|
|
1810
|
+
if ((ix + needed) > byteLen) {
|
|
1811
|
+
_reportInvalidEOF(" in field name");
|
|
1812
|
+
}
|
|
1813
|
+
|
|
1814
|
+
// Ok, always need at least one more:
|
|
1815
|
+
int ch2 = quads[ix >> 2]; // current quad, need to shift+mask
|
|
1816
|
+
byteIx = (ix & 3);
|
|
1817
|
+
ch2 = (ch2 >> ((3 - byteIx) << 3));
|
|
1818
|
+
++ix;
|
|
1819
|
+
|
|
1820
|
+
if ((ch2 & 0xC0) != 0x080) {
|
|
1821
|
+
_reportInvalidOther(ch2);
|
|
1822
|
+
}
|
|
1823
|
+
ch = (ch << 6) | (ch2 & 0x3F);
|
|
1824
|
+
if (needed > 1) {
|
|
1825
|
+
ch2 = quads[ix >> 2];
|
|
1826
|
+
byteIx = (ix & 3);
|
|
1827
|
+
ch2 = (ch2 >> ((3 - byteIx) << 3));
|
|
1828
|
+
++ix;
|
|
1829
|
+
|
|
1830
|
+
if ((ch2 & 0xC0) != 0x080) {
|
|
1831
|
+
_reportInvalidOther(ch2);
|
|
1832
|
+
}
|
|
1833
|
+
ch = (ch << 6) | (ch2 & 0x3F);
|
|
1834
|
+
if (needed > 2) { // 4 bytes? (need surrogates on output)
|
|
1835
|
+
ch2 = quads[ix >> 2];
|
|
1836
|
+
byteIx = (ix & 3);
|
|
1837
|
+
ch2 = (ch2 >> ((3 - byteIx) << 3));
|
|
1838
|
+
++ix;
|
|
1839
|
+
if ((ch2 & 0xC0) != 0x080) {
|
|
1840
|
+
_reportInvalidOther(ch2 & 0xFF);
|
|
1841
|
+
}
|
|
1842
|
+
ch = (ch << 6) | (ch2 & 0x3F);
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
if (needed > 2) { // surrogate pair? once again, let's output one here, one later on
|
|
1846
|
+
ch -= 0x10000; // to normalize it starting with 0x0
|
|
1847
|
+
if (cix >= cbuf.length) {
|
|
1848
|
+
cbuf = _textBuffer.expandCurrentSegment();
|
|
1849
|
+
}
|
|
1850
|
+
cbuf[cix++] = (char) (0xD800 + (ch >> 10));
|
|
1851
|
+
ch = 0xDC00 | (ch & 0x03FF);
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
if (cix >= cbuf.length) {
|
|
1855
|
+
cbuf = _textBuffer.expandCurrentSegment();
|
|
1856
|
+
}
|
|
1857
|
+
cbuf[cix++] = (char) ch;
|
|
1858
|
+
}
|
|
1859
|
+
|
|
1860
|
+
// Ok. Now we have the character array, and can construct the String
|
|
1861
|
+
String baseName = new String(cbuf, 0, cix);
|
|
1862
|
+
// And finally, un-align if necessary
|
|
1863
|
+
if (lastQuadBytes < 4) {
|
|
1864
|
+
quads[qlen-1] = lastQuad;
|
|
1865
|
+
}
|
|
1866
|
+
return _symbols.addName(baseName, quads, qlen);
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
/*
|
|
1870
|
+
/**********************************************************
|
|
1871
|
+
/* Internal methods, String value parsing
|
|
1872
|
+
/**********************************************************
|
|
1873
|
+
*/
|
|
1874
|
+
|
|
1875
|
+
@Override
|
|
1876
|
+
protected void _finishString()
|
|
1877
|
+
throws IOException, JsonParseException
|
|
1878
|
+
{
|
|
1879
|
+
// First, single tight loop for ASCII content, not split across input buffer boundary:
|
|
1880
|
+
int ptr = _inputPtr;
|
|
1881
|
+
if (ptr >= _inputEnd) {
|
|
1882
|
+
loadMoreGuaranteed();
|
|
1883
|
+
ptr = _inputPtr;
|
|
1884
|
+
}
|
|
1885
|
+
int outPtr = 0;
|
|
1886
|
+
char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
|
|
1887
|
+
final int[] codes = sInputCodesUtf8;
|
|
1888
|
+
|
|
1889
|
+
final int max = Math.min(_inputEnd, (ptr + outBuf.length));
|
|
1890
|
+
final byte[] inputBuffer = _inputBuffer;
|
|
1891
|
+
while (ptr < max) {
|
|
1892
|
+
int c = (int) inputBuffer[ptr] & 0xFF;
|
|
1893
|
+
if (codes[c] != 0) {
|
|
1894
|
+
if (c == INT_QUOTE) {
|
|
1895
|
+
_inputPtr = ptr+1;
|
|
1896
|
+
_textBuffer.setCurrentLength(outPtr);
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1899
|
+
break;
|
|
1900
|
+
}
|
|
1901
|
+
++ptr;
|
|
1902
|
+
outBuf[outPtr++] = (char) c;
|
|
1903
|
+
}
|
|
1904
|
+
_inputPtr = ptr;
|
|
1905
|
+
_finishString2(outBuf, outPtr);
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1908
|
+
private final void _finishString2(char[] outBuf, int outPtr)
|
|
1909
|
+
throws IOException, JsonParseException
|
|
1910
|
+
{
|
|
1911
|
+
int c;
|
|
1912
|
+
|
|
1913
|
+
// Here we do want to do full decoding, hence:
|
|
1914
|
+
final int[] codes = sInputCodesUtf8;
|
|
1915
|
+
final byte[] inputBuffer = _inputBuffer;
|
|
1916
|
+
|
|
1917
|
+
main_loop:
|
|
1918
|
+
while (true) {
|
|
1919
|
+
// Then the tight ASCII non-funny-char loop:
|
|
1920
|
+
ascii_loop:
|
|
1921
|
+
while (true) {
|
|
1922
|
+
int ptr = _inputPtr;
|
|
1923
|
+
if (ptr >= _inputEnd) {
|
|
1924
|
+
loadMoreGuaranteed();
|
|
1925
|
+
ptr = _inputPtr;
|
|
1926
|
+
}
|
|
1927
|
+
if (outPtr >= outBuf.length) {
|
|
1928
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1929
|
+
outPtr = 0;
|
|
1930
|
+
}
|
|
1931
|
+
final int max = Math.min(_inputEnd, (ptr + (outBuf.length - outPtr)));
|
|
1932
|
+
while (ptr < max) {
|
|
1933
|
+
c = (int) inputBuffer[ptr++] & 0xFF;
|
|
1934
|
+
if (codes[c] != 0) {
|
|
1935
|
+
_inputPtr = ptr;
|
|
1936
|
+
break ascii_loop;
|
|
1937
|
+
}
|
|
1938
|
+
outBuf[outPtr++] = (char) c;
|
|
1939
|
+
}
|
|
1940
|
+
_inputPtr = ptr;
|
|
1941
|
+
}
|
|
1942
|
+
// Ok: end marker, escape or multi-byte?
|
|
1943
|
+
if (c == INT_QUOTE) {
|
|
1944
|
+
break main_loop;
|
|
1945
|
+
}
|
|
1946
|
+
|
|
1947
|
+
switch (codes[c]) {
|
|
1948
|
+
case 1: // backslash
|
|
1949
|
+
c = _decodeEscaped();
|
|
1950
|
+
break;
|
|
1951
|
+
case 2: // 2-byte UTF
|
|
1952
|
+
c = _decodeUtf8_2(c);
|
|
1953
|
+
break;
|
|
1954
|
+
case 3: // 3-byte UTF
|
|
1955
|
+
if ((_inputEnd - _inputPtr) >= 2) {
|
|
1956
|
+
c = _decodeUtf8_3fast(c);
|
|
1957
|
+
} else {
|
|
1958
|
+
c = _decodeUtf8_3(c);
|
|
1959
|
+
}
|
|
1960
|
+
break;
|
|
1961
|
+
case 4: // 4-byte UTF
|
|
1962
|
+
c = _decodeUtf8_4(c);
|
|
1963
|
+
// Let's add first part right away:
|
|
1964
|
+
outBuf[outPtr++] = (char) (0xD800 | (c >> 10));
|
|
1965
|
+
if (outPtr >= outBuf.length) {
|
|
1966
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1967
|
+
outPtr = 0;
|
|
1968
|
+
}
|
|
1969
|
+
c = 0xDC00 | (c & 0x3FF);
|
|
1970
|
+
// And let the other char output down below
|
|
1971
|
+
break;
|
|
1972
|
+
default:
|
|
1973
|
+
if (c < INT_SPACE) {
|
|
1974
|
+
// As per [JACKSON-208], call can now return:
|
|
1975
|
+
_throwUnquotedSpace(c, "string value");
|
|
1976
|
+
} else {
|
|
1977
|
+
// Is this good enough error message?
|
|
1978
|
+
_reportInvalidChar(c);
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
// Need more room?
|
|
1982
|
+
if (outPtr >= outBuf.length) {
|
|
1983
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
1984
|
+
outPtr = 0;
|
|
1985
|
+
}
|
|
1986
|
+
// Ok, let's add char to output:
|
|
1987
|
+
outBuf[outPtr++] = (char) c;
|
|
1988
|
+
}
|
|
1989
|
+
_textBuffer.setCurrentLength(outPtr);
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
/**
|
|
1993
|
+
* Method called to skim through rest of unparsed String value,
|
|
1994
|
+
* if it is not needed. This can be done bit faster if contents
|
|
1995
|
+
* need not be stored for future access.
|
|
1996
|
+
*/
|
|
1997
|
+
protected void _skipString()
|
|
1998
|
+
throws IOException, JsonParseException
|
|
1999
|
+
{
|
|
2000
|
+
_tokenIncomplete = false;
|
|
2001
|
+
|
|
2002
|
+
// Need to be fully UTF-8 aware here:
|
|
2003
|
+
final int[] codes = sInputCodesUtf8;
|
|
2004
|
+
final byte[] inputBuffer = _inputBuffer;
|
|
2005
|
+
|
|
2006
|
+
main_loop:
|
|
2007
|
+
while (true) {
|
|
2008
|
+
int c;
|
|
2009
|
+
|
|
2010
|
+
ascii_loop:
|
|
2011
|
+
while (true) {
|
|
2012
|
+
int ptr = _inputPtr;
|
|
2013
|
+
int max = _inputEnd;
|
|
2014
|
+
if (ptr >= max) {
|
|
2015
|
+
loadMoreGuaranteed();
|
|
2016
|
+
ptr = _inputPtr;
|
|
2017
|
+
max = _inputEnd;
|
|
2018
|
+
}
|
|
2019
|
+
while (ptr < max) {
|
|
2020
|
+
c = (int) inputBuffer[ptr++] & 0xFF;
|
|
2021
|
+
if (codes[c] != 0) {
|
|
2022
|
+
_inputPtr = ptr;
|
|
2023
|
+
break ascii_loop;
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
_inputPtr = ptr;
|
|
2027
|
+
}
|
|
2028
|
+
// Ok: end marker, escape or multi-byte?
|
|
2029
|
+
if (c == INT_QUOTE) {
|
|
2030
|
+
break main_loop;
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
switch (codes[c]) {
|
|
2034
|
+
case 1: // backslash
|
|
2035
|
+
_decodeEscaped();
|
|
2036
|
+
break;
|
|
2037
|
+
case 2: // 2-byte UTF
|
|
2038
|
+
_skipUtf8_2(c);
|
|
2039
|
+
break;
|
|
2040
|
+
case 3: // 3-byte UTF
|
|
2041
|
+
_skipUtf8_3(c);
|
|
2042
|
+
break;
|
|
2043
|
+
case 4: // 4-byte UTF
|
|
2044
|
+
_skipUtf8_4(c);
|
|
2045
|
+
break;
|
|
2046
|
+
default:
|
|
2047
|
+
if (c < INT_SPACE) {
|
|
2048
|
+
// As per [JACKSON-208], call can now return:
|
|
2049
|
+
_throwUnquotedSpace(c, "string value");
|
|
2050
|
+
} else {
|
|
2051
|
+
// Is this good enough error message?
|
|
2052
|
+
_reportInvalidChar(c);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
/**
|
|
2059
|
+
* Method for handling cases where first non-space character
|
|
2060
|
+
* of an expected value token is not legal for standard JSON content.
|
|
2061
|
+
*
|
|
2062
|
+
* @since 1.3
|
|
2063
|
+
*/
|
|
2064
|
+
protected JsonToken _handleUnexpectedValue(int c)
|
|
2065
|
+
throws IOException, JsonParseException
|
|
2066
|
+
{
|
|
2067
|
+
// Most likely an error, unless we are to allow single-quote-strings
|
|
2068
|
+
switch (c) {
|
|
2069
|
+
case '\'':
|
|
2070
|
+
if (isEnabled(Feature.ALLOW_SINGLE_QUOTES)) {
|
|
2071
|
+
return _handleApostropheValue();
|
|
2072
|
+
}
|
|
2073
|
+
break;
|
|
2074
|
+
case 'N':
|
|
2075
|
+
_matchToken("NaN", 1);
|
|
2076
|
+
if (isEnabled(Feature.ALLOW_NON_NUMERIC_NUMBERS)) {
|
|
2077
|
+
return resetAsNaN("NaN", Double.NaN);
|
|
2078
|
+
}
|
|
2079
|
+
_reportError("Non-standard token 'NaN': enable JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS to allow");
|
|
2080
|
+
break;
|
|
2081
|
+
case '+': // note: '-' is taken as number
|
|
2082
|
+
if (_inputPtr >= _inputEnd) {
|
|
2083
|
+
if (!loadMore()) {
|
|
2084
|
+
_reportInvalidEOFInValue();
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
return _handleInvalidNumberStart(_inputBuffer[_inputPtr++] & 0xFF, false);
|
|
2088
|
+
}
|
|
2089
|
+
|
|
2090
|
+
_reportUnexpectedChar(c, "expected a valid value (number, String, array, object, 'true', 'false' or 'null')");
|
|
2091
|
+
return null;
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
protected JsonToken _handleApostropheValue()
|
|
2095
|
+
throws IOException, JsonParseException
|
|
2096
|
+
{
|
|
2097
|
+
int c = 0;
|
|
2098
|
+
// Otherwise almost verbatim copy of _finishString()
|
|
2099
|
+
int outPtr = 0;
|
|
2100
|
+
char[] outBuf = _textBuffer.emptyAndGetCurrentSegment();
|
|
2101
|
+
|
|
2102
|
+
// Here we do want to do full decoding, hence:
|
|
2103
|
+
final int[] codes = sInputCodesUtf8;
|
|
2104
|
+
final byte[] inputBuffer = _inputBuffer;
|
|
2105
|
+
|
|
2106
|
+
main_loop:
|
|
2107
|
+
while (true) {
|
|
2108
|
+
// Then the tight ascii non-funny-char loop:
|
|
2109
|
+
ascii_loop:
|
|
2110
|
+
while (true) {
|
|
2111
|
+
if (_inputPtr >= _inputEnd) {
|
|
2112
|
+
loadMoreGuaranteed();
|
|
2113
|
+
}
|
|
2114
|
+
if (outPtr >= outBuf.length) {
|
|
2115
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
2116
|
+
outPtr = 0;
|
|
2117
|
+
}
|
|
2118
|
+
int max = _inputEnd;
|
|
2119
|
+
{
|
|
2120
|
+
int max2 = _inputPtr + (outBuf.length - outPtr);
|
|
2121
|
+
if (max2 < max) {
|
|
2122
|
+
max = max2;
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
while (_inputPtr < max) {
|
|
2126
|
+
c = (int) inputBuffer[_inputPtr++] & 0xFF;
|
|
2127
|
+
if (c == INT_APOSTROPHE || codes[c] != 0) {
|
|
2128
|
+
break ascii_loop;
|
|
2129
|
+
}
|
|
2130
|
+
outBuf[outPtr++] = (char) c;
|
|
2131
|
+
}
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
// Ok: end marker, escape or multi-byte?
|
|
2135
|
+
if (c == INT_APOSTROPHE) {
|
|
2136
|
+
break main_loop;
|
|
2137
|
+
}
|
|
2138
|
+
|
|
2139
|
+
switch (codes[c]) {
|
|
2140
|
+
case 1: // backslash
|
|
2141
|
+
if (c != INT_QUOTE) { // marked as special, isn't here
|
|
2142
|
+
c = _decodeEscaped();
|
|
2143
|
+
}
|
|
2144
|
+
break;
|
|
2145
|
+
case 2: // 2-byte UTF
|
|
2146
|
+
c = _decodeUtf8_2(c);
|
|
2147
|
+
break;
|
|
2148
|
+
case 3: // 3-byte UTF
|
|
2149
|
+
if ((_inputEnd - _inputPtr) >= 2) {
|
|
2150
|
+
c = _decodeUtf8_3fast(c);
|
|
2151
|
+
} else {
|
|
2152
|
+
c = _decodeUtf8_3(c);
|
|
2153
|
+
}
|
|
2154
|
+
break;
|
|
2155
|
+
case 4: // 4-byte UTF
|
|
2156
|
+
c = _decodeUtf8_4(c);
|
|
2157
|
+
// Let's add first part right away:
|
|
2158
|
+
outBuf[outPtr++] = (char) (0xD800 | (c >> 10));
|
|
2159
|
+
if (outPtr >= outBuf.length) {
|
|
2160
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
2161
|
+
outPtr = 0;
|
|
2162
|
+
}
|
|
2163
|
+
c = 0xDC00 | (c & 0x3FF);
|
|
2164
|
+
// And let the other char output down below
|
|
2165
|
+
break;
|
|
2166
|
+
default:
|
|
2167
|
+
if (c < INT_SPACE) {
|
|
2168
|
+
_throwUnquotedSpace(c, "string value");
|
|
2169
|
+
}
|
|
2170
|
+
// Is this good enough error message?
|
|
2171
|
+
_reportInvalidChar(c);
|
|
2172
|
+
}
|
|
2173
|
+
// Need more room?
|
|
2174
|
+
if (outPtr >= outBuf.length) {
|
|
2175
|
+
outBuf = _textBuffer.finishCurrentSegment();
|
|
2176
|
+
outPtr = 0;
|
|
2177
|
+
}
|
|
2178
|
+
// Ok, let's add char to output:
|
|
2179
|
+
outBuf[outPtr++] = (char) c;
|
|
2180
|
+
}
|
|
2181
|
+
_textBuffer.setCurrentLength(outPtr);
|
|
2182
|
+
|
|
2183
|
+
return JsonToken.VALUE_STRING;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
/**
|
|
2187
|
+
* Method called if expected numeric value (due to leading sign) does not
|
|
2188
|
+
* look like a number
|
|
2189
|
+
*/
|
|
2190
|
+
protected JsonToken _handleInvalidNumberStart(int ch, boolean negative)
|
|
2191
|
+
throws IOException, JsonParseException
|
|
2192
|
+
{
|
|
2193
|
+
if (ch == 'I') {
|
|
2194
|
+
if (_inputPtr >= _inputEnd) {
|
|
2195
|
+
if (!loadMore()) {
|
|
2196
|
+
_reportInvalidEOFInValue();
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
ch = _inputBuffer[_inputPtr++];
|
|
2200
|
+
if (ch == 'N') {
|
|
2201
|
+
String match = negative ? "-INF" :"+INF";
|
|
2202
|
+
_matchToken(match, 3);
|
|
2203
|
+
if (isEnabled(Feature.ALLOW_NON_NUMERIC_NUMBERS)) {
|
|
2204
|
+
return resetAsNaN(match, negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY);
|
|
2205
|
+
}
|
|
2206
|
+
_reportError("Non-standard token '"+match+"': enable JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS to allow");
|
|
2207
|
+
} else if (ch == 'n') {
|
|
2208
|
+
String match = negative ? "-Infinity" :"+Infinity";
|
|
2209
|
+
_matchToken(match, 3);
|
|
2210
|
+
if (isEnabled(Feature.ALLOW_NON_NUMERIC_NUMBERS)) {
|
|
2211
|
+
return resetAsNaN(match, negative ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY);
|
|
2212
|
+
}
|
|
2213
|
+
_reportError("Non-standard token '"+match+"': enable JsonParser.Feature.ALLOW_NON_NUMERIC_NUMBERS to allow");
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
reportUnexpectedNumberChar(ch, "expected digit (0-9) to follow minus sign, for valid numeric value");
|
|
2217
|
+
return null;
|
|
2218
|
+
}
|
|
2219
|
+
|
|
2220
|
+
protected final void _matchToken(String matchStr, int i)
|
|
2221
|
+
throws IOException, JsonParseException
|
|
2222
|
+
{
|
|
2223
|
+
final int len = matchStr.length();
|
|
2224
|
+
|
|
2225
|
+
do {
|
|
2226
|
+
if (_inputPtr >= _inputEnd) {
|
|
2227
|
+
if (!loadMore()) {
|
|
2228
|
+
_reportInvalidEOF(" in a value");
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
if (_inputBuffer[_inputPtr] != matchStr.charAt(i)) {
|
|
2232
|
+
_reportInvalidToken(matchStr.substring(0, i), "'null', 'true', 'false' or NaN");
|
|
2233
|
+
}
|
|
2234
|
+
++_inputPtr;
|
|
2235
|
+
} while (++i < len);
|
|
2236
|
+
|
|
2237
|
+
// but let's also ensure we either get EOF, or non-alphanum char...
|
|
2238
|
+
if (_inputPtr >= _inputEnd) {
|
|
2239
|
+
if (!loadMore()) {
|
|
2240
|
+
return;
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
int ch = _inputBuffer[_inputPtr] & 0xFF;
|
|
2244
|
+
if (ch < '0' || ch == ']' || ch == '}') { // expected/allowed chars
|
|
2245
|
+
return;
|
|
2246
|
+
}
|
|
2247
|
+
// but actually only alphanums are problematic
|
|
2248
|
+
char c = (char) _decodeCharForError(ch);
|
|
2249
|
+
if (Character.isJavaIdentifierPart(c)) {
|
|
2250
|
+
++_inputPtr;
|
|
2251
|
+
_reportInvalidToken(matchStr.substring(0, i), "'null', 'true', 'false' or NaN");
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
protected void _reportInvalidToken(String matchedPart, String msg)
|
|
2256
|
+
throws IOException, JsonParseException
|
|
2257
|
+
{
|
|
2258
|
+
StringBuilder sb = new StringBuilder(matchedPart);
|
|
2259
|
+
/* Let's just try to find what appears to be the token, using
|
|
2260
|
+
* regular Java identifier character rules. It's just a heuristic,
|
|
2261
|
+
* nothing fancy here (nor fast).
|
|
2262
|
+
*/
|
|
2263
|
+
while (true) {
|
|
2264
|
+
if (_inputPtr >= _inputEnd && !loadMore()) {
|
|
2265
|
+
break;
|
|
2266
|
+
}
|
|
2267
|
+
int i = (int) _inputBuffer[_inputPtr++];
|
|
2268
|
+
char c = (char) _decodeCharForError(i);
|
|
2269
|
+
if (!Character.isJavaIdentifierPart(c)) {
|
|
2270
|
+
break;
|
|
2271
|
+
}
|
|
2272
|
+
++_inputPtr;
|
|
2273
|
+
sb.append(c);
|
|
2274
|
+
}
|
|
2275
|
+
_reportError("Unrecognized token '"+sb.toString()+"': was expecting "+msg);
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
/*
|
|
2279
|
+
/**********************************************************
|
|
2280
|
+
/* Internal methods, ws skipping, escape/unescape
|
|
2281
|
+
/**********************************************************
|
|
2282
|
+
*/
|
|
2283
|
+
|
|
2284
|
+
private final int _skipWS()
|
|
2285
|
+
throws IOException, JsonParseException
|
|
2286
|
+
{
|
|
2287
|
+
while (_inputPtr < _inputEnd || loadMore()) {
|
|
2288
|
+
int i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2289
|
+
if (i > INT_SPACE) {
|
|
2290
|
+
if (i != INT_SLASH) {
|
|
2291
|
+
return i;
|
|
2292
|
+
}
|
|
2293
|
+
_skipComment();
|
|
2294
|
+
} else if (i != INT_SPACE) {
|
|
2295
|
+
if (i == INT_LF) {
|
|
2296
|
+
_skipLF();
|
|
2297
|
+
} else if (i == INT_CR) {
|
|
2298
|
+
_skipCR();
|
|
2299
|
+
} else if (i != INT_TAB) {
|
|
2300
|
+
_throwInvalidSpace(i);
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
throw _constructError("Unexpected end-of-input within/between "+_parsingContext.getTypeDesc()+" entries");
|
|
2305
|
+
}
|
|
2306
|
+
|
|
2307
|
+
private final int _skipWSOrEnd()
|
|
2308
|
+
throws IOException, JsonParseException
|
|
2309
|
+
{
|
|
2310
|
+
while ((_inputPtr < _inputEnd) || loadMore()) {
|
|
2311
|
+
int i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2312
|
+
if (i > INT_SPACE) {
|
|
2313
|
+
if (i != INT_SLASH) {
|
|
2314
|
+
return i;
|
|
2315
|
+
}
|
|
2316
|
+
_skipComment();
|
|
2317
|
+
} else if (i != INT_SPACE) {
|
|
2318
|
+
if (i == INT_LF) {
|
|
2319
|
+
_skipLF();
|
|
2320
|
+
} else if (i == INT_CR) {
|
|
2321
|
+
_skipCR();
|
|
2322
|
+
} else if (i != INT_TAB) {
|
|
2323
|
+
_throwInvalidSpace(i);
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
// We ran out of input...
|
|
2328
|
+
_handleEOF();
|
|
2329
|
+
return -1;
|
|
2330
|
+
}
|
|
2331
|
+
|
|
2332
|
+
/**
|
|
2333
|
+
* Helper method for matching and skipping a colon character,
|
|
2334
|
+
* optionally surrounded by white space
|
|
2335
|
+
*
|
|
2336
|
+
* @since 1.9
|
|
2337
|
+
*/
|
|
2338
|
+
private final int _skipColon()
|
|
2339
|
+
throws IOException, JsonParseException
|
|
2340
|
+
{
|
|
2341
|
+
if (_inputPtr >= _inputEnd) {
|
|
2342
|
+
loadMoreGuaranteed();
|
|
2343
|
+
}
|
|
2344
|
+
// first fast case: we just got a colon without white space:
|
|
2345
|
+
int i = _inputBuffer[_inputPtr++];
|
|
2346
|
+
if (i == INT_COLON) {
|
|
2347
|
+
if (_inputPtr < _inputEnd) {
|
|
2348
|
+
i = _inputBuffer[_inputPtr] & 0xFF;
|
|
2349
|
+
if (i > INT_SPACE && i != INT_SLASH) {
|
|
2350
|
+
++_inputPtr;
|
|
2351
|
+
return i;
|
|
2352
|
+
}
|
|
2353
|
+
}
|
|
2354
|
+
} else {
|
|
2355
|
+
// need to skip potential leading space
|
|
2356
|
+
i &= 0xFF;
|
|
2357
|
+
|
|
2358
|
+
space_loop:
|
|
2359
|
+
while (true) {
|
|
2360
|
+
switch (i) {
|
|
2361
|
+
case INT_SPACE:
|
|
2362
|
+
case INT_TAB:
|
|
2363
|
+
case INT_CR:
|
|
2364
|
+
_skipCR();
|
|
2365
|
+
break;
|
|
2366
|
+
case INT_LF:
|
|
2367
|
+
_skipLF();
|
|
2368
|
+
break;
|
|
2369
|
+
case INT_SLASH:
|
|
2370
|
+
_skipComment();
|
|
2371
|
+
break;
|
|
2372
|
+
default:
|
|
2373
|
+
if (i < INT_SPACE) {
|
|
2374
|
+
_throwInvalidSpace(i);
|
|
2375
|
+
}
|
|
2376
|
+
break space_loop;
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
if (_inputPtr >= _inputEnd) {
|
|
2380
|
+
loadMoreGuaranteed();
|
|
2381
|
+
}
|
|
2382
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2383
|
+
if (i != INT_COLON) {
|
|
2384
|
+
_reportUnexpectedChar(i, "was expecting a colon to separate field name and value");
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
// either way, found colon, skip through trailing WS
|
|
2389
|
+
while (_inputPtr < _inputEnd || loadMore()) {
|
|
2390
|
+
i = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2391
|
+
if (i > INT_SPACE) {
|
|
2392
|
+
if (i != INT_SLASH) {
|
|
2393
|
+
return i;
|
|
2394
|
+
}
|
|
2395
|
+
_skipComment();
|
|
2396
|
+
} else if (i != INT_SPACE) {
|
|
2397
|
+
if (i == INT_LF) {
|
|
2398
|
+
_skipLF();
|
|
2399
|
+
} else if (i == INT_CR) {
|
|
2400
|
+
_skipCR();
|
|
2401
|
+
} else if (i != INT_TAB) {
|
|
2402
|
+
_throwInvalidSpace(i);
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
throw _constructError("Unexpected end-of-input within/between "+_parsingContext.getTypeDesc()+" entries");
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
private final void _skipComment()
|
|
2410
|
+
throws IOException, JsonParseException
|
|
2411
|
+
{
|
|
2412
|
+
if (!isEnabled(Feature.ALLOW_COMMENTS)) {
|
|
2413
|
+
_reportUnexpectedChar('/', "maybe a (non-standard) comment? (not recognized as one since Feature 'ALLOW_COMMENTS' not enabled for parser)");
|
|
2414
|
+
}
|
|
2415
|
+
// First: check which comment (if either) it is:
|
|
2416
|
+
if (_inputPtr >= _inputEnd && !loadMore()) {
|
|
2417
|
+
_reportInvalidEOF(" in a comment");
|
|
2418
|
+
}
|
|
2419
|
+
int c = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2420
|
+
if (c == INT_SLASH) {
|
|
2421
|
+
_skipCppComment();
|
|
2422
|
+
} else if (c == INT_ASTERISK) {
|
|
2423
|
+
_skipCComment();
|
|
2424
|
+
} else {
|
|
2425
|
+
_reportUnexpectedChar(c, "was expecting either '*' or '/' for a comment");
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
private final void _skipCComment()
|
|
2430
|
+
throws IOException, JsonParseException
|
|
2431
|
+
{
|
|
2432
|
+
// Need to be UTF-8 aware here to decode content (for skipping)
|
|
2433
|
+
final int[] codes = CharTypes.getInputCodeComment();
|
|
2434
|
+
|
|
2435
|
+
// Ok: need the matching '*/'
|
|
2436
|
+
while ((_inputPtr < _inputEnd) || loadMore()) {
|
|
2437
|
+
int i = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
2438
|
+
int code = codes[i];
|
|
2439
|
+
if (code != 0) {
|
|
2440
|
+
switch (code) {
|
|
2441
|
+
case INT_ASTERISK:
|
|
2442
|
+
if (_inputBuffer[_inputPtr] == INT_SLASH) {
|
|
2443
|
+
++_inputPtr;
|
|
2444
|
+
return;
|
|
2445
|
+
}
|
|
2446
|
+
break;
|
|
2447
|
+
case INT_LF:
|
|
2448
|
+
_skipLF();
|
|
2449
|
+
break;
|
|
2450
|
+
case INT_CR:
|
|
2451
|
+
_skipCR();
|
|
2452
|
+
break;
|
|
2453
|
+
case 2: // 2-byte UTF
|
|
2454
|
+
_skipUtf8_2(i);
|
|
2455
|
+
break;
|
|
2456
|
+
case 3: // 3-byte UTF
|
|
2457
|
+
_skipUtf8_3(i);
|
|
2458
|
+
break;
|
|
2459
|
+
case 4: // 4-byte UTF
|
|
2460
|
+
_skipUtf8_4(i);
|
|
2461
|
+
break;
|
|
2462
|
+
default: // e.g. -1
|
|
2463
|
+
// Is this good enough error message?
|
|
2464
|
+
_reportInvalidChar(i);
|
|
2465
|
+
}
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
_reportInvalidEOF(" in a comment");
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2471
|
+
private final void _skipCppComment()
|
|
2472
|
+
throws IOException, JsonParseException
|
|
2473
|
+
{
|
|
2474
|
+
// Ok: need to find EOF or linefeed
|
|
2475
|
+
final int[] codes = CharTypes.getInputCodeComment();
|
|
2476
|
+
while ((_inputPtr < _inputEnd) || loadMore()) {
|
|
2477
|
+
int i = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
2478
|
+
int code = codes[i];
|
|
2479
|
+
if (code != 0) {
|
|
2480
|
+
switch (code) {
|
|
2481
|
+
case INT_LF:
|
|
2482
|
+
_skipLF();
|
|
2483
|
+
return;
|
|
2484
|
+
case INT_CR:
|
|
2485
|
+
_skipCR();
|
|
2486
|
+
return;
|
|
2487
|
+
case INT_ASTERISK: // nop for these comments
|
|
2488
|
+
break;
|
|
2489
|
+
case 2: // 2-byte UTF
|
|
2490
|
+
_skipUtf8_2(i);
|
|
2491
|
+
break;
|
|
2492
|
+
case 3: // 3-byte UTF
|
|
2493
|
+
_skipUtf8_3(i);
|
|
2494
|
+
break;
|
|
2495
|
+
case 4: // 4-byte UTF
|
|
2496
|
+
_skipUtf8_4(i);
|
|
2497
|
+
break;
|
|
2498
|
+
default: // e.g. -1
|
|
2499
|
+
// Is this good enough error message?
|
|
2500
|
+
_reportInvalidChar(i);
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
|
|
2506
|
+
@Override
|
|
2507
|
+
protected final char _decodeEscaped()
|
|
2508
|
+
throws IOException, JsonParseException
|
|
2509
|
+
{
|
|
2510
|
+
if (_inputPtr >= _inputEnd) {
|
|
2511
|
+
if (!loadMore()) {
|
|
2512
|
+
_reportInvalidEOF(" in character escape sequence");
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2515
|
+
int c = (int) _inputBuffer[_inputPtr++];
|
|
2516
|
+
|
|
2517
|
+
switch ((int) c) {
|
|
2518
|
+
// First, ones that are mapped
|
|
2519
|
+
case INT_b:
|
|
2520
|
+
return '\b';
|
|
2521
|
+
case INT_t:
|
|
2522
|
+
return '\t';
|
|
2523
|
+
case INT_n:
|
|
2524
|
+
return '\n';
|
|
2525
|
+
case INT_f:
|
|
2526
|
+
return '\f';
|
|
2527
|
+
case INT_r:
|
|
2528
|
+
return '\r';
|
|
2529
|
+
|
|
2530
|
+
// And these are to be returned as they are
|
|
2531
|
+
case INT_QUOTE:
|
|
2532
|
+
case INT_SLASH:
|
|
2533
|
+
case INT_BACKSLASH:
|
|
2534
|
+
return (char) c;
|
|
2535
|
+
|
|
2536
|
+
case INT_u: // and finally hex-escaped
|
|
2537
|
+
break;
|
|
2538
|
+
|
|
2539
|
+
default:
|
|
2540
|
+
return _handleUnrecognizedCharacterEscape((char) _decodeCharForError(c));
|
|
2541
|
+
}
|
|
2542
|
+
|
|
2543
|
+
// Ok, a hex escape. Need 4 characters
|
|
2544
|
+
int value = 0;
|
|
2545
|
+
for (int i = 0; i < 4; ++i) {
|
|
2546
|
+
if (_inputPtr >= _inputEnd) {
|
|
2547
|
+
if (!loadMore()) {
|
|
2548
|
+
_reportInvalidEOF(" in character escape sequence");
|
|
2549
|
+
}
|
|
2550
|
+
}
|
|
2551
|
+
int ch = (int) _inputBuffer[_inputPtr++];
|
|
2552
|
+
int digit = CharTypes.charToHex(ch);
|
|
2553
|
+
if (digit < 0) {
|
|
2554
|
+
_reportUnexpectedChar(ch, "expected a hex-digit for character escape sequence");
|
|
2555
|
+
}
|
|
2556
|
+
value = (value << 4) | digit;
|
|
2557
|
+
}
|
|
2558
|
+
return (char) value;
|
|
2559
|
+
}
|
|
2560
|
+
|
|
2561
|
+
protected int _decodeCharForError(int firstByte)
|
|
2562
|
+
throws IOException, JsonParseException
|
|
2563
|
+
{
|
|
2564
|
+
int c = (int) firstByte;
|
|
2565
|
+
if (c < 0) { // if >= 0, is ascii and fine as is
|
|
2566
|
+
int needed;
|
|
2567
|
+
|
|
2568
|
+
// Ok; if we end here, we got multi-byte combination
|
|
2569
|
+
if ((c & 0xE0) == 0xC0) { // 2 bytes (0x0080 - 0x07FF)
|
|
2570
|
+
c &= 0x1F;
|
|
2571
|
+
needed = 1;
|
|
2572
|
+
} else if ((c & 0xF0) == 0xE0) { // 3 bytes (0x0800 - 0xFFFF)
|
|
2573
|
+
c &= 0x0F;
|
|
2574
|
+
needed = 2;
|
|
2575
|
+
} else if ((c & 0xF8) == 0xF0) {
|
|
2576
|
+
// 4 bytes; double-char with surrogates and all...
|
|
2577
|
+
c &= 0x07;
|
|
2578
|
+
needed = 3;
|
|
2579
|
+
} else {
|
|
2580
|
+
_reportInvalidInitial(c & 0xFF);
|
|
2581
|
+
needed = 1; // never gets here
|
|
2582
|
+
}
|
|
2583
|
+
|
|
2584
|
+
int d = nextByte();
|
|
2585
|
+
if ((d & 0xC0) != 0x080) {
|
|
2586
|
+
_reportInvalidOther(d & 0xFF);
|
|
2587
|
+
}
|
|
2588
|
+
c = (c << 6) | (d & 0x3F);
|
|
2589
|
+
|
|
2590
|
+
if (needed > 1) { // needed == 1 means 2 bytes total
|
|
2591
|
+
d = nextByte(); // 3rd byte
|
|
2592
|
+
if ((d & 0xC0) != 0x080) {
|
|
2593
|
+
_reportInvalidOther(d & 0xFF);
|
|
2594
|
+
}
|
|
2595
|
+
c = (c << 6) | (d & 0x3F);
|
|
2596
|
+
if (needed > 2) { // 4 bytes? (need surrogates)
|
|
2597
|
+
d = nextByte();
|
|
2598
|
+
if ((d & 0xC0) != 0x080) {
|
|
2599
|
+
_reportInvalidOther(d & 0xFF);
|
|
2600
|
+
}
|
|
2601
|
+
c = (c << 6) | (d & 0x3F);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
return c;
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
/*
|
|
2609
|
+
/**********************************************************
|
|
2610
|
+
/* Internal methods,UTF8 decoding
|
|
2611
|
+
/**********************************************************
|
|
2612
|
+
*/
|
|
2613
|
+
|
|
2614
|
+
private final int _decodeUtf8_2(int c)
|
|
2615
|
+
throws IOException, JsonParseException
|
|
2616
|
+
{
|
|
2617
|
+
if (_inputPtr >= _inputEnd) {
|
|
2618
|
+
loadMoreGuaranteed();
|
|
2619
|
+
}
|
|
2620
|
+
int d = (int) _inputBuffer[_inputPtr++];
|
|
2621
|
+
if ((d & 0xC0) != 0x080) {
|
|
2622
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2623
|
+
}
|
|
2624
|
+
return ((c & 0x1F) << 6) | (d & 0x3F);
|
|
2625
|
+
}
|
|
2626
|
+
|
|
2627
|
+
private final int _decodeUtf8_3(int c1)
|
|
2628
|
+
throws IOException, JsonParseException
|
|
2629
|
+
{
|
|
2630
|
+
if (_inputPtr >= _inputEnd) {
|
|
2631
|
+
loadMoreGuaranteed();
|
|
2632
|
+
}
|
|
2633
|
+
c1 &= 0x0F;
|
|
2634
|
+
int d = (int) _inputBuffer[_inputPtr++];
|
|
2635
|
+
if ((d & 0xC0) != 0x080) {
|
|
2636
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2637
|
+
}
|
|
2638
|
+
int c = (c1 << 6) | (d & 0x3F);
|
|
2639
|
+
if (_inputPtr >= _inputEnd) {
|
|
2640
|
+
loadMoreGuaranteed();
|
|
2641
|
+
}
|
|
2642
|
+
d = (int) _inputBuffer[_inputPtr++];
|
|
2643
|
+
if ((d & 0xC0) != 0x080) {
|
|
2644
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2645
|
+
}
|
|
2646
|
+
c = (c << 6) | (d & 0x3F);
|
|
2647
|
+
return c;
|
|
2648
|
+
}
|
|
2649
|
+
|
|
2650
|
+
private final int _decodeUtf8_3fast(int c1)
|
|
2651
|
+
throws IOException, JsonParseException
|
|
2652
|
+
{
|
|
2653
|
+
c1 &= 0x0F;
|
|
2654
|
+
int d = (int) _inputBuffer[_inputPtr++];
|
|
2655
|
+
if ((d & 0xC0) != 0x080) {
|
|
2656
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2657
|
+
}
|
|
2658
|
+
int c = (c1 << 6) | (d & 0x3F);
|
|
2659
|
+
d = (int) _inputBuffer[_inputPtr++];
|
|
2660
|
+
if ((d & 0xC0) != 0x080) {
|
|
2661
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2662
|
+
}
|
|
2663
|
+
c = (c << 6) | (d & 0x3F);
|
|
2664
|
+
return c;
|
|
2665
|
+
}
|
|
2666
|
+
|
|
2667
|
+
/**
|
|
2668
|
+
* @return Character value <b>minus 0x10000</c>; this so that caller
|
|
2669
|
+
* can readily expand it to actual surrogates
|
|
2670
|
+
*/
|
|
2671
|
+
private final int _decodeUtf8_4(int c)
|
|
2672
|
+
throws IOException, JsonParseException
|
|
2673
|
+
{
|
|
2674
|
+
if (_inputPtr >= _inputEnd) {
|
|
2675
|
+
loadMoreGuaranteed();
|
|
2676
|
+
}
|
|
2677
|
+
int d = (int) _inputBuffer[_inputPtr++];
|
|
2678
|
+
if ((d & 0xC0) != 0x080) {
|
|
2679
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2680
|
+
}
|
|
2681
|
+
c = ((c & 0x07) << 6) | (d & 0x3F);
|
|
2682
|
+
|
|
2683
|
+
if (_inputPtr >= _inputEnd) {
|
|
2684
|
+
loadMoreGuaranteed();
|
|
2685
|
+
}
|
|
2686
|
+
d = (int) _inputBuffer[_inputPtr++];
|
|
2687
|
+
if ((d & 0xC0) != 0x080) {
|
|
2688
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2689
|
+
}
|
|
2690
|
+
c = (c << 6) | (d & 0x3F);
|
|
2691
|
+
if (_inputPtr >= _inputEnd) {
|
|
2692
|
+
loadMoreGuaranteed();
|
|
2693
|
+
}
|
|
2694
|
+
d = (int) _inputBuffer[_inputPtr++];
|
|
2695
|
+
if ((d & 0xC0) != 0x080) {
|
|
2696
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
/* note: won't change it to negative here, since caller
|
|
2700
|
+
* already knows it'll need a surrogate
|
|
2701
|
+
*/
|
|
2702
|
+
return ((c << 6) | (d & 0x3F)) - 0x10000;
|
|
2703
|
+
}
|
|
2704
|
+
|
|
2705
|
+
private final void _skipUtf8_2(int c)
|
|
2706
|
+
throws IOException, JsonParseException
|
|
2707
|
+
{
|
|
2708
|
+
if (_inputPtr >= _inputEnd) {
|
|
2709
|
+
loadMoreGuaranteed();
|
|
2710
|
+
}
|
|
2711
|
+
c = (int) _inputBuffer[_inputPtr++];
|
|
2712
|
+
if ((c & 0xC0) != 0x080) {
|
|
2713
|
+
_reportInvalidOther(c & 0xFF, _inputPtr);
|
|
2714
|
+
}
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
/* Alas, can't heavily optimize skipping, since we still have to
|
|
2718
|
+
* do validity checks...
|
|
2719
|
+
*/
|
|
2720
|
+
private final void _skipUtf8_3(int c)
|
|
2721
|
+
throws IOException, JsonParseException
|
|
2722
|
+
{
|
|
2723
|
+
if (_inputPtr >= _inputEnd) {
|
|
2724
|
+
loadMoreGuaranteed();
|
|
2725
|
+
}
|
|
2726
|
+
//c &= 0x0F;
|
|
2727
|
+
c = (int) _inputBuffer[_inputPtr++];
|
|
2728
|
+
if ((c & 0xC0) != 0x080) {
|
|
2729
|
+
_reportInvalidOther(c & 0xFF, _inputPtr);
|
|
2730
|
+
}
|
|
2731
|
+
if (_inputPtr >= _inputEnd) {
|
|
2732
|
+
loadMoreGuaranteed();
|
|
2733
|
+
}
|
|
2734
|
+
c = (int) _inputBuffer[_inputPtr++];
|
|
2735
|
+
if ((c & 0xC0) != 0x080) {
|
|
2736
|
+
_reportInvalidOther(c & 0xFF, _inputPtr);
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
|
|
2740
|
+
private final void _skipUtf8_4(int c)
|
|
2741
|
+
throws IOException, JsonParseException
|
|
2742
|
+
{
|
|
2743
|
+
if (_inputPtr >= _inputEnd) {
|
|
2744
|
+
loadMoreGuaranteed();
|
|
2745
|
+
}
|
|
2746
|
+
int d = (int) _inputBuffer[_inputPtr++];
|
|
2747
|
+
if ((d & 0xC0) != 0x080) {
|
|
2748
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2749
|
+
}
|
|
2750
|
+
if (_inputPtr >= _inputEnd) {
|
|
2751
|
+
loadMoreGuaranteed();
|
|
2752
|
+
}
|
|
2753
|
+
d = (int) _inputBuffer[_inputPtr++];
|
|
2754
|
+
if ((d & 0xC0) != 0x080) {
|
|
2755
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2756
|
+
}
|
|
2757
|
+
if (_inputPtr >= _inputEnd) {
|
|
2758
|
+
loadMoreGuaranteed();
|
|
2759
|
+
}
|
|
2760
|
+
d = (int) _inputBuffer[_inputPtr++];
|
|
2761
|
+
if ((d & 0xC0) != 0x080) {
|
|
2762
|
+
_reportInvalidOther(d & 0xFF, _inputPtr);
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
/*
|
|
2767
|
+
/**********************************************************
|
|
2768
|
+
/* Internal methods, input loading
|
|
2769
|
+
/**********************************************************
|
|
2770
|
+
*/
|
|
2771
|
+
|
|
2772
|
+
/**
|
|
2773
|
+
* We actually need to check the character value here
|
|
2774
|
+
* (to see if we have \n following \r).
|
|
2775
|
+
*/
|
|
2776
|
+
protected final void _skipCR() throws IOException
|
|
2777
|
+
{
|
|
2778
|
+
if (_inputPtr < _inputEnd || loadMore()) {
|
|
2779
|
+
if (_inputBuffer[_inputPtr] == BYTE_LF) {
|
|
2780
|
+
++_inputPtr;
|
|
2781
|
+
}
|
|
2782
|
+
}
|
|
2783
|
+
++_currInputRow;
|
|
2784
|
+
_currInputRowStart = _inputPtr;
|
|
2785
|
+
}
|
|
2786
|
+
|
|
2787
|
+
protected final void _skipLF() throws IOException
|
|
2788
|
+
{
|
|
2789
|
+
++_currInputRow;
|
|
2790
|
+
_currInputRowStart = _inputPtr;
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
private int nextByte()
|
|
2794
|
+
throws IOException, JsonParseException
|
|
2795
|
+
{
|
|
2796
|
+
if (_inputPtr >= _inputEnd) {
|
|
2797
|
+
loadMoreGuaranteed();
|
|
2798
|
+
}
|
|
2799
|
+
return _inputBuffer[_inputPtr++] & 0xFF;
|
|
2800
|
+
}
|
|
2801
|
+
|
|
2802
|
+
/*
|
|
2803
|
+
/**********************************************************
|
|
2804
|
+
/* Internal methods, error reporting
|
|
2805
|
+
/**********************************************************
|
|
2806
|
+
*/
|
|
2807
|
+
|
|
2808
|
+
protected void _reportInvalidChar(int c)
|
|
2809
|
+
throws JsonParseException
|
|
2810
|
+
{
|
|
2811
|
+
// Either invalid WS or illegal UTF-8 start char
|
|
2812
|
+
if (c < INT_SPACE) {
|
|
2813
|
+
_throwInvalidSpace(c);
|
|
2814
|
+
}
|
|
2815
|
+
_reportInvalidInitial(c);
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
protected void _reportInvalidInitial(int mask)
|
|
2819
|
+
throws JsonParseException
|
|
2820
|
+
{
|
|
2821
|
+
_reportError("Invalid UTF-8 start byte 0x"+Integer.toHexString(mask));
|
|
2822
|
+
}
|
|
2823
|
+
|
|
2824
|
+
protected void _reportInvalidOther(int mask)
|
|
2825
|
+
throws JsonParseException
|
|
2826
|
+
{
|
|
2827
|
+
_reportError("Invalid UTF-8 middle byte 0x"+Integer.toHexString(mask));
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
protected void _reportInvalidOther(int mask, int ptr)
|
|
2831
|
+
throws JsonParseException
|
|
2832
|
+
{
|
|
2833
|
+
_inputPtr = ptr;
|
|
2834
|
+
_reportInvalidOther(mask);
|
|
2835
|
+
}
|
|
2836
|
+
|
|
2837
|
+
public static int[] growArrayBy(int[] arr, int more)
|
|
2838
|
+
{
|
|
2839
|
+
if (arr == null) {
|
|
2840
|
+
return new int[more];
|
|
2841
|
+
}
|
|
2842
|
+
int[] old = arr;
|
|
2843
|
+
int len = arr.length;
|
|
2844
|
+
arr = new int[len + more];
|
|
2845
|
+
System.arraycopy(old, 0, arr, 0, len);
|
|
2846
|
+
return arr;
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2849
|
+
/*
|
|
2850
|
+
/**********************************************************
|
|
2851
|
+
/* Binary access
|
|
2852
|
+
/**********************************************************
|
|
2853
|
+
*/
|
|
2854
|
+
|
|
2855
|
+
/**
|
|
2856
|
+
* Efficient handling for incremental parsing of base64-encoded
|
|
2857
|
+
* textual content.
|
|
2858
|
+
*/
|
|
2859
|
+
protected byte[] _decodeBase64(Base64Variant b64variant)
|
|
2860
|
+
throws IOException, JsonParseException
|
|
2861
|
+
{
|
|
2862
|
+
ByteArrayBuilder builder = _getByteArrayBuilder();
|
|
2863
|
+
|
|
2864
|
+
//main_loop:
|
|
2865
|
+
while (true) {
|
|
2866
|
+
// first, we'll skip preceding white space, if any
|
|
2867
|
+
int ch;
|
|
2868
|
+
do {
|
|
2869
|
+
if (_inputPtr >= _inputEnd) {
|
|
2870
|
+
loadMoreGuaranteed();
|
|
2871
|
+
}
|
|
2872
|
+
ch = (int) _inputBuffer[_inputPtr++] & 0xFF;
|
|
2873
|
+
} while (ch <= INT_SPACE);
|
|
2874
|
+
int bits = b64variant.decodeBase64Char(ch);
|
|
2875
|
+
if (bits < 0) { // reached the end, fair and square?
|
|
2876
|
+
if (ch == INT_QUOTE) {
|
|
2877
|
+
return builder.toByteArray();
|
|
2878
|
+
}
|
|
2879
|
+
bits = _decodeBase64Escape(b64variant, ch, 0);
|
|
2880
|
+
if (bits < 0) { // white space to skip
|
|
2881
|
+
continue;
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
int decodedData = bits;
|
|
2885
|
+
|
|
2886
|
+
// then second base64 char; can't get padding yet, nor ws
|
|
2887
|
+
|
|
2888
|
+
if (_inputPtr >= _inputEnd) {
|
|
2889
|
+
loadMoreGuaranteed();
|
|
2890
|
+
}
|
|
2891
|
+
ch = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2892
|
+
bits = b64variant.decodeBase64Char(ch);
|
|
2893
|
+
if (bits < 0) {
|
|
2894
|
+
bits = _decodeBase64Escape(b64variant, ch, 1);
|
|
2895
|
+
}
|
|
2896
|
+
decodedData = (decodedData << 6) | bits;
|
|
2897
|
+
|
|
2898
|
+
// third base64 char; can be padding, but not ws
|
|
2899
|
+
if (_inputPtr >= _inputEnd) {
|
|
2900
|
+
loadMoreGuaranteed();
|
|
2901
|
+
}
|
|
2902
|
+
ch = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2903
|
+
bits = b64variant.decodeBase64Char(ch);
|
|
2904
|
+
|
|
2905
|
+
// First branch: can get padding (-> 1 byte)
|
|
2906
|
+
if (bits < 0) {
|
|
2907
|
+
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
|
|
2908
|
+
// as per [JACKSON-631], could also just be 'missing' padding
|
|
2909
|
+
if (ch == '"' && !b64variant.usesPadding()) {
|
|
2910
|
+
decodedData >>= 4;
|
|
2911
|
+
builder.append(decodedData);
|
|
2912
|
+
return builder.toByteArray();
|
|
2913
|
+
}
|
|
2914
|
+
bits = _decodeBase64Escape(b64variant, ch, 2);
|
|
2915
|
+
}
|
|
2916
|
+
if (bits == Base64Variant.BASE64_VALUE_PADDING) {
|
|
2917
|
+
// Ok, must get padding
|
|
2918
|
+
if (_inputPtr >= _inputEnd) {
|
|
2919
|
+
loadMoreGuaranteed();
|
|
2920
|
+
}
|
|
2921
|
+
ch = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2922
|
+
if (!b64variant.usesPaddingChar(ch)) {
|
|
2923
|
+
throw reportInvalidBase64Char(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'");
|
|
2924
|
+
}
|
|
2925
|
+
// Got 12 bits, only need 8, need to shift
|
|
2926
|
+
decodedData >>= 4;
|
|
2927
|
+
builder.append(decodedData);
|
|
2928
|
+
continue;
|
|
2929
|
+
}
|
|
2930
|
+
}
|
|
2931
|
+
// Nope, 2 or 3 bytes
|
|
2932
|
+
decodedData = (decodedData << 6) | bits;
|
|
2933
|
+
// fourth and last base64 char; can be padding, but not ws
|
|
2934
|
+
if (_inputPtr >= _inputEnd) {
|
|
2935
|
+
loadMoreGuaranteed();
|
|
2936
|
+
}
|
|
2937
|
+
ch = _inputBuffer[_inputPtr++] & 0xFF;
|
|
2938
|
+
bits = b64variant.decodeBase64Char(ch);
|
|
2939
|
+
if (bits < 0) {
|
|
2940
|
+
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
|
|
2941
|
+
// as per [JACKSON-631], could also just be 'missing' padding
|
|
2942
|
+
if (ch == '"' && !b64variant.usesPadding()) {
|
|
2943
|
+
decodedData >>= 2;
|
|
2944
|
+
builder.appendTwoBytes(decodedData);
|
|
2945
|
+
return builder.toByteArray();
|
|
2946
|
+
}
|
|
2947
|
+
bits = _decodeBase64Escape(b64variant, ch, 3);
|
|
2948
|
+
}
|
|
2949
|
+
if (bits == Base64Variant.BASE64_VALUE_PADDING) {
|
|
2950
|
+
/* With padding we only get 2 bytes; but we have
|
|
2951
|
+
* to shift it a bit so it is identical to triplet
|
|
2952
|
+
* case with partial output.
|
|
2953
|
+
* 3 chars gives 3x6 == 18 bits, of which 2 are
|
|
2954
|
+
* dummies, need to discard:
|
|
2955
|
+
*/
|
|
2956
|
+
decodedData >>= 2;
|
|
2957
|
+
builder.appendTwoBytes(decodedData);
|
|
2958
|
+
continue;
|
|
2959
|
+
}
|
|
2960
|
+
}
|
|
2961
|
+
// otherwise, our triplet is now complete
|
|
2962
|
+
decodedData = (decodedData << 6) | bits;
|
|
2963
|
+
builder.appendThreeBytes(decodedData);
|
|
2964
|
+
}
|
|
2965
|
+
}
|
|
2966
|
+
}
|