Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor API, add Parser Interface #13

Merged
merged 8 commits into from
Jul 9, 2018
Merged

Conversation

suyashkumar
Copy link
Contributor

@suyashkumar suyashkumar commented Jul 7, 2018

This change refactors the core go-dicom API to use an interface called Parser. This allows for more elegant dependency injection of items (like channels, previous data elements) with a clean end user api (so that the user doesn't have to worry about passing in those references themselves). Using an interface like this will also make typical testing easier on the end user, and is also more canonical golang imho. This closes #11 and addresses #3. This also puts some plumbing in place for #5.

// Parser represents an entity that can read and parse DICOMs
type Parser interface {
	// Parse DICOM data
	Parse(options ParseOptions) (*DataSet, error)
	// ParseNext reads and parses the next element
	ParseNext(options ParseOptions) *Element

        // The below two should go away as we continue to refactor the library
	DecoderError() error // This should go away as we continue refactors
	Finish() error       // This should maybe go away as we continue refactors
}

Usage:

p, err := dicom.NewParserFromFile("myfile.dcm", nil)
opts := dicom.ParseOptions{DropPixelData: true}

element := p.ParseNext(opts) // parse and return the next dicom element
// or
dataset, err := p.Parse(opts) // parse whole dicom

@suyashkumar suyashkumar self-assigned this Jul 7, 2018
@suyashkumar suyashkumar added the enhancement New feature or request label Jul 7, 2018
}

func (p *parser) ParseNext(options ParseOptions) *Element {
tag := readTag(p.decoder)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function came over mostly as is for the refactor from ReadElement but this will itself need additional refactors to hopefully make it more modular.

const GoDICOMImplementationVersionName = "GODICOM_1_1"

// Parser represents an entity that can read and parse DICOMs
type Parser interface {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new interface! :)
(github keeps collapsing this file because it thinks it's too large of a diff)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was thinking maybe dicom.Reader would be cool, but Parser is maybe more clear? would be nice to pair with dicom.Writer for the writing func in this lib

@@ -57,7 +57,11 @@ func main() {
if err != nil {
panic(err)
}
data, err := dicom.ReadDataSetInBytes(bytes, dicom.ReadOptions{})
p, err := dicom.NewParserFromBytes(bytes, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for folks who just want to parse a file and not do any intermediate header checking we can likely make a helper function to collapse this

// Parse DICOM data
Parse(options ParseOptions) (*DataSet, error)
// ParseNext reads and parses the next element
ParseNext(options ParseOptions) *Element
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From before when this was ReadElement it has not returned an error, rather it sets an error on the dicomio.Decoder...I expect this was done in the past because it is convenient to just have a *Element returned and deal with the errors later (particularly given there seem to be recursive calls to this function)...should see if it makes sense to have this return a canonical error though

@@ -22,7 +22,8 @@ func ParseDICOMDIR(in io.Reader) (recs []DirectoryRecord, err error) {
if err != nil {
return nil, err
}
ds, err := ReadDataSetInBytes(bytes, ReadOptions{})
p, err := NewParserFromBytes(bytes, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deal with this err

@@ -33,7 +33,8 @@ func main() {
dicomlog.SetLevel(math.MaxInt32)
}
path := flag.Arg(0)
parsedData, err := dicom.ReadDataSetFromFile(path, dicom.ReadOptions{DropPixelData: !*extractImages})
p, err := dicom.NewParserFromFile(path, nil)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deal with this err

@suyashkumar suyashkumar changed the title [WIP] Refactor go-dicom API, add Parser Interface [WIP] Refactor API, add Parser Interface Jul 9, 2018
@suyashkumar suyashkumar changed the title [WIP] Refactor API, add Parser Interface Refactor API, add Parser Interface Jul 9, 2018
@suyashkumar suyashkumar merged commit 9504516 into master Jul 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Explore making ReadElement independent of parsedData
1 participant