I am working with large json files and memory is a concern. I would like to read one object into memory at a time from file. Is this possible?
In ServiceStack.Text docs it says there is an API using reader/stream
But I can't see how to get that working. The files are too large to deserialize in one go. Is it possible to handle this scenario with SS?
Thanks
No you'll want to use a streaming JSON parser like System.Text.Json Utf8JsonReader, this is the example on System.Text.Json introductory page:
byte[] data = Encoding.UTF8.GetBytes(json);
Utf8JsonReader reader = new Utf8JsonReader(data, isFinalBlock: true, state: default);
while (reader.Read())
{
Console.Write(reader.TokenType);
switch (reader.TokenType)
{
case JsonTokenType.PropertyName:
case JsonTokenType.String:
{
string text = reader.GetString();
Console.Write(" ");
Console.Write(text);
break;
}
case JsonTokenType.Number:
{
int value = reader.GetInt32();
Console.Write(" ");
Console.Write(value);
break;
}
// Other token types elided for brevity
}
Console.WriteLine();
}
Related
I'm looking at the docs, but it does not mention file Upload.
The GraphQl Upload service I need to consume is this one.
Would it be possible with GraphQlClient?
I believe it is possible indeed.
You should build your GraphQlClient or reuse a previous one. Then, you should write the the document (or refer to an existing one using documentName) specifying the variables required. Finally, you assign that variable to a value, which can be any Object (in your case, a file; in my example, an Integer number 1), using the variable method of the RequestSpec.
graphQlClient
.mutate()
.header("Authorization","Basic XXXXX")
.build()
.document("""
query artistaPorId($unId:ID){
artistaPorId(id:$unId){
apellido
}
}
""")
.variable("unId",1)
.retrieve("artistaPorId")
.toEntity(Artista.class)
.subscribe( // handle onNext, onError, etc
);
My schema.graphqls:
type Query {
artistaPorId(id:ID): Artista
}
type Artista {
id: ID
apellido: String
estilo: String
}
I have figured it out with the help of this answner.
This uses Spring WebClient. I just need to figure it out how to extract data from the response (it's a graphql response).
var variables = new LinkedHashMap<String, Object>();
variables.put("cartao", cartao);
variables.put("mime", MediaType.APPLICATION_PDF_VALUE);
variables.put("file", null);
var query = StreamUtils.copyToString(new ClassPathResource("/graphql-documents/UploadPrescriptionMutation.graphql").getInputStream(),
Charset.defaultCharset());
var params = new LinkedHashMap<String, Object>();
params.put("operationName", "upload");
params.put("query", query);
params.put("variables", variables);
MultipartBodyBuilder builder = new MultipartBodyBuilder();
builder.part("operations", objectMapper.writeValueAsString(params));
builder.part("map", "{\"uploaded_file\": [\"variables.file\"]}");
builder.part("uploaded_file", new FileSystemResource(file));
return webClient.post()
.headers(h -> h.setBearerAuth(token))
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(builder.build()))
.retrieve()
.bodyToMono(Prescription_AddPrescriptionDto.class)
.block();
GraphQL file:
mutation upload($file: Prescription_Upload!, $cartao: String!, $mime: String!) {
Prescription_uploadPrescription(
file: $file uploadInfo: {
cardNumber: $cartao
source: UNKNOWN
mime: $mime })
{
id
uploadedAt
deletedAt
expiresAt
source
file
name
cardNumber
identity
status
storage
originalName
extension
}
}
I have a TypeScript server trying to read a JSON object using a Struct but it seems to be partially working only for objects containing a "fields" key which then expects an object as value. Nonetheless, a Struct should work with any JSON object.
Using BloomRPC I am trying the following message:
{
"payload": {
"fields": {
"Hello": {
"whatever": 0
}
}
}
}
The server reads:
{ fields: { Hello: {} } }
If I send:
{
"payload": {
"anotherfield": {
"HelloWorld": {
"whatever": 0
}
}
}
}
I get an empty object on the server.
The simplified protobuf file looks like this:
syntax = "proto3";
import "google/protobuf/struct.proto";
// The service definition.
service TestTicketService {
rpc UpdateTicket (UpdateTicketRequest) returns (UpdateTicketResponse);
}
// The request message containing the required ticket information.
message UpdateTicketRequest {
string ticketId = 1;
google.protobuf.Struct payload = 2;
}
// The response message containing any potential error message
message UpdateTicketResponse {
string error = 1;
}
Any idea why google/protobuf/struct.proto doesn't work as expected?
What really confused me is that I was trying to pass normal JSON objects and expecting to read them. The whole point is that from the client side, the JSON object needs to be encoded in a very specific way.
For example:
"payload": {
"fields": {
"name": {
"stringValue": "joe"
},
"age": {
"numberValue": 28
}
}
}
You can figure out the format of the message by looking at the Struct proto file here: https://googleapis.dev/nodejs/asset/latest/v1_doc_google_protobuf_doc_struct.js.html
The idea of a struct is that you can store arbitrary data - but only simple types: null, number, string, bool, array and object.
This maps perfectly to JSON, and this is not by accident.
The google.protobuf.Struct message has a special JSON representation:
The JSON representation for Struct is JSON object.
So you can parse any JSON string into a protobuf Struct, and when serializing to JSON again, you also get the same JSON string again.
It is important to note that the in-memory representation of the parsed Struct is not equal to a JSON object. Protobuf does not have dynamic fields and has to represent JSON data in a more complicated manner. That is why struct.proto defines some other types.
When you want to create a Struct in JavaScript, it is probably the easiest way to just create the JSON object you want:
var jsonObject = {foo: "bar"};
var jsonString = JSON.stringify(jsonObject);
Now you can parse you Struct from this jsonObject or jsonString and put set resulting Struct as a field value in another protobuf message.
Since you are already using TypeScript, it might be worth checking out one of the alternative TypeScript implementations for protobuf.
I am the author of protobuf-ts. Creating a Struct is pretty straight-forward:
let struct = Struct.fromJson({foo: "bar"});
First, install #types/google-protobuf and:
let rqm = new UpdateTicketRequest();
rqm.setTicketId("1");
rqm.setPayload(Struct.fromJavaScript({
Hello:{
whatever: 0,
}
});
//and call the api....
UpdateTicket(rqm);
I am working on a breakout-type game using Cocos2dx.
I need to make a highscore table. After the game is finished, I'd like to display a page, where player types his username into text field.
I don't know how to add the user input into variable, so I can manipulate it later (mainly saving along with score to display it on the selected scene).
What is the simplest way of doing so?
Approach One:
If you just need to handle keyboard as key-event, It's as easy as these below lines of code:
HelloWorld::init()
{
...
auto keyboardListener = EventListenerKeyboard::create();
keyboardListener->onKeyPressed = [](EventKeyboard::KeyCode keyCode, Event* event)
{
switch (keyCode)
{
case EventKeyboard::KeyCode::KEY_UP_ARROW: /*Jump maybe*/ break;
case EventKeyboard::KeyCode::KEY_DOWN_ARROW: /*Crouch maybe*/ break;
case EventKeyboard::KeyCode::KEY_RIGHT_ARROW: /*Move Right maybe*/ break;
case EventKeyboard::KeyCode::KEY_LEFT_ARROW: /*Move Left maybe*/ break;
}
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
...
return true;
}
I think it's clear enough not to need any extra description.
Approach Two: if you need an input box that user/player can enter string with keyboard and you get what is entered, I recommend to use TextField which is available in cocos2d v3 ( and with some difficulty in v2) and has a full functionality. You can create and initial one of them as:
auto textField = cocos2d::ui::TextField::create("hint: enter here","Arial" , 30);
textField->setTextHorizontalAlignment(cocos2d::TextHAlignment::CENTER);
textField->setTextVerticalAlignment(cocos2d::TextVAlignment::CENTER);
textField->setColor(Color3B(100,100,100));
textField->setMaxLength(10);
textField->setMaxLengthEnabled(true);
textField->setTouchAreaEnabled(true);
textField->setTouchSize(Size(200,400));
textField->setPosition(...);
textField->addEventListener(CC_CALLBACK_2(HelloWorld::textFieldEvent, this));
this->addChild(textField, 10);
You can get entered data any time with std::string enteredData= textField->getString();
You can also do something when user entering text with two event as :
void HelloWorld::textFieldEvent(Ref *pSender, cocos2d::ui::TextField::EventType type)
{
switch (type)
{
case cocos2d::ui::TextField::EventType::ATTACH_WITH_IME:
{
textField->setColor(Color3B::BLACK);
// or whatever elese
break;
}
case cocos2d::ui::TextField::EventType::DETACH_WITH_IME:
{
textField->setColor(Color3B(100,100,100));
// or whatever elese
break;
}
}
}
Enjoy !
We have a small utility program that removes ICC profile, and I'm trying to optimize it.
The current program uses roughly this method to remove an ICC profile:
foreach (var item in doc.ObjectSoup)
{
if (item != null && doc.GetInfo(item.ID, "/ColorSpace*[0]*:Name").Equals("ICCBased", StringComparison.InvariantCultureIgnoreCase))
{
int profileId = doc.GetInfoInt(item.ID, "/ColorSpace*[1]:Ref"); // note the [1]: why is it there?
if (profileId != 0)
{
doc.GetInfo(profileId, "Decompress");
string profileData = doc.GetInfo(profileId, "Stream");
// this outputs the ICC profile raw data, with the profile's name somewhere up top
Console.WriteLine(string.Format("ICC profile for object ID {0}: {1}", item.ID, profileData));
doc.SetInfo(profileId, "Stream", string.Empty);
doc.GetInfo(profileId, "Compress");
}
}
}
Now, I want to optimize it, to be able to remove only some profiles (depending on the names), or only RGB profiles for instance (and keep CMYK ones). So I wanted to use actual objects :
foreach (var item in doc.ObjectSoup)
{
if (doc.GetInfo(item.ID, "Type") == "jpeg") // only work on PixMaps
{
PixMap pm = (PixMap)item;
if (pm.ColorSpaceType == ColorSpaceType.ICCBased)
{
// pm.ColorSpace.IccProfile is always null so I can't really set it to null or Recolor() it because it would change noting
// Also, there should already be an ICC profile (ColorSpaceType = ICCBased) but ColorSpace.IccProfile creates one (which is by design if there is none)
Console.WriteLine(string.Format("ICC profile for object ID {0}: {1}", item.ID, pm.ColorSpace.IccProfile));
}
}
}
Here is a sample program that showcases the problem : https://github.com/tbroust-trepia/abcpdf8-icc-profiles
Am I doing something wrong ? Is there something weird going on with the provided images ?
I'm using ABCPdf 8.
Thanks for your help.
Is there any way to get text(or any other) layer shadow params in Adobe Photoshop CS5 using ExtendScript for further convertion to CSS3 like text string?
Thanks!
There is a way.
You have to use the ActionManager:
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref).getObjectValue(stringIDToTypeID('layerEffects')).getObjectValue(stringIDToTypeID('dropShadow'));
desc.getUnitDoubleValue(stringIDToTypeID('distance'))
Where "dropShadow" is the layereffect you want to read and for example "distance" is the parameter that will be returned. Other layereffects and parameters are only known as eventids. Look in the documentation (bad documented) if you need other eventids.
The next AM-Code will check if there is a layerstyle shadow.
var res = false;
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var hasFX = executeActionGet(ref).hasKey(stringIDToTypeID('layerEffects'));
if ( hasFX ){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
res = executeActionGet(ref).getObjectValue(stringIDToTypeID('layerEffects')).hasKey(stringIDToTypeID('dropShadow'));
}
return res;
This will explain http://forums.adobe.com/thread/714406 more.
If you find a way to SET the shadow, without setting other params, let me know...
Probably not the answer you're looking for but there is really no way to access the individual properties of layer styles from extendscript. The only method in the API (as of CS6) that references layer styles is ArtLayer.applyStyle(name). You actually have to create a style in Photoshop and save to the palette by name in order to use this.
The only thing I can think of is to actually parse the .asl files found in adobe/Adobe Photoshop/presets/styles/ using C/C++. These files contain several layer styles saved in a proprietary format. I haven't found any libraries to parse these files but they may exist.
If you have Photoshop CS6.1 (or later), you can check out the implementation of the "Copy CSS to Clipboard" feature to see how to access the drop shadow parameters.
On Windows, the source code for this is in
Adobe Photoshop CS6\Required\CopyCSSToClipboard.jsx
On the Mac, the source code is in:
Adobe Photoshop CS6/Adobe Photoshop CS6.app/Contents/Required/CopyCSSToClipboard.jsx
(if you're looking in the Finder on the Mac, you'll need to control-click on the Photoshop app icon and select "Show Package Contents" to get to the Contents/Required folder).
Look for the routine cssToClip.addDropShadow for an example of how to extract the information. If you want to use routines from CopyCSSToClipboard.jsx in your own code, add the following snippet to your JSX file:
runCopyCSSFromScript = true;
if (typeof cssToClip == "undefined")
$.evalFile( app.path + "/" + localize("$$$/ScriptingSupport/Required=Required") + "/CopyCSSToClipboard.jsx" );
Also, at the bottom of CopyCSSToClipboard.jsx, there are sample calls to cssToClip.dumpLayerAttr. This is a useful way to explore parameters you may want to access from your scripts that aren't accessible from the Photoshop DOM.
Be forewarned that code in the Required folder is subject to change in future versions.
I was able to make an ActionPrinter method that dumps out a tree of all the data in an action using C# and the photoshop COM wrapper.
The PrintCurrentLayer method will dump all the data in a layer, including all of the Layer Effects data.
static void PrintCurrentLayer(Application ps)
{
var action = new ActionReference();
action.PutEnumerated(ps.CharIDToTypeID("Lyr "), ps.CharIDToTypeID("Ordn"), ps.CharIDToTypeID("Trgt"));
var desc = ps.ExecuteActionGet(action);//.GetObjectValue(ps.StringIDToTypeID("layerEffects"));//.getObjectValue(ps.StringIDToTypeID('dropShadow'));
ActionPrinter(desc);
}
static void ActionPrinter(ActionDescriptor action)
{
for (int i = 0; i < action.Count; i++)
{
var key = action.GetKey(i);
if (action.HasKey(key))
{
//var charId = action.Application.TypeIDToCharID((int)key);
//Debug.WriteLine(charId);
switch (action.GetType(key))
{
case PsDescValueType.psIntegerType:
Debug.WriteLine("{0}: {1}", (PSConstants)key, action.GetInteger(key));
break;
case PsDescValueType.psStringType:
Debug.WriteLine("{0}: \"{1}\"", (PSConstants)key, action.GetString(key));
break;
case PsDescValueType.psBooleanType:
Debug.WriteLine("{0}: {1}", (PSConstants)key, action.GetBoolean(key));
break;
case PsDescValueType.psDoubleType:
Debug.WriteLine("{0}: {1}", (PSConstants)key, action.GetDouble(key));
break;
case PsDescValueType.psUnitDoubleType:
Debug.WriteLine("{0}: {1} {2}", (PSConstants)key, action.GetUnitDoubleValue(key), (PSConstants)action.GetUnitDoubleType(key));
break;
case PsDescValueType.psEnumeratedType:
Debug.WriteLine("{0}: {1} {2}", (PSConstants)key, (PSConstants)action.GetEnumerationType(key), (PSConstants)action.GetEnumerationValue(key));
break;
case PsDescValueType.psObjectType:
Debug.WriteLine($"{(PSConstants)key}: {(PSConstants)action.GetObjectType(key)} ");
Debug.Indent();
ActionPrinter(action.GetObjectValue(key));
Debug.Unindent();
break;
case PsDescValueType.psListType:
var list = action.GetList(key);
Debug.WriteLine($"{(PSConstants)key}: List of {list.Count} Items");
Debug.Indent();
for (int count = 0; count < list.Count; count++)
{
var type = list.GetType(count);
Debug.WriteLine($"{count}: {type} ");
Debug.Indent();
switch (type)
{
case PsDescValueType.psObjectType:
ActionPrinter(list.GetObjectValue(count));
break;
case PsDescValueType.psReferenceType:
var reference = list.GetReference(count);
Debug.WriteLine(" Reference to a {0}", (PSConstants)reference.GetDesiredClass());
break;
case PsDescValueType.psEnumeratedType:
Debug.WriteLine(" {0} {1}", (PSConstants)list.GetEnumerationType(count), (PSConstants)list.GetEnumerationValue(count));
break;
default:
Debug.WriteLine($"UNHANDLED LIST TYPE {type}");
break;
}
Debug.Unindent();
}
Debug.Unindent();
break;
default:
Debug.WriteLine($"{(PSConstants)key} UNHANDLED TYPE {action.GetType(key)}");
break;
}
}
}
}