This is something simple and stupid that I cant just see.
If a new type is defined:
newtype Binary
Constructors
Binary ByteString
Instances:
Eq Binary
Ord Binary
Read Binary
Show Binary
Typeable Binary
Val Binary
How can I deconstruct the Binary value to get the ByteString back?
If I want to save a binary data into mongodb, say a jpg picture, I am able to construct the Val Binary type out of ByteString read from the filesystem. I then insert it into a document.
When I read the data back from the database and take it out of the document I end up with the Binary type and I am sooo stuck with it. I can not get the ByteString type back for use with ByteString.writeFile.
So skipping all the connection stuff the flow is like this:
file <- B.readFile "pic.jpg" -- reading file
let doc = ["file" =: (Binary file)] -- constructing a document to be inserted
run $ insert_ "files" doc -- insert the document
r <- run $ fetch (select [] "files") -- get Either Failure Document back from db
let d = either (error . show) (id ) r -- Get the Document out
let f = at "file" d :: Binary -- Get the data out of the document of type Binary
Thank you.
Assuming your newtype looks like this,
newtype Binary = Binary ByteString
then you can simply pattern match on the constructor to get the ByteString back:
unBinary :: Binary -> ByteString
unBinary (Binary s) = s
Related
I have a ReactiveMongo BSONDocument but I want to write it to a file - I know there's the BSON format (http://bsonspec.org/spec.html) and I want to write it according to those specs, but the problem is that I can't find any method call to do this. I've been able to convert it to an array of Bytes, but the problem begins when I convert to a string, UTF8 format by default.
However the BSON specs require a 32 bit number in the beginning. Is there a library that can do this for me? If not, how can I add string representing a 32 bit number and UTF8 string together without losing the encoding for either or both?
Here's what I've got in Scala:
import reactivemongo.bson.buffer.ArrayBSONBuffer
val doc = BSONDocument("data" -> overall)
val buffer = new ArrayBSONBuffer()
BSONDocument.write(doc, buffer)
val bytes = buffer.array
val str = new String(bytes, Charset.forName("UTF8"))
For reference, I know in Ruby, we can do something like this, but how do I do the same thing with ReactiveMongo?
bson_data = BSON.serialize({data: arr}).to_s
As indicated in the documentation, you can use BSONDocument.pretty(myDoc).
Note that you are using the deprecated/being removed BSON API.
I'm using Akka to develop a server application and I was wondering if there was a "cleaner" way to go about getting a substring of a ByteString - Something like
bytestr.getSubstringAtFor(int start, int len): ByteString
or similar. Right now I'm converting the ByteString to a list, creating another List[Byte], looping over it with a for loop and copying the relevant bytes to my new list, then converting that list of bytes back to a ByteString.
Is there a "cleaner" way to get a substring of a ByteString?
You should be able to use slice to get a contiguous subset of the bytes taking a start index that is inclusive and an end index that is exclusive. For instance, if you had a ByteString wrapping the string "foobar" and wanted to get a ByteString of just "oob" then that would look like this:
val bs = ByteString("foobar")
val subbs = bs.slice(1, 4)
I am trying to get hold of some files content I read from a file via Node.FS.Aff.readTextFile so using asynchrous effects.
However my question is more general.
myFile::forall r. String -> Aff ( fs :: FS | r) (Either Error String)
myFile file = attempt $ readTextFile Node.Encoding.UTF8 file
So I want to get at the Left or Right value. If it where Eff instead of Aff I could use
let x = unsafePerformEff $ myFile "someFile.txt"
Thanks
You should never try to "get at" the value by using unsafePerformEff, as such is truly unsafe and will introduce serious bugs into any larger code base.
Instead, you can use do notation to "get at" the values. For example:
do
result <- attempt $ readTextFile Node.Encoding.UTF8
case result of
Left error -> ...
Right file -> ...
...
Note that there exists no unsafePerformAff, because the computation is asynchronous, and there is no way to block in Javascript runtimes.
I use python-docx to generate word document. the user want that he create a template(in a field description) and when he write for example %(company_logo)s in the template, I replace this expression by the picture of the company that I recupered from the database.
as a first issue, I recupered the logo of a company from the database(Postgresql) and I use this code to replace this expression:
cr.execute("select name, logo_web from res_company where id=%s",[soc_id])
r=cr.fetchone()
if r :
company_name=r[0]
logo_company = r[1]
output = cStringIO.StringIO()
doc = docx.Document()
contenu=contenu % {'company_logo': logo_company, 'company_name': company_name,}
doc.add_paragraph(contenu)
The output was a document word that contains the base 64 code of the image as a string. I decoded this code and I tried to add it as a picture with the following code:
logo_company = base64.b64decode(r[1])
doc.add_picture(logo_company)
But I have this error that tells to me that argument must be the path to the picture.
TypeError: file() argument 1 must be encoded string without NULL bytes, not str
The documentation here explains that the add_picture() method takes a file as an argument. The file can be in the form of a path, or it can be a file-like object, such as an open file or a StringIO object. It cannot accept a bytestring containing the bytes of the image, which is what you've tried to do.
So you'll need to convert the image bytes into a file-like object, perhaps using StringIO(), and hand the resulting file-like object to add_picture(). That will get it working for you. Something like:
logo_file = StringIO(base64.b64decode(r[1]))
doc.add_picture(logo_file)
I have a PDF file at client and i want to send this PDF file on AppServer. How can i send this pdf file at AppServer?
define temp-table ttFileList no-undo
field file-id as integer
field file-content as blob.
create ttFileList.
assign ttFileList.file-id = 1.
copy-lob from file("pdffilename") to ttFileList.file-content.
run DoSomethingWithAPDF on hAppServer
( input table ttFileList ).
This depends on the version of progress you are using, if you are using v9 then you will need to use small chunks of raw data streamed in segments. With OpenEdge (might have been 10.1B) we got CLOB and BLOB support, you can create a procedure which takes a temp-table as an argument.
It also depends on your calling language. For .NET and Java this will get translated into a byte array.
For your app-server create a procedure similar to the following:
def temp-table ObjectTransfer no-undo
field Code as char
field Number as int
field DataContent as blob
field MimeType as char.
procedure AddObjectData:
def input param table for ObjectTransfer.
def var k as int no-undo.
for each ObjectTransfer:
find last ObjectTable no-lock
where ObjectTable.Code = ObjectTransfer.Code
no-error.
if avail ObjectTable then
k = ObjectTable.Number + 1.
else
k = 1.
create ObjectTable.
assign
ObjectTable.Code = ObjectTransfer.Code
ObjectTable.Number = k
ObjectTable.MimeType = ObjectTransfer.MimeType
ObjectTable.DataContent = ObjectTransfer.DataContent
.
end.
end procedure.
Generate proxies, you will now call this from .NET and Java using a simple byte array as an input temp-table data-type.
Use raw datatype, you might need to send the file in chunks. Another alternative is to use character+BASE64.